:root {
  --bg-cream: #F7F2E8;
  --bg-warm: #FBF6EB;
  --bg-paper: #FFFFFF;
  --ink: #1F2937;
  --ink-mid: #4B5563;
  --ink-light: #6B7280;
  --navy: #1A365D;
  --navy-deep: #0F2A4A;
  --red: #B91C1C;
  --red-soft: #DC2626;
  --green: #15803D;
  --gold: #B8893E;
  --tan: #E8DCC4;
  --border: #E2D9C7;
  --shadow-sm: 0 1px 2px rgba(20,30,50,0.04), 0 2px 4px rgba(20,30,50,0.04);
  --shadow-md: 0 4px 12px rgba(20,30,50,0.06), 0 2px 4px rgba(20,30,50,0.04);
  --shadow-lg: 0 12px 32px rgba(20,30,50,0.10), 0 4px 8px rgba(20,30,50,0.05);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* HTML-атрибут `hidden` обязан полностью скрывать элемент даже у тех,
   у кого по классу задан display: flex/grid/inline-* (например, у нас
   `#admin-zone.submit-row` или `#screen-quiz.container`). Без этого
   `[hidden]` от user-agent проигрывает по специфичности и админская
   зона остаётся видна обычному участнику без `?olga`. */
[hidden] { display: none !important; }
body {
  margin: 0;
  font-family: 'Onest', system-ui, -apple-system, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg-cream);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

h1, h2, h3 {
  font-family: 'Spectral', Georgia, serif;
  color: var(--navy-deep);
  margin: 0;
  font-weight: 600;
  line-height: 1.2;
}
h1 { font-size: clamp(2rem, 4.5vw, 2.8rem); }
h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); }

p { margin: 0.5em 0; }
a { color: var(--navy); }

.container {
  max-width: 880px;
  margin: 0 auto;
  padding: 24px;
}
/* Экран банка задач (админ) — растягиваем во всю доступную ширину экрана,
   чтобы две колонки «условие | решение» в карточке шаблона получили
   достаточно места для рисунков и длинных решений с дробями. На узких
   экранах падение до 880px происходит само (max-width не вытягивает за viewport). */
#screen-bank.container,
#screen-stats.container,
#screen-board.container { max-width: 1280px; }

.top-bar {
  background: var(--navy-deep);
  color: #F0EFEB;
  padding: 14px 0;
}
.top-bar .container {
  padding-top: 0;
  padding-bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}
.top-bar .brand {
  font-family: 'Spectral', serif;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}
.top-bar .brand strong { color: #fff; }
.top-bar .brand .muted { color: #D8C490; }
.top-bar .home {
  font-size: 0.9rem;
  color: #D8C490;
  text-decoration: none;
  border-bottom: 1px dotted #D8C490;
  padding-bottom: 1px;
}

.btn {
  display: inline-block;
  padding: 14px 28px;
  border-radius: 8px;
  font-family: 'Onest', sans-serif;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all 0.15s ease;
  text-align: center;
}
.btn-primary { background: var(--navy); color: #fff; border-color: var(--navy); }
.btn-primary:hover { background: var(--navy-deep); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-primary:disabled { background: #94a3b8; border-color: #94a3b8; cursor: not-allowed; transform: none; }
.btn-ghost { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-ghost:hover { background: var(--navy); color: #fff; }
.btn-accent { background: var(--red); color: #fff; border-color: var(--red); }
.btn-accent:hover { background: var(--red-soft); transform: translateY(-1px); }

.card {
  background: var(--bg-paper);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  box-shadow: var(--shadow-md);
}

.eyebrow {
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  font-weight: 600;
}

/* ========== START ========== */
.intro h1 { margin-top: 8px; margin-bottom: 8px; }
/* Подпись под H1. На банке.html строка длинная — стягиваем шрифт чуть меньше,
   чтобы помещалась на одной строке на ноутбучных экранах. На телефоне
   браузер сам перенесёт куда удобно. */
.intro .lead {
  font-size: clamp(0.95rem, 1.8vw, 1.02rem);
  color: var(--ink-mid);
  line-height: 1.4;
}
.bank-mode .intro .lead { font-size: clamp(0.92rem, 1.6vw, 1rem); }
.rules {
  margin-top: 18px;
  padding: 18px 22px;
  background: var(--bg-warm);
  border-left: 3px solid var(--gold);
  border-radius: 0 10px 10px 0;
}
.rules ul { margin: 6px 0 0; padding-left: 22px; }
.rules li { margin: 4px 0; }

.start-form { margin-top: 28px; display: grid; gap: 14px; }
.start-form label { font-weight: 500; font-size: 0.95rem; color: var(--ink-mid); }
.start-form input[type=email],
.start-form input[type=text] {
  font-family: 'Onest', sans-serif;
  font-size: 1.05rem;
  padding: 12px 14px;
  border: 2px solid var(--border);
  border-radius: 8px;
  background: #fff;
  outline: none;
  transition: border-color 0.15s;
  width: 100%;
}
.start-form input:focus { border-color: var(--navy); }
.start-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 540px) { .start-form .row { grid-template-columns: 1fr; } }
.start-form .submit-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.hint { color: var(--ink-light); font-size: 0.88rem; }

/* ========== ВЫБОР ТЕМ — КАРТОЧКИ ========== */
/* Двухуровневая навигация: одна большая тема активна (раскрыта), внутри —
   чекбоксы подтем. Клик по заголовку другой карточки переключает активную.
   Иконка слева + название + короткое описание + метка «N подтем · M шаблонов». */
.topic-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 6px;
  align-items: start;
}
.topic-card {
  border: 2px solid var(--border);
  border-radius: 14px;
  background: #fff;
  overflow: hidden;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}
.topic-card:hover {
  border-color: var(--gold);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.topic-card.active {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(26, 54, 93, 0.08);
  grid-column: 1 / -1;       /* активная карточка во всю ширину */
  transform: none;
}
.topic-card-head {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 16px 18px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
}
.topic-card.active .topic-card-head {
  background: #FFFBEB;
  border-bottom: 1px solid var(--border);
}
.topic-card-icon {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--bg-warm);
  color: var(--navy-deep);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Spectral', Georgia, serif;
  font-size: 1.55rem;
  font-weight: 600;
  border: 1.5px solid var(--border);
  transition: all 0.2s;
  line-height: 1;
}
.topic-card:hover .topic-card-icon {
  border-color: var(--gold);
  background: #FFF7E0;
}
.topic-card.active .topic-card-icon {
  background: var(--navy-deep);
  color: #F0C871;
  border-color: var(--navy-deep);
}
.topic-card-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.topic-card-name {
  font-family: 'Spectral', serif;
  font-weight: 600;
  font-size: 1.1rem;
  color: var(--navy-deep);
  line-height: 1.25;
}
.topic-card-desc {
  font-size: 0.86rem;
  color: var(--ink-mid);
  line-height: 1.35;
}
.topic-card-meta {
  font-size: 0.78rem;
  color: var(--ink-light);
  margin-top: 2px;
  letter-spacing: 0.02em;
}
.topic-card-subs {
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  padding: 14px 18px 18px;
  background: #FAF6EE;
}
.topic-card.active .topic-card-subs { display: flex; }
.sub-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  font-size: 0.95rem;
  user-select: none;
  transition: border-color 0.15s, background 0.15s;
}
.sub-pill:hover { border-color: var(--gold); }
.sub-pill input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--gold);
  cursor: pointer;
}
.sub-pill.checked {
  border-color: var(--gold);
  background: #FFF7E0;
}
.sub-pill-meta {
  color: var(--ink-light);
  font-size: 0.82rem;
}

/* ========== BANK_MODE — компактные карточки тем на главной банк.html ==========
   На обычной (index.html) странице карточки полные: иконка + описание +
   счётчик подтем. В банке хотим только иконку и название — описание перенесено
   в админский «Банк задач», и при выборе темы появляется кнопка «Начать спринт»
   прямо внутри карточки. */
.bank-mode .topic-card-desc,
.bank-mode .topic-card-meta { display: none; }
.bank-mode .topic-card-head { padding: 12px 14px; gap: 12px; }
.bank-mode .topic-card-icon {
  width: 34px; height: 34px;
  font-size: 1.1rem;
  border-width: 1px;
}
.bank-mode .topic-card-name { font-size: 1rem; }
/* Активная карточка не растягивается на всю ширину сетки — только подсветка. */
.bank-mode .topic-card.active { grid-column: auto; }
.bank-mode .topic-card.active .topic-card-head { border-bottom: 0; }

.topic-card-start {
  display: none;
  margin: 0 14px 14px;
  padding: 8px 16px;
  background: var(--navy-deep);
  color: #F0C871;
  border: 0;
  border-radius: 8px;
  font-family: 'Onest', sans-serif;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.15s;
}
.topic-card-start:hover { background: var(--navy); }
.bank-mode .topic-card.active .topic-card-start { display: inline-block; }

/* Контейнер двух кнопок (Начать спринт + Посмотреть таблицу) в активной
   карточке темы. Если кнопки не помещаются в одну строку — переносятся. */
.topic-card-actions {
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 14px 14px;
}
.bank-mode .topic-card.active .topic-card-actions { display: flex; }
/* Когда кнопка живёт внутри .topic-card-actions, ей не нужны собственные
   margin'ы карточки — контейнер уже их задаёт. */
.topic-card-actions .topic-card-start,
.topic-card-actions .topic-card-view {
  margin: 0;
  display: inline-block;
}
/* «Посмотреть таблицу» — призрачный стиль (вторичная кнопка). */
.topic-card-view {
  padding: 8px 16px;
  background: transparent;
  color: var(--navy-deep);
  border: 1.5px solid var(--navy-deep);
  border-radius: 8px;
  font-family: 'Onest', sans-serif;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.topic-card-view:hover { background: var(--navy-deep); color: #F0C871; }

/* Маленькая третья кнопка «PDF» в карточке темы. Шире не делаем — это
   не основное действие, а удобный шорткат для учителя «скачать готовый
   вариант из 12 задач для распечатки». Если кнопка занята генерацией —
   js/pdf-export.js меняет её текст на «Готовлю…» и ставит disabled. */
.topic-card-pdf {
  padding: 8px 12px;
  background: transparent;
  color: var(--navy-deep);
  border: 1.5px solid var(--navy-deep);
  border-radius: 8px;
  font-family: 'Onest', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, opacity 0.15s;
}
.topic-card-pdf:hover { background: var(--navy-deep); color: #F0C871; }
.topic-card-pdf:disabled { opacity: 0.55; cursor: progress; }
.topic-card-actions .topic-card-pdf { margin: 0; display: inline-block; }

/* Подпись «регистрация обязательна» — тонкая, ненавязчивая. */
.bank-reg-note {
  margin: 0 0 8px;
  color: var(--ink-light);
  font-size: 0.88rem;
  font-weight: 400;
}
.bank-reg-hint { margin: 6px 0 18px; display: block; }
.bank-topic-block { margin-top: 4px; }

/* Большой стартовый CTA. */
.btn-big {
  padding: 16px 36px;
  font-size: 1.08rem;
  border-radius: 10px;
  letter-spacing: 0.01em;
}

/* Кнопка «Завершить» в navy-баре викторины — ненавязчивая, но видимая. */
.btn-finish-early {
  padding: 8px 16px;
  font-size: 0.92rem;
  font-weight: 500;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
  color: #F0EFEB;
  border: 1.5px solid rgba(240, 239, 235, 0.35);
  cursor: pointer;
  transition: all 0.15s;
  font-family: 'Onest', sans-serif;
}
.btn-finish-early:hover {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  border-color: #fff;
}

/* Сообщение об ошибке валидации формы старта. */
.form-error {
  margin-top: 12px;
  padding: 12px 16px;
  background: #FEF2F2;
  border: 1px solid #FCA5A5;
  border-radius: 10px;
  color: var(--red);
  font-size: 0.95rem;
  font-weight: 500;
}
.form-error[hidden] { display: none; }

/* ========== QUIZ ========== */
.quiz-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--navy);
  color: #fff;
  border-radius: 12px;
  padding: 14px 20px;
  margin-bottom: 18px;
  flex-wrap: wrap;
  gap: 10px;
}
.quiz-bar .stat { font-family: 'Spectral', serif; }
.quiz-bar .stat .label { font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: #D8C490; display: block; font-family: 'Onest', sans-serif; }
.quiz-bar .stat .val { font-size: 1.6rem; font-weight: 600; }
.quiz-bar .timer.warn { color: #FCA5A5; }

.problem-area {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 24px;
  align-items: start;
  /* position: relative — чтобы .draw-canvas позиционировался относительно
     этого блока, а не относительно .card. */
  position: relative;
}
/* Полотно для рисования (синий «маркер» 2 px). Перекрывает всю .problem-area,
   но clip-path в draw.js вырезает «дырку» под строку с кнопками ответа,
   так что input и кнопки остаются кликабельными.
   touch-action: none → палец на телефоне рисует, а не скроллит страницу.
   Курсор-карандаш (SVG-data URI, горячая точка на кончике грифеля).  */
.draw-canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  touch-action: none;
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zm17.71-10.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z' fill='%231E40AF' stroke='white' stroke-width='0.6'/></svg>") 3 21, crosshair;
}
/* Иконка-ластик в строке ответа (рядом с «Пропустить»). Высоту подстраиваем
   под соседние .btn (у них padding 14×28), чтобы строка выглядела ровно. */
.btn-erase {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 12px;
  background: transparent;
  border: 2px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  line-height: 0;
}
.btn-erase:hover { background: #F1F5F9; border-color: #CBD5E1; }
.btn-erase:active { background: #E2E8F0; }
.btn-erase svg { display: block; }
.problem-area.no-figure { grid-template-columns: 1fr; }
@media (max-width: 720px) { .problem-area { grid-template-columns: 1fr; } }

.fig-box {
  background: #FAF6EE;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fig-box svg { width: 100%; height: auto; max-width: 360px; }

.task-box .given {
  font-family: 'Spectral', serif;
  font-size: 1.25rem;
  color: var(--ink);
  margin-bottom: 10px;
  line-height: 1.5;
}
.task-box .question {
  font-family: 'Spectral', serif;
  font-size: 1.25rem;
  color: var(--navy-deep);
  margin: 10px 0 16px;
}
/* Само математическое выражение (неравенство, формула) — крупнее окружающего текста. */
.task-box .given .math,
.task-box .question .math,
.solution-card .math,
.bank-given .math,
.bank-question .math {
  font-size: 1.45em;
  letter-spacing: 0.005em;
  white-space: nowrap;
}
/* Длинные математические выражения вроде «(√50 − √18) · √2» при инлайн-подаче
   могут разорваться где-нибудь посередине (например, «· √2» уезжает на
   следующую строку). Поэтому .math в условии и вопросе всегда начинается
   с новой строки: трюк `content: '\A'` в ::before + `white-space: pre` на
   самом спане превращает псевдоэлемент в принудительный перенос строки
   ВНУТРИ .math, а сам спан остаётся в потоке родителя — значит точка/запятая
   после спана продолжает находиться на той же строке, что и math (а не
   повисает в одиночестве на следующей). `pre` к тому же запрещает авто-перенос
   внутри самого выражения, заменяя прежний `nowrap`.
   Применяется ВЕЗДЕ, где условие/вопрос/ответ выводится крупно:
   на quiz-экране (.task-box), в админ-банке (.bank-given/.bank-question)
   и в карточке решения после спринта (.sc-given/.sc-question).
   Внутри тела решения (.sc-solution) — НЕ применяется (там в одном абзаце
   много коротких формул, разделённых `\n`, и собственная строка для каждой
   через `\A` раздувала бы разбор). */
.task-box .given .math,
.task-box .question .math,
.bank-given .math,
.bank-question .math,
.solution-card .sc-given .math,
.solution-card .sc-question .math {
  white-space: pre;
}
.task-box .given .math::before,
.task-box .question .math::before,
.bank-given .math::before,
.bank-question .math::before,
.solution-card .sc-given .math::before,
.solution-card .sc-question .math::before {
  content: '\A';
}
/* .math-i — крупный inline-вариант для коротких обозначений «y = f(x)», «f(x)»,
   «x₀» в условиях задач, где НЕ хочется автоматического переноса на новую
   строку (в отличие от .math). Используется в тексте условия деривативной темы:
   тех, кому нужен «учебниковый» крупный курсив, но условие — это полное
   предложение, которое не должно разрываться вокруг каждого выражения. */
.task-box .given .math-i,
.task-box .question .math-i,
.solution-card .sc-given .math-i,
.solution-card .sc-question .math-i,
.bank-given .math-i,
.bank-question .math-i {
  font-size: 1.55em;
  font-style: italic;
  font-family: 'Spectral', Georgia, serif;
  white-space: nowrap;
}
/* Нижний индекс (например, основание логарифма) — мельче браузерного default
   «smaller» (≈0.83em), иначе при увеличенном размере .math индекс растёт
   слишком крупным. Подбирается так, чтобы при .math 1.45em основание
   логарифма выглядело примерно как раньше или чуть мельче. */
.math sub { font-size: 0.72em; }
/* Внутри <sub> в условии (.math) корень-основание логарифма «висит» на
   уровне log из-за того, что после перехода .rt на inline-flex baseline
   контейнера определяется нижним краем SVG-крючка, а не текстом
   подкоренного — sub-родитель не успевает утянуть корень вниз.
   Compensate'им сдвигом 0.35em вниз — это уровень настоящего sub-индекса
   в типографике. В решении (.bank-solution sub .rt без .math-обвёртки)
   корень опускается естественно и трогать его НЕ нужно — пользователь
   2026-05-12 явно попросила правку только в условии. */
.math sub .rt {
  vertical-align: baseline;
  transform: translateY(0.35em);
}
/* Неразрывная вставка в обычном тексте: для коротких равенств типа «AB = 10»,
   «∠C = 90°» внутри условия задачи, чтобы перенос строки не отрывал имя
   от знака «=» и значения. Без увеличения шрифта (в отличие от .math). */
.nb { white-space: nowrap; }
/* Векторное обозначение «a⃗» для inline-текста условий и решений.
   Реализация через inline-SVG (см. helper vec() в math.js) — Unicode U+20D7
   рендерится не во всех шрифтах, поэтому стрелочка нарисована вручную.
   padding-top + margin-top компенсируют друг друга: ставим стрелочку в зоне
   паддинга над буквой, при этом базовая линия буквы совпадает с окружающим
   текстом. overflow: visible на самом SVG не даёт стрелочке обрезаться. */
.vec {
  display: inline-block;
  position: relative;
  font-style: italic;
  white-space: nowrap;
  padding-top: 0.38em;
  margin-top: -0.38em;
  vertical-align: baseline;
  /* КРИТИЧНО: своя line-height: 1. Без неё `.vec` наследует line-height
     родителя (в `.bank-solution`/`.sc-solution` это 4.2), inline-block
     раздувается на всю высоту строки, и absolutely-позиционированная
     стрелочка `.vec-arr` (top: 0.06em от верха `.vec`) улетает высоко
     над буквой, выглядит «отдельно». Та же логика, что у `.rt` — см.
     комментарий styles.css:898. */
  line-height: 1;
}
.vec-arr {
  position: absolute;
  top: 0.06em;
  left: 50%;
  transform: translateX(-50%);
  width: 0.95em;
  height: 0.32em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
  pointer-events: none;
}
.vec-let { display: inline-block; line-height: 1; }
/* Степени и основания — школьный стиль: показатель повыше и побольше, индекс пониже. */
.task-box sup, .task-box sub,
.solution-card sup, .solution-card sub {
  font-size: 0.7em;
  line-height: 0;
  position: relative;
}
.task-box sup, .solution-card sup { vertical-align: 0.55em; }
.task-box sub, .solution-card sub { vertical-align: -0.3em; font-size: 0.75em; }
/* Если показатель степени — это дробь (внутри sup есть .fr), обычного
   подъёма 0.55em мало: дробь высокая, и её низ оказывается у самой базы,
   из-за чего «4<sup>1/5</sup>» читается как смешанное число «4 1/5».
   Поднимаем такие показатели заметно выше — чтобы низ дроби был ВЫШЕ верха
   основания, как пишут показатель в учебнике. Селектор :has() поддерживается
   во всех современных браузерах.
   ВАЖНО: правило обязано охватывать и `.bank-solution` тоже — иначе в админ-
   режиме (просмотр банка) дробные показатели в решении ложатся на базовую
   линию и читаются как смешанная дробь. */
.task-box sup:has(.fr),
.solution-card sup:has(.fr),
.bank-given sup:has(.fr),
.bank-question sup:has(.fr),
.bank-solution sup:has(.fr) {
  /* Серия 2026-05-12: 1.1 → 1.7 → 2.8em → 5em vertical-align → отказ от
     vertical-align в пользу прямого position+top → !important + transform.
     Пользователь сравнила «36^(1/3) · 36^(1/5) / 36^(1/30)» в Вычислениях:
     показатели стоят прямо рядом с основанием, как смешанная дробь.
     После hard refresh правило по-прежнему «не работает» (визуально).
     Гипотеза: в каскаде где-то теряется по специфичности или из-за того,
     что sup сидит в grid-cell `.fr-n` и position:relative + top плохо
     взаимодействует с inline-grid контейнером. Используем transform:
     translateY(...) — это гарантированный сдвиг, независимый от layout
     и baseline. И !important — чтобы перебить любой каскад точно. */
  display: inline-block !important;
  /* translateY(-2.5em) при font-size 0.45em → подъём ≈ 22 px (em считается
     от font-size самого sup'а: 2.5 × 0.45 × 20px ≈ 22px). Это поднимает
     НИЗ дроби-показателя выше cap-height основания, как в учебнике. */
  transform: translateY(-2.5em) !important;
  vertical-align: baseline !important;
  font-size: 0.45em !important;
  line-height: 1 !important;
  top: 0 !important;
  /* Жирность по просьбе пользователя 2026-05-12 — чтобы маленький дробный
     показатель лучше читался на фоне крупного основания. */
  font-weight: 700 !important;
}
/* В банке задач (admin-режим) показатели тоже стоит подкорректировать,
   на случай если sup попадает в .bank-* без обёрток .task-box/.solution-card.
   `.bank-solution sup` тоже подключен — без этого глобальное правило
   `sup:not(.rt-deg):not(.pow-exp) { top: -0.6em }` отвечает за подъём, но
   оно не учитывает дроби и оставляет 1/5 на уровне основания. */
.bank-given sup, .bank-question sup, .bank-solution sup { font-size: 0.7em; line-height: 0; vertical-align: 0.55em; position: relative; }
.bank-given sub, .bank-question sub, .bank-solution sub { font-size: 0.75em; line-height: 0; vertical-align: -0.3em; position: relative; }

.answer-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.answer-row input {
  font-family: 'Onest', sans-serif;
  font-size: 1.3rem;
  padding: 10px 14px;
  border: 2px solid var(--border);
  border-radius: 8px;
  width: 140px;
  outline: none;
  text-align: center;
}
.answer-row input:focus { border-color: var(--navy); }
.answer-row.correct input { border-color: var(--green); background: #ECFDF5; }
.answer-row.wrong input { border-color: var(--red); background: #FEF2F2; }
.answer-row .btn { padding: 10px 18px; }
/* Кнопка «минус» слева от поля ответа: даёт возможность ввести знак «−»,
   когда стоит числовая клавиатура (inputmode="decimal"), на которой минуса
   нет. По размеру совпадает с полем ввода по высоте. */
.answer-row .btn-minus {
  font-family: 'Onest', sans-serif;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1;
  width: 44px;
  padding: 10px 0;
  border: 2px solid var(--border);
  border-radius: 8px;
  background: #F8FAFC;
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  user-select: none;
}
.answer-row .btn-minus:hover { background: #E2E8F0; }
.answer-row .btn-minus:active { background: #CBD5E1; }

.feedback {
  margin-top: 12px;
  font-size: 0.95rem;
  min-height: 1.4em;
}
.feedback.ok { color: var(--green); font-weight: 600; }
.feedback.bad { color: var(--red); font-weight: 600; }
.round-hint { font-size: 0.85rem; color: var(--ink-light); margin-top: 6px; }

/* ========== RESULT ========== */
.result-head {
  text-align: center;
  margin-bottom: 18px;
}
.result-head .big-num {
  font-family: 'Spectral', serif;
  font-size: clamp(3rem, 9vw, 5.5rem);
  color: var(--gold);
  font-weight: 700;
  line-height: 1;
}
.result-head .label { color: var(--ink-mid); font-size: 1.1rem; }

.result-meta {
  display: flex; gap: 24px; justify-content: center; flex-wrap: wrap;
  margin-top: 8px; color: var(--ink-mid); font-size: 0.95rem;
}
.result-meta b { color: var(--ink); }

.history { margin-top: 24px; }
.history h3 { margin-bottom: 8px; font-size: 1.1rem; color: var(--navy-deep); }
.history-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
  gap: 6px;
}
.history-cell {
  aspect-ratio: 1;
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.85rem; font-weight: 600; color: #fff;
  cursor: pointer;
}
.history-cell.ok { background: var(--green); }
.history-cell.bad { background: var(--red); }
.history-cell.skip { background: #cbd5e1; }
.history-cell { cursor: pointer; transition: transform 0.15s; }
.history-cell:hover { transform: scale(1.08); }
.history-cell.active { outline: 3px solid var(--gold); outline-offset: 2px; }
.history-cell.no-flip { cursor: default; }
.history-cell.no-flip:hover { transform: none; }

/* ========== БАНК ЗАДАЧ (АДМИН) ========== */
.bank-head {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.bank-title {
  flex: 1;
  margin: 0;
  font-size: 1.6rem;
}
.bank-topic {
  margin-bottom: 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
}
.bank-topic-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  background: #FFFBEB;
  border: 0;
  cursor: pointer;
  font-family: 'Spectral', serif;
  font-size: 1.05rem;
  font-weight: 600;
  text-align: left;
  color: var(--navy-deep);
}
.bank-topic-header:hover { background: #FEF3C7; }
.bank-arrow {
  font-size: 0.85rem; color: var(--gold);
  width: 14px; display: inline-block;
  transition: transform 0.2s;
}
.bank-topic.open .bank-arrow { transform: rotate(90deg); }
.bank-topic-name { flex: 1; }
.bank-topic-count {
  color: var(--ink-mid); font-size: 0.88rem; font-weight: 400;
  font-family: 'Onest', sans-serif;
}
.bank-topic-body { padding: 14px 18px; background: #FAFAF9; }

.bank-subtopic {
  margin-bottom: 16px;
}
.bank-subtopic:last-child { margin-bottom: 0; }
.bank-subtopic-title {
  font-family: 'Spectral', serif;
  font-size: 1rem;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 8px;
  padding-left: 4px;
  border-left: 3px solid var(--gold);
  padding-left: 10px;
}
.bank-template {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 16px 14px;
  margin-bottom: 10px;
}
.bank-template-title {
  font-family: 'Onest', sans-serif;
  font-size: 0.78rem;
  color: #94a3b8;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 10px;
}
.bank-examples {
  /* Один пример на шаблон — растягиваем во всю доступную ширину карточки
     шаблона, чтобы две колонки (.bank-front и .bank-back внутри .bank-example)
     получили по половине этой ширины. До правки 2026-05-11 здесь стоял
     auto-fill grid с minmax(280px, 1fr), который при одном ребёнке создавал
     пустые колонки справа — карточки получались узкими. */
  display: block;
  margin-bottom: 10px;
}
/* В банке задач — две колонки рядом: слева условие+вопрос+ответ, справа
   сразу решение. Никаких кликов «перевернуть карточку» — нажатие на
   «🎲 Другой пример» перегенерирует обе колонки одновременно. */
.bank-example {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  background: #F8FAFC;
  border-radius: 8px;
  padding: 14px 16px;
  font-size: 0.92rem;
  line-height: 1.45;
}
.bank-front, .bank-back { min-width: 0; }
.bank-back {
  border-left: 1px solid var(--border);
  padding-left: 16px;
}
/* Единый шрифт и размер для условия / вопроса / «Решение:» / решения
   в правой колонке (2026-05-13, по просьбе пользователя). Раньше label был
   Spectral 1.05rem, а bank-solution — 1.25rem; и условие в bank-given/
   bank-question с .math-обвёрткой ещё крупнее. Теперь всё одной гарнитурой
   ('Onest' от body) и одним размером 1.05rem. */
.bank-back .bank-given,
.bank-back .bank-question,
.bank-back-label,
.bank-solution {
  font-family: 'Onest', sans-serif;
  font-size: 1.05rem;
}
.bank-back-label {
  color: var(--ink);
  margin: 14px 0 6px;
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}
/* «Ответ:» в самом конце карточки решения. Гарнитура и размер — те же,
   что у .bank-back-label / .bank-given / .bank-question / .bank-solution
   (наследует от глобального правила выше). Слово «Ответ:» подчёркнуто
   и жирное; значение — обычным жирным шрифтом. */
.bank-back-answer {
  font-family: 'Onest', sans-serif;
  font-size: 1.05rem;
  color: var(--ink);
  margin-top: 14px;
}
.bank-back-answer-label {
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}
.bank-back-answer b { color: var(--ink); font-weight: 700; }
.bank-solution {
  white-space: pre-wrap;
  color: var(--ink-mid);
  /* Воздух между строками. 1,85 → 2,6 → 2,0 → 3.6 → 4.2 (2026-05-12).
     При font-size 1.05rem (вместо 1.25rem) line-height 4.2 даёт ~70 px
     между строками — достаточно для строк с дробными показателями и
     корнями (значения CSS-paddings в формулах в абсолютных px не
     масштабируются вместе со шрифтом). Согласован с .sc-solution. */
  line-height: 4.2;
}
/* На узких экранах — складываем в одну колонку, чтобы решение читалось
   нормально, а не выжималось в 150 px. */
@media (max-width: 720px) {
  .bank-example { grid-template-columns: 1fr; gap: 12px; }
  .bank-back {
    border-left: none;
    border-top: 1px solid var(--border);
    padding-left: 0;
    padding-top: 12px;
  }
  /* На карточке «Решение» в одноколоночном режиме колонка занимает всю
     ширину экрана — текст прекрасно переносится сам, и принудительные
     переносы (которые нужны на десктопе для узкой правой колонки) только
     дробят строки на короткие куски. Скрываем их (по просьбе пользователя
     2026-05-14: «на телефоне/планшете строки должны переноситься сами»). */
  br.bank-soft-break { display: none; }
  /* Решение использует white-space: pre-wrap, чтобы рендерить \n из исходных
     строк solution как переносы. На узком экране сворачиваем в обычный
     поток — текст течёт естественно по доступной ширине. */
  .bank-solution,
  .sc-solution { white-space: normal; }
  /* В мини-чертеже банка max-width 270/340 px — на телефоне он становится
     слишком маленьким относительно полной ширины экрана. Растягиваем до
     100% ширины колонки (но не больше «настоящего» размера 540 px). */
  .bank-back .bank-example-fig.bank-fig-mini { max-width: 100%; }
  .bank-back .bank-example-fig.bank-fig-mini svg.figure { max-width: 100%; }
}
.bank-example-fig {
  margin-bottom: 6px;
  text-align: center;
}
.bank-example-fig svg.figure {
  width: 100%; max-width: 540px; height: auto;
}
/* Крупные чертежи в банке (для задач, где фигуре нужно больше места:
   прямоугольный треугольник с медианой/высотой/биссектрисой и т. п.).
   Класс ставится из fig_*-функций через svgFrame(parts, 'figure-large').
   При max-width 540 (увеличение по просьбе 2026-05-12) figure-large
   совпадает с базовой — отдельный кейс остался для будущего расширения. */
.bank-example-fig svg.figure.figure-large {
  max-width: 540px;
}
/* Увеличение фигур в банке (240→540 px = ~5× по площади) повысило бы и
   экранный размер меток (font-size в viewBox-юнитах × scale). Чтобы метки
   не стали гигантскими, уменьшаем их шрифт в контейнере .bank-example-fig.
   Для обычных фигур: было 22×240/360 ≈ 14,7 px на экране, стало 12×540/360
   = 18 px (чуть крупнее, соразмерно увеличенной фигуре). */
.bank-example-fig svg.figure .lbl,
.bank-example-fig svg.figure .num { font-size: 12px; }
.bank-example-fig svg.figure .ang { font-size: 10px; }
.bank-example-fig svg.figure .axis-lbl { font-size: 10px; }
.bank-example-fig svg.figure .vec-name { font-size: 12px; }
.bank-example-fig svg.figure.figure-large .lbl,
.bank-example-fig svg.figure.figure-large .num { font-size: 9px; }
.bank-example-fig svg.figure.figure-large .ang { font-size: 8px; }
.bank-example-fig svg.figure.figure-large .axis-lbl { font-size: 8px; }
.bank-example-fig svg.figure.figure-large .vec-name { font-size: 9px; }
/* Уменьшенная копия чертежа в колонке «Решение» (admin-банк). Линейный
   размер примерно в 2 раза меньше, чем в условии слева — это «напоминалка»
   о том, что было дано. Шрифт меток внутри SVG увеличиваем в viewBox-
   единицах, чтобы при сжатии в 2× они не стали совсем мелкими на экране. */
.bank-back .bank-example-fig.bank-fig-mini {
  max-width: 270px;
  margin: 0 auto 8px;
}
.bank-back .bank-example-fig.bank-fig-mini svg.figure,
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large {
  max-width: 270px;
}
.bank-back .bank-example-fig.bank-fig-mini svg.figure .lbl,
.bank-back .bank-example-fig.bank-fig-mini svg.figure .num { font-size: 20px; }
/* В мини-чертеже (карточка «Решение») единички 1 на осях не жирные
   (по просьбе пользователя 2026-05-13). В большой версии в условии
   остаются жирными — глобальное правило svg.figure .num font-weight: 700. */
.bank-back .bank-example-fig.bank-fig-mini svg.figure .num { font-weight: 400; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure .ang { font-size: 17px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure .axis-lbl { font-size: 17px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure .vec-name { font-size: 20px; }
/* «figure-large» (планиметрия — сложные задачи с биссектрисой / медианой /
   высотой и т. п., где много меток на одну фигуру) спроектирован с тесной
   разметкой: в условии .lbl/.num задано 9 px в viewBox-единицах, что при
   540 px display даёт ~13 px на экране. В мини (270 px) нужен пропорциональный
   bump: 15 px viewBox даёт ~11 px на экране — читаемо, без раздувания меток
   относительно тесной фигуры. Если оставить общий 20 px без этого override,
   метки бы «надулись» и заходили друг на друга на маленьком чертеже. */
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large .lbl,
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large .num { font-size: 15px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large .ang { font-size: 13px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large .axis-lbl { font-size: 13px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure.figure-large .vec-name { font-size: 15px; }

/* Жирность подписей на мини-чертежах решения (только для отдельных тем).
   .fig-light-all  — все подписи нежирные: и буквы (.lbl, .vec-name), и цифры
                     (.num, .ang, .axis-lbl). Используется стереометрией —
                     там «жирные» буквы в трёхмерных чертежах сливаются
                     с рёбрами фигуры.
   .fig-light-nums — нежирные только цифры. Используется в векторах —
                     там единичные отрезки «1» на осях были слишком толстыми
                     (по просьбе пользователя 2026-05-14).
   Применяются как на админ-банке (.bank-back), так и на ученической
   карточке решения (.solution-card) — добавляются из admin.js и result.js
   по префиксу id шаблона (st-real- / v-real-). */
.bank-back.fig-light-all svg.figure .lbl,
.bank-back.fig-light-all svg.figure .num,
.bank-back.fig-light-all svg.figure .ang,
.bank-back.fig-light-all svg.figure .axis-lbl,
.bank-back.fig-light-all svg.figure .vec-name,
.solution-card.fig-light-all svg.figure .lbl,
.solution-card.fig-light-all svg.figure .num,
.solution-card.fig-light-all svg.figure .ang,
.solution-card.fig-light-all svg.figure .axis-lbl,
.solution-card.fig-light-all svg.figure .vec-name,
.fig-box.fig-light-all svg.figure .lbl,
.fig-box.fig-light-all svg.figure .num,
.fig-box.fig-light-all svg.figure .ang,
.fig-box.fig-light-all svg.figure .axis-lbl,
.fig-box.fig-light-all svg.figure .vec-name { font-weight: 400; }

.bank-back.fig-light-nums svg.figure .num,
.solution-card.fig-light-nums svg.figure .num,
.fig-box.fig-light-nums svg.figure .num { font-weight: 400; }

/* Дробные показатели в sup поднимаются translateY(-2.5em) и физически
   уходят выше базовой линии math на ~25 px. Если строка с .math
   стоит сразу после «Найдите значение выражения», обычного line-height
   1.5 хватает только на «обычные» цифровые показатели — дробные
   налезают на верхнюю строку. Когда внутри .math есть sup→.fr,
   даём строке заметный line-height (= больше воздуха над дробью).
   :has() поддерживается во всех современных браузерах.
   Применяется ВЕЗДЕ, где crops условия рисуется крупно:
   quiz-экран, карточка решения, админ-банк. */
.task-box .given .math:has(sup .fr),
.task-box .question .math:has(sup .fr),
.solution-card .sc-given .math:has(sup .fr),
.solution-card .sc-question .math:has(sup .fr),
.bank-given .math:has(sup .fr),
.bank-question .math:has(sup .fr) {
  line-height: 2.5;
}

/* «Исследование функции» — в формуле y = … − x·√x фрагмент «x·√x»
   визуально проседает относительно соседних «x»: подкоренное «x» уходит
   ниже базовой линии из-за того, как inline-flex выравнивает .rt.
   Поднимаем весь блок на ~5 px (по просьбе пользователя 2026-05-15).
   Используется только в нескольких прототипах темы function-research. */
.fr-lift-up {
  position: relative;
  top: -5px;
}

/* Не переопределяем font-size у .vec-fig-label в мини-чертеже: размер
   <foreignObject> в svg.js фиксирован как 28×28 user-space-units, и
   увеличение шрифта внутри приводит к тому, что блок .vec (буква + стрелочка
   сверху) перерастает контейнер, и стрелочка обрезается. Пусть масштабируется
   естественно вместе с остальным чертежом (на 270 px ≈ 0,75×). */
.bank-given { color: var(--ink-mid); margin-bottom: 4px; }
.bank-question { margin-bottom: 8px; color: var(--ink); }
.bank-answer {
  color: var(--green);
  font-family: 'Onest', sans-serif;
}
.bank-answer b { color: var(--green); font-weight: 700; }
.bank-refresh {
  margin-top: 4px;
  font-size: 0.85rem;
  padding: 4px 12px;
}

/* Математические дроби: числитель и знаменатель полноценным шрифтом, и
   вся запись (с «=» и правой частью) центрируется по черте дроби.

   Используем `display: inline-grid` с `grid-template-rows: 1fr 1fr`, чтобы
   оба ряда (числитель / знаменатель) получали РАВНУЮ высоту, и черта дроби
   (граница между рядами) автоматически оказывалась в геометрическом центре
   всей записи. Это критично для многоэтажных дробей типа `(1 + √2/2) / 2`:
   при обычном `inline-block` черта «сползает» вниз, потому что числитель
   с вложенной дробью выше знаменателя. С grid-1fr-1fr строки выравниваются
   по высоте бо́льшего, и черта чётко по середине. */
.fr {
  display: inline-grid;
  grid-template-rows: 1fr 1fr;
  vertical-align: middle;
  text-align: center;
  font-size: 1em;
  line-height: 1.05;
  margin: 0 2px;
  position: relative;
}
.fr-n {
  /* Числитель — внизу своего ряда, прямо над чертой. */
  align-self: end;
  border-bottom: 1.4px solid currentColor;
  padding: 0 5px 2px;
}
.fr-d {
  /* Знаменатель — вверху своего ряда, прямо под чертой.
     2026-05-12: padding-top 2px → 5px по просьбе пользователя. При знаменателе
     со сложным контентом (x², корень и пр.) высокая часть налезала на черту.
     Добавили 3 px воздуха — простые знаменатели остались близко к черте,
     сложные перестали в неё упираться. */
  align-self: start;
  padding: 5px 5px 0;
}
/* Если знаменатель содержит корень со степенью (например, ³⁰√36), индекс
   степени торчит выше обычной строки и налезает на горизонтальную черту
   дроби. В этом случае опускаем весь знаменатель пониже. */
.fr-d:has(.rt-deg) {
  /* +6px относительно базы (которая выросла с 2 до 5 в 2026-05-12). */
  padding-top: 11px;
}
/* Если в знаменателе стоит основание с дробным показателем (например,
   «36^(1/30)»), показатель теперь поднят на 22 px вверх через translateY
   и визуально лезет ВЫШЕ горизонтальной черты внешней дроби. Опускаем
   весь знаменатель ниже, чтобы дробь-показатель оказалась под чертой
   как и положено. По просьбе пользователя 2026-05-12 в Вычислениях
   (прототип R-4 «36^(1/3) · 36^(1/5) / 36^(1/30)»). */
.fr-d:has(sup .fr) {
  padding-top: 22px;
}
/* Большие формулы-задания (внутри <span class="math">) с дробью — даём чуть
   больше воздуха между текстом задания и самой дробью, чтобы «Найдите значение
   выражения» не упиралось в числитель. */
.math .fr {
  margin-top: 6px;
  margin-bottom: 4px;
}
/* Корни в решении и в банке задач — того же размера, что окружающий текст.
   Раньше здесь стоял переразмер 1,32em (компенсация мелкого 0,93rem-шрифта
   решения), из-за которого √3 в строке решения становился ощутимо крупнее
   букв и цифр вокруг, а горизонтальная палочка над корнем «болталась»
   высоко над строкой. С тех пор базовый шрифт `.sc-solution`/`.bank-solution`
   поднят до 1,08rem (см. ниже), и переразмер `.rt` больше не нужен —
   радикал собирается естественного размера и стоит ровно в строке. */
/* «Настоящий» верхний индекс — для <sup>, кроме степени корня (.rt-deg) и
   показателя «дробное основание» (.pow-exp), у которых своё позиционирование.
   Браузерный default `vertical-align: super` плохо работает, когда внутри <sup>
   стоит inline-block (например, дробь-показатель ¹⁄₃): дробь садится по центру
   строки, а должна быть наверху. Поднимаем sup явным top и уменьшаем размер. */
sup:not(.rt-deg):not(.pow-exp) {
  display: inline-block;
  position: relative;
  top: -0.6em;
  font-size: 0.7em;
  line-height: 1;
  vertical-align: baseline;
}
/* ───── Радикал (SVG-крючок + border-top как крышка) ─────────────────────
   КРИТИЧНО (2026-05-12). Старая реализация рисовала знак √ глифом шрифта
   Spectral, а крышку — отдельным CSS-псевдоэлементом, и пыталась стыковать
   их в пикселях (`top: -1px`, `margin-right: -3px`). Глиф и линия сходились
   на одной высоте только в одном конкретном контексте; при смене размера
   шрифта (условие 1,52rem vs решение 1,4rem), смене содержимого (буквы
   vs цифры vs дробь) или режима (compact vs tall) крышка либо парила над
   √, либо перечёркивала подкоренное. Пиксельная подгонка ничего не лечила:
   правка в одном контексте ломала другой.

   Новая модель — крючок и крышка как ОДНА непрерывная линия:
     .rt-hook  — inline-SVG фиксированной ширины (0.62em). Внутри path:
                 входной штрих → дно V → подъём к Y=0 → стартер крышки.
                 stroke-width="1.5" + vector-effect="non-scaling-stroke",
                 толщина в CSS-px одинакова при любой высоте контейнера.
     .rt-arg   — подкоренное, у него border-top: 1.5px solid currentColor.
                 Это продолжение того же росчерка вправо.
   Оба элемента — flex-item'ы у `.rt` (display: inline-flex; align-items:
   stretch), сидят встык, на y=0 контейнера. Линия SVG-стартера крышки
   заканчивается на y=0 viewBox = y=0 .rt-hook = y=0 .rt = верх .rt-arg,
   где начинается border-top. Толщина и цвет совпадают → визуально нет шва.

   Высокий режим (дробь под корнем): align-items: stretch сам растягивает
   `.rt-hook` по высоте `.rt-arg`. Координаты path остаются процентными,
   галочка автоматически вытягивается. Никаких override'ов высоты не нужно. */
.rt {
  display: inline-flex;
  align-items: stretch;
  /* vertical-align: middle — знак «=» должен горизонтально делить запись
     «√(...) = N» пополам. Со «strict baseline» корень визуально стоял выше «=». */
  vertical-align: middle;
  white-space: nowrap;
  position: relative;
  margin-left: 0.1em;
  /* КРИТИЧНО: своя line-height: 1, иначе в `.bank-solution` / `.sc-solution`,
     где line-height: 3.6 (для воздуха между строками столбика решения,
     см. styles.css:694 и :1014), контейнер корня раздувался до 3,6em и
     `align-items: stretch` тянул SVG-крючок на эту же высоту — крючок
     становился «очень высоким», а крышка лежала далеко над текстом.
     С line-height: 1 высота .rt = высоте содержимого (em-метрика шрифта
     + padding .rt-arg), и радикал одинаков в условии и в решении. */
  line-height: 1;
}
.rt-hook {
  flex: 0 0 0.62em;
  align-self: stretch;
  /* margin-right: -0.5px чтобы стартер крышки в SVG слегка нахлёстывал на
     border-top .rt-arg и закрывал возможный субпиксельный шов. */
  margin-right: -0.5px;
}
.rt-hook svg {
  display: block;
  width: 100%;
  height: 100%;
  /* stroke сверху рисуется с центром на y=0 — половина уходит вверх SVG;
     overflow: visible нужно, чтобы эта половина не обрезалась. */
  overflow: visible;
}
.rt-arg {
  display: inline-flex;
  align-items: center;
  border-top: 1.5px solid currentColor;
  padding: 0.12em 0.18em 0.02em 0.15em;
  font-family: 'Spectral', Georgia, serif;
}
/* «Хвост» уравнения после корня: «= 6», «= 2» и т.п. Корень из-за крышки
   визуально стоит выше baseline, и `=` оказывается над серединой
   подкоренного, а не на её уровне. Опускаем хвост вниз через .rt-tail,
   чтобы знак «=» поделил пополам подкоренное по горизонтали (2026-05-12,
   просьба пользователя для прототипов √(...) = c и ⁿ√(...) = c).
   Условие (.math) опускаем сильнее, решение (.bank-solution / .sc-solution)
   мягче — там шрифт меньше и эффект слабее. */
.math .rt-tail {
  display: inline-block;
  transform: translateY(0.28em);
}
.bank-solution .rt-tail,
.sc-solution .rt-tail {
  display: inline-block;
  transform: translateY(0.18em);
}
/* Степень корня (³√, ⁴√, ⁵√). Абсолютно позиционирована над крючком,
   не занимает места в потоке, не двигает крышку. */
.rt-deg {
  position: absolute;
  /* Однозначные степени (³√, ⁴√, ⁵√, ⁶√, ⁷√): обычное положение
     -0.15em. Двузначные — см. .rt-deg-2 ниже. */
  left: -0.15em;
  top: -0.45em;
  font-size: 0.55em;
  line-height: 1;
  pointer-events: none;
}
/* Двузначная степень (например, ³⁰√36 в Вычислениях): обычное положение
   .rt-deg даёт наезд цифры «30» на крючок √. Сдвигаем такие степени
   сильнее влево — −0.85em от обычной точки (≈ −9-10 px). По просьбе
   пользователя 2026-05-12: «подвинь именно двузначную, однозначные не
   трогать». Определяется в math.js по n >= 10. */
.rt-deg-2 {
  left: -0.85em;
}
/* Высокий режим — подкоренное содержит дробь. Контейнер автоматически высокий,
   крючок растягивается вместе с ним; нужны лишь чуть больший воздух сверху и
   снизу у `.rt-arg`, чтобы дробь не упиралась в крышку. */
.rt-tall .rt-arg {
  padding-top: 0.06em;
  padding-bottom: 0.04em;
}

/* Дробное основание степени — берём в высокие тонкие скобки и поднимаем
   показатель выше обычного (иначе sup налезает на скобку). */
.pow-base {
  display: inline-block;
  vertical-align: middle;
  position: relative;
  padding: 0 2px;
}
.pow-base::before,
.pow-base::after {
  display: inline-block;
  font-family: 'Spectral', Georgia, serif;
  font-weight: 300;
  transform: scaleY(2.3);
  transform-origin: center;
  vertical-align: middle;
  margin: 0 1px;
}
.pow-base::before { content: '('; }
.pow-base::after  { content: ')'; }
sup.pow-exp {
  vertical-align: 1em;
  font-size: 0.72em;
}

.best-note {
  margin-top: 14px;
  padding: 10px 16px;
  border-radius: 10px;
  font-size: 0.96rem;
  text-align: center;
}
.best-note:empty { display: none; }
.best-note.new-best {
  background: #ECFDF5; color: var(--green);
  border: 1px solid #6EE7B7;
}
.best-note.tied {
  background: #FEF3C7; color: #92400E;
  border: 1px solid #FCD34D;
}
.best-note.kept {
  background: #EFF6FF; color: #1E40AF;
  border: 1px solid #93C5FD;
}

.solution-card-wrap {
  perspective: 1400px;
  margin-top: 16px;
}
.solution-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 22px 20px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
  position: relative;
  transform-origin: center top;
  animation: flipCardIn 0.55s cubic-bezier(0.2, 0.85, 0.4, 1.05);
  max-width: 100%;
  box-sizing: border-box;
}
.solution-card[hidden] { display: none; }
@keyframes flipCardIn {
  0%   { transform: rotateX(-95deg); opacity: 0; }
  60%  { opacity: 1; }
  100% { transform: rotateX(0);     opacity: 1; }
}
.solution-card.flipping {
  animation: flipCardOut 0.35s cubic-bezier(0.4, 0, 0.7, 0.4) forwards;
}
@keyframes flipCardOut {
  0%   { transform: rotateX(0);     opacity: 1; }
  100% { transform: rotateX(-95deg); opacity: 0; }
}
.solution-card .sc-close {
  position: absolute; top: 6px; right: 12px;
  background: transparent; border: 0;
  font-size: 26px; line-height: 1; cursor: pointer; color: #94a3b8;
  padding: 4px 8px;
}
.solution-card .sc-close:hover { color: #475569; }
.solution-card .sc-head {
  font-family: 'Spectral', serif;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--navy-deep);
  margin-bottom: 10px;
}
.solution-card .sc-body {
  display: flex;
  gap: 22px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.solution-card .sc-figure {
  flex: 0 0 auto;
  max-width: 360px;
}
.solution-card .sc-figure svg.figure { width: 100%; height: auto; }
.solution-card .sc-text {
  flex: 1 1 240px;
  font-size: 0.96rem;
  line-height: 1.5;
}
/* Карточка решения после спринта (та, что ученик видит при клике на красную
   ячейку). Формат тот же, что у админ-банка bank-back: условие → вопрос →
   ваш ответ → «Решение:» (подчёркнуто) → разбор → «Ответ:» (подчёркнуто)
   с правильным значением. */
.solution-card .sc-given,
.solution-card .sc-question,
.solution-card .sc-user,
.solution-card .sc-solution {
  font-family: 'Onest', sans-serif;
  font-size: 1.05rem;
}
.solution-card .sc-given { color: var(--ink-mid); margin-bottom: 4px; }
.solution-card .sc-question { color: var(--ink); margin-bottom: 12px; }
.solution-card .sc-answer { display: none; }   /* ответ переехал в конец .sc-solution */
.solution-card .sc-user b { color: var(--red); }
.solution-card .sc-user.skipped b { color: #64748b; font-style: italic; }
.solution-card .sc-user.correct b { color: var(--green); }
.solution-card .sc-solution {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed #e2e8f0;
  /* Воздух между строками — оставляем 4.2, чтобы дробные показатели и
     знаменатели не наезжали на соседние строки (паддинги в формулах в
     абсолютных px, не масштабируются с font-size). Согласован с .bank-solution. */
  line-height: 4.2;
  color: var(--ink-mid);
  white-space: pre-wrap;
}
.solution-card .sc-solution:empty { display: none; }
/* «Решение:» — подчёркнуто, блок на отдельной строке (тот же стиль,
   что .bank-back-label в админ-банке). Раньше было b.sc-solution-label,
   теперь div.sc-solution-label — render внутри solEl создаёт <div>. */
.solution-card .sc-solution .sc-solution-label,
.solution-card .sc-solution b.sc-solution-label {
  display: block;
  color: var(--ink);
  margin: 0 0 6px;
  font-family: 'Onest', sans-serif;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* «Ответ:» в самом конце .sc-solution. Тот же стиль, что .bank-back-answer. */
.solution-card .sc-back-answer {
  font-family: 'Onest', sans-serif;
  font-size: 1.05rem;
  color: var(--ink);
  margin-top: 14px;
}
.solution-card .sc-back-answer-label {
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}
.solution-card .sc-back-answer b { color: var(--ink); font-weight: 700; }

.leaderboard { margin-top: 30px; }
.leaderboard h3 { color: var(--navy-deep); margin-bottom: 10px; }
.leaderboard table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
/* Селектор расширен на .board-public (таблица на экране «Посмотреть
   таблицу»): по тем же правилам — горизонтальные и вертикальные
   границы, паддинг, выравнивание. Раньше .board-public table стилей не
   имела и сидела без разделителей столбцов. */
.leaderboard th, .leaderboard td,
.board-public th, .board-public td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  /* Тонкие вертикальные границы между столбцами. Правая граница
     последнего столбца убирается ниже. */
  border-right: 1px solid var(--border);
  /* vertical-align middle — без него ячейки с разным font-size в одной строке
     (rank/score крупнее остальных) выравниваются по baseline, и числа
     визуально «съезжают» относительно соседей. */
  vertical-align: middle;
}
.leaderboard th:last-child,
.leaderboard td:last-child,
.board-public th:last-child,
.board-public td:last-child { border-right: none; }
.leaderboard th { font-family: 'Onest', sans-serif; font-weight: 600; color: var(--ink-mid); font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.08em; }
.leaderboard tr.me { background: #FEF3C7; }
.leaderboard td.rank { font-family: 'Spectral', serif; font-weight: 600; color: var(--gold); font-size: 1.05rem; }
.leaderboard td.score { font-family: 'Spectral', serif; font-weight: 600; color: var(--navy); font-size: 1.05rem; }

.actions { margin-top: 24px; display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* ========== FIGURES ========== */
svg.figure { font-family: 'Onest', sans-serif; }
svg.figure .circle { fill: none; stroke: #000; stroke-width: 2.2; }
svg.figure .line { stroke: #000; stroke-width: 2; fill: none; }
svg.figure .dash { stroke: #000; stroke-width: 2; fill: none; }
svg.figure .helper { stroke: #000; stroke-width: 1.4; fill: none; }
/* Размер точки задаётся через CSS-`r` (SVG2, поддерживается Chrome 90+,
   Firefox 87+, Safari 14.1+). Это нужно, чтобы выровнять визуальный размер
   точек между обычными и крупными чертежами: viewBox-радиус 6 в обычных
   (scale 240/360 = 0.667) даёт 4 px on screen; в .figure-large (scale
   420/360 = 1.167) тот же 6 дал бы 7 px — слишком крупно. Override 3.5
   возвращает 4.08 px — те же 4 px on screen. CSS-`r` сильнее presentation-
   атрибута `r="3.5"` в JS-хелпере s_pt, поэтому атрибут можно оставить —
   CSS перекроет на всех современных браузерах. */
/* Размер точки задаётся через CSS-`r` (SVG2). Точки делаем мельче, чтобы
   на крупном чертеже они смотрелись «деликатно», а не как кляксы:
   - обычная фигура (scale 0.667): r=4 viewBox → 2.7 px on screen
   - крупная (scale 1.167): r=2.5 viewBox → 2.9 px on screen
   Согласовано с просьбой пользователя 2026-05-12: «точки уменьшила бы как
   во всех остальных прототипах». */
svg.figure .pt { fill: #000; r: 4px; }
svg.figure.figure-large .pt { r: 2.5px; }
/* Шрифт меток. Лейблы делаем заметно крупнее: пользователь хотела «как в
   первом прототипе» — то есть жирные читаемые буквы, не сливающиеся с линиями.
   Подобраны так, чтобы on-screen размер был ~17-18 px в обоих контекстах:
   - обычная (scale 0.667): 26px viewBox → 17.3 px on screen
   - крупная (scale 1.167): 15px viewBox → 17.5 px on screen
   После этой правки RightTriSinA переведён на figure-large, чтобы ВСЕ
   чертежи реального банка были одного масштаба. */
svg.figure .lbl { font-size: 30px; font-weight: 600; fill: #000; font-family: 'Spectral', serif; paint-order: stroke; stroke: #FAF6EE; stroke-width: 3; stroke-linejoin: round; }
svg.figure .num { font-size: 30px; fill: #000; font-weight: 700; font-family: 'Onest', sans-serif; paint-order: stroke; stroke: #FAF6EE; stroke-width: 3.5; stroke-linejoin: round; }
svg.figure .ang { font-size: 22px; fill: #000; font-weight: 700; font-family: 'Onest', sans-serif; paint-order: stroke; stroke: #FAF6EE; stroke-width: 3; stroke-linejoin: round; }
svg.figure.figure-large .lbl { font-size: 17px; }
svg.figure.figure-large .num { font-size: 17px; }
svg.figure.figure-large .ang { font-size: 13px; }
svg.figure .arc { fill: none; stroke: #000; stroke-width: 1.6; }
/* Координатная сетка и оси для задач по векторам: тонкие серые клетки,
   оси с наконечниками-стрелочками, засечки единичных отрезков.
   stroke-width осей уменьшен с 1.6 до 1.0 (2026-05-13, по просьбе
   пользователя) — оси визуально не должны конкурировать с самими векторами. */
svg.figure .grid { stroke: #D9D2C3; stroke-width: 0.8; fill: none; }
svg.figure .axis-line { stroke: #1F2937; stroke-width: 1.0; fill: none; }
svg.figure .axis-head { fill: #1F2937; stroke: none; }
svg.figure .axis-tick { stroke: #1F2937; stroke-width: 1.0; fill: none; }
svg.figure .axis-lbl  { font-size: 15px; fill: #1F2937; font-weight: 600; font-family: 'Spectral', serif; font-style: italic; paint-order: stroke; stroke: #FAF6EE; stroke-width: 3; stroke-linejoin: round; }
/* Сами векторы — насыщенный «золотой» цвет, чтобы выделялись на фоне сетки.
   Подпись (буква со стрелочкой) рисуется через s_vecLabel — буква в той же
   палитре, тонкая дугообразная стрелка над буквой. */
svg.figure .curve { stroke: #1F2937; stroke-width: 2.4; fill: none; stroke-linecap: round; stroke-linejoin: round; }
svg.figure .tangent { stroke: #1F2937; stroke-width: 1.3; fill: none; stroke-dasharray: 0; }
svg.figure .marker-pt { fill: #1F2937; stroke: #FAF6EE; stroke-width: 0.9; }
svg.figure .dash-thin { stroke: #1F2937; stroke-width: 0.8; stroke-dasharray: 3 3; fill: none; }
svg.figure .x-mark-lbl { font-size: 13px; fill: #1F2937; font-family: 'Spectral', serif; font-style: italic; paint-order: stroke; stroke: #FAF6EE; stroke-width: 2.5; stroke-linejoin: round; }
svg.figure .open-pt { fill: #fff; stroke: #1F2937; stroke-width: 1.6; }
/* Красные «подсвечивающие» элементы в решениях темы Производная:
   - .curve-red    — красный участок кривой (например, на заданном отрезке)
   - .segment-red  — красный отрезок [a; b] на оси абсцисс
   - .marker-red   — красная точка-ответ (на кривой или на оси)
   - .pt-red       — красный кружок отметки на оси для «правильных» точек
   - .dash-red     — красный пунктир от оси к кривой для «правильных» точек
   - .x-mark-lbl-red — подпись x_idx красным цветом */
/* Красные элементы делаем заметно крупнее/жирнее обычных — мини-картинка
   в карточке «Решение» небольшая, нужно чтобы ответ читался без напряжения
   (по просьбе пользователя 2026-05-13). */
svg.figure .curve-red { stroke: #B91C1C; stroke-width: 3.6; fill: none; stroke-linecap: round; stroke-linejoin: round; }
svg.figure .segment-red { stroke: #B91C1C; stroke-width: 4.2; stroke-linecap: round; }
svg.figure .marker-red { fill: #B91C1C; stroke: #FAF6EE; stroke-width: 1.6; r: 6px; }
svg.figure .pt-red { fill: #B91C1C; stroke: #FAF6EE; stroke-width: 1.4; r: 5.5px; }
svg.figure .dash-red { stroke: #B91C1C; stroke-width: 1.6; stroke-dasharray: 3 3; fill: none; }
svg.figure .x-mark-lbl-red { font-size: 14px; font-weight: 700; fill: #B91C1C; font-family: 'Spectral', serif; font-style: italic; paint-order: stroke; stroke: #FAF6EE; stroke-width: 2.8; stroke-linejoin: round; }

/* SVG-фрейм темы Производная (svgFrame с extraClass='deriv-fig'). У этих
   чертежей нужны меньшие подписи на осях — чтобы цифры -7/0/7/-1/1 не
   смотрелись «огромными» рядом с тонкой кривой. Применяется во ВСЕХ
   контекстах вывода (бок-фигура в банке, фигура в квизе, в карточке
   решения), поэтому достаточно одного селектора `svg.figure.deriv-fig`. */
svg.figure.deriv-fig .num { font-size: 11px; }
svg.figure.deriv-fig .axis-lbl { font-size: 10px; }
svg.figure.deriv-fig .lbl { font-size: 11px; }
svg.figure.deriv-fig .ang { font-size: 10px; }
svg.figure.deriv-fig .x-mark-lbl,
svg.figure.deriv-fig .x-mark-lbl-red { font-size: 11px; font-weight: 700; }

/* Тема «Графики функций» (fg-fig в function-graphs.js → fg_figure).
   Кривые и прямые тоньше базовых (curve 2.4→1.6, line 2→1.4), подписи
   облегчены: меньше font-weight и тоньше «гало» (stroke вокруг текста). */
svg.figure.fg-fig .curve { stroke-width: 1.6; }
svg.figure.fg-fig .line  { stroke-width: 1.4; }
svg.figure.fg-fig .num     { font-weight: 500; stroke-width: 2.5; }
svg.figure.fg-fig .axis-lbl { font-weight: 500; stroke-width: 2.2; }
/* На телефоне (≤540 px) подписи в графиках функций становятся слишком
   крупными: 30 px в viewBox 360×320 ≈ 28 px на экране. Уменьшаем
   .num (это и цифры на осях «1, 2, 3», и подписи кривых «y=f(x)»,
   «y=g(x)», «A»), .lbl и .axis-lbl. На компьютере и планшете
   оставляем как было — там размер комфортный. */
@media (max-width: 540px) {
  svg.figure.fg-fig .num      { font-size: 17px; stroke-width: 2; }
  svg.figure.fg-fig .lbl      { font-size: 17px; stroke-width: 2; }
  svg.figure.fg-fig .axis-lbl { font-size: 11px; stroke-width: 1.5; }
}
/* Чертёж Производной в карточке «Решение» (admin-банк) — увеличиваем
   max-width c 270 до 340px, иначе красные подписи и точки слишком мелкие
   для чтения. Применяем только к деривативу — для других тем оставляем 270px. */
.bank-back .bank-example-fig.bank-fig-mini:has(svg.figure.deriv-fig),
.bank-back .bank-example-fig.bank-fig-mini:has(.deriv-img-wrap) {
  max-width: 340px;
}
.bank-back .bank-example-fig.bank-fig-mini svg.figure.deriv-fig { max-width: 340px; }
/* Красные подписи x_i в мини-чертеже деривативного решения — крупнее обычных
   подписей (черные ~10 px, красные 12 px, жирные). */
.bank-back .bank-example-fig.bank-fig-mini svg.figure.deriv-fig .x-mark-lbl-red { font-size: 13px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure.deriv-fig .pt-red { r: 4.2px; }
.bank-back .bank-example-fig.bank-fig-mini svg.figure.deriv-fig .marker-red { r: 4.6px; }

/* Компактное оформление решения для темы «Производная» (admin.js ставит
   класс .solution-compact-host на .bank-solution когда tpl.id начинается
   с 'der-real-'). По умолчанию .bank-solution имеет font 1.25rem и
   line-height 3.6 — это нужно для дробных показателей в уравнениях,
   в производной избыточно. Шрифт приведён к размеру условия (1rem). */
.bank-solution.solution-compact-host,
.solution-card .sc-solution.solution-compact-host {
  /* По просьбе пользователя 2026-05-13: шрифт чуть крупнее (был 1rem),
     line-height пропорционально больше (был 1.6). Приближает компактные
     темы к читаемости остальных тем (Векторы, Текстовые — 1.05rem). */
  font-size: 1.1rem;
  line-height: 1.8;
}
/* Корень √x в компактном решении (темы Производная, Исследование функции).
   Изначально подняли на 0.18em — оказалось слишком высоко, √x начал
   выглядеть как показатель. По просьбе пользователя 2026-05-13 опускаем
   обратно вниз на ~5 px (0.28em при font-size 1.1rem ≈ 5 px) — итого
   −0.1em от базовой линии текста. */
.bank-solution.solution-compact-host .rt,
.solution-card .sc-solution.solution-compact-host .rt {
  vertical-align: -0.1em;
}
.bank-solution.solution-compact-host svg.figure,
.solution-card .sc-solution.solution-compact-host svg.figure {
  display: block;
  margin: 10px auto;
  width: 100%;
}
/* Шрифты внутри SVG-решения: уменьшаем до тех же значений, что
   в условии (.bank-example-fig svg.figure). При width:100% колонки
   решения scale ~ 1,6× — без уменьшения font-size цифры «1», «0»,
   подписи x_n становятся гигантскими (см. жалобу пользователя 2026-05-13). */
.bank-solution.solution-compact-host svg.figure .lbl,
.bank-solution.solution-compact-host svg.figure .num,
.solution-card .sc-solution.solution-compact-host svg.figure .lbl,
.solution-card .sc-solution.solution-compact-host svg.figure .num { font-size: 12px; }
.bank-solution.solution-compact-host svg.figure .ang,
.solution-card .sc-solution.solution-compact-host svg.figure .ang { font-size: 10px; }
.bank-solution.solution-compact-host svg.figure .axis-lbl,
.solution-card .sc-solution.solution-compact-host svg.figure .axis-lbl { font-size: 10px; }
.bank-solution.solution-compact-host svg.figure .x-mark-lbl,
.bank-solution.solution-compact-host svg.figure .x-mark-lbl-red,
.solution-card .sc-solution.solution-compact-host svg.figure .x-mark-lbl,
.solution-card .sc-solution.solution-compact-host svg.figure .x-mark-lbl-red { font-size: 11px; }

/* Картинки-прототипы лежат в подпапке sprint/Производная. Прототипы/crop/
   — это оригинальные ФИПИ-скриншоты с уже срезанной текстовой шапкой.
   Показываем картинку на всю ширину доступного места карточки (без
   max-width 540 как у svg.figure) — графики из банка читаются на крупном
   экране заметно лучше, чем зажатые в узкую колонку. */
.deriv-img-wrap {
  width: 100%;
  margin: 0 auto;
  background: #fff;
}
.deriv-img-wrap img {
  display: block;
  width: 100%;
  height: auto;
}
svg.figure .vec-line { stroke: #1F2937; stroke-width: 2.2; fill: none; }
svg.figure .vec-head { fill: #1F2937; stroke: none; }
svg.figure .vec-arr  { stroke: #1F2937; stroke-width: 1.4; fill: none; stroke-linecap: round; stroke-linejoin: round; }
/* Подпись вектора на чертеже. Вставляется через <foreignObject> в s_vecLabel
   (svg.js) и содержит обычный inline-блок vec() из math.js. То есть буква и
   стрелочка — один HTML-элемент, стрелочка не может «оторваться» от буквы. */
svg.figure .vec-fig-label {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-family: 'Spectral', serif;
  /* font-weight: 400 (раньше было 700, по просьбе пользователя 2026-05-13
     — подписи a, b на чертеже не должны быть жирными). Естественная плотность
     Spectral italic + белое halo делают букву достаточно различимой. */
  font-weight: 400;
  color: #1F2937;
  line-height: 1;
}
/* Лёгкое белое «гало» вокруг буквы, чтобы она читалась поверх сетки/осей.
   Замена paint-order: stroke + stroke у SVG-<text> (в foreignObject это HTML,
   и paint-order не работает). text-shadow применяется только к глифу буквы;
   стрелочка-SVG внутри vec() сама достаточно тонкая, ей halo не нужен. */
svg.figure .vec-fig-label .vec-let {
  text-shadow:
    -1.4px -1.4px 0 #FAF6EE,  1.4px -1.4px 0 #FAF6EE,
    -1.4px  1.4px 0 #FAF6EE,  1.4px  1.4px 0 #FAF6EE,
     0    -1.4px 0 #FAF6EE,   0     1.4px 0 #FAF6EE,
    -1.4px  0    0 #FAF6EE,   1.4px  0    0 #FAF6EE;
}

.shake { animation: shake 0.35s; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}

/* Баннер «Незавершённая попытка» поверх стартовой формы. */
.resume-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: linear-gradient(135deg, #FBF1D9 0%, #F4E5BD 100%);
  border: 1px solid var(--gold);
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.resume-banner .resume-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.resume-banner .resume-text strong {
  font-family: 'Spectral', Georgia, serif;
  color: var(--navy-deep);
  font-size: 1.1rem;
}
.resume-banner .resume-text span {
  color: var(--ink-mid);
  font-size: 0.95rem;
}
.resume-banner .resume-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
@media (max-width: 540px) {
  .resume-banner { flex-direction: column; align-items: stretch; }
  .resume-banner .resume-actions { justify-content: flex-end; }
}

footer.bot {
  text-align: center;
  color: var(--ink-light);
  font-size: 0.85rem;
  padding: 24px 16px 32px;
}
footer.bot #admin-link {
  color: var(--ink-light);
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-light);
  opacity: 0.7;
}
footer.bot #admin-link:hover {
  opacity: 1;
  color: var(--navy);
  border-bottom-color: var(--navy);
}

/* ============================================================
   АДАПТИВ — планшет (≤720 px) и телефон (≤540 px)
   ============================================================
   Идея. На десктопе авторы шаблонов часто вставляют принудительные переносы
   в условиях/вопросах (`<br>`) и сами поднимают длинную формулу на отдельную
   строку (`.math` с `white-space: pre` + псевдоэлемент `\A`). На узкой
   ширине эти переносы дробят и без того короткие строки. Дополнительно
   `withSoftBreaks` (см. core.js) превращает «голый» `<br>` шаблонов в
   управляемый CSS-маркер `.soft-break`, который тут на ≤720 px заменяется
   обычным пробелом. Шаблоны не редактируем — переключение полностью
   на стороне CSS/рендера.

   Чего НЕ трогаем на мобильном:
     · `.nb` («AB = 10», короткие неразрывные атомы) — они короче ширины
       любого экрана, рвать их некрасиво.
     · `.math-i` (короткие «y = f(x)», «x₀») — то же самое.
     · SVG-чертежи (у них уже width: 100%, max-width 360/540).            */

/* --- управляемый маркер «мягкого» переноса --- */
.soft-break { white-space: pre; }
.soft-break::before { content: '\A'; }
@media (max-width: 720px) {
  .soft-break { white-space: normal; }
  .soft-break::before { content: ' '; }
}

/* --- маркер переноса перед уравнением/выражением --- */
/* Используется в темах «Уравнения» и «Вычисления»: после фразы
   «Найдите корень уравнения / Найдите значение выражения» вставляется
   <span class="mobile-break"></span>, чтобы само уравнение/выражение
   шло на отдельной строке. Имя оставлено историческое: раньше работало
   только на телефоне, теперь — на всех экранах (по просьбе пользователя
   2026-05-19, чтобы карточки в банке/результате выглядели аккуратно
   и на широких экранах). */
.mobile-break { display: block; }
.mobile-break::before { content: ''; }

/* --- ≤720 px (планшет): убираем принудительные переносы внутри условий
   и вопросов; разрешаем длинной формуле переноситься. --- */
@media (max-width: 720px) {
  /* Любые «голые» <br>, попавшие в текст условий и вопросов (на случай,
     если withSoftBreaks где-то пропустят) — нейтрализуем. */
  .task-box .given br:not([class]),
  .task-box .question br:not([class]),
  .solution-card .sc-given br:not([class]),
  .solution-card .sc-question br:not([class]),
  .bank-given br:not([class]),
  .bank-question br:not([class]) { display: none; }

  /* `.math` больше не прыгает на свою строку и переносится внутри потока
     по ширине экрана (вместо `white-space: pre` + `\A` псевдоэлемента). */
  .task-box .given .math,
  .task-box .question .math,
  .solution-card .sc-given .math,
  .solution-card .sc-question .math,
  .bank-given .math,
  .bank-question .math {
    white-space: pre-wrap;
    word-break: break-word;
  }
  .task-box .given .math::before,
  .task-box .question .math::before,
  .solution-card .sc-given .math::before,
  .solution-card .sc-question .math::before,
  .bank-given .math::before,
  .bank-question .math::before { content: ''; }

  /* Лидерборд — ужимаем ячейки, но колонки всё ещё видны. */
  .leaderboard table { font-size: 0.9rem; }
  .leaderboard th,
  .leaderboard td { padding: 6px 8px; }
}

/* --- ≤540 px (телефон): компактные отступы, читаемые шрифты, лидерборд
   без колонки «Дата». --- */
@media (max-width: 540px) {
  .container { padding: 14px; }
  .card { padding: 18px; border-radius: 12px; }

  /* Шапка спринта (Решено / Попыток / Осталось / Завершить) — компактнее. */
  .quiz-bar { padding: 10px 12px; gap: 8px; }
  .quiz-bar .stat .val { font-size: 1.3rem; }
  .quiz-bar .stat .label { font-size: 0.7rem; letter-spacing: 0.08em; }

  /* Текст условия и вопроса — чуть меньше, формула — заметно меньше. */
  .task-box .given,
  .task-box .question {
    font-size: 1.08rem;
    line-height: 1.45;
  }
  .task-box .given .math,
  .task-box .question .math,
  .solution-card .sc-given .math,
  .solution-card .sc-question .math,
  .bank-given .math,
  .bank-question .math { font-size: 1.22em; }
  .task-box .given .math-i,
  .task-box .question .math-i { font-size: 1.32em; }

  .fig-box { padding: 10px; }
  .answer-row input { font-size: 1rem; padding: 10px 12px; }

  /* Карточка с задачей во время игры — почти во всю ширину экрана:
     уменьшаем поля контейнера и собственный padding карточки, чтобы
     рисунок, условие и три кнопки помещались. Другие экраны (старт,
     результат, банк, статистика) сохраняют стандартные отступы. */
  #screen-quiz { padding: 4px; }
  #screen-quiz > .card { padding: 10px 10px 12px; border-radius: 10px; }
  /* На телефоне три элемента (поле + «Ответить» + «Пропустить») в один ряд
     не помещаются — Пропустить уезжает за экран. Делаем кнопки чуть уже,
     а Пропустить отправляем на 2-ю строку во всю ширину. */
  .answer-row .btn { padding: 10px 14px; font-size: 0.95rem; }
  .answer-row .btn-minus { width: 40px; padding: 9px 0; font-size: 1.3rem; }
  .answer-row #skip-btn { flex: 1 1 100%; margin-top: 4px; }

  /* Карточка с условием во время игры: без min-width: 0 grid/flex-item
     .task-box не ужимается, и длинная неразрывная формула выталкивает
     текст за пределы карточки. То же — для .problem-area, .fig-box и
     контейнера .card. overflow-wrap позволяет в крайнем случае разорвать
     слишком длинное слово/атом по символу. */
  .problem-area { min-width: 0; }
  .problem-area > * { min-width: 0; max-width: 100%; }
  .task-box { min-width: 0; }
  .task-box .given,
  .task-box .question { overflow-wrap: anywhere; }
  .fig-box { max-width: 100%; box-sizing: border-box; }
  .fig-box svg { max-width: 100%; }

  /* Кубики истории — мельче, чтобы строка влезала. */
  .history-grid { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 5px; }
  .history-cell { font-size: 0.78rem; border-radius: 5px; }

  /* Лидерборд — прячем «Дата» (последняя колонка), остальное ужимаем. */
  .leaderboard table { font-size: 0.88rem; }
  .leaderboard th, .leaderboard td { padding: 5px 6px; }
  .leaderboard th:nth-child(5),
  .leaderboard td:nth-child(5) { display: none; }
  .leaderboard td.rank,
  .leaderboard td.score { font-size: 0.95rem; }

  /* Топик-карточки — иконка ещё чуть меньше, головка компактнее. */
  .topic-card-head { padding: 12px 14px; gap: 10px; }
  .topic-card-icon { width: 38px; height: 38px; font-size: 1.25rem; }
  .topic-card-name { font-size: 1rem; }
  .bank-mode .topic-card-head { padding: 10px 12px; gap: 10px; }
  .bank-mode .topic-card-icon { width: 30px; height: 30px; font-size: 1rem; }
  /* Кнопки внутри активной карточки в столбик и во всю ширину.
     border-box делает calc корректным для padding+border. */
  .topic-card-actions {
    flex-direction: column;
    margin: 0 12px 12px;
  }
  .bank-mode .topic-card.active .topic-card-start,
  .bank-mode .topic-card.active .topic-card-view,
  .bank-mode .topic-card.active .topic-card-pdf {
    display: block;
    width: 100%;
    padding: 10px 14px;
  }

  /* Большой стартовый CTA на десктопе занимает свою ширину; на телефоне —
     удобнее во всю строку. */
  .btn-big { padding: 12px 22px; font-size: 1rem; width: 100%; }
  .submit-row { flex-direction: column; align-items: stretch; }
  .submit-row .hint { text-align: center; }

  /* Карточка решения (sc) — меньше отступы и заголовки. */
  .solution-card { padding: 14px 16px 16px; }
  .solution-card .sc-head { font-size: 0.98rem; }
  .solution-card .sc-given,
  .solution-card .sc-question,
  .solution-card .sc-user,
  .solution-card .sc-solution { font-size: 1rem; }
  /* Защита от горизонтального выхода: без min-width: 0 flex-item .sc-text
     не ужимается и длинная неразрывная формула раздвигает карточку
     шире экрана; overflow-x: auto оставлен на самый крайний случай —
     если внутри есть атом, который физически не помещается, скролл
     возникает ВНУТРИ карточки, а не у всей страницы. */
  .solution-card .sc-body { min-width: 0; flex-wrap: wrap; }
  .solution-card .sc-text {
    min-width: 0;
    max-width: 100%;
    flex-basis: 100%;
    overflow-x: auto;
    overflow-wrap: anywhere;
  }
  .solution-card .sc-figure { max-width: 100%; }

  /* Шапка сайта и подпись «Только задачи из реального банка ФИПИ» —
     слегка ужимаются, чтобы H1 не оказался один на экране. */
  .top-bar { padding: 10px 0; }
  .intro .lead { font-size: 1rem; }
  .rules { padding: 14px 16px; }
  .rules ul { padding-left: 18px; }
}

/* ============================================================
   ЭКРАН ТАБЛИЦЫ ТЕМЫ ДЛЯ УЧАСТНИКА (screen-board)
   ============================================================
   Открывается с главной по кнопке «Посмотреть таблицу» (когда в теме
   уже ≥10 участников). Содержит приветствие, личную строку с клик-
   ячейками, общую таблицу и кнопку «Начать спринт» внизу. */
.board-welcome {
  font-family: 'Onest', sans-serif;
  font-size: 1.02rem;
  color: var(--ink);
  line-height: 1.5;
  margin: 6px 0 18px;
  padding: 14px 16px;
  background: #FFFBEB;
  border-left: 3px solid var(--gold);
  border-radius: 0 10px 10px 0;
}
.board-welcome b { color: var(--navy-deep); }

.board-section-title {
  margin: 18px 0 6px;
  color: var(--navy-deep);
  font-size: 1.05rem;
}
/* Заголовок над общей таблицей — крупный (h2), чтобы было видно, какая
   тема перед вами (по просьбе пользователя 2026-05-15). */
.board-public-heading {
  margin: 24px 0 10px;
  color: var(--navy-deep);
  font-family: 'Spectral', serif;
  font-size: clamp(1.4rem, 2.6vw, 1.8rem);
  font-weight: 600;
  line-height: 1.25;
}
.board-personal .stats-table { max-width: 720px; }
.board-personal .stats-table th,
.board-personal .stats-table td { padding: 8px 10px; }

/* Layout экрана таблицы (board): главная колонка слева (приветствие +
   личная строка + общая таблица), панель «детали» — справа, sticky,
   со своей прокруткой. Когда панель скрыта — главная занимает всю ширину.
   На узких экранах (≤900 px) — складываются в одну колонку. */
.board-content-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  align-items: start;
}
.board-content-layout:has(.board-detail:not([hidden])) {
  grid-template-columns: 1fr 380px;
}
@media (max-width: 900px) {
  .board-content-layout,
  .board-content-layout:has(.board-detail:not([hidden])) {
    grid-template-columns: 1fr;
  }
}
.board-content-main { min-width: 0; }

/* Панель «детали» в board-режиме — как у админа: справа, sticky,
   собственный скролл. По просьбе пользователя 2026-05-15. */
.board-detail {
  position: sticky;
  top: 10px;
  max-height: calc(100vh - 60px);
  overflow-y: auto;
  max-width: none;
  margin: 0;
}
@media (max-width: 900px) {
  .board-detail {
    position: static;
    max-height: none;
  }
}

/* Шапка board-экрана — слева «← На старт», справа крупная кнопка
   «Начать спринт «Тема»». Заголовка с названием темы здесь больше нет
   (он перенесён над таблицей крупным h2.board-public-heading). */
.bank-head.board-head {
  justify-content: space-between;
  gap: 12px;
}
.board-start-cta {
  font-family: 'Onest', sans-serif;
  font-size: 1.02rem;
  font-weight: 600;
}

/* ============================================================
   ПУБЛИЧНАЯ ТАБЛИЦА (результат спринта в BANK_MODE) — прокрутка
   ============================================================
   Контейнер ограничен по высоте, чтобы при большом числе участников
   таблица не растягивала всю карточку. Заголовок thead фиксируется
   вверху прокрутки. */
.leaderboard-scroll {
  max-height: 380px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
  /* scrollbar-gutter: stable резервирует место под скроллбар даже когда
     прокрутки нет — иначе при появлении вертикального скроллбара ширина
     таблицы внутри меняется, и колонки thead не совпадают с tbody. */
  scrollbar-gutter: stable;
}
.leaderboard-scroll table {
  width: 100%;
  border-collapse: collapse;
  /* table-layout: fixed + явные ширины колонок гарантируют, что thead и
     tbody используют одинаковые столбцы. При auto-layout с разным
     font-size в .rank/.score (1.05rem) и в шапке (0.82rem uppercase
     + letter-spacing) ширины расходились, и данные «уезжали» относительно
     названий колонок (по жалобе пользователя 2026-05-15). */
  table-layout: fixed;
}
.leaderboard-scroll th:nth-child(1),
.leaderboard-scroll td:nth-child(1) { width: 12%; }
.leaderboard-scroll th:nth-child(2),
.leaderboard-scroll td:nth-child(2) { width: auto; }
.leaderboard-scroll th:nth-child(3),
.leaderboard-scroll td:nth-child(3) { width: 18%; }
.leaderboard-scroll th:nth-child(4),
.leaderboard-scroll td:nth-child(4) { width: 18%; }
.leaderboard-scroll thead th {
  position: sticky;
  top: 0;
  background: #FFFBEB;
  z-index: 1;
}
/* В столбце «Спринтер» длинные имена пусть переносятся (table-layout: fixed
   ширину уже зафиксировал, само содержимое умеет переноситься). */
.leaderboard-scroll td:nth-child(2) {
  word-wrap: break-word;
  overflow-wrap: break-word;
}

/* ============================================================
   ЭКРАН «СТАТИСТИКА» (АДМИН, BANK_MODE)
   ============================================================
   Layout: слева вертикальный список 13 кнопок-тем, по центру —
   широкая таблица участников, справа — выезжающая панель «детали»
   с топом задач выбранного участника по выбранному ведру (решено /
   ошибок / пропусков). На узком экране (≤900 px) колонки складываются
   вертикально, панель «детали» становится модальной снизу. */
.stats-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 18px;
  align-items: start;
}
.stats-layout:has(.stats-detail:not([hidden])) {
  grid-template-columns: 220px 1fr 360px;
}
@media (max-width: 900px) {
  .stats-layout,
  .stats-layout:has(.stats-detail:not([hidden])) {
    grid-template-columns: 1fr;
  }
}

.stats-tabs {
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 10px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
}
.stats-tab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  font-family: 'Onest', sans-serif;
  font-size: 0.92rem;
  color: var(--navy-deep);
  text-align: left;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.stats-tab:hover { border-color: var(--gold); background: #FFFBEB; }
.stats-tab.active {
  background: var(--navy-deep);
  color: #F0C871;
  border-color: var(--navy-deep);
}
.stats-tab.active .stats-tab-count { color: #F0C871; opacity: 0.85; }
.stats-tab-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.stats-tab-count { font-size: 0.82rem; color: var(--ink-light); font-variant-numeric: tabular-nums; }

/* «Сводка» — выделенная кнопка в самом верху сайдбара (по сути отдельный
   режим: одна общая таблица по всем темам, а не список участников темы). */
.stats-tab-overview {
  margin-bottom: 6px;
  background: #FFFBEB;
  border-color: var(--gold);
  font-weight: 600;
}
.stats-tab-overview:hover { background: #FEF3C7; }

.stats-main { min-width: 0; }
.stats-title {
  margin: 0 0 10px;
  color: var(--navy-deep);
  font-size: 1.2rem;
}
.stats-table-wrap {
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
}
.stats-table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.stats-table th,
.stats-table td {
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  /* Тонкие вертикальные границы между столбцами — единообразно
     с .leaderboard. Правая граница последнего столбца убирается ниже. */
  border-right: 1px solid var(--border);
}
.stats-table th:last-child,
.stats-table td:last-child { border-right: none; }
.stats-table thead th {
  position: sticky;
  top: 0;
  background: #FFFBEB;
  font-family: 'Onest', sans-serif;
  font-weight: 600;
  color: var(--ink-mid);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  z-index: 1;
}
/* Кликабельные заголовки «Сводки» — клик сортирует таблицу по этому
   столбцу (по убыванию). Активный столбец помечен стрелочкой ↓. */
.stats-overview-table thead th.stats-sort {
  cursor: pointer;
  user-select: none;
}
.stats-overview-table thead th.stats-sort:hover {
  background: #FEF3C7;
  color: var(--ink);
}
.stats-overview-table thead th.stats-sort.active {
  color: var(--navy-deep);
  background: #FEF3C7;
}
.stats-overview-table thead th.stats-sort.active::after {
  content: ' ↓';
  font-size: 0.9em;
}
.stats-table td.rank {
  font-family: 'Spectral', serif;
  font-weight: 600;
  color: var(--gold);
}
.stats-table td.stats-acc {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
  color: var(--ink-light);
}
.stats-table td.stats-cell {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
  cursor: pointer;
  user-select: none;
}
.stats-table td.stats-cell.stats-ok    { color: var(--green); }
.stats-table td.stats-cell.stats-wrong { color: var(--red); }
.stats-table td.stats-cell.stats-skip  { color: var(--ink-light); }
.stats-table td.stats-cell:hover { background: #FFFBEB; }
.stats-table td.stats-cell.active {
  background: #FEF3C7;
  box-shadow: inset 0 0 0 2px var(--gold);
}

/* Сводная таблица: имя темы слева, три ведра + итог. В каждой клетке —
   число и процент. Клик по числу открывает топ-5 шаблонов справа. */
.stats-overview-table .stats-overview-name {
  font-family: 'Spectral', serif;
  font-weight: 600;
  color: var(--navy-deep);
  font-size: 0.98rem;
}
.stats-overview-table .stats-cell {
  text-align: right;
  white-space: nowrap;
}
.stats-overview-table .stats-cell-num {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.stats-overview-table .stats-cell-sep {
  color: var(--ink-light);
  margin: 0 4px;
}
.stats-overview-table .stats-cell-pct {
  color: var(--ink-mid);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}
.stats-overview-table .stats-overview-total {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--ink-mid);
}
.stats-empty {
  color: var(--ink-light);
  font-style: italic;
  margin: 10px 0;
}

.stats-detail {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  position: sticky;
  top: 10px;
}
.stats-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px;
  background: #FFFBEB;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 1;
}
.stats-detail-head h4 {
  margin: 0;
  font-family: 'Spectral', serif;
  font-size: 1rem;
  color: var(--navy-deep);
  font-weight: 600;
}
.stats-detail-close {
  background: transparent;
  border: 0;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: #94a3b8;
  padding: 2px 6px;
}
.stats-detail-close:hover { color: #475569; }
.stats-detail-body { padding: 10px 14px; }
.stats-detail-empty { color: var(--ink-light); font-style: italic; margin: 4px 0; }
.stats-detail-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: #FAFAF9;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.stats-detail-item-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.85rem;
  margin-bottom: 6px;
  color: var(--ink-mid);
}
.stats-detail-item-rank { font-family: 'Spectral', serif; font-weight: 600; color: var(--gold); }
.stats-detail-item-count {
  font-weight: 600;
  color: var(--navy-deep);
  font-variant-numeric: tabular-nums;
}
.stats-detail-item-body {
  font-size: 0.92rem;
  color: var(--ink);
  line-height: 1.4;
}
.stats-detail-item-fig {
  max-width: 200px;
  margin: 0 auto 8px;
}
.stats-detail-item-fig svg.figure { width: 100%; height: auto; }
.stats-detail-item-fig svg.figure .lbl,
.stats-detail-item-fig svg.figure .num { font-size: 22px; }
.stats-detail-item-given { color: var(--ink-mid); margin-bottom: 2px; }
.stats-detail-item-question { color: var(--ink); margin-bottom: 4px; }
.stats-detail-item-answer { color: var(--ink); }
.stats-detail-item-answer-label {
  text-decoration: underline;
  text-underline-offset: 3px;
  font-weight: 600;
}

/* --- очень узкие экраны (≤380 px, старые iPhone SE) — последняя страховка. */
@media (max-width: 380px) {
  h1 { font-size: 1.7rem; }
  .container { padding: 10px; }
  .card { padding: 14px; }
  .task-box .given,
  .task-box .question { font-size: 1.02rem; }
}

/* ============================================================
   PDF-ЭКСПОРТ ВАРИАНТА (offscreen-страница для html2canvas+jsPDF)
   ============================================================
   Эти стили применяются к невидимому контейнеру .pdf-host, который
   js/pdf-export.js строит при клике на кнопку «PDF» в карточке темы.
   Контейнер уезжает за пределы экрана (left:-10000px) и режется
   html2canvas-ом по блокам — каждый блок становится отдельной картинкой,
   которые jsPDF раскладывает по A4-страницам.
   ВАЖНО. Не убирайте white-space-нюансы и фиксированные пиксельные размеры —
   html2canvas рендерит при ширине ровно 794 px (A4 при 96 dpi). Любые em/% от
   браузерного окна будут зависеть от устройства пользователя, а это уплывёт
   в PDF. Поэтому здесь — почти везде px. */
.pdf-host {
  font-size: 14px;
  line-height: 1.45;
  letter-spacing: 0.005em;
}
.pdf-host * { box-sizing: border-box; }
.pdf-host .pdf-block {
  padding: 10px 36px;
  background: #fff;
}
/* ─── Шапка ─── */
.pdf-host .pdf-top-line {
  display: flex;
  gap: 10px;
  font-size: 11px;
  color: #333;
  border-bottom: 1px solid #c4b9a3;
  padding-bottom: 6px;
  margin-bottom: 14px;
}
.pdf-host .pdf-top-sep { color: #999; }
.pdf-host .pdf-title-block { text-align: center; margin-bottom: 14px; }
.pdf-host .pdf-h1 {
  font-family: 'Spectral', serif;
  font-weight: 700;
  font-size: 18px;
  margin-bottom: 4px;
}
.pdf-host .pdf-h2 {
  font-family: 'Spectral', serif;
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 8px;
  color: #1a2b3a;
}
.pdf-host .pdf-h3 {
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 12px;
}
.pdf-host .pdf-h4 {
  font-weight: 700;
  font-size: 13px;
  text-transform: none;
}
.pdf-host .pdf-instr p {
  margin: 0 0 8px;
  font-size: 13px;
  text-align: justify;
  text-indent: 24px;
}
.pdf-host .pdf-wish { text-align: center; margin: 14px 0 4px; font-size: 14px; }
/* Образец заполнения «Ответ: −0,8» — внутри инструкции, ОДИН раз. Слева
   подпись «КИМ» (то, что пишется в тексте работы), справа — «Бланк»
   (то, что переносится в бланк ответов №1). Визуально повторяет образец
   из шапки школьного бланка ЕГЭ. */
.pdf-host .pdf-sample-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
  margin: 10px 0 14px;
  flex-wrap: nowrap;
}
.pdf-host .pdf-sample-tag {
  font-size: 10px;
  color: #666;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-right: 6px;
}
.pdf-host .pdf-sample-kim,
.pdf-host .pdf-sample-blank {
  display: inline-flex;
  align-items: center;
}
.pdf-host .pdf-sample-label {
  font-size: 13px;
  font-weight: 600;
  margin-right: 6px;
}
.pdf-host .pdf-sample-written {
  font-family: 'Caveat', 'Comic Sans MS', cursive;
  font-size: 18px;
  color: #1a2b3a;
  border-bottom: 1px solid #1a2b3a;
  padding: 0 6px 1px;
  letter-spacing: 0.04em;
}
.pdf-host .pdf-sample-cells {
  display: inline-flex;
  gap: 0;
}
.pdf-host .pdf-sample-cell {
  display: inline-flex;
  width: 18px;
  height: 22px;
  border: 1px solid #1a2b3a;
  margin-left: -1px;
  background: #fff;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: #1a2b3a;
}
.pdf-host .pdf-sample-cell.pdf-sample-filled {
  font-weight: 700;
}
.pdf-host .pdf-copyright {
  margin-top: 8px;
  text-align: right;
  font-size: 11px;
  color: #555;
  font-style: italic;
}
/* ─── Лицензия ─── */
.pdf-host .pdf-license {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid #c4b9a3;
  border-bottom: 1px solid #c4b9a3;
  padding-top: 6px;
  padding-bottom: 6px;
  margin: 4px 0;
  font-size: 11px;
  color: #555;
}
.pdf-host .pdf-site { font-weight: 700; color: #1a2b3a; }
/* ─── Часть 1 ─── */
.pdf-host .pdf-part-header { margin-top: 8px; }
.pdf-host .pdf-part-title {
  text-align: center;
  font-family: 'Spectral', serif;
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 8px;
}
.pdf-host .pdf-part-frame {
  border: 1px solid #1a2b3a;
  padding: 10px 14px;
  font-size: 12px;
  line-height: 1.5;
  text-align: justify;
  font-style: italic;
  background: #fdfaf3;
}
/* ─── Задача ─── */
/* По просьбе пользователя 2026-05-17: текст задач в PDF сильно крупнее,
   чем на сайте. На сайте 13 px при экранной ширине удобно читать с экрана;
   но на печати то же 13 px (после масштабирования html2canvas → jsPDF
   на A4) становится ~8,5 pt — мелковато для распечатки задачника.
   Увеличиваем условия / вопросы / номер задачи / клеточки до ~19–22 px
   в исходнике, что даёт ~12–14 pt на готовой странице. Все правила
   обёрнуты в `.pdf-host` — на сами уроки спринта и карточки банка не
   влияют. */
.pdf-host .pdf-problem {
  display: flex;
  gap: 12px;
  padding-top: 18px;
  padding-bottom: 10px;
  align-items: flex-start;
}
.pdf-host .pdf-problem-num {
  flex: 0 0 32px;
  font-weight: 700;
  font-size: 22px;
  padding-top: 1px;
}
.pdf-host .pdf-problem-body {
  flex: 1 1 auto;
  min-width: 0;
}
.pdf-host .pdf-figure {
  float: right;
  width: 260px;
  margin: 2px 0 10px 18px;
}
.pdf-host .pdf-figure svg.figure {
  width: 100%;
  height: auto;
  max-width: 260px;
}
/* Подписи в SVG-чертеже (.lbl/.num) — в viewBox-юнитах. При ширине
   чертежа 260 px и текущих 22 px они визуально становятся ~16 px —
   читаемо и не перекрывают линии. */
.pdf-host .pdf-figure svg.figure .lbl,
.pdf-host .pdf-figure svg.figure .num { font-size: 22px; }
.pdf-host .pdf-figure svg.figure .ang { font-size: 18px; }
.pdf-host .pdf-figure svg.figure .axis-lbl { font-size: 14px; }
.pdf-host .pdf-given {
  font-size: 19px;
  line-height: 1.45;
  margin-bottom: 6px;
  text-align: justify;
}
.pdf-host .pdf-question {
  font-size: 19px;
  line-height: 1.4;
  font-weight: 600;
  margin-bottom: 14px;
}
.pdf-host .pdf-answer-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  clear: both;
}
.pdf-host .pdf-answer-label { font-size: 19px; font-weight: 600; }
.pdf-host .pdf-answer-cells {
  display: inline-flex;
  gap: 0;
}
.pdf-host .pdf-answer-cell {
  display: inline-block;
  width: 28px;
  height: 36px;
  border: 1.2px solid #1a2b3a;
  margin-left: -1px;
  background: #fff;
}
/* ─── Футер PDF ─── */
.pdf-host .pdf-footer {
  border-top: 1px solid #c4b9a3;
  margin-top: 12px;
  font-size: 11px;
  color: #555;
  text-align: center;
}

/* ============================================================
   ЛИСТ С ОТВЕТАМИ (отдельный маленький PDF для учителя)
   ============================================================
   На вход — массив задач варианта. Рендерим заголовок «Ответы к
   варианту N» и таблицу из двух столбиков: номер задачи и ответ.
   Никаких чертежей, условий, шапок ЕГЭ — это служебный лист. */
.pdf-host .pdf-answers-header { padding-bottom: 4px; }
/* Большой баннер «ОТВЕТЫ К ВАРИАНТУ N — для учителя» — это явный
   визуальный разделитель: учитель не должен напечатать эту страницу
   ученикам. Цвет фона тёмно-синий, текст белый — броско и понятно
   с первого взгляда. */
.pdf-host .pdf-answers-banner {
  background: #1a2b3a;
  color: #ffffff;
  text-align: center;
  font-family: 'Spectral', serif;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 12px 16px;
  margin: 18px 0 6px;
  border-radius: 6px;
}
.pdf-host .pdf-answers-subtitle {
  text-align: center;
  font-size: 14px;
  color: #444;
  margin-bottom: 8px;
}
.pdf-host .pdf-answers-hint {
  text-align: center;
  font-size: 12px;
  color: #B14B4B;
  font-style: italic;
  margin-bottom: 14px;
}
.pdf-host .pdf-answers-table-block { padding-top: 4px; }
.pdf-host .pdf-ans-table {
  max-width: 360px;
  margin: 0 auto;
  border: 1.5px solid #1a2b3a;
}
.pdf-host .pdf-ans-row {
  display: flex;
  border-bottom: 1px solid #b9b0a0;
  font-size: 15px;
  font-family: 'Onest', sans-serif;
}
.pdf-host .pdf-ans-row:last-child { border-bottom: none; }
.pdf-host .pdf-ans-num {
  flex: 0 0 80px;
  text-align: center;
  padding: 7px 10px;
  border-right: 1.5px solid #1a2b3a;
  background: #fdfaf3;
  font-weight: 700;
  color: #1a2b3a;
}
.pdf-host .pdf-ans-val {
  flex: 1 1 auto;
  padding: 7px 16px;
  font-weight: 600;
}
