/* ==========================================================================
   Оформление сайта.

   ВНИМАНИЕ: здесь не должно быть ни одного цвета в виде #hex.
   Все значения берутся из tokens.css. Если нужен новый цвет —
   добавьте токен туда, а сюда поставьте var(--...).
   ========================================================================== */

@import url("tokens.40295fb22639.css");

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--text-primary);
  background-color: var(--bg-page);
  background-image: var(--bg-page-decor);
  background-repeat: no-repeat;
  -webkit-font-smoothing: antialiased;
  /* Длинные слова и адреса (имена файлов, e-mail) переносятся,
     а не распирают страницу вбок на телефоне. */
  overflow-wrap: break-word;
  /* iOS не увеличивает шрифт сам при повороте экрана. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Подвал прижат к низу экрана даже на короткой странице (вход,
     пустой список новостей): фон страницы дотягивается сам, а не
     обрывается сразу под коротким контентом. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.site-header, .site-footer { flex: none; }
body > main { flex: 1 0 auto; }

img, video, iframe { max-width: 100%; }

.container {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--space-4);
}

/* --- Шапка: тёмная, как баннеры олимпиады ------------------------------- */

.site-header {
  position: relative;
  /* Выше .hero (тоже position:relative): иначе она перекрывает собой
     хвост .header-mascot там, где он заходит на её верхний край. */
  z-index: 2;
  background: var(--bg-header);
  color: var(--text-on-dark);
  /* Фирменная полоса под шапкой: оранжевый → лавандовый → синий. */
  border-bottom: 4.5px solid transparent;
  border-image: var(--gradient-stripe) 1;
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 68px;
  flex-wrap: wrap;
}

/* Пингвин в шапке, выглядывает мордой из-под неё: верхний край картинки
   приклеен точно к нижнему краю тёмной панели, будто она его и
   отрезает. Декор, поэтому aria-hidden. На компьютере — слева, на
   телефоне — справа (см. медиазапрос ниже). */
.header-mascot {
  position: absolute;
  left: var(--space-2);
  top: 100%;
  height: 60px;
  width: auto;
  pointer-events: none;
}

.logo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  color: var(--text-on-dark);
  text-decoration: none;
  letter-spacing: 0.02em;
}

.logo img { height: 34px; width: auto; }

/* Семь пунктов в строку помещаются не всегда: на узких экранах меню
   переносится, поэтому зазор по горизонтали больше, чем по вертикали. */
.main-nav { display: flex; gap: var(--space-2) var(--space-5); flex-wrap: wrap; }

.main-nav a {
  color: var(--text-on-dark-muted);
  text-decoration: none;
  font-size: var(--text-sm);
  transition: color var(--transition);
}
.main-nav a:hover { color: var(--text-on-dark); }
.main-nav a[aria-current="page"] {
  color: var(--text-on-dark);
  text-decoration: underline;
  text-decoration-color: var(--color-accent-500);
  text-decoration-thickness: 2px;
  text-underline-offset: 8px;
}

.user-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
}
.user-nav a { color: var(--text-on-dark-muted); text-decoration: none; }
.user-nav a:hover { color: var(--text-on-dark); }
.user-nav .btn-accent, .user-nav .btn-accent:hover { color: var(--button-accent-text); }

.inline-form { display: inline; }
.link-button {
  background: none; border: 0; padding: 0;
  color: var(--text-on-dark-muted); cursor: pointer;
  font-size: var(--text-sm); font-family: inherit;
}
.link-button:hover { color: var(--text-on-dark); }

/* --- Типографика --------------------------------------------------------- */

h1 { font-family: var(--font-display); font-size: var(--text-3xl); line-height: var(--leading-tight); margin: var(--space-6) 0 var(--space-2); }
h2 { font-size: var(--text-xl); margin: var(--space-6) 0 var(--space-2); }

/* Короткая оранжевая черта под заголовком страницы — единственный
   постоянный тёплый акцент в светлой части сайта. */
main > h1::after,
.page-head h1::after,
.not-found h1::after {
  content: "";
  display: block;
  width: 56px;
  height: 4px;
  margin-top: var(--space-3);
  border-radius: var(--radius-full);
  background: var(--gradient-accent);
}
h3 { font-size: var(--text-lg); margin: 0 0 var(--space-2); }

a { color: var(--text-link); }

.muted { color: var(--text-secondary); }
.lead { font-size: var(--text-lg); color: var(--text-secondary); }
.prose { max-width: var(--content-width); }

/* Юридические тексты (политика ПД) — длинные, набираем мельче. */
.legal-text { font-size: var(--text-sm); line-height: 1.55; }
.legal-text h2 { font-size: var(--text-base); margin-top: var(--space-5); }
.legal-text th, .legal-text td { font-size: var(--text-xs); vertical-align: top; }

/* --- Герой на главной ---------------------------------------------------- */

.hero {
  position: relative;
  background: var(--bg-hero);
  color: var(--text-on-dark);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin: var(--space-4) 0 var(--space-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  overflow: hidden;
}
.hero-main { min-width: 0; position: relative; z-index: 1; flex: 1 1 auto; }
.hero h1 { margin: 0 0 var(--space-1); font-size: var(--text-3xl); }
.hero .lead { margin: 0; color: var(--text-on-dark-muted); font-size: var(--text-base); }
.hero .deadline { margin: 0; color: var(--text-on-dark-muted); }
.hero .deadline strong { color: var(--color-accent-500); }
.hero .btn { flex: none; position: relative; z-index: 1; }

/* Кнопка регистрации — под названием олимпиады, примерно на одной
   строке со статусом этапа (а не в правом углу героя). */
.hero-cta-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3);
}

/* Маскот-пингвин фоном в углу героя — чисто декоративный, поэтому
   aria-hidden и без alt-текста. Отражён по горизонтали, чтобы смотрел
   в сторону текста. На узких экранах убираем совсем: там ему негде
   поместиться, не наезжая на текст. */
.hero-mascot {
  position: absolute;
  right: var(--space-5);
  bottom: 0;
  height: 92%;
  max-height: 144px;
  width: auto;
  opacity: 1;
  pointer-events: none;
  z-index: 0;
  transform: scaleX(-1);
  filter: var(--hero-mascot-filter);
}

@media (max-width: 720px) {
  /* Отступ от шапки увеличен в 1.5 раза (16px → 24px): héro начинается
     ниже, оставляя место голове Рядового, которая заходит на его
     верхний край сверху — см. .header-mascot в мобильном медиазапросе. */
  .hero { padding: var(--space-5) var(--space-4); margin-top: var(--space-5); }
  .hero-mascot { display: none; }
}

/* --- Кнопки -------------------------------------------------------------- */

.btn {
  display: inline-block;
  padding: var(--space-3) var(--space-5);
  border: 0;
  border-radius: var(--radius-md);
  background: var(--button-bg);
  color: var(--button-text);
  font-family: inherit;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition);
}
.btn:hover { background: var(--button-bg-hover); }
.btn:active { background: var(--button-bg-active); }
.btn:disabled { background: var(--color-ink-300); cursor: not-allowed; }

.btn-small { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }

/* Кнопка призыва: регистрация и главное действие на экране. Одна на
   экран, не больше — иначе оранжевый перестаёт выделять. Текст тёмный:
   белый на оранжевом не проходит контраст. */
.btn-accent {
  background: var(--gradient-accent);
  color: var(--button-accent-text);
  box-shadow: var(--shadow-accent);
}
.btn-accent:hover { background: var(--gradient-accent-hover); }
.btn-accent:active { background: var(--color-accent-600); }

.btn-secondary {
  background: var(--bg-muted);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
}
.btn-secondary:hover { background: var(--color-surface-alt); }

/* --- Карточки ------------------------------------------------------------ */

.grid {
  display: grid;
  gap: var(--space-4);
  /* min(…, 100%): на экране уже 280px колонка сжимается, а не вылезает. */
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

.card {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  background: var(--bg-card);
  transition: box-shadow var(--transition);
}
.card:hover { box-shadow: var(--shadow-md); border-color: var(--color-lavender-300); }
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }
.card a { text-decoration: none; }
.card a:hover { text-decoration: underline; }

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

table { width: 100%; border-collapse: collapse; margin: var(--space-4) 0; }
th, td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border-default);
  font-size: var(--text-sm);
}
th { color: var(--text-secondary); font-weight: var(--weight-medium); }
tbody tr:hover { background: var(--bg-muted); }

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

form p { margin: 0 0 var(--space-4); }
label { display: block; font-size: var(--text-sm); color: var(--text-secondary); margin-bottom: var(--space-1); }

input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=datetime-local], input[type=time], input[type=tel],
input[type=search], input[type=file], input[type=url], select, textarea {
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--text-primary);
  background: var(--bg-page);
  transition: border-color var(--transition);
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--color-brand-500);
  outline-offset: 1px;
  border-color: var(--color-brand-500);
}
input[type=checkbox] { width: auto; margin-right: var(--space-2); }

/* Галочка слева от подписи, а не отдельной строкой под ней: Django
   выводит подпись первой, разворачиваем порядок. Сама галочка
   крупнее обычной — в неё попадают пальцем. */
form p:has(> input[type=checkbox]) {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  align-items: flex-start;
  gap: var(--space-3);
}
form p:has(> input[type=checkbox]) label { margin: 0; color: var(--text-primary); font-size: var(--text-sm); }
form p > input[type=checkbox] { flex: none; width: 20px; height: 20px; margin: 0; accent-color: var(--color-brand-500); }

.helptext { font-size: var(--text-xs); color: var(--text-secondary); display: block; margin-top: var(--space-1); }
.upload-note-error { color: var(--color-danger-500); }
.errorlist { font-size: var(--text-xs); color: var(--color-danger-500); list-style: none; padding: 0; margin: var(--space-1) 0 0; }

.form-narrow { max-width: 480px; }

.gate ul { margin: var(--space-2) 0; padding-left: var(--space-5); }
.gate p:last-child { margin-bottom: 0; }

/* --- Кабинет участника: шаги до участия и согласие ------------------------ */

.steps { margin: var(--space-5) 0; max-width: var(--content-width); }
.step-list { margin: var(--space-3) 0 0; padding-left: var(--space-5); }
.step-list li { margin-bottom: var(--space-2); }
.step-list li.done { color: var(--text-secondary); text-decoration: line-through; }
.step-list li.done::marker { content: "✓  "; color: var(--color-success-500); }

.form-section {
  border: 0;
  padding: 0;
  margin: 0 0 var(--space-5);
}
.form-section legend {
  font-weight: var(--weight-medium);
  font-size: var(--text-lg);
  margin-bottom: var(--space-3);
  padding: 0;
}
/* Серия и номер документа — в одну строку. */
.field-row { display: grid; grid-template-columns: 2fr 3fr; gap: var(--space-3); }
/* Дата тремя списками: число, месяц, год. */
.profile-form select[name$="_day"], .profile-form select[name$="_month"],
.profile-form select[name$="_year"] { width: auto; display: inline-block; margin-right: var(--space-2); }
.profile-form select[name$="_month"] { min-width: 9em; }

.field-error input, .field-error select, .field-error textarea { border-color: var(--color-danger-500); }

.consent-status {
  max-width: var(--content-width);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--bg-muted);
  border-left: 3px solid var(--color-lavender-300);
  margin-bottom: var(--space-4);
}
.consent-status p { margin: 0 0 var(--space-2); }
.consent-status p:last-child { margin-bottom: 0; }
.consent-approved { border-left-color: var(--color-success-500); }
.consent-rejected, .consent-outdated { border-left-color: var(--color-warning-500); }
.profile-details summary { cursor: pointer; color: var(--text-link); padding: var(--space-2) 0; }
.consent-steps { padding-left: var(--space-5); max-width: var(--content-width); }
.consent-steps > li { margin-bottom: var(--space-4); }

/* Блок решения администратора в форме задачи. */
.moderation {
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--color-brand-500);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-5) 0;
}
.moderation legend { padding: 0 var(--space-2); font-weight: var(--weight-medium); }

/* Ряд кнопок под формой: на телефоне переносятся и встают одинаковой ширины. */
.actions { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }
@media (max-width: 480px) {
  .actions > .btn { flex: 1 1 100%; text-align: center; }
}
.form-wide { max-width: var(--content-width); }

/* --- Статусы и бейджи ---------------------------------------------------- */

.badge {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  background: var(--bg-muted);
  color: var(--text-secondary);
}
.badge.ok   { background: var(--color-success-100); color: var(--color-success-500); }
.badge.warn { background: var(--color-warning-100); color: var(--color-warning-500); }
.badge.err  { background: var(--color-danger-100);  color: var(--color-danger-500); }
.badge.none { background: var(--bg-muted); color: var(--text-secondary); }

.messages { list-style: none; padding: 0; margin: var(--space-4) 0; }
.message {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--bg-muted);
  margin-bottom: var(--space-2);
}
.message.error   { background: var(--color-danger-100);  color: var(--color-danger-500); }
.message.success { background: var(--color-success-100); color: var(--color-success-500); }
.message.warning { background: var(--color-warning-100); color: var(--color-warning-500); }

/* --- Видео --------------------------------------------------------------- */

.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  max-width: 100%;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-space-900);
  box-shadow: var(--shadow-md);
  margin: var(--space-4) 0 var(--space-5);
}

/* На широком экране плеер выходит за колонку текста — лекцию
   смотрят, а не читают, поэтому картинке отдаём больше места. */
@media (min-width: 1180px) {
  .video-frame {
    width: calc(100% + var(--space-8));
    margin-inline: calc(var(--space-7) * -1);
  }
}
.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* --- Плейлисты ----------------------------------------------------------- */

.playlist-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  margin-bottom: var(--space-6);
}

.playlist-card {
  display: grid;
  grid-template-columns: 116px 1fr;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--text-primary);
  background: var(--bg-card);
  transition: box-shadow var(--transition), border-color var(--transition);
}
.playlist-card:hover { box-shadow: var(--shadow-md); border-color: var(--color-brand-500); }

/* Превью: 16:9, чтобы карточки не прыгали, пока грузятся картинки. */
.playlist-cover {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--color-space-900);
}
.playlist-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.playlist-cover svg {
  width: 100%;
  height: 100%;
  padding: 18%;
  fill: var(--color-lavender-300);
}

/* Кружок play поверх обложки — общий знак для всех площадок. */
.playlist-play {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: var(--radius-full);
  background: var(--overlay-dark);
  transition: background var(--transition);
}
.playlist-play::after {
  content: "";
  position: absolute;
  left: 13px;
  top: 10px;
  border-left: 11px solid var(--text-on-dark);
  border-block: 7px solid transparent;
}
.playlist-card:hover .playlist-play { background: var(--color-brand-500); }
.playlist-card .playlist-cover img ~ .playlist-play { background: var(--overlay-dark); }

.playlist-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.playlist-body strong { font-size: var(--text-base); line-height: var(--leading-tight); }

.playlist-meta { display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap; }

.playlist-platform {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}

/* Цвет метки площадки: видно с одного взгляда, где что лежит. */
.platform-vk .playlist-platform { color: var(--color-brand-500); }
.platform-youtube .playlist-platform { color: var(--color-accent-700); }

.playlist-season {
  font-size: var(--text-xs);
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--bg-muted);
  color: var(--text-secondary);
}

.playlist-note {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.4;
}

/* --- Карта --------------------------------------------------------------- */

#map {
  height: 520px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-default);
}

/* --- Подвал -------------------------------------------------------------- */

.site-footer {
  background: var(--bg-footer);
  color: var(--text-on-dark-muted);
  margin-top: var(--space-8);
  padding: var(--space-6) 0;
  font-size: var(--text-sm);
}
.site-footer {
  position: relative;
  border-top: 4.5px solid transparent;
  border-image: var(--gradient-stripe) 1;
}
.site-footer a { color: var(--color-lavender-300); }
.site-footer a:hover { color: var(--color-accent-500); }

/* Пингвин сидит на градиентной линии подвала справа: нижний край
   картинки утоплен в полосу, чтобы лапы стояли прямо на линии. */
.footer-mascot {
  position: absolute;
  right: var(--space-5);
  bottom: calc(100% - 2px);
  height: 128px;
  width: auto;
  pointer-events: none;
}

.footer-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
}
.footer-grid p { margin: 0 0 var(--space-2); }

.footer-title {
  color: var(--text-on-dark);
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-3);
}

.footer-links { list-style: none; padding: 0; margin: 0; }
.footer-links li { margin-bottom: var(--space-2); }

/* Логотипы спонсоров — мелко, в одну строку, чтобы не растягивать
   подвал по высоте: по размеру примерно как заголовок колонки. */
.footer-sponsors { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.footer-sponsors img { height: 28px; width: auto; max-width: 100%; opacity: 0.9; }

@media (max-width: 720px) {
  .footer-sponsors img { height: 22px; }
}

/* --- Мобильные ----------------------------------------------------------- */

/* Рассчитано на ширину 360–430px (большинство смартфонов) и не
   ломается до 320px (iPhone SE первого поколения). */
@media (max-width: 720px) {
  /* Первая строка — логотип и вход, вторая — меню во всю ширину.
     Меню не переносится на несколько строк, а листается вбок:
     пять пунктов в две кривые строки читаются хуже одной ленты. */
  .header-inner {
    gap: var(--space-2) var(--space-3);
    padding-block: var(--space-3) 0;
    min-height: 0;
  }
  /* На телефоне — справа, а не слева, и так же приклеен к шапке
     (top: 100% из базового правила) — без зазора до полосы. */
  .header-mascot { left: auto; right: var(--space-3); }
  .footer-mascot { right: var(--space-3); }
  .user-nav { gap: var(--space-3); margin-left: auto; }
  .main-nav + .user-nav { margin-left: auto; }
  .main-nav {
    order: 3;
    width: calc(100% + 2 * var(--space-4));
    margin-inline: calc(var(--space-4) * -1);
    padding: var(--space-1) var(--space-4) 0;
    flex-wrap: nowrap;
    gap: var(--space-5);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .main-nav::-webkit-scrollbar { display: none; }
  .main-nav a {
    flex: none;
    white-space: nowrap;
    /* Палец, а не курсор: высота пункта не меньше 44px. */
    padding: var(--space-3) 0;
    border-bottom: 2px solid transparent;
  }
  .main-nav a[aria-current="page"] { border-bottom-color: var(--color-accent-500); text-decoration: none; }

  h1 { font-size: var(--text-2xl); margin-top: var(--space-5); }
  h2 { margin-top: var(--space-5); }
  .lead { font-size: var(--text-base); }
  .hero { padding: var(--space-5) var(--space-4); }
  .hero h1 { font-size: var(--text-2xl); }
  .card { padding: var(--space-4); }
  #map { height: 380px; }
  .site-footer { margin-top: var(--space-7); }

  /* Кнопка отправки формы — во всю ширину: в неё проще попасть. */
  .form-narrow .btn[type=submit], .form-wide .btn[type=submit] { width: 100%; }
  .filter-bar { gap: var(--space-3); }
  .filter-bar label, .filter-bar select { width: 100%; }

  /* Таблицы-матрицы (ведомость баллов) по-прежнему прокручиваются
     внутри себя, чтобы вбок не уезжала вся страница. Списочные
     таблицы помечены .table-stack и превращаются в карточки ниже. */
  table:not(.table-stack):not(.table-fit) { display: block; overflow-x: auto; }
  table:not(.table-stack):not(.table-fit) th,
  table:not(.table-stack):not(.table-fit) td { min-width: 72px; }
  /* .table-fit — узкие таблицы, которые и так помещаются в экран. */
  .table-fit th, .table-fit td { padding: var(--space-3) var(--space-2); }
  .score-table th:first-child, .score-table td:first-child {
    position: sticky; left: 0; z-index: 1; background: var(--bg-page);
  }
  /* 16px в поле ввода — иначе iOS увеличивает страницу при фокусе. */
  .score-table input { font-size: var(--text-base); width: 4em; }
}

@media (max-width: 480px) {
  .playlist-card { grid-template-columns: 96px 1fr; gap: var(--space-3); }
}

/* На самых узких экранах шапка должна уместиться в одну строку:
   админка с телефона всё равно неудобна, ссылка на неё остаётся
   в кабинете и на широком экране. */
@media (max-width: 480px) {
  .user-nav { gap: var(--space-2); }
  .nav-admin { display: none; }
  .logo { font-size: var(--text-base); }
}

/* --- Таблица-список на телефоне ------------------------------------------ */

/* Строка таблицы становится карточкой: подпись столбца (data-label)
   слева, значение справа. Так на телефоне видно всё сразу, и не надо
   листать таблицу вбок в поисках статуса или балла. */
@media (max-width: 640px) {
  .table-stack, .table-stack tbody, .table-stack tr, .table-stack td, .table-stack th {
    display: block;
  }
  .table-stack thead { display: none; }
  .table-stack tr {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--bg-card);
  }
  .table-stack tbody tr:hover { background: var(--bg-card); }
  .table-stack td, .table-stack th {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border-default);
    text-align: right;
  }
  .table-stack td:last-child, .table-stack th:last-child { border-bottom: 0; }
  .table-stack td > * { min-width: 0; margin: 0; }
  .table-stack td > div { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); }
  .table-stack td::before {
    content: attr(data-label);
    flex: none;
    color: var(--text-secondary);
    text-align: left;
  }
  /* Первая ячейка — заголовок карточки, без подписи и крупнее. */
  .table-stack td:first-child {
    display: block;
    text-align: left;
    font-size: var(--text-base);
    font-weight: var(--weight-medium);
  }
  .table-stack td:first-child::before { content: none; }
  /* Ячейка без подписи (ссылка «Проверить →») — кнопкой справа. */
  .table-stack td:not([data-label]):not(:first-child) { justify-content: flex-end; }
  .table-stack td:not([data-label])::before { content: none; }
  .table-stack td[colspan] { display: block; text-align: left; }
  .table-stack .table-total { display: flex; justify-content: space-between; }
  .table-stack .table-total th { border: 0; padding: var(--space-1) 0; }
}

/* --- Панель организатора ------------------------------------------------- */

/* Показывается только организаторам: добавить площадку, проверить решения.
   Намеренно неяркая — это служебный блок поверх обычной страницы. */
.organizer-bar {
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--color-brand-500);
  border-radius: var(--radius-md);
  background: var(--bg-muted);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-6);
}

.organizer-bar-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.organizer-bar ul {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.organizer-bar ul:last-child { margin-bottom: 0; }
.organizer-bar li { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* --- Проверка решений ---------------------------------------------------- */

/* Файлы слева, форма оценки справа: смотреть и оценивать приходится
   одновременно, и прокручивать туда-сюда не хочется. */
.review-grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 900px) {
  .review-grid { grid-template-columns: 1fr 340px; }
}

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: end;
  margin-bottom: var(--space-5);
}

.filter-bar label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.file-list { list-style: none; padding: 0; margin: var(--space-3) 0; }
.file-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-default);
}
.file-list li > a:first-child { overflow-wrap: anywhere; min-width: 0; }
.file-download { margin-left: auto; font-size: var(--text-sm); }

/* --- Моё решение (страница задачи) --------------------------------------- */

.my-solution { margin: var(--space-5) 0; max-width: var(--content-width); }
.my-solution-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
}
.my-solution-head h2 { margin: 0; }
.my-solution-comment, .my-solution-grade {
  margin: var(--space-3) 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--bg-muted);
}
.my-solution-comment > p:first-child, .my-solution-grade > p:first-child { margin-top: 0; }
.my-solution-comment > :last-child, .my-solution-grade > :last-child { margin-bottom: 0; }
.my-solution-history { margin-top: var(--space-3); }
.my-solution-history summary { cursor: pointer; color: var(--text-link); padding: var(--space-2) 0; }
.my-solution-history ul { padding-left: var(--space-5); }
.my-solution-history li { margin-bottom: var(--space-2); overflow-wrap: anywhere; }
.cell-files a { overflow-wrap: anywhere; }

/* Формулы KaTeX и код шире экрана телефона листаются внутри себя. */
.katex-display { overflow-x: auto; overflow-y: hidden; padding-block: var(--space-1); }
pre { overflow-x: auto; }
.prose img { height: auto; }

/* Пояснение к равноценным форматам тура: заметнее обычного текста,
   но не тревожное — это не предупреждение, а развилка выбора. */
.note {
  border-left: 3px solid var(--color-lavender-300);
  background: var(--bg-muted);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  max-width: var(--content-width);
}

/* --- Роль в шапке -------------------------------------------------------- */

/* Организатор и администратор должны видеть, под кем они вошли: иначе
   легко принять свой вид сайта за то, что видит школьник. */
.role-tag {
  font-size: 11px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-accent-700);
  color: var(--text-on-dark);
  white-space: nowrap;
}

/* --- Рисунок к задаче ---------------------------------------------------- */

.problem-figure {
  margin: var(--space-5) 0;
  max-width: var(--content-width);
}
.problem-figure img {
  max-width: 100%;
  height: auto;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-card);
}
.problem-figure figcaption {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

/* --- Ведомость баллов ---------------------------------------------------- */

/* Задач может быть много: таблица прокручивается вбок, а не ломает страницу. */
.table-scroll { overflow-x: auto; margin-bottom: var(--space-4); }

.score-table th, .score-table td { white-space: nowrap; }
.score-table input {
  width: 4.5em;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.score-table input:focus-visible { outline: 2px solid var(--color-brand-500); outline-offset: 1px; }

/* --- Список площадок организатора ---------------------------------------- */

/* Площадок может быть много: строка на площадку читается, а вереница
   ссылок в строку — нет. */
.venue-table { width: 100%; margin: 0; }
.venue-table th, .venue-table td { padding: var(--space-2) var(--space-3); }

/* Подсказка под картой: расходится ли выбранная точка с указанным регионом. */
.map-hint-warn {
  color: var(--color-warning-500);
  font-size: var(--text-sm);
}

/* --- Фотогалерея --------------------------------------------------------- */

/* Ровно три в ряд: шесть финалов ложатся в две ровные строки.
   На планшете — две колонки, на телефоне — одна. */
.photo-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-bottom: var(--space-6);
}

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

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

.photo { margin: 0; }
.photo a { display: block; }
.photo a:focus-visible img { outline: 2px solid var(--color-brand-500); outline-offset: 2px; }

/* 3:2 — компромисс между двумя форматами, в которых сняты финалы:
   при 4:3 у широких кадров срезало бы края с людьми. */
.photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-default);
  background: var(--bg-muted);
  display: block;
}

.photo figcaption {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  text-align: center;
}

.photo-year {
  display: inline-block;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-lavender-100);
  color: var(--color-space-700);
  font-size: var(--text-xs);
}

/* --- Схема проведения олимпиады (главная) -------------------------------- */

/* Три вложенные области показывают структуру олимпиады без лишних слов:
   чем глубже вложенность, тем насыщеннее фон. Карточки при этом остаются
   белыми и различимыми на любом из трёх фонов. */

.scheme { margin-bottom: var(--space-6); }

/* Скруглённые углы у всех трёх областей. Внутренняя скругляется на
   величину отступа меньше внешней — так дуги вложенных углов идут
   параллельно, а не «разъезжаются». */
.scheme-all {
  display: grid;
  grid-template-columns: minmax(0, 3fr) auto minmax(190px, 1fr);
  align-items: stretch;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--scheme-radius);
  background: var(--scheme-bg-all);
  box-shadow: var(--shadow-sm);
}

.scheme-qualifying {
  padding: var(--space-4);
  border-radius: calc(var(--scheme-radius) - var(--space-2));
  background: var(--scheme-bg-qualifying);
}

.scheme-label {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-space-800);
}

.scheme-qualifying-row {
  display: grid;
  grid-template-columns: minmax(0, 2fr) auto minmax(170px, 1fr);
  align-items: stretch;
  gap: var(--space-4);
}

.scheme-primary {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: calc(var(--scheme-radius) - var(--space-3));
  background: var(--scheme-bg-primary);
}

/* Два равнозначных формата — рядом, одинаковой ширины и высоты. */
.scheme-primary-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  align-items: stretch;
  flex: 1;
}

.scheme-note {
  margin: 0;
  text-align: center;
  font-size: var(--text-xs);
  /* Тёмно-синий по самому насыщенному фону: на лавандовом
     обычный вторичный серый теряет контраст. */
  color: var(--color-space-900);
}

.scheme-second, .scheme-final { display: flex; }

/* --- Карточка этапа ------------------------------------------------------ */

.stage-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-3);
  /* Рамка темнее обычной: на насыщенной лавандовой подложке светло-серая
     граница пропадает, и белая карточка сливается с фоном. Этот тон
     держит контраст не ниже 4.8 на всех трёх подложках. */
  border: 1px solid var(--color-space-600);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  color: var(--text-primary);
  text-align: center;
  text-decoration: none;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}

.stage-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--color-accent-500);
}

/* Финал — цель всей олимпиады: единственная карточка с тёплым акцентом. */
.scheme-final .stage-card {
  border-color: var(--color-accent-500);
  box-shadow: inset 0 3px 0 var(--color-accent-500);
}
.scheme-final .stage-card-icon { color: var(--color-accent-700); }

.stage-card:focus-visible {
  outline: 2px solid var(--color-brand-700);
  outline-offset: 2px;
}

.stage-card-icon {
  width: 34px;
  height: 34px;
  margin-bottom: var(--space-1);
  color: var(--color-brand-500);
}

.stage-card-title {
  font-weight: 600;
  font-size: var(--text-base);
  line-height: 1.2;
}

.stage-card-dates { font-size: var(--text-sm); color: var(--text-secondary); }
.stage-card-place { font-size: var(--text-xs); color: var(--text-secondary); }

/* Стрелка между группами. Небольшая, но оранжевая: показывает, куда
   двигаться дальше, — это и есть «путь участника». */
.scheme-arrow {
  align-self: center;
  width: 16px;
  height: 10px;
  background: var(--color-accent-700);
  clip-path: polygon(0 35%, 55% 35%, 55% 0, 100% 50%, 55% 100%, 55% 65%, 0 65%);
}

/* На узком экране схема разворачивается вертикально, стрелки — вниз.
   Горизонтальная прокрутка как способ смотреть схему не годится. */
@media (max-width: 560px) {
  .scheme-all { padding: var(--space-3); gap: var(--space-3); }
  .scheme-qualifying, .scheme-primary { padding: var(--space-3); }
  .scheme-qualifying-row { gap: var(--space-3); }
  .stage-card { padding: var(--space-3); }
}

@media (max-width: 860px) {
  .scheme-all, .scheme-qualifying-row { grid-template-columns: minmax(0, 1fr); }
  .scheme-primary-cards { grid-template-columns: minmax(0, 1fr); }
  .scheme-arrow {
    justify-self: center;
    width: 10px;
    height: 16px;
    clip-path: polygon(35% 0, 35% 55%, 0 55%, 50% 100%, 100% 55%, 65% 55%, 65% 0);
  }
}

/* --- Архив лекций -------------------------------------------------------- */

/* Полсотни записей: заголовок темы держит строку взгляда, сам список —
   плотный, чтобы раздел целиком умещался на экране. */
.topic-title {
  margin: var(--space-5) 0 var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--color-space-700);
}

.lecture-list { list-style: none; margin: 0; padding: 0; }

.lecture-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-default);
}

.lecture-list a { font-weight: var(--weight-medium); }

/* --- Заголовок страницы с маскотом ---------------------------------------- */

/* Заголовок и вводный абзац слева, пингвин справа — стоит на нижней
   линии блока. У каждого раздела свой пингвин, чтобы разделы узнавались
   с одного взгляда. */
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
}
.page-head > :first-child { min-width: 0; flex: 1; }
.page-head > :first-child > :last-child { margin-bottom: 0; }
.page-mascot {
  flex: none;
  width: auto;
  height: 72px;
  margin-bottom: calc(var(--space-2) * -1);
  pointer-events: none;
}

@media (max-width: 720px) {
  .page-mascot { height: 52px; }
}

/* Принудительный перенос строки — только на телефоне, например
   в длинном заголовке страницы. */
.br-mobile-only { display: none; }
@media (max-width: 720px) {
  .br-mobile-only { display: inline; }
}

/* --- Пустые состояния с маскотом ------------------------------------------ */

/* «Новостей пока нет», «архив пуст» и т.п. — маскот делает голое
   сообщение дружелюбнее. Картинка декоративная (alt=""), сам текст
   всё ещё несёт смысл для скринридера. */
.empty-state {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) 0;
}
.empty-state img { flex: none; width: 72px; height: 72px; }
.empty-state img.empty-state-mascot--lg { width: 108px; height: 108px; }
.empty-state .muted { margin: 0; }

/* Маленький пингвин в пустой строке таблицы. */
.cell-mascot { display: inline-flex; align-items: center; gap: var(--space-3); }
.cell-mascot img { flex: none; width: 40px; height: 40px; }

/* --- Страница 404 --------------------------------------------------------- */

.not-found {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  margin: var(--space-7) 0;
}
.not-found img { flex: none; width: 240px; height: auto; }
.not-found h1 { margin-top: 0; }

@media (max-width: 640px) {
  .not-found { flex-direction: column; align-items: flex-start; gap: var(--space-4); }
  .not-found img { width: 160px; }
}
