:root {
  --bg: #0b1120;
  --panel: #111a2e;
  --panel-2: #16213a;
  --line: rgba(148, 163, 184, 0.16);
  --text: #e2e8f0;
  --muted: #94a3b8;
  --accent: #4ade80;
  --accent-2: #60a5fa;
  --warn: #fbbf24;
  --bad: #f87171;
  --good: #4ade80;
  --radius: 12px;
}

* { box-sizing: border-box; }

/* Атрибут hidden обязан прятать даже то, чему классы задали display:
   у кнопки-ссылки «Игры» display: inline-flex из .btn перебивал hidden,
   и в офлайн-файле в шапке висел пустой квадрат без подписи. */
[hidden] { display: none !important; }

/* Видимый фокус для клавиатуры — на всех интерактивных элементах разом.
   Safari 14.1 не знает :focus-visible: правило стоит отдельно, чтобы он
   отбросил только его, а мышиные нажатия колец не рисуют нигде. */
:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

html, body {
  margin: 0;
  background: radial-gradient(1200px 600px at 20% -10%, #16233d 0%, var(--bg) 55%);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  min-height: 100%;
}

button { font-family: inherit; }

/* ------------------------------- Шапка ---------------------------------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  background: rgba(11, 17, 32, 0.9);
  /* Safari до сих пор понимает только префиксную форму */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  position: sticky;
  top: 0;
  z-index: 20;
  flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 10px; }
.logo { font-size: 26px; }
.brand-title { font-weight: 800; letter-spacing: 0.14em; font-size: 15px; }
.brand-sub { color: var(--muted); font-size: 11px; }

.kpis { display: flex; gap: 8px; flex: 1; flex-wrap: wrap; }
.kpi {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 5px 10px;
  min-width: 96px;
}
.kpi .k-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; }
.kpi .k-value { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; }
.kpi .k-delta { font-size: 11px; font-variant-numeric: tabular-nums; }
.up { color: var(--good); }
.down { color: var(--bad); }
.neutral { color: var(--muted); }

.topbar-actions { display: flex; gap: 8px; }

/* Планшет и узкий десктоп: шапке не хватает ширины на три блока сразу.
   Раньше показатели сжимались в столбец шириной в одну плашку между
   названием и кнопками, и шапка вырастала на пол-экрана. Теперь на этих
   ширинах строка показателей переезжает на собственную строку во всю
   ширину; телефоны (≤700px) живут по своим правилам ниже. */
@media (min-width: 701px) and (max-width: 1250px) {
  .topbar-actions { margin-left: auto; }
  .kpis { order: 3; flex-basis: 100%; }
}

.btn {
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  padding: 9px 14px;
  cursor: pointer;
  /* Кнопкой бывает и ссылка (например «Игры» в шапке): без этого <a>
     подчёркивается и красится как ссылка, а не как кнопка. */
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-weight: 600;
  transition: 0.15s;
}
.btn:hover { border-color: rgba(148, 163, 184, 0.4); background: #1b2946; }
/* Нажатие отвечает телом кнопки: без сдвига клик по тёмной кнопке немой */
.btn:active { transform: translateY(1px); }
.btn.primary { background: linear-gradient(180deg, #22c55e, #16a34a); border-color: #16a34a; color: #04240f; box-shadow: 0 2px 12px rgba(34, 197, 94, 0.25); }
.btn.primary:hover { filter: brightness(1.08); background: linear-gradient(180deg, #22c55e, #16a34a); box-shadow: 0 3px 16px rgba(34, 197, 94, 0.35); }
.btn.ghost { background: transparent; }
.btn.ghost:hover { background: rgba(148, 163, 184, 0.08); }
.btn.small { padding: 5px 9px; font-size: 12px; font-weight: 500; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }

/* ------------------------------- Сетка ---------------------------------- */
.layout {
  display: grid;
  grid-template-columns: 340px minmax(420px, 1fr) 360px;
  gap: 14px;
  padding: 14px;
  align-items: start;
}
/* На средних экранах правая колонка уходит под центральную, но остаётся во
   ВТОРОЙ колонке. Растягивать её на всю ширину нельзя: липкая левая колонка
   не ограничена своей строкой грида и накрывала бы её левый край. */
@media (max-width: 1400px) {
  .layout { grid-template-columns: 320px minmax(0, 1fr); }
  .col-right { grid-column: 2; }
}
@media (max-width: 980px) {
  .col-right { grid-column: auto; }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
}
.col-center { display: flex; flex-direction: column; gap: 14px; }
.col-left { max-height: calc(100vh - 90px); overflow-y: auto; position: sticky; top: 74px; }
.col-right { max-height: calc(100vh - 90px); overflow-y: auto; position: sticky; top: 74px; }
@media (max-width: 1400px) { .col-right { position: static; max-height: none; } }
@media (max-width: 980px) { .col-left { position: static; max-height: none; } }

.panel-title {
  /* Переход по подсказке ведёт к заголовку блока. На средних экранах шапка
     ещё липкая, а колонка уже обычная — без этого отступа заголовок уезжает
     под шапку и виден только сам блок, без названия. */
  scroll-margin-top: 88px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin: 4px 0 10px;
  font-weight: 700;
}
.panel-title.inline { margin: 0; }

/* ------------------------------- Рычаги --------------------------------- */
.lever { margin-bottom: 14px; }
.lever-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.lever-label { font-weight: 600; font-size: 13px; }
.lever-value { font-variant-numeric: tabular-nums; color: var(--accent-2); font-weight: 700; font-size: 13px; cursor: pointer; }
.lever input[type="range"] { width: 100%; margin: 6px 0 2px; }
.lever-tip { color: var(--muted); font-size: 11px; line-height: 1.4; display: none; }
.lever.open .lever-tip { display: block; }
/* «Зачем это?» — раскрывашка, а не ссылка: каретка вместо пунктира, как у
   «Как читать карту». Двенадцать пунктирных подчёркиваний в столбце рычагов
   читались как двенадцать ссылок наружу. */
.lever-why {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: 11px; padding: 0; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
}
.lever-why::before { content: '▸'; font-size: 9px; transition: transform 0.15s ease; }
.lever.open .lever-why::before { content: '▾'; }
.lever-why:hover { color: var(--text); }

/* ------------------------------ Ползунки ---------------------------------
   Свой вид вместо системного: на планке совместимости Safari 14.1 нет
   accent-color, и ползунки там оставались белыми системными. Дорожка
   заливается до ручки цветом акцента: в WebKit процент заливки задаёт
   переменная --fill (её ставит shared/sliders.js), в Firefox заливку рисует
   ::-moz-range-progress без всякого скрипта. Синие ползунки алгоритмов
   задают свой цвет переменной --range-accent. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  height: 22px;
  padding: 0;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(to right,
    var(--range-accent, var(--accent)) var(--fill, 0%),
    rgba(148, 163, 184, 0.22) var(--fill, 0%));
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -5px;
  border-radius: 50%;
  background: var(--range-accent, var(--accent));
  border: 2px solid #0b1120;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
  transition: transform 0.12s ease;
}
input[type="range"]:hover::-webkit-slider-thumb { transform: scale(1.18); }
input[type="range"]:disabled::-webkit-slider-thumb { transform: none; }
input[type="range"]::-moz-range-track {
  height: 6px; border-radius: 999px; background: rgba(148, 163, 184, 0.22);
}
input[type="range"]::-moz-range-progress {
  height: 6px; border-radius: 999px; background: var(--range-accent, var(--accent));
}
input[type="range"]::-moz-range-thumb {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--range-accent, var(--accent));
  border: 2px solid #0b1120;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}
input[type="range"]:disabled { opacity: 0.45; }

/* ------------------------------- Районы --------------------------------- */
.districts { display: flex; flex-direction: column; gap: 8px; }
.district {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 10px;
  background: var(--panel-2);
  cursor: pointer;
  transition: 0.15s;
}
.district:hover { border-color: rgba(148, 163, 184, 0.35); background: #1a2540; }
.district.active { border-color: rgba(74, 222, 128, 0.5); background: rgba(74, 222, 128, 0.07); }
/* Шапка второго города в панели районов: выглядит как карточка, но не кликается —
   вход в город платится сам, вместе с запуском первого района. */
.district-city {
  border: 1px dashed rgba(148, 163, 184, 0.35);
  border-radius: 10px;
  padding: 9px 10px;
  margin-top: 10px;
  background: transparent;
}
.district-head { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.district-name { font-weight: 700; font-size: 13px; }
.district-meta { color: var(--muted); font-size: 11px; margin-top: 3px; line-height: 1.45; }
.badge {
  font-size: 11px; padding: 2px 6px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted); white-space: nowrap;
}
/* Длинный бейдж (например, условия ворот совета) обязан переноситься:
   с nowrap он уезжал за правый край панели, и прочитать его можно было
   только горизонтальной прокруткой внутри колонки. */
.badge.wrap { white-space: normal; text-align: right; }
.district-head { flex-wrap: wrap; }
.badge.on { color: var(--good); border-color: rgba(74, 222, 128, 0.4); }

/* Самокаты (НОВОГРАД, год конгломерата): план года улица/склад.
   Столбик в клетке — сезонный спрос месяца, клик переключает режим. */
.scoot-actions { display: flex; gap: 6px; margin-top: 7px; flex-wrap: wrap; }
.scoot-plan {
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 3px;
  margin-top: 5px;
}
.scoot-cell {
  border: 1px solid rgba(148, 163, 184, 0.25);
  border-radius: 6px;
  padding: 3px 0 2px;
  text-align: center;
  cursor: pointer;
  font-size: 9px;
  color: var(--muted);
  user-select: none;
  -webkit-user-select: none;
  transition: 0.15s;
}
.scoot-cell b { display: block; font-size: 10px; font-weight: 400; }
.scoot-bar { height: 16px; display: flex; align-items: flex-end; justify-content: center; margin-bottom: 2px; }
.scoot-bar i { display: block; width: 5px; background: rgba(96, 165, 250, 0.55); border-radius: 2px 2px 0 0; }
.scoot-cell.street { border-color: rgba(74, 222, 128, 0.45); background: rgba(74, 222, 128, 0.08); }
.scoot-cell.store { opacity: 0.7; }
.scoot-cell.past { opacity: 0.3; cursor: default; }
.scoot-cell.now { box-shadow: 0 0 0 1px rgba(250, 204, 21, 0.6); }

/* ------------------------------ Инвестиции ------------------------------ */
.funding { display: flex; flex-direction: column; gap: 8px; }
.funding-row {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; background: var(--panel-2);
}
.funding-note { color: var(--muted); font-size: 11px; line-height: 1.45; }
/* Фраза вердикта в финале («Совет директоров аплодирует сидя, но искренне»):
   главная строчка с характером, а не сноска — крупнее, курсивом, с чертой. */
.quip {
  margin: 10px 0 4px;
  padding: 7px 12px;
  font-size: 15px;
  font-style: italic;
  line-height: 1.5;
  color: var(--text);
  border-left: 3px solid var(--warn);
  border-radius: 0 8px 8px 0;
  background: rgba(251, 191, 36, 0.07);
}

/* ------------------------------- Событие -------------------------------- */
.event {
  border-left: 3px solid var(--warn);
  background: linear-gradient(90deg, rgba(251, 191, 36, 0.09), transparent 60%);
}
.event h3 { margin: 0 0 6px; font-size: 15px; }
.event p { margin: 0 0 10px; color: #cbd5e1; line-height: 1.5; }
.event-options { display: flex; gap: 8px; flex-wrap: wrap; }
.event-option {
  flex: 1 1 200px; text-align: left; border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 11px; background: var(--panel-2); cursor: pointer; color: var(--text);
  transition: border-color 0.15s, background-color 0.15s, transform 0.15s;
}
/* Подсветка наведения — только там, где наведение существует. На тачскрине
   :hover «залипает» на последней тронутой кнопке, и рядом с настоящим
   выбором появлялась вторая жёлтая рамка — выглядело как два выбранных
   уровня сложности сразу. */
@media (hover: hover) {
  .event-option:hover { border-color: var(--warn); background: rgba(251, 191, 36, 0.07); transform: translateY(-1px); }
}
.event-option.selected { border-color: var(--warn); background: rgba(251, 191, 36, 0.12); }
.event-option b { display: block; margin-bottom: 3px; font-size: 13px; }
.event-option span { color: var(--muted); font-size: 11px; }
/* Кнопка выбора: название сверху, пояснение под ним. Без этого они слипаются
   в одну строку, и решение перестаёт читаться с первого взгляда. */
.event-option .opt-label {
  display: block;
  color: var(--text);
  font-weight: 700;
  font-size: 13px;
  margin-bottom: 3px;
}
.event-option .opt-detail { display: block; color: var(--muted); font-size: 11px; line-height: 1.5; }
.lesson {
  margin-top: 10px; font-size: 11px; color: var(--muted);
  border-top: 1px dashed var(--line); padding-top: 8px;
}
.lesson b { color: var(--warn); }

/* ------------------------------- Отчёт ---------------------------------- */
.report-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; flex-wrap: wrap; gap: 8px; }
.report-head h3 { margin: 0; font-size: 15px; }
.report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 8px; }
.stat { background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.stat .s-label { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; }
.stat .s-value { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; margin-top: 2px; }
.stat .s-sub { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }

.drivers { margin-top: 12px; }
.driver { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 2px 0; }
.driver .d-name { width: 150px; color: var(--muted); flex-shrink: 0; }
.driver .d-bar { flex: 1; height: 8px; background: rgba(148, 163, 184, 0.1); border-radius: 4px; position: relative; }
.driver .d-fill { position: absolute; top: 0; bottom: 0; border-radius: 4px; }
.driver .d-val { width: 62px; text-align: right; font-variant-numeric: tabular-nums; }
.driver .d-people { width: 62px; text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
.drivers .d-sum { display: flex; align-items: center; gap: 8px; font-size: 12px;
  padding: 4px 0 0; border-top: 1px solid var(--line); margin-top: 4px; }
.drivers .d-sum .d-name { width: 150px; flex-shrink: 0; color: var(--text); }
.drivers .d-sum .d-bar { flex: 1; }

.alerts { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.alert { font-size: 12px; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--line); line-height: 1.45; }
.alert.bad { border-color: rgba(248, 113, 113, 0.4); background: rgba(248, 113, 113, 0.08); }
.alert.warn { border-color: rgba(251, 191, 36, 0.4); background: rgba(251, 191, 36, 0.08); }
.alert.good { border-color: rgba(74, 222, 128, 0.4); background: rgba(74, 222, 128, 0.08); }

/* ------------------------------- Графики -------------------------------- */
.charts-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
.chart-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.chart-tabs button {
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; padding: 3px 10px; font-size: 11px; cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.chart-tabs button:hover { color: var(--text); border-color: rgba(148, 163, 184, 0.45); }
.chart-tabs button.active { color: var(--text); border-color: var(--accent-2); background: rgba(96, 165, 250, 0.12); }
#chart { width: 100%; height: 230px; margin-top: 6px; }
.chart-legend { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; font-size: 11px; color: var(--muted); }
.legend-item { display: inline-flex; align-items: center; gap: 5px; }
.legend-item i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.chart-caption { color: var(--muted); font-size: 11px; margin-top: 6px; line-height: 1.45; }

/* -------------------------------- Табы ---------------------------------- */
.tabs { display: flex; gap: 4px; margin-bottom: 12px; flex-wrap: wrap; }
.tab {
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  border-radius: 8px; padding: 5px 9px; font-size: 12px; cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.tab:hover { color: var(--text); border-color: rgba(148, 163, 184, 0.45); }
.tab.active { color: var(--text); border-color: var(--accent); background: rgba(74, 222, 128, 0.1); }
.tab-content { font-size: 12px; line-height: 1.5; }

table.data { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
/* Отступы по бокам узкие: таблицы на пять колонок стоят в правой колонке
   шириной 358 пикселей, и лишние два пикселя с каждой стороны — это те самые
   шестнадцать, из-за которых заголовок не помещается и колонка уезжает. */
table.data th, table.data td { padding: 5px 4px; text-align: right; border-bottom: 1px solid var(--line); }
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data th { color: var(--muted); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; }
table.data tr.total td { font-weight: 700; border-top: 1px solid var(--line); }
/* Ячейки, где не одно число, а фраза из нескольких: выравниваем по левому
   краю, иначе перенос рвёт её в неожиданных местах и читать приходится
   справа налево. */
table.data td.wide { text-align: left; }
table.data tr.sub td:first-child { padding-left: 16px; color: var(--muted); }
.pos { color: var(--good); }
.neg { color: var(--bad); }

.help h4 { margin: 14px 0 6px; font-size: 13px; }
.help p, .help li { color: #cbd5e1; }
.help ul { padding-left: 18px; margin: 6px 0; }
.help code { background: var(--panel-2); padding: 1px 5px; border-radius: 4px; font-size: 11px; }
.formula {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; margin: 6px 0; font-family: ui-monospace, monospace; font-size: 11px; color: #cbd5e1;
  overflow-x: auto; white-space: pre-wrap;
}

/* ------------------------------- Модалка -------------------------------- */
.modal-bg {
  position: fixed; inset: 0; background: rgba(2, 6, 16, 0.8);
  /* Выравнивание по верху + прокрутка подложки и margin:auto у окна:
     невысокое окно центрируется, высокое прокручивается целиком.
     Центрирование align-items:center обрезало бы верх высокого окна —
     на телефонах vh больше видимой области из-за шапки браузера. */
  display: flex; align-items: flex-start; justify-content: center;
  overflow-y: auto; z-index: 50; padding: 20px;
}
.modal {
  background: var(--panel); border: 1px solid rgba(148, 163, 184, 0.24); border-radius: 14px;
  padding: 22px; max-width: 620px; width: 100%; margin: auto;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.55);
}
.modal h2 { margin: 0 0 10px; font-size: 20px; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px; }

.score-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; margin: 14px 0; }
.hint-box {
  border: 1px dashed rgba(96, 165, 250, 0.45); background: rgba(96, 165, 250, 0.07);
  border-radius: 10px; padding: 10px 12px; font-size: 12px; line-height: 1.5; color: #cbd5e1;
}
/* Синий цвет означает «кликабельно» и больше ничего. Раньше им же красился
   любой жирный текст в подсказке, и человек пытался нажать на слово, которое
   никуда не ведёт. Выделение осталось, цвет ссылки — только у ссылок. */
.hint-box b { color: var(--text); }

/* ------------------------------ Алгоритмы ------------------------------- */
.quality-box { margin-bottom: 10px; }
.quality-row { display: flex; align-items: center; gap: 8px; font-size: 11px; margin-bottom: 4px; }
.quality-row .q-name { width: 74px; color: var(--muted); flex-shrink: 0; }
.quality-row .q-bar { flex: 1; height: 6px; background: rgba(148, 163, 184, 0.12); border-radius: 3px; overflow: hidden; }
.quality-row .q-fill { height: 100%; border-radius: 3px; background: var(--accent-2); }
.quality-row .q-val { width: 36px; text-align: right; font-variant-numeric: tabular-nums; }

.algo {
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 10px;
  background: var(--panel-2); margin-bottom: 8px;
}
.algo.locked { opacity: 0.5; }
.algo.on { border-color: rgba(96, 165, 250, 0.5); background: rgba(96, 165, 250, 0.07); }
.algo-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.algo-title { display: flex; align-items: center; gap: 7px; font-weight: 700; font-size: 13px; cursor: pointer; }
.algo-title input { accent-color: var(--accent-2); cursor: pointer; }
.algo-what { color: var(--muted); font-size: 11px; line-height: 1.45; margin-top: 4px; }
.algo-tradeoff { color: #cbd5e1; font-size: 11px; line-height: 1.45; margin-top: 5px;
  border-left: 2px solid rgba(251, 191, 36, 0.5); padding-left: 7px; }
.algo-param { margin-top: 7px; }
.algo-param input[type="range"] { width: 100%; --range-accent: var(--accent-2); margin: 3px 0 0; }
.algo-param-head { display: flex; justify-content: space-between; font-size: 11px; }
.algo-param-head b { color: var(--accent-2); font-variant-numeric: tabular-nums; }

/* ------------------------------- Погода --------------------------------- */
.weather { display: flex; gap: 12px; align-items: stretch; flex-wrap: wrap; }
.weather-now, .weather-next {
  flex: 1 1 220px; display: flex; gap: 10px; align-items: center;
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; background: var(--panel-2);
}
.weather-next.alarm { border-color: rgba(251, 191, 36, 0.55); background: rgba(251, 191, 36, 0.09); }
.weather-icon { font-size: 26px; line-height: 1; }
.weather-body { min-width: 0; }
.weather-when { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; }
.weather-name { font-weight: 700; font-size: 14px; }
.weather-fx { color: var(--muted); font-size: 11px; line-height: 1.4; font-variant-numeric: tabular-nums; }
.weather-fx b.up { color: var(--good); }
.weather-fx b.down { color: var(--bad); }

/* ---------------- Конкурент, цели совета, кризис (КИНОРЕКА) ------------- */
.rival-head {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  align-items: flex-start;
  margin-bottom: 10px;
}
.rival-stance { flex: 1 1 220px; }
.rival-stance-hint { display: block; color: var(--muted); font-size: 12px; line-height: 1.5; margin-top: 5px; }
.rival-facts { flex: 1 1 260px; display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--muted); }
.rival-facts b { color: var(--text); }

.share-bar {
  display: flex;
  height: 22px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
}
.share-bar span {
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  overflow: hidden;
  transition: width 0.35s ease;
}
.share-you { background: rgba(74, 222, 128, 0.30); color: var(--good); }
.share-them { background: rgba(248, 113, 113, 0.20); color: var(--bad); flex: 1; }

.goal-card {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-2);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.goal-card.done { border-left-color: var(--good); }
.goal-card.urgent { border-left-color: var(--warn); }
.goal-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.goal-year { font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; }
.goal-left { color: var(--muted); font-size: 11px; }
.goal-line { margin: 6px 0 8px; line-height: 1.5; font-size: 13px; }
.goal-card .q-bar { display: block; margin-bottom: 6px; }
.q-fill.ok { background: var(--good); }
.goal-past { font-size: 11px; padding: 3px 0; color: var(--muted); }
.goal-past.pos { color: var(--good); }
.goal-past.neg { color: var(--bad); }

.event-card.crisis { border-left: 3px solid var(--bad); }
.event-card.crisis h3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.event-option.chosen { border-color: var(--accent); background: rgba(74, 222, 128, 0.12); }

/* ------------- Слейт, ход месяца, группы рычагов (КИНОРЕКА) ------------- */
.lever-group { border-bottom: 1px solid var(--line); }
.lever-group:last-child { border-bottom: none; }
.lever-group-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 9px 0;
  cursor: pointer;
}
.lever-group-head:hover { color: var(--text); }
.lg-caret { transition: transform 0.15s ease; display: inline-block; }
.lever-group:not(.open) .lg-caret { transform: rotate(-90deg); }
.lg-count { margin-left: auto; opacity: 0.6; }
.lever-group-body { display: none; padding-bottom: 6px; }
.lever-group.open .lever-group-body { display: block; }

/* --- Панель хода --- */
.panel.turn { border-left: 3px solid var(--accent-2); }
.todos { display: flex; flex-direction: column; gap: 8px; }
.todo {
  border-radius: 8px;
  padding: 9px 11px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  border-left-width: 3px;
}
.todo.act { border-left-color: var(--accent); }
.todo.warn { border-left-color: var(--warn); }
.todo.bad { border-left-color: var(--bad); }
.todo.ok { border-left-color: var(--line); }
.todo-title { font-weight: 700; font-size: 13px; margin-bottom: 3px; }
.todo-text { color: var(--muted); font-size: 12px; line-height: 1.55; }
.todo .btn { margin-top: 7px; }

/* --- Карточки проектов --- */
.slate-section { margin-top: 12px; }
.slate-section:first-of-type { margin-top: 4px; }
.slate-label {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 6px;
}
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.proj {
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 9px 11px;
  background: var(--panel-2);
}
.proj.ready { border-color: rgba(74, 222, 128, 0.35); }
.proj.ready.planned { border-color: var(--accent); background: rgba(74, 222, 128, 0.08); }
.proj.queued { border-style: dashed; opacity: 0.85; }
.proj-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.proj-name { font-weight: 700; font-size: 13px; }
.proj-meta { color: var(--muted); font-size: 11px; line-height: 1.5; margin-top: 3px; }
.proj .q-bar { display: block; margin: 6px 0 3px; }
.proj .btn.tiny { margin-top: 7px; width: 100%; }
.btn.tiny { padding: 5px 9px; font-size: 12px; }
.release-row { display: flex; align-items: center; gap: 7px; margin-top: 7px; flex-wrap: wrap; }
.release-row label { color: var(--muted); font-size: 11px; flex-basis: 100%; }
.release-row input[type=range] { flex: 1; min-width: 90px; }
.release-budget { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* --- Форма запуска --- */
.commission.blocked { opacity: 0.55; }
.commission-row { margin-bottom: 6px; }
.pick { display: flex; flex-wrap: wrap; gap: 5px; }
.pick button {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--muted);
  border-radius: 7px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.pick button:hover { color: var(--text); border-color: rgba(148, 163, 184, 0.45); }
.pick button.active { background: var(--accent-2); border-color: transparent; color: #06210f; font-weight: 700; }
.commission-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 12px;
  color: var(--muted);
}

/* ------------------- Партнёрства и разрыв цены (КИНОРЕКА) --------------- */
.deals { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; margin-bottom: 10px; }
.deal { border: 1px solid var(--line); border-radius: 9px; padding: 8px 10px; background: var(--panel-2); }
.deal.ending { border-color: rgba(251, 191, 36, 0.45); }
.deal-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.deal-name { font-weight: 700; font-size: 13px; }
.deal-meta { color: var(--muted); font-size: 11px; line-height: 1.5; margin-top: 3px; }

.offer { border: 1px solid var(--line); border-left: 3px solid var(--accent-2); border-radius: 9px; padding: 11px 13px; }
.offer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.offer-head h3 { margin: 0; font-size: 15px; }
.offer p { margin: 7px 0; line-height: 1.6; }
.offer-terms { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; color: var(--muted); margin-bottom: 9px; }
.offer-terms .warn { color: var(--warn); }

.gap-box { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--panel-2); border: 1px solid var(--line); }
.gap-box.wide { border-color: rgba(251, 191, 36, 0.45); }
.gap-row { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; font-size: 11px; color: var(--muted); }
.gap-row b { color: var(--text); font-size: 13px; font-variant-numeric: tabular-nums; }
.gap-row b.warn { color: var(--warn); }
.gap-arrow { opacity: 0.5; }
.gap-value { margin-left: auto; font-weight: 700; font-size: 12px; }
.gap-box .q-bar { display: block; margin: 6px 0; }
.gap-box .btn { width: 100%; }

/* --------------- Переходы по подсказкам к блокам управления -------------- */
.jump {
  color: var(--accent-2);
  font-weight: 700;
  cursor: pointer;
  border-bottom: 1px dashed rgba(96, 165, 250, 0.5);
  text-decoration: none;
}
.jump:hover { color: var(--text); border-bottom-color: var(--text); }

/* Тач-цели телефона. Инлайн-ссылки остаются инлайновыми (иначе поедет
   вёрстка), но их область нажатия расширяется псевдоэлементом — палец
   попадает в 15-пиксельную строку не лучше, чем в игольное ушко. */
@media (max-width: 560px) {
  .jump, .todo-jump, a.small-link { position: relative; }
  .jump::after, .todo-jump::after, a.small-link::after {
    content: ''; position: absolute; inset: -9px -6px;
  }
  /* Кнопки шапки: минимальная ширина, чтобы иконка не превращалась в полоску */
  .topbar-actions .btn, .topbar .btn { min-width: 40px; }
  /* Флажки алгоритмов: 13 пикселей — это не тач-цель */
  input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--accent); }
}

/* Подсветка блока, к которому перешли: без неё непонятно, куда попал */
@keyframes jump-flash {
  0%   { box-shadow: 0 0 0 2px var(--accent-2), 0 0 18px rgba(96, 165, 250, 0.5); }
  100% { box-shadow: 0 0 0 2px rgba(96, 165, 250, 0), 0 0 18px rgba(96, 165, 250, 0); }
}
.jump-target { animation: jump-flash 1.6s ease-out; border-radius: 10px; }
.todo-jump { display: inline-block; margin-top: 6px; font-size: 12px; }
.alert .jump { white-space: nowrap; }

/* Экран отказа: показывается только когда игра не смогла запуститься */
.crash { padding: 24px; max-width: 720px; margin: 0 auto; }
.crash-panel .panel { border-color: var(--bad); }
.crash .crash-message {
  white-space: pre-wrap; word-break: break-word; font-size: 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 10px; margin: 10px 0; color: var(--muted); font-family: ui-monospace, monospace;
}

/* Скрипты выключены — например, при предпросмотре файла в Быстром просмотре
   или в «Файлах» на айфоне. WebKit там рисует HTML, но не выполняет JS, и от
   игры остаётся пустой каркас. Прячем каркас и объясняем, что произошло:
   пустые панели без объяснения читаются как сломанная программа. */
.nojs-hint { display: none; padding: 20px; max-width: 640px; margin: 0 auto; }
.nojs-hint .panel { border-color: var(--warn); }
.nojs-hint p { margin: 0 0 8px; }
.no-js .nojs-hint { display: block; }
.no-js .topbar, .no-js .layout, .no-js #modal-root, .no-js #file-hint { display: none; }

/* Телефон: шапка из шести показателей занимает по высоте пол-экрана, и если
   оставить её липкой, на игру места не остаётся. Отпускаем — прокрутка вверх
   стоит одного движения, а экран нужен весь. */
/* Одна колонка — значит порядок сверху вниз решает всё. По разметке первой
   идёт левая колонка с ползунками: на широком экране она стоит сбоку и ничему
   не мешает, а на телефоне отодвигала итоги месяца почти на три экрана вниз.
   Порядок чтения на телефоне тот же, что и логика хода: что случилось →
   что делать → чем управлять → справочные таблицы. */
@media (max-width: 980px) {
  .layout { display: flex; flex-direction: column; }
  .col-center { order: 1; }
  .col-left { order: 2; }
  .col-right { order: 3; }
  /* Без min-width: 0 колонка не может стать уже своего самого широкого
     содержимого — и широкая таблица растягивает всю страницу вместо того,
     чтобы прокручиваться внутри панели. */
  .col-center, .col-left, .col-right { min-width: 0; }
  .col-center > * { min-width: 0; }
}

/* --------------------- Пальцы, а не курсор ------------------------------
   На телефоне попасть в ползунок высотой 16 px и во вкладку высотой 21 px
   нечем: общепринятый минимум для пальца — 44 px. Увеличивается только
   область нажатия, внешний вид остаётся прежним — иначе интерфейс, собранный
   под плотную сетку показателей, расползётся. Приём один и тот же:
   вертикальные отступы плюс подложка-псевдоэлемент.
   ------------------------------------------------------------------------ */
@media (hover: none) and (pointer: coarse), (max-width: 700px) {
  .lever input[type="range"],
  .algo-param input[type="range"],
  .release-row input[type=range] {
    /* Дорожка остаётся тонкой, а хвататься можно за всю высоту */
    height: 40px;
    padding: 0;
    background: transparent;
  }
  .tab, .chart-tabs button {
    position: relative;
    min-height: 32px;
    display: inline-flex;
    align-items: center;
  }
  .tab::after, .chart-tabs button::after, .lever-why::after {
    content: "";
    position: absolute;
    inset: -8px -6px;
  }
  .lever-why {
    position: relative;
    display: inline-block;
    padding: 9px 0;
  }
  /* Плитки выбора (жанр, масштаб, сегмент) и мелкие кнопки в таблицах */
  .pick button, .btn.small {
    position: relative;
    min-height: 32px;
  }
  .pick button::after, .btn.small::after {
    content: "";
    position: absolute;
    inset: -7px -4px;
  }
}

@media (max-width: 700px) {
  /* Кнопки уходят вниз отдельной полосой, поэтому шапка складывается в две
     строки: название и плитка показателей. Без этого показатели вытягивались
     в узкий столбец у правого края — рядом с пустым местом во всю ширину. */
  .topbar {
    position: static;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 10px 12px;
    /* Размытие обязано уйти: элемент с backdrop-filter становится точкой
       отсчёта для position: fixed внутри себя, и полоса кнопок прилипала
       не к экрану, а к низу шапки. Шапка здесь всё равно не липкая — размывать
       под ней нечего. */
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .kpi { min-width: 0; padding: 5px 8px; }
  .kpi .k-value { font-size: 15px; }
  .kpi .k-label, .kpi .k-delta { font-size: 11px; }
  .layout { padding: 10px; gap: 10px; }
  .col-left, .col-right { position: static; max-height: none; }

  /* Кнопки уезжают вниз и остаются на месте. Шапка на телефоне занимает по
     высоте пол-экрана, и держать её липкой нельзя — а «сыграть месяц» нужен
     всегда: без этого после каждого хода приходится прокручивать страницу
     обратно наверх. */
  .topbar-actions {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
    background: rgba(11, 17, 32, 0.96);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--line);
  }
  /* Четыре кнопки должны поместиться в ширину телефона: без права ужиматься
     полоса становится шире экрана, браузер отдаляет страницу целиком, и
     закреплённая полоса уезжает за нижний край. */
  .topbar-actions { flex-wrap: wrap; }
  .topbar-actions .btn { padding: 10px 10px; min-width: 0; flex-shrink: 1; }
  /* Кнопка хода забирает отдельную строку: вчетвером они в ширину телефона
     не помещаются, а полоса шире экрана заставляет браузер отдалить страницу
     целиком — и тогда она же уезжает за нижний край. */
  .topbar-actions #btn-next { flex: 1 1 100%; order: -1; }
  /* Отступ снизу — под реальную высоту полосы. Кнопка хода на своей строке
     делает полосу двухэтажной (~96px): с прежними 72px полоса накрывала
     последние строки страницы, включая сноску о числах. */
  body { padding-bottom: calc(104px + env(safe-area-inset-bottom)); }

  /* Модалка на телефоне — плотнее: экран приветствия должен помещаться
     в один экран без прокрутки, и половину его высоты съедали поля
     и межабзацные отступы, а не текст. */
  .modal-bg { padding: 10px; }
  .modal { padding: 14px; }
  .modal h2 { font-size: 17px; margin: 0 0 8px; }
  .modal p { margin: 6px 0; }
  .modal-actions { margin-top: 10px; }

  /* Широкая таблица прокручивается внутри своей панели, а не растягивает
     страницу. Горизонтальная прокрутка всего экрана на телефоне ломает не
     только вёрстку: браузер отдаляет страницу целиком, визуальная область
     становится выше вёрстки, и закреплённая полоса кнопок уезжает за экран. */
  /* Панель никогда не шире колонки: лишнее прокручивается внутри неё.
     max-width обязателен — одного overflow-x мало, потому что ширину
     колонке задаёт самое широкое содержимое. */
  .col-center, .col-center > *, .col-center .panel,
  .col-left, .col-right { max-width: 100%; }
  .col-center .panel, .col-right, .col-left { overflow-x: auto; }
  /* Таблица перестаёт быть таблицей.
     Пять-шесть колонок в 390 пикселей не помещаются ни при каком размере
     шрифта: либо уезжают вбок и последних не видно, либо шапка ломается
     по слогам в столбик из отдельных слов. Поэтому строка становится
     карточкой, а имя колонки — подписью слева от числа. Подписи ставит
     shared/tables.js, забирая их из шапки той же таблицы. */
  table.data thead { display: none; }
  table.data, table.data tbody, table.data tr, table.data td { display: block; }
  /* Короткие значения идут по два в ряд: столбик из «31», «54%», «40%»
     растягивает карточку на пол-экрана впустую. Название строки и последняя
     ячейка (обычно кнопка) занимают всю ширину. */
  table.data tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 9px 12px;
    margin-bottom: 8px;
    background: rgba(255, 255, 255, 0.015);
  }
  table.data td:first-child,
  table.data td.wide { grid-column: 1 / -1; }
  /* Подпись стоит над числом, а не слева от него. Бок о бок они дерутся
     за ширину: длинная подпись съедает место, и число переносится по слогам
     столбиком. Сверху вниз места хватает всегда. */
  table.data td {
    display: block;
    border-bottom: 0;
    padding: 5px 0 0;
    text-align: left;
    font-size: 14px;
  }
  table.data td[data-label]::before {
    content: attr(data-label);
    display: block;
    color: var(--muted);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 1px;
  }
  /* Первая ячейка — это название строки, ему подпись не нужна: оно и есть
     заголовок карточки. */
  table.data td:first-child {
    display: block;
    text-align: left;
    font-size: 15px;
    padding-bottom: 6px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--line);
  }
  table.data td:first-child::before { content: none; }
  table.data td:empty { display: none; }
  table.data tr.sub td:first-child { padding-left: 0; }
  table.data tr.total { border-color: var(--accent-2); }
  /* Кнопка в карточке занимает всю ширину: попасть пальцем в узкую ячейку
     на краю экрана невозможно. */
  table.data td .btn { width: 100%; margin-top: 4px; }
}

/* Постоянная оговорка о числах — одна строка мелким шрифтом под всеми
   колонками. Живёт в обычном потоке документа: на телефоне отступ снизу
   у body резервирует место под закреплённую полосу кнопок, поэтому сноска
   стоит над ней и ни на что не наезжает. */
.app-foot {
  padding: 2px 14px 14px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
  text-align: center;
}

/* ============================================================================
   НОВОГРАД (games/ecosystem): собственные органы управления — сегментные
   политики, бюджетная полоса, карта экосистемы. Только новые классы:
   старые игры этих имён не используют, правки обратимо-совместимы.
   ============================================================================ */
.policy-seg { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; }
.policy-seg button {
  /* Не ужиматься уже текста: лучше перенос на новую строку, чем срезанная подпись */
  flex: 1 0 auto; background: transparent; border: 1px solid var(--line);
  color: var(--muted); border-radius: 8px; padding: 5px 6px; font-size: 11px;
  cursor: pointer; line-height: 1.2; min-height: 30px;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.policy-seg button:hover { color: var(--text); border-color: rgba(148, 163, 184, 0.45); }
.policy-seg button.active {
  color: var(--text); border-color: var(--accent); background: rgba(74, 222, 128, 0.1);
}
.policy-note { font-size: 11px; color: var(--muted); margin-top: 4px; line-height: 1.4; }

.budget-bar {
  display: flex; height: 12px; border-radius: 6px; overflow: hidden;
  margin: 6px 0 5px; background: rgba(148, 163, 184, 0.12);
}
.budget-bar span { display: block; height: 100%; min-width: 1px; }
.budget-legend { display: flex; flex-wrap: wrap; gap: 3px 12px; font-size: 11px; color: var(--muted); }
.budget-legend i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; margin-right: 4px; }

/* Карта адаптивная: на узком контейнере она перестраивается вертикально
   (класс map-v ставит рендер), поэтому ни прокрутки, ни ужатия текста нет. */
.eco-map svg { width: 100%; height: auto; display: block; }
.eco-map svg.map-v { max-width: 430px; margin: 0 auto; }
.eco-map .node { cursor: pointer; }
.eco-map .flow { fill: none; stroke-width: 1.5; opacity: 0.75; }
.eco-map text { font-size: 12px; fill: var(--text); }
/* На широком мониторе схема растягивалась на всю панель вместе с текстом:
   при viewBox 700 и панели 1400 всё внутри удваивалось, подписи наезжали на
   край и обрезались. Ширина схемы ограничена — на больших экранах она стоит
   по центру в своём естественном масштабе. */
.eco-map svg { display: block; max-width: 820px; margin: 0 auto; }
.eco-map svg.map-v { max-width: 420px; }
.eco-map .m-muted { fill: var(--muted); font-size: 11px; }
.eco-map .m-num { font-weight: 700; }

/* Карточки типов организаторов (БИЛЕТВИЛЬ): решение о канале продаж — это
   не строка таблицы, а карточка с ценой, темпом и тем, что тип принесёт. */
.org-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px;
}
.org-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--panel);
}
.org-card.on { border-color: var(--accent); }
.org-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.org-rows { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.org-rows > div { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.org-rows span { color: var(--muted); }
.org-rows b { text-align: right; font-variant-numeric: tabular-nums; }
.org-card .btn { margin-top: auto; }

/* Карта города (НОВОЕДА): плитки районов по оси расстояния */
/* Заливка полупрозрачностью, а не смешиванием цветов средствами CSS:
   планка совместимости — Safari 14.1, а функция смешивания появилась только
   в 16.2. Проверка сборок ловит её по имени, включая упоминание в
   комментарии, — поэтому здесь оно и не написано. */
.eco-map .m-name { fill: var(--text); font-size: 12px; font-weight: 600; }
.eco-map .m-small { fill: var(--text); font-size: 11px; }
.eco-map .m-axis { stroke: var(--line); }
.map-scroll { overflow-x: auto; }
.map-foot {
  display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap;
  font-size: 12px; margin-top: 6px;
}

/* Легенда сегментов под схемой месяца (КИНОРЕКА) */
.flow-legend { display: flex; flex-wrap: wrap; gap: 10px; margin: 6px 0 2px; font-size: 11px; }
.flow-key { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); }
.flow-key i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }

/* Карта холдинга (НОВОГРАД): круги баз, связи, волны охвата */
.holding .e-link { fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-dasharray: 4 4; opacity: 0.5; }
.holding .e-link.on { stroke-width: 2.6; stroke-dasharray: none; opacity: 0.8; }
.holding .e-wave { fill: none; stroke: var(--line); opacity: 0.5; }
/* Подписи лежат поверх связей и волн — отсюда обводка фоном панели */
.holding text { paint-order: stroke; stroke: var(--panel); stroke-width: 3px; stroke-linejoin: round; }
.holding .node { cursor: pointer; }



/* Условная карта города (НОВОЕДА): кварталы, дороги, граница нормы */
.city-map .m-quarter { fill: var(--panel-2, #1b2333); stroke: var(--line); stroke-width: 1.5; }
/* Фон квартала и уровень «наша доля района» внутри него */
.city-map .m-quarter-bg { fill: var(--panel-2, #16213a); fill-opacity: 0.5; stroke: none; }
.city-map .m-share { fill-opacity: 0.55; }
.city-map .m-share.m-good { fill: var(--good); }
.city-map .m-share.m-bad, .city-map .m-share.m-closing { fill: var(--bad); }
.city-map .m-quarter.m-good { fill: none; stroke: var(--good); }
.city-map .m-quarter.m-bad { fill: none; stroke: var(--bad); }
.city-map .m-quarter.m-off { fill: none; stroke: var(--line); }
.city-map .m-quarter.m-closing { fill: none; stroke: var(--bad); stroke-dasharray: 5 4; }
.city-map .m-quarter.m-plan { fill: none; stroke: var(--accent); }
/* Квартал — орган управления: нажатие открывает район */
/* pointer-events: all — иначе незакрашенный квартал (закрытый район) не
   ловит нажатие вовсе: по спецификации SVG прозрачная заливка не цель */
/* Городская черта: край города, штрихпунктиром — как на карте */
.city-map .m-border {
  fill: var(--panel-2, #16213a); fill-opacity: 0.45;
  stroke: var(--line); stroke-width: 1.4; stroke-dasharray: 12 4 3 4;
}

/* Плечо доставки внутри квартала: ресторан, путь, клиент */
.city-map .m-leg rect, .city-map .m-leg circle { fill: var(--text); fill-opacity: 0.8; }
.city-map .m-leg line { stroke: var(--text); stroke-opacity: 0.7; stroke-width: 1.6; stroke-dasharray: 3 2; }
/* Опоздание должно быть видно с расстояния вытянутой руки: ниточка в
   ~20 px — самый мелкий орган карты, и прежнее покраснение при той же
   толщине читалось только в упор (аудит 2026-08, ось визуала) */
.city-map .m-leg.late rect, .city-map .m-leg.late circle { fill: var(--bad); fill-opacity: 1; }
.city-map .m-leg.late line { stroke: var(--bad); stroke-opacity: 1; stroke-width: 2.6; stroke-dasharray: 4 2; }
.city-map .m-leader { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 3; }
.city-map .m-hit { cursor: pointer; }
.city-map .m-hit polygon { pointer-events: all; }
.city-map .m-hit:hover .m-quarter { stroke-width: 2.4; }
.map-list li { cursor: pointer; }

/* Интерактивная легенда карты: пункт подсвечивает свой орган, остальное гаснет */
.map-legend .legend-item { cursor: help; border-bottom: 1px dotted var(--line); }
.map-legend .legend-item:hover, .map-legend .legend-item:focus { color: var(--text); border-bottom-color: var(--text); outline: none; }
.city-map[data-hl] .m-quarter, .city-map[data-hl] .m-quarter-bg, .city-map[data-hl] .m-share,
.city-map[data-hl] .m-block, .city-map[data-hl] .m-leg, .city-map[data-hl] .m-name { opacity: 0.18; transition: opacity 0.15s; }
.city-map[data-hl="area"] .m-quarter-bg, .city-map[data-hl="area"] .m-quarter, .city-map[data-hl="area"] .m-name { opacity: 1; }
.city-map[data-hl="share"] .m-share, .city-map[data-hl="share"] .m-quarter { opacity: 1; }
.city-map[data-hl="color"] .m-quarter, .city-map[data-hl="color"] .m-share { opacity: 1; }
.city-map[data-hl="houses"] .m-block, .city-map[data-hl="houses"] .m-quarter { opacity: 1; }
.city-map[data-hl="leg"] .m-leg, .city-map[data-hl="leg"] .m-quarter { opacity: 1; }
.city-map[data-hl="outline"] .m-quarter { opacity: 1; }
.city-map .m-water { fill: var(--accent); fill-opacity: 0.13; stroke: var(--accent); stroke-opacity: 0.3; }
.city-map .m-block { fill: var(--text); fill-opacity: 0.42; }
.city-map .m-hub rect, .city-map .m-hub path { fill: var(--accent); }
/* Подписи в кварталах читаются поверх застройки — отсюда обводка фоном */
.city-map .m-name, .city-map .m-small, .city-map .m-muted {
  paint-order: stroke; stroke: var(--panel); stroke-width: 3px; stroke-linejoin: round; }
.city-map.narrow .m-name { font-size: 16px; font-weight: 800; }
.city-map.narrow .m-muted { font-size: 18px; }
/* Легенда карты под катом: полный разбор кодировок нужен один раз, а место
   под картой занимает каждый ход */
.map-legend { margin-top: 6px; }
.map-legend summary {
  cursor: pointer; color: var(--muted); font-size: 11px;
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
}
.map-legend summary::-webkit-details-marker { display: none; }
.map-legend summary::before { content: '▸'; font-size: 10px; }
.map-legend[open] summary::before { content: '▾'; }
.map-legend summary:hover { color: var(--text); }
.map-legend .funding-note { margin-top: 6px; }
.map-list { list-style: none; margin: 6px 0 0; padding: 0; font-size: 12px; }
.map-list li { padding: 2px 0; border-bottom: 1px solid var(--line); }
.map-list li:last-child { border-bottom: 0; }

/* Длинное объяснение под катом: раскрывашка в стиле «Как читать карту».
   Справочный абзац нужен один раз, а место в панели занимает каждый ход. */
.more { margin-top: 4px; }
.more > summary {
  cursor: pointer; color: var(--muted); font-size: 11px;
  list-style: none; display: inline-flex; align-items: center; gap: 5px;
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::before { content: '▸'; font-size: 10px; }
.more[open] > summary::before { content: '▾'; }
.more > summary:hover { color: var(--text); }
.more > .funding-note { margin-top: 6px; }

/* «Мультиплекс» КИНОРЕКИ: подсветка группы с легенды, как на карте НОВОЕДЫ */
.plex[data-hl] .px { opacity: 0.15; transition: opacity 0.15s; }
.plex[data-hl="premium"] .px-premium, .plex[data-hl="premium"] .px-down { opacity: 1; }
.plex[data-hl="ads"] .px-ads, .plex[data-hl="ads"] .px-down { opacity: 1; }
.plex[data-hl="rival"] .px-rival, .plex[data-hl="rival"] .px-net { opacity: 1; }
.plex[data-hl="in"] .px-in { opacity: 1; }
.plex[data-hl="out"] .px-out { opacity: 1; }
.plex .legend-item { cursor: help; border-bottom: 1px dotted var(--line); }
.plex .legend-item:hover, .plex .legend-item:focus { color: var(--text); border-bottom-color: var(--text); outline: none; }

/* «Кварталы» БИЛЕТВИЛЯ: подсветка группы с легенды, как на карте НОВОЕДЫ */
.quarters[data-hl] .qx { opacity: 0.15; transition: opacity 0.15s; }
.quarters[data-hl] .qx-frame, .quarters[data-hl] .qx-name { opacity: 0.45; }
.quarters[data-hl="share"] .qx-share { opacity: 1; }
.quarters[data-hl="widget"] .qx-widget { opacity: 1; }
.quarters[data-hl="own"] .qx-frame { opacity: 1; }
.quarters[data-hl="loss"] .qx-loss { opacity: 1; }
.quarters[data-hl="loss"] .qt:not(.qt-dead) .qx-frame { opacity: 1; }
.quarters .legend-item { cursor: help; border-bottom: 1px dotted var(--line); }
.quarters .legend-item:hover, .quarters .legend-item:focus { color: var(--text); border-bottom-color: var(--text); outline: none; }

/* Полоса каналов в карточке типа организаторов (БИЛЕТВИЛЬ): те же три числа,
   что раньше пыталась показать схема потоков, — одной 100%-полосой */
.chan-bar {
  display: flex; height: 11px; border-radius: 6px; overflow: hidden;
  margin: 8px 0 3px; background: rgba(148, 163, 184, 0.12);
}
.chan-bar span { height: 100%; }
.chan-lbl { display: flex; justify-content: space-between; gap: 6px; font-size: 10px; color: var(--muted); margin-bottom: 6px; }

/* Группы рычагов (НОВОЕДА): сворачиваемые подзаголовки делят столбец по смыслу */
.lever-group { margin-top: 16px; }
.lever-group:first-child { margin-top: 0; }
.lever-group-title {
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line);
  padding-bottom: 5px; margin-bottom: 8px;
  cursor: pointer; list-style: none; user-select: none;
}
.lever-group-title::-webkit-details-marker { display: none; }
.lever-group-title::before {
  content: '▸'; display: inline-block; margin-right: 6px;
  transition: transform 0.15s ease;
}
details[open] > .lever-group-title::before { transform: rotate(90deg); }
.lever-group-title:hover { color: var(--fg, #e2e8f0); }
