/*
 * poker-edge — единый внешний stylesheet (UIX-01).
 *
 * Дизайн-система редизайна: токены (spacing/typography/color/verdict) +
 * все CSS-классы из .planning/phases/11-ui-dataviz/11-UI-SPEC.md
 * (Component Inventory). Раздаётся через app.mount("/static", ...) с
 * cache-busting query из web/assets.py::static_url() (UIX-03) — редеплой
 * без ручного бампа версии.
 *
 * Легаси-классы (.panel/.muted/.good/.bad/.btn/.secondary/.leak/.cardbox/
 * .actions) сохранены по имени — большинство из 9 Jinja-шаблонов не
 * переписываются этим планом, только их визуальная основа (base.html +
 * этот файл). Исключение — план 11-07: .feedback-good/.feedback-bad
 * переименованы в grade-параметризованные .feedback-{ok,neutral,
 * inaccuracy,mistake,blunder} вместе с единственным потребителем
 * (train.html) — задел под 4-ступенчатую EV-градацию GAME-02.
 */

:root {
  /* ---- Spacing scale (кратно 4px, UI-SPEC "Spacing Scale") ---- */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;
  --space-3xl: 64px;
  --hit-target: 44px; /* мин. hit-target для icon-only интерактивных элементов */
  --bar-height: 20px; /* высота одного бара графика (dataviz.py) — размер данных, не spacing-токен */
  --quiz-pip-size: 20px; /* сторона пипса прогресс-бара квиза (10-UI-SPEC.md), прецедент --bar-height */

  /* ---- Typography — ровно 4 размера, 2 начертания (UI-SPEC "Typography") ---- */
  --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-size-label: 13px;
  --font-size-body: 16px;
  --font-size-heading: 20px;
  --font-size-display: 32px;
  --font-weight-regular: 400;
  --font-weight-semibold: 600;
  --line-height-label: 1.4;
  --line-height-body: 1.5;
  --line-height-heading: 1.25;
  --line-height-display: 1.15;

  /* ---- Радиусы (UI-SPEC "Layout & Navigation -> Радиусы") ---- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  /* ---- Тень — единственная, только для tooltip/popover ---- */
  --shadow-tooltip: 0 4px 16px rgba(0, 0, 0, .4);

  /* ---- Базовая цветовая система (UI-SPEC "Color") ---- */
  --bg: #0b0d12;
  --surface: #151822;
  --surface-2: #1b1f29;
  --accent: #4f8cff;
  --text: #e9ebf1;
  --text-muted: #8b93a7;
  --border: #333a46;
  --destructive: #e05555; /* зарезервирован (UI-SPEC Copywriting -> Destructive), не используется на кнопке в этой фазе */

  /* ---- Verdict/EV-грейды — 5 ступеней (UI-SPEC "Color -> Verdict/EV-градация") ---- */
  --grade-ok: #3fbf6f;
  --grade-neutral: #9aa3b2;
  --grade-inaccuracy: #d98080;
  /* bugfix контраст-снап 2026-07-12 (одобрен оркестратором, см. 11-UI-SPEC.md
     §Color): было #e05555 — 4.39:1 на --surface-2 (RESEARCH.md Pitfall #1),
     ниже требуемых 4.5:1. #e86b6b даёт 5.29:1 на surface-2 / 5.69:1 на surface. */
  --grade-mistake: #e86b6b;
  /* bugfix контраст-снап 2026-07-12: было #ff4d4d — 3.27:1 белый текст на
     заливке (RESEARCH.md Pitfall #1). #cc2b2b даёт 5.32:1. */
  --grade-blunder-fill: #cc2b2b;
  --grade-blunder-text: #ffffff;

  /* ---- Легаси-имена — алиасы новых токенов (Component Inventory: сохранить
     существующие CSS-классы рабочими без правки разметки 9 шаблонов) ---- */
  --panel: var(--surface);
  --panel-2: var(--surface-2);
  --muted: var(--text-muted);
  --good: var(--grade-ok);
  --bad: var(--grade-mistake);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-family);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  font-weight: var(--font-weight-regular);
}

/* Числа — везде tabular-nums (UI-SPEC "Typography"), чтобы колонки таблиц и
   подписи графиков выравнивались по разрядам. */
table,
.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* ==================== Легаси-классы (сохранены по имени) ====================
 * Component Inventory: .panel/.muted/.good/.bad/.btn/.secondary/.leak/
 * .cardbox/.actions переопределены под новые токены — существующие
 * 9 Jinja-шаблонов рендерятся без переверстки (кроме .feedback-*, см.
 * ниже — переименованы планом 11-07 вместе с train.html).
 */

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  margin-bottom: var(--space-md);
}

.muted {
  color: var(--muted);
}
.good {
  color: var(--good);
}
.bad {
  color: var(--bad);
}
/* 11-04: accuracy — сводная продуктовая метрика, ВСЕГДА accent, никогда good/bad
   (UI-SPEC "Color -> Accent reserved for" п.4 / Per-Screen Contracts -> Турниры). */
.accent {
  color: var(--accent);
}

h2 {
  font-size: var(--font-size-heading);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-heading);
  margin: 0 0 var(--space-md);
}
h3 {
  font-size: var(--font-size-body);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-sm);
}

table {
  border-collapse: collapse;
  width: 100%;
}
th,
td {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border);
}
th {
  color: var(--muted);
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-label);
}

button,
.btn {
  background: var(--accent);
  border: 0;
  color: #fff;
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-body);
  font-family: var(--font-family);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: filter 150ms ease, background-color 150ms ease;
}
button:hover:not(:disabled),
.btn:hover:not(.disabled) {
  filter: brightness(0.9);
}

button.secondary,
.btn.secondary {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
}
button.secondary:hover:not(:disabled),
.btn.secondary:hover:not(.disabled) {
  background: var(--surface-2);
  filter: none;
}

input[type="text"],
input[type="number"],
input[type="file"],
input[type="password"] {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm) var(--space-md);
  width: 100%;
  font-family: var(--font-family);
  font-size: var(--font-size-body);
}

/* Кнопка «Выйти» (сайдбар) — POST-форма вместо GET-ссылки (12-04, T-12-04-CSRF);
 * минимальный сброс, чтобы <button> выглядела как обычный пункт .sidebar__link. */
.sidebar__logout {
  margin: 0;
}
.sidebar__logout button {
  background: none;
  border: 0;
  cursor: pointer;
  width: 100%;
  text-align: left;
  font: inherit;
}

form.inline {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
}

pre.explain {
  white-space: pre-wrap;
  background: var(--panel-2);
  padding: var(--space-md);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}

.leak {
  border-left: 3px solid var(--bad);
  padding-left: var(--space-md);
  margin-bottom: var(--space-lg);
}

/* 11-07: карточка-ссылка (report.html «Топ-леки»/«План учёбы») — оборачивает
 * .leak в <a>, снимает цвет/подчёркивание ссылки, hover — фон surface-2
 * (UI-SPEC Interaction States: «для карточек-ссылок: фон --surface-2»).
 */
.leak-link {
  display: block;
  color: inherit;
  text-decoration: none;
}
.leak-link:hover .leak {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}

.cardbox {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  font-size: var(--font-size-body);
  white-space: pre-line;
  margin-bottom: var(--space-md);
}

.actions {
  display: flex;
  gap: var(--space-sm);
  margin: var(--space-sm) 0 var(--space-xs);
}

/* 11-07: переименовано из .feedback-good/.feedback-bad — параметризовано
 * токеном grade (train.html: `grade = 'ok' if feedback.is_correct else
 * 'mistake'`); крючки под все 5 грейдов готовы для GAME-02 (фаза 10),
 * сегодня достижимы только ok/mistake (answer_card бинарен).
 */
.feedback-ok {
  border-left: 3px solid var(--grade-ok);
  padding-left: var(--space-md);
  white-space: pre-line;
}
.feedback-neutral {
  border-left: 3px solid var(--grade-neutral);
  padding-left: var(--space-md);
  white-space: pre-line;
}
.feedback-inaccuracy {
  border-left: 3px solid var(--grade-inaccuracy);
  padding-left: var(--space-md);
  white-space: pre-line;
}
.feedback-mistake {
  border-left: 3px solid var(--grade-mistake);
  padding-left: var(--space-md);
  white-space: pre-line;
}
.feedback-blunder {
  background: var(--grade-blunder-fill);
  color: var(--grade-blunder-text);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  white-space: pre-line;
}

/* ==================== Layout & Navigation ==================== */

body {
  display: flex;
  min-height: 100vh;
}

/* Один и тот же разметочный список (base.html) — оба класса на одном <nav>,
 * брейкпоинт 900px переключает вид (сайдбар <-> горизонтальная top-полоса),
 * без гамбургера/JS (UI-SPEC "Layout & Navigation"). */
.sidebar,
.topnav-strip {
  background: var(--surface);
  border-right: 1px solid var(--border);
  width: 240px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-lg) 0;
}

.sidebar__brand,
.topnav-strip__brand {
  padding: 0 var(--space-lg);
  margin-bottom: var(--space-lg);
  font-size: var(--font-size-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--accent);
}

.sidebar__nav,
.topnav-strip__nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sidebar__link,
.topnav-strip__link {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-lg);
  color: var(--text-muted);
  text-decoration: none;
  border-left: 3px solid transparent;
  font-size: var(--font-size-body);
  transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}
.sidebar__link:hover,
.topnav-strip__link:hover {
  color: var(--text);
  background: var(--surface-2);
}
.sidebar__link.active,
.topnav-strip__link.active {
  /* Активный пункт: акцент на иконке И тексте (currentColor) + левая полоса */
  color: var(--accent);
  border-left-color: var(--accent);
  background: var(--surface-2);
}

.sidebar__divider,
.topnav-strip__divider {
  height: 1px;
  background: var(--border);
  margin: var(--space-sm) var(--space-lg);
}

main {
  flex: 1;
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-3xl) var(--space-lg);
  min-width: 0;
}

@media (max-width: 900px) {
  body {
    flex-direction: column;
  }

  .sidebar,
  .topnav-strip {
    width: 100%;
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding: 0;
  }
  .sidebar__brand,
  .topnav-strip__brand {
    display: none;
  }
  .sidebar__nav,
  .topnav-strip__nav {
    flex-direction: row;
  }
  .sidebar__link,
  .topnav-strip__link {
    flex-shrink: 0;
    scroll-snap-align: start;
    border-left: 0;
    border-bottom: 3px solid transparent;
  }
  .sidebar__link.active,
  .topnav-strip__link.active {
    border-left: 0;
    border-bottom-color: var(--accent);
  }
  .sidebar__divider,
  .topnav-strip__divider {
    display: none;
  }

  main {
    padding: var(--space-lg) var(--space-md);
  }

  table {
    display: block;
    overflow-x: auto;
  }
}

/* ==================== Component Inventory (новые классы) ==================== */

.stat-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.stat-tile__value {
  font-size: var(--font-size-display);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-display);
  font-variant-numeric: tabular-nums;
}
.stat-tile__value.good {
  color: var(--good);
}
.stat-tile__value.bad {
  color: var(--bad);
}
.stat-tile__label {
  font-size: var(--font-size-label);
  color: var(--text-muted);
}

.badge-verdict {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 2px var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-label);
  font-weight: var(--font-weight-semibold);
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}
.badge-ok {
  color: var(--grade-ok);
}
.badge-neutral {
  color: var(--grade-neutral);
}
.badge-inaccuracy {
  color: var(--grade-inaccuracy);
}
.badge-mistake {
  color: var(--grade-mistake);
}
.badge-blunder {
  /* Заливка отличает «Грубую ошибку» доп. к оттенку (visual weight) */
  background: var(--grade-blunder-fill);
  color: var(--grade-blunder-text);
}

.chart-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
}
.chart-card__caption {
  font-size: var(--font-size-label);
  color: var(--text-muted);
  margin-top: var(--space-sm);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-md);
  padding: var(--space-3xl) var(--space-lg);
  color: var(--text-muted);
}
.empty-state__heading {
  font-size: var(--font-size-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--text);
}
.empty-state__body {
  font-size: var(--font-size-body);
}

.alert-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  background: var(--surface-2);
  border-left: 3px solid var(--bad);
  border-radius: var(--radius-sm);
  padding: var(--space-md);
  color: var(--text);
}

/* 11-06: privacy-текст /import (hosted) — тот же силуэт, что .alert-error,
 * но нейтральный accent (не error-цвет) — это не проблема, а информация
 * (UI-SPEC "Per-Screen Contracts -> Импорт"). */
.alert-info {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  background: var(--surface-2);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: var(--space-md);
  color: var(--text-muted);
}

/* 11-06: drop-zone /import — обёртка ПОВЕРХ нативного <input type=file>,
 * само поле остаётся видимым и кликабельным внутри (T-11-17, accept-with-test:
 * инпут не прячется, drag&drop — прогрессивное улучшение, не реализовано
 * здесь, зона кликабельна как обычный label+input уже сейчас). */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  border: 2px dashed var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-xl) var(--space-lg);
  margin: var(--space-md) 0;
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}
.dropzone:hover {
  border-color: var(--accent);
  background: var(--surface-2);
}
.dropzone__text {
  font-size: var(--font-size-body);
  text-align: center;
}

/* 13-03: подсветка «проверь меня» — поле /spot распознано скриншотом с
 * confidence ниже CONFIDENCE_THRESHOLD (SHOT-03, Pitfall 4). Минимальный
 * акцент поверх токена --bad — новый визуальный язык не заводим. */
.confidence-low {
  border-left: 3px solid var(--bad);
  padding-left: var(--space-sm);
}

.timeline-row {
  border-left: 3px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  margin-bottom: var(--space-sm);
}
.timeline-row--bust {
  border-left-width: 6px;
  border-left-color: var(--grade-mistake);
  background: var(--surface-2);
}
.timeline-row__header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  min-height: var(--hit-target);
}
.timeline-row__body {
  margin-top: var(--space-sm);
  font-size: var(--font-size-body);
}
.timeline-row__body[hidden] {
  display: none;
}
/* Контракт app.js (план 11-01): .is-open переключается делегированным
 * обработчиком [data-timeline-toggle], поворачивает chevron-иконку. */
.timeline-row.is-open .timeline-row__header .chevron {
  transform: rotate(180deg);
}

.disclosure-muted {
  color: var(--text-muted);
  font-size: var(--font-size-label);
  margin-top: var(--space-sm);
  padding-left: var(--space-md);
  border-left: 2px solid var(--border);
}

.tooltip-term {
  border-bottom: 1px dotted var(--text-muted);
  cursor: help;
}
.tooltip-term .icon-info {
  vertical-align: middle;
  margin-left: 2px;
}
/* 14-01 (EDU-01): ссылки-термины наследуют цвет текста (не «линковый» accent —
 * иначе абзацы с 3-4 терминами пестрят), отличаются пунктиром .tooltip-term. */
a.tooltip-term {
  color: inherit;
  text-decoration: none;
}
a.tooltip-term:hover {
  color: var(--accent);
}

/* 14-01 (EDU-01/03): экран /help — сценарии «как пользоваться» + словарь. */
.help-scenarios li {
  margin-bottom: var(--space-sm);
}
.glossary__entry {
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--border);
  scroll-margin-top: var(--space-xl);
}
.glossary__entry:last-child {
  border-bottom: none;
}
.glossary__entry dt {
  font-weight: 600;
  margin-bottom: var(--space-xs);
}
.glossary__entry dd {
  margin: 0;
}
/* 14-02 (EDU-02): гайд-туры — backdrop + подсветка элемента + карточка шага.
 * z-index выше сайдбара; управление из app.js (startTour). */
.tour-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 90;
}
.tour-ring {
  position: absolute;
  border: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 4px rgba(79, 140, 255, 0.35);
  z-index: 95;
  pointer-events: none;
  transition: top 0.2s, left 0.2s, width 0.2s, height 0.2s;
}
.tour-card {
  position: absolute;
  z-index: 96;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  max-width: 340px;
  box-shadow: var(--shadow-tooltip);
}
.tour-card__title {
  font-weight: var(--font-weight-semibold);
  margin-bottom: var(--space-xs);
}
.tour-card__text {
  margin: 0 0 var(--space-sm);
}
.tour-card__meta {
  font-size: var(--font-size-label);
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}
.tour-card__actions {
  display: flex;
  gap: var(--space-sm);
}

/* 14-03 (EDU-03): свёрнутое пояснение «Как это читать» у ключевых
 * результатов — details, чтобы не шуметь для тех, кто уже разобрался. */
.how-to-read {
  margin-top: var(--space-sm);
}
.how-to-read summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: var(--font-size-label);
}
.how-to-read summary:hover {
  color: var(--accent);
}
.how-to-read[open] > div {
  margin-top: var(--space-sm);
  padding-left: var(--space-md);
  border-left: 2px solid var(--border);
  font-size: var(--font-size-label);
  line-height: var(--line-height-body);
  color: var(--text-muted);
}
.how-to-read[open] > div p {
  margin: 0 0 var(--space-xs);
}

/* 14-02: список туров на /help — отметка «пройден» + счётчик прогресса. */
.tour-list li {
  margin-bottom: var(--space-sm);
}
.tour-done-mark {
  color: var(--grade-ok);
  font-size: var(--font-size-label);
  margin-left: var(--space-xs);
}

/* Подсветка термина, к которому перешли по якорю из ссылки-термина. */
.glossary__entry:target {
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  padding-left: var(--space-sm);
  padding-right: var(--space-sm);
}

/* 10-05 (GAME-01): ряд пипсов прогресса дневного квиза + Label-подпись
 * «Спот N из M» под ним (train.html — над .cardbox активного квиза). */
.quiz-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}
.quiz-progress__row {
  display: flex;
  gap: var(--space-xs);
}
.quiz-progress__label {
  font-size: var(--font-size-label);
  color: var(--text-muted);
}
.quiz-pip {
  width: var(--quiz-pip-size);
  height: var(--quiz-pip-size);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.quiz-pip.current {
  border: 2px solid var(--accent);
}
.quiz-pip.grade-ok {
  background: var(--grade-ok);
  border: none;
}
.quiz-pip.grade-inaccuracy {
  background: var(--grade-inaccuracy);
  border: none;
}
.quiz-pip.grade-mistake {
  background: var(--grade-mistake);
  border: none;
}
.quiz-pip.grade-blunder {
  background: var(--grade-blunder-fill);
  border: none;
}

/* 10-05 (GAME-03): стрик-виджет completion-экрана — иконка flame + Body-текст. */
.streak-widget {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--font-size-body);
}

/* 10-05 (GAME-05): обёртка <pre id="share-text"> + кнопка «Скопировать результат». */
.share-grid {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

/* 10-06 (GAME-04): панель «Ликов закрыто: N» на /leaks — наследует .panel,
 * доп. стилей не требуется (класс зарезервирован этим планом под будущее
 * использование плана 10-06). */
.leaks-closed-panel {
}

/* Accessibility utility (WCAG 1.4.1 «Use of Color») — визуально скрытый, но
 * доступный screen reader'ам текстовый дубликат эмодзи-грида на экране. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ==================== Interaction States ==================== */

a {
  color: var(--accent);
  transition: color 150ms ease;
}

a:focus-visible,
button:focus-visible,
.btn:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button:disabled,
.btn.disabled,
.btn[disabled],
input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
button:disabled:hover,
.btn.disabled:hover {
  filter: none;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
  }
}

/* --- Матрица диапазона 13x13 (фаза 15, RNG-01) --- */
.range-matrix { margin-top: var(--space-md); max-width: 466px; }

/* --- Дрилл чартов (фаза 16, DRL-03): счёт серии и лента ответов --- */
.drill-score { display: flex; align-items: center; gap: var(--space-sm); }
.drill-tape { display: inline-flex; gap: 3px; margin-left: var(--space-sm); }

/* --- Редактор кастомного диапазона (фаза 19, LIB-02) --- */
.range-editor { border-collapse: collapse; user-select: none; margin-top: var(--space-md); }
.range-editor td {
  width: 33px; height: 26px; text-align: center; font-size: 11px;
  border: 1px solid var(--border, rgba(128,128,128,.25)); cursor: pointer;
  color: var(--text-muted); background: var(--surface);
}
.range-editor td[data-action] { color: var(--bg); font-weight: 600; }
.range-editor td[data-action="call"] { background: var(--good); }
.range-editor td[data-action="raise"],
.range-editor td[data-action="push"],
.range-editor td[data-action="3bet"],
.range-editor td[data-action="4bet"] { background: var(--accent); }
.range-palette { display: flex; flex-wrap: wrap; gap: var(--space-md); align-items: center; margin-top: var(--space-md); }
.range-palette label { display: inline-flex; align-items: center; gap: 4px; }
.range-notation { width: 100%; min-height: 56px; font-family: var(--font-mono, monospace); font-size: 12px; }
.range-list { columns: 2; margin: var(--space-sm) 0 var(--space-md); }
.range-list li { margin-bottom: 4px; }

/* --- Мои диапазоны из истории (фаза 18, MYR-01): две матрицы рядом --- */
.matrix-pair { display: flex; gap: var(--space-lg, 24px); flex-wrap: wrap; }
.matrix-pair > div { flex: 1 1 320px; min-width: 280px; }

