/* Тема день/ночь через CSS-переменные. Нейтральная деловая палитра. */
:root[data-theme="light"] {
  --bg: #f5f6f8; --surface: #ffffff; --text: #1c2330; --muted: #6b7484;
  --border: #e1e4ea; --accent: #2b6cb0; --accent-weak: #e6f0fa;
  --ok: #1f7a4d; --warn: #b7791f; --error: #c23b3b; --recalc: #6b46c1;
  --shadow: 0 1px 3px rgba(20,30,50,.08);
}
:root[data-theme="dark"] {
  --bg: #11151c; --surface: #1a212c; --text: #e6e9ef; --muted: #93a0b4;
  --border: #2a3340; --accent: #5aa2e0; --accent-weak: #1d2c3d;
  --ok: #54c08a; --warn: #e0b35a; --error: #e57373; --recalc: #b794f4;
  --shadow: 0 1px 3px rgba(0,0,0,.4);
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--text);
  font: 15px/1.5 -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code, .mono { font-family: "SF Mono", "Cascadia Code", Consolas, monospace; }

/* --- Раскладка с левой панелью --- */
.layout { display: flex; min-height: 100vh; }
/* overflow-y: auto — у панели своя прокрутка. Без неё меню админа (десяток пунктов + подвал
   с темой и выходом) в невысоком окне просто обрезается: докрутить до «Выхода» нечем. */
.sidebar { width: 220px; flex-shrink: 0; background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; padding: 16px 14px; position: sticky; top: 0; height: 100vh;
  overflow-y: auto; overscroll-behavior: contain; }
.sidebar .brand { font-weight: 700; font-size: 18px; display: block; margin-bottom: 14px; }
.search-mini input { width: 100%; padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg); color: var(--text); margin-bottom: 14px; }
/* flex-shrink: 0 — иначе во flex-колонке с прокруткой пункты сжимаются в тонкие полоски вместо
   того, чтобы дать панели прокрутиться: содержимое «влезает», и скроллить становится нечего. */
.side-nav { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.side-nav a { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px;
  color: var(--text); }
.side-nav a:hover { background: var(--bg); text-decoration: none; }
.side-nav a.active { background: var(--accent-weak); color: var(--accent); font-weight: 600; }
.side-nav .ic { width: 18px; text-align: center; opacity: .8; }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 8px; padding-top: 14px;
  border-top: 1px solid var(--border); flex-shrink: 0; }
.side-foot .user-line { color: var(--muted); font-size: 12.5px; }
.side-foot .logout { font-size: 13px; }
.side-foot .copyright { color: var(--muted); font-size: 11px; opacity: .7; }
.theme-toggle { background: none; border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); cursor: pointer; font-size: 13px; padding: 6px 10px; text-align: left; }
.content { flex: 1; min-width: 0; padding: 24px 28px; max-width: 1100px; }
.page-head { display: flex; align-items: center; justify-content: space-between; }

/* Верхняя плашка с «бургером» и затемнение — только на узких экранах (см. @media ниже). */
.topbar { display: none; align-items: center; gap: 12px; position: sticky; top: 0; z-index: 40;
  background: var(--surface); border-bottom: 1px solid var(--border); padding: 9px 14px; }
.topbar .brand { font-weight: 700; font-size: 17px; }
.nav-toggle { background: none; border: 1px solid var(--border); border-radius: 8px; color: var(--text);
  cursor: pointer; font-size: 19px; line-height: 1; padding: 5px 10px; }
/* touch-action: none — по затемнению не «протаскиваем» страницу под ним; оно только закрывает
   панель по нажатию, прокручивать там нечего. */
.nav-overlay { display: none; position: fixed; inset: 0; background: rgba(10,15,25,.45); z-index: 45;
  touch-action: none; overscroll-behavior: contain; }

/* Узкий экран (телефон вертикально / узкое окно): панель уезжает за левый край, выезжает по «бургеру». */
@media (max-width: 860px) {
  /* Зоны нажатия в выехавшей панели: «Выход» был высотой 20px, переключатель темы — 29px.
     Порог именно 860px, а не 760: панель становится выезжающей здесь, и ниже этой ширины
     по её пунктам попадают пальцем, а не курсором. */
  .side-foot .logout { display: inline-block; padding: 8px 2px; }
  .theme-toggle { padding: 9px 12px; }
  .topbar .brand, .sidebar .brand { display: inline-block; padding: 4px 0; }
  .layout { flex-direction: column; }
  .topbar { display: flex; }
  /* height: 100dvh, а не 100vh: на телефоне 100vh считается по экрану БЕЗ учёта выезжающей
     панели браузера, поэтому низ меню (тема, выход) оказывался под ней и не доставался.
     100vh оставлен первым — как запасной для браузеров без dvh. */
  .sidebar { position: fixed; top: 0; left: 0; height: 100vh; height: 100dvh;
    width: 264px; max-width: 84vw; z-index: 50;
    transform: translateX(-100%); transition: transform .22s ease; box-shadow: 2px 0 16px rgba(0,0,0,.25);
    overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .sidebar.open { transform: translateX(0); }
  body.nav-open .nav-overlay { display: block; }
  /* Пока панель открыта, страница под ней не двигается. Без этого жест листания уходил насквозь:
     панель стояла на месте, а прокручивалось то, что за ней. overflow: hidden (а не position:
     fixed) выбран намеренно — он не сбрасывает позицию прокрутки при закрытии.
     Класс висит и на <html>, и на <body>: какой из них является прокручиваемым элементом,
     зависит от браузера, и запереть надо тот, который реально едет. */
  html.nav-open, body.nav-open { overflow: hidden; }
  .content { padding: 16px 16px 28px; max-width: none; }
}

.container { max-width: 1080px; margin: 24px auto; padding: 0 20px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 18px 20px; margin-bottom: 18px; box-shadow: var(--shadow); }
h1 { font-size: 24px; margin: 0 0 4px; } h2 { font-size: 17px; margin: 0 0 12px; }
h3 { font-size: 15px; margin: 14px 0 6px; }
.muted { color: var(--muted); } .small { font-size: 12.5px; }

.grid { width: 100%; border-collapse: collapse; }
.grid th, .grid td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); }
.grid th { color: var(--muted); font-weight: 600; font-size: 13px; }
.grid.prov td:nth-child(2) { font-variant-numeric: tabular-nums; }

.badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 12px;
  border: 1px solid var(--border); vertical-align: middle; }
.badge.ours { background: var(--accent-weak); color: var(--accent); border-color: transparent; }
.badge.tech { background: transparent; } .badge.appclass { color: var(--muted); }
.badge.verified { color: var(--ok); border-color: transparent; }
.badge.warn { color: var(--warn); border-color: var(--warn); }

.conf { font-variant-numeric: tabular-nums; padding: 0 6px; border-radius: 6px; font-size: 12.5px; }
.conf-high { color: var(--ok); } .conf-mid { color: var(--warn); }
.conf-low { color: var(--error); } .conf-unknown { color: var(--muted); }

.flag { padding: 9px 12px; border-radius: 8px; margin: 6px 0; border-left: 4px solid var(--muted); background: var(--bg); }
.flag.error { border-color: var(--error); }
.flag.warn { border-color: var(--warn); }
.flag.info { border-color: var(--accent); }
.flag .mono { white-space: pre-wrap; word-break: break-word; }
.flag-title { font-weight: 600; }
.flag-level { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  padding: 1px 7px; border-radius: 6px; margin-right: 6px; vertical-align: middle; }
.flag.error .flag-level { background: var(--error); color: #fff; }
.flag.warn .flag-level { background: var(--warn); color: #fff; }
.flag.info .flag-level { background: var(--accent); color: #fff; }
.flag-why { margin-top: 3px; }

/* Разрядная таблица + график.
   Тень у края показывает, что вбок есть ещё содержимое. Без неё широкая таблица на телефоне
   выглядит не «прокручивается», а «обрезана»: колонка обрывается ровно по краю экрана, и человек
   считает это поломкой вёрстки, а не приглашением сдвинуть. Приём стандартный (Kizu/Roman
   Komarov): две «крышки» цветом фона держатся за содержимое (background-attachment: local) и
   уезжают вместе с ним, открывая радиальную тень, которая держится за рамку. */
.table-scroll {
  overflow-x: auto;
  background:
    linear-gradient(to right, var(--surface) 30%, transparent) 0 0,
    linear-gradient(to left,  var(--surface) 30%, transparent) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .13), transparent) 0 0,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .13), transparent) 100% 0;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* Панель прогресса: закрепляется вверху, пока идёт обход/распознавание (страница не прыгает). */
/* Панель прогресса: всегда закреплена вверху (наложением), видна одна — последняя обработка. */
/* Закрепляем панель, ТОЛЬКО пока идёт задание (класс pinned ставит скрипт страницы бренда).
   Раньше она липла всегда и при прокрутке длинного списка серий закрывала собой строку-другую —
   ради сообщения «DONE», которое уже никому не нужно. */
.jobs-panel.pinned { position: sticky; top: 8px; z-index: 6;
  border-color: var(--accent); box-shadow: 0 2px 12px rgba(0,0,0,.14); }
.jobs-history { margin-top: 8px; }
.jobs-history > summary { cursor: pointer; padding: 4px 0; }
.jobs-history .job.mini { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; }
/* Список кандидатов: компактные сворачиваемые серии в ограниченной по высоте области. */
.cand-list { max-height: 56vh; overflow-y: auto; border: 1px solid var(--border); border-radius: 8px; }
.cand-series { border-bottom: 1px solid var(--border); }
.cand-series:last-child { border-bottom: none; }
.cand-series > summary { cursor: pointer; padding: 7px 10px; display: flex; align-items: center; gap: 8px; list-style: none; }
.cand-series > summary::-webkit-details-marker { display: none; }
.cand-series > summary::before { content: "▸"; color: var(--muted); transition: transform .12s; }
.cand-series[open] > summary::before { content: "▾"; }
.cand-series > summary:hover { background: var(--bg); }
.cand-items { margin: 0; padding: 2px 10px 8px 30px; list-style: none; }
.cand-items li { display: flex; align-items: baseline; gap: 8px; padding: 2px 0; }
.cand-items .ci-model { word-break: break-word; overflow-wrap: anywhere; }
.cand-head { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-bottom: 8px; }

/* Подбор аналога */
.match-form .mode-tabs { display: flex; gap: 18px; margin-bottom: 10px; }
.match-form select, .match-form input[type=text], .match-form .pfields input { min-width: 160px; }
.pfields { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.pfields label, .match-form > .match-form label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.match-form .mode-model label, .match-form .tol-row label { display: inline-flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.tol-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px; margin-top: 12px; }
.match-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.match-card .mh { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 8px; }
.match-card .score { font-size: 12.5px; font-weight: 600; color: var(--accent); white-space: nowrap; }
.mtable td, .mtable th { padding: 5px 8px; }
.mtag { display: inline-block; padding: 1px 7px; border-radius: 5px; font-size: 12px; }
/* Три цвета светофора: зелёный — подходит/лучше, жёлтый — частично/обратить внимание
   (включая «нет данных» — не путать с зелёным «то же»), красный — сильно не подходит. */
.v-better, .v-fit, .v-same { background: color-mix(in srgb, var(--ok) 26%, transparent); }
.v-nofit { background: color-mix(in srgb, var(--error) 24%, transparent); }
.v-worse, .v-smaller, .v-amber, .v-na { background: color-mix(in srgb, #b7791f 26%, transparent); }
.match-tabs { display: flex; gap: 6px; margin-bottom: 12px; border-bottom: 1px solid var(--border); }
.match-tabs a { padding: 8px 14px; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; }
.match-tabs a.on { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
.spec-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.pass-row { padding: 7px 0; border-top: 1px solid var(--border); }
.pass-row:first-child { border-top: none; }
.pass-cells { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.spec-used li { margin: 3px 0; }
@media (max-width: 760px) { .spec-cols { grid-template-columns: 1fr; } }

/* Страница «О проекте» — рендер Markdown */
.md-body { max-width: 920px; line-height: 1.6; }
.md-body h1 { font-size: 26px; margin: 0 0 12px; }
.md-body h2 { font-size: 20px; margin: 26px 0 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.md-body h3 { font-size: 16px; margin: 18px 0 8px; }
.md-body p, .md-body li { color: var(--text); }
.md-body a { color: var(--accent); }
.md-body ul, .md-body ol { padding-left: 22px; }
.md-body li { margin: 3px 0; }
.md-body code { background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; font-size: 13px; }
.md-body pre { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; overflow-x: auto; }
.md-body pre code { background: none; border: none; padding: 0; font-size: 12.5px; line-height: 1.45; }
.md-body table { border-collapse: collapse; margin: 10px 0; width: 100%; }
.md-body th, .md-body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; vertical-align: top; }
.md-body th { background: var(--bg); color: var(--muted); }
.md-body blockquote { border-left: 3px solid var(--accent); margin: 10px 0; padding: 4px 12px; color: var(--muted); }
.md-body hr { border: none; border-top: 1px solid var(--border); margin: 22px 0; }

/* Иконка проекта (SVG): корпус — currentColor, молния — accent → реагирует на тему. */
.logo-ic { width: 1.15em; height: 1.15em; vertical-align: -0.2em; flex-shrink: 0; }
.brand .logo-ic { margin-right: 2px; }
.login h1 .logo-ic { width: 1.1em; height: 1.1em; vertical-align: -0.16em; }

/* Разделитель служебной части меню — видна только администратору. */
.side-sep { margin: 12px 0 4px; padding: 0 12px; font-size: 10px; font-weight: 700;
  letter-spacing: .8px; text-transform: uppercase; color: var(--muted); }
.side-sep:empty { margin: 8px 0 0; padding: 0; border-top: 1px solid var(--border); }

/* Маркер нестыковки у модели в каталоге + галочка фильтра по ним. */
.issue-mark { color: var(--warn); font-size: 12px; cursor: help; }
.cat-issues-chk { white-space: nowrap; font-size: 13px; }
.cat-issues-chk:has(:checked) { color: var(--warn); font-weight: 600; }

/* Бренд, скрытый от пользователей: бейдж в каталоге + карточка переключателя на странице бренда. */
.tag.hidden-brand { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); }
.vis-card.vis-off { border-color: color-mix(in srgb, var(--warn) 55%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }

/* Личная статистика в «Аккаунте». */
.stat-row { display: flex; flex-wrap: wrap; gap: 10px; }
.stat { flex: 1 1 110px; min-width: 100px; text-align: center; padding: 10px 8px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface); }
.stat-n { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* Переписка по обращению. */
.msg { padding: 8px 10px; border-radius: 8px; margin: 6px 0; border: 1px solid var(--border); }
.msg-admin { background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.msg-body { white-space: pre-wrap; margin-top: 4px; }
.tag.st-new { color: var(--warn); }
.tag.st-answered, .tag.st-closed { color: var(--muted); }
.copy-link { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  padding: 4px 6px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }
/* Разрядная таблица: заголовки и данные по центру колонки, чтобы значение совпадало со своим
   столбцом длительности; первый столбец (В/эл) — по левому краю. */
.grid.discharge th, .grid.discharge td { text-align: center; white-space: nowrap; }
.grid.discharge td { font-variant-numeric: tabular-nums; }
.grid.discharge th:first-child, .grid.discharge td:first-child { text-align: left; }
.discharge-chart { margin: 4px 0 14px; }
.dchart { width: 100%; max-width: 660px; height: auto; cursor: grab; touch-action: none; }
.dchart:active { cursor: grabbing; }
.dchart .axis { stroke: var(--border); stroke-width: 1; }
.dchart .grid { stroke: var(--border); stroke-width: 1; opacity: .4; }
.dchart .tick { fill: var(--muted); font-size: 10px; }
.dctrl { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.dctrl button { width: 26px; height: 24px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text); cursor: pointer; font-size: 14px; line-height: 1; }
.dctrl button:hover { background: var(--bg); }
.dctrl .small { margin-left: 6px; }
.dlegend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: var(--muted); margin-top: 4px; }
.dlegend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: middle; }
.chart-tip { position: absolute; z-index: 5; pointer-events: none; background: var(--card); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px; font-size: 12px; line-height: 1.35;
  box-shadow: 0 2px 8px rgba(0,0,0,0.18); white-space: nowrap; }
.dchart { cursor: crosshair; }
.btn.small { padding: 4px 10px; font-size: 12.5px; }

.normalized { margin-top: 12px; padding-top: 10px; border-top: 1px dashed var(--border); }
.recalc { color: var(--recalc); font-weight: 700; }

.tag { display: inline-block; padding: 1px 9px; border-radius: 999px; font-size: 12px;
  border: 1px solid var(--border); color: var(--muted); }
.tag.tech { background: var(--accent-weak); color: var(--accent); border-color: transparent; font-weight: 600; }
.tag.appclass { background: transparent; }

.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; }
.chips li { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 4px 10px; font-size: 13px; }

.filters { display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap; }
.filters label, .login label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.filters input, .filters select, .login input {
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg); color: var(--text); }
.btn { border: 1px solid var(--border); border-radius: 8px; padding: 8px 16px; cursor: pointer;
  background: var(--surface); color: var(--text); font-size: 14px; }
.btn.primary { background: var(--accent); color: #fff; border-color: transparent; }

.login-wrap { display: flex; justify-content: center; margin-top: 8vh; }
.login { width: 340px; display: flex; flex-direction: column; gap: 12px; }
.login h1 { text-align: center; }

.foot { text-align: center; color: var(--muted); font-size: 12.5px; padding: 24px; }

/* Задания и прогресс */
.progress { height: 4px; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; overflow: hidden; margin: 4px 0; }
.progress .bar { height: 100%; background: var(--accent); transition: width .4s ease; }

.slow-status { display: none; align-items: center; gap: 8px; margin-top: 8px; }
.slow-status.on { display: flex; }
.slow-status .progress .bar { transition: width .15s linear; }
.job-head { display: flex; align-items: center; gap: 10px; }
.job-title { font-weight: 600; }
.job-status { font-size: 11px; text-transform: uppercase; padding: 1px 8px; border-radius: 6px; border: 1px solid var(--border); color: var(--muted); }
.st-running { color: var(--accent); border-color: var(--accent); }
.st-done { color: var(--ok); border-color: var(--ok); }
.st-error, .st-stopped { color: var(--error); border-color: var(--error); }
.job-meta { display: flex; justify-content: space-between; gap: 12px; margin-top: 2px; }
.job-result { color: var(--muted); margin-top: 2px; }
.job-result .err { color: var(--error); }
.job-errors { margin: 4px 0 0; padding-left: 18px; color: var(--error); }
.job-errors li { word-break: break-word; }
.job.mini { padding: 5px 0; border-top: 1px solid var(--border); }
/* компактная панель прогресса, чтобы не занимала много места */
.jobs-panel { padding: 12px 14px; }
.jobs-panel h2 { margin: 0 0 6px; font-size: 15px; }
.job.mini:first-child { border-top: none; }
form.inline { display: inline; }
.proc-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 8px 0; }
.inline-form { display: flex; gap: 10px 14px; align-items: center; flex-wrap: wrap; }
/* подпись + поле как единый блок, чтобы не разъезжались и не переносились по отдельности */
.inline-form label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.inline-form input[type=text], .inline-form input:not([type]), .inline-form select {
  padding: 6px 9px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg);
  color: var(--text); height: 34px; box-sizing: border-box; }

/* Формы редактирования */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form-grid label, .inline-form input, .series-form input, .danger-zone input {
  display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.form-grid label.wide, .form-grid .wide { grid-column: 1 / -1; }
.form-grid input, .form-grid textarea, .series-form input, .danger-zone input {
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg); color: var(--text); font-size: 14px; }
label.chk { flex-direction: row; align-items: center; gap: 6px; color: var(--text); }
.series-edit { padding: 10px 0; border-top: 1px solid var(--border); }
.series-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.series-name { min-width: 180px; } .restr { min-width: 180px; flex: 1; }
.series-tech { padding: 6px 8px; border: 1px solid var(--border); border-radius: 7px; background: var(--surface); color: var(--text); }
.save-ok { margin-left: 6px; font-size: 12.5px; color: var(--ok); opacity: 0; transition: opacity .2s; white-space: nowrap; }
.save-ok.show { opacity: 1; } .save-ok.err { color: var(--error); }
.tagpick { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.tagpick .chk { font-size: 12px; }
.btn.xs { padding: 0 6px; font-size: 12px; line-height: 1.6; }
.btn.danger { color: var(--error); border-color: var(--error); background: transparent; }
.danger-zone { border-color: var(--error); }
.hidden { display: none; }
/* Сравнение */
.nav-badge { background: var(--accent); color: #fff; border-radius: 999px; font-size: 11px; padding: 0 6px; margin-left: 2px; }
.head-actions { display: flex; align-items: center; gap: 10px; }
.cmp-basket { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
.chip { display: inline-flex; align-items: center; gap: 4px; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; padding: 3px 6px 3px 12px; }
.chip .x { border: none; background: none; color: var(--muted); cursor: pointer; font-size: 15px; }
.add-cmp .combo-input { min-width: 240px; }
/* Поисковый combobox — замена <select> на большие списки моделей (сравнение, подбор). */
.combo { position: relative; display: inline-block; }
.combo-menu { position: absolute; z-index: 20; top: 100%; left: 0; right: 0; margin-top: 2px;
  max-height: 260px; overflow-y: auto; background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,.18); }
.combo-opt { padding: 6px 10px; cursor: pointer; font-size: 13.5px; }
.combo-opt:hover, .combo-opt.active { background: var(--accent-weak); }
.combo-hint { padding: 6px 10px; }
.grid.cmp th, .grid.cmp td { text-align: center; vertical-align: top; }
.grid.cmp td.rlabel, .grid.cmp th:first-child { text-align: left; color: var(--muted); }
.grid.cmp tr.differ td.rlabel { color: var(--text); font-weight: 600; }
.grid.cmp td.best { background: color-mix(in srgb, var(--ok) 30%, transparent); box-shadow: inset 3px 0 0 var(--ok); font-weight: 600; }
.grid.cmp td.worst { background: color-mix(in srgb, var(--error) 26%, transparent); box-shadow: inset 3px 0 0 var(--error); }
.compare-chart { margin: 10px 0; }
.cand-form { margin-top: 12px; }
.cand-head { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin-bottom: 8px; }
.cand-form .grid td:first-child, .cand-form .grid th:first-child { width: 30px; text-align: center; }
.cand-form .series-row td { background: var(--bg); }
.check-head { display: flex; align-items: center; }
.param-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; }
.param-row label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.param-row input { padding: 6px 9px; border: 1px solid var(--border); border-radius: 7px; background: var(--bg); color: var(--text); }

/* Рендер README (страница /readme) */
.readme { line-height: 1.55; }
.readme h1 { font-size: 22px; }
.readme h2 { font-size: 18px; margin-top: 22px; border-top: 1px solid var(--border); padding-top: 14px; }
.readme h3 { font-size: 15px; }
.readme img { max-width: 100%; height: auto; border: 1px solid var(--border); border-radius: 8px; }
.readme table { border-collapse: collapse; margin: 8px 0; }
.readme th, .readme td { border: 1px solid var(--border); padding: 5px 9px; text-align: left; vertical-align: top; }
.readme pre { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 10px; overflow: auto; }
.readme code { background: var(--bg); padding: 1px 4px; border-radius: 4px; font-size: 12.5px; }
.readme pre code { background: none; padding: 0; }
.readme details { margin: 8px 0; } .readme summary { cursor: pointer; color: var(--accent); }
.readme .mermaid { background: var(--surface); text-align: center; margin: 12px 0; }
.readme blockquote { border-left: 3px solid var(--accent); margin: 8px 0; padding: 4px 12px; color: var(--muted); }

/* --- Каталог: панель, сворачиваемые бренды, сетка моделей --- */
.cat-toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 10px 0 8px; }
.cat-filter { flex: 1 1 260px; min-width: 0; padding: 8px 12px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface); color: var(--text); font-size: 14px; }
.cat-toolbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.brand-jump { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.brand-jump .jump { font-size: 12.5px; padding: 3px 10px; border: 1px solid var(--border);
  border-radius: 999px; color: var(--muted); }
.brand-jump .jump:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.brand-jump .jump.ours { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }

/* Бренд — <details>: заголовок остаётся кликабельным, содержимое сворачивается. */
details.brand-block > summary { list-style: none; cursor: pointer; }
details.brand-block > summary::-webkit-details-marker { display: none; }
.brand-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.brand-head::before { content: "▾"; color: var(--muted); font-size: 13px; width: 12px; }
details.brand-block:not([open]) > summary .brand-head::before,
details.brand-block:not([open]) > summary::before { content: "▸"; }
.brand-head h2 { margin: 0; }
.brand-head .counts { margin-left: 2px; white-space: nowrap; }
.gear { margin-left: auto; font-size: 18px; color: var(--muted); text-decoration: none; line-height: 1;
  padding: 4px 6px; }
.gear:hover { color: var(--accent); text-decoration: none; }
.series-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 14px 0 6px; }
.series-head h3 { margin: 0; }
.series-head .counts { font-variant-numeric: tabular-nums; }
/* Модели — настоящая сетка, а не флекс с min-width: колонки выравниваются, глаз идёт по столбцу. */
.model-list { list-style: none; padding-left: 0; margin: 4px 0 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 4px 14px; }
.model-list li { min-width: 0; padding: 3px 0; }
.model-list li[hidden] { display: none; }

/* --- Порядок серий в настройках бренда --- */
.section-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.section-head h2 { margin: 0; }
.series-edit { position: relative; }
.series-edit.dragging { opacity: .45; }
.series-order-ctl { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.drag-handle { cursor: grab; color: var(--muted); font-size: 15px; line-height: 1; padding: 2px 4px;
  user-select: none; }
.drag-handle:active { cursor: grabbing; }
.order-status { min-height: 18px; }

/* --- Мобильная раскладка и попадание пальцем --- */
/* Чекбокс с подписью — всегда в строку. Общее правило `label{flex-direction:column}` для форм
   ставило квадратик НАД текстом, из-за чего галочки «клемма», «технология» и теги серий
   выглядели как оторванные кнопки. */
label.chk, .tagpick label, .tol-row label.chk, .match-form label.chk {
  flex-direction: row; align-items: center; gap: 6px; }
.tagpick label { display: inline-flex; }
input[type=checkbox], input[type=radio] { width: 16px; height: 16px; flex-shrink: 0; margin: 0; }

@media (max-width: 760px) {
  /* Две колонки в формах на телефоне не помещаются: правая уезжала за край экрана. */
  .form-grid { grid-template-columns: 1fr; }
  .page-head { flex-wrap: wrap; gap: 8px; }
  .head-actions { flex-wrap: wrap; }
  .head-actions .btn { white-space: nowrap; }
  /* Любая таблица шире экрана скроллится внутри себя, а не растягивает страницу. */
  .card > table, .card > form > table { display: block; overflow-x: auto; max-width: 100%; }
  .match-tabs { overflow-x: auto; white-space: nowrap; }
  .match-tabs a { padding: 8px 10px; }
  .model-list { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  /* Пальцем в ссылку размером со строку текста не попасть — даём вертикальный запас. */
  .model-list li { padding: 6px 0; }
  .side-nav a { padding: 11px 10px; }
  .btn { padding: 9px 16px; }
  .btn.small { padding: 7px 12px; }
  /* Кнопки держим вместе справа: со space-between пустой счётчик разводил их по краям. */
  .cat-toolbar-right { width: 100%; justify-content: flex-end; }
}
/* «как считается» — пояснение к пересчёту прячется до востребования (см. model.html). */
.why { margin-top: 4px; }
.why > summary { cursor: pointer; color: var(--accent); font-size: 12.5px; list-style: none; }
.why > summary::-webkit-details-marker { display: none; }
.why > summary::before { content: "▸ "; }
.why[open] > summary::before { content: "▾ "; }

/* Подсказка требований к паролю: заполняется из app.js по ходу набора (см. data-password-form).
   Нейтральная точка до первого символа, галочка/крестик — после: красные крестики на пустом
   поле выглядят как претензия на пустом месте. */
.pw-hints { list-style: none; margin: 6px 0 10px; padding: 0; font-size: 12.5px; color: var(--muted); }
.pw-check { display: flex; align-items: baseline; gap: 6px; padding: 1px 0; }
.pw-check .pw-mark { width: 12px; flex-shrink: 0; text-align: center; }
.pw-check.ok { color: var(--ok); }
.pw-check.bad { color: var(--muted); }
.pw-check.bad .pw-mark { color: var(--warn); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* Гистограмма активности (/admin/activity). Столбцы рисуются флексом и процентами высоты,
   без графического движка: данных тут десятки точек, а не кривая с зумом. */
.hist { display: flex; gap: 8px; align-items: stretch; margin-bottom: 8px; }
.hist-scale { display: flex; flex-direction: column; justify-content: space-between;
  height: 160px; text-align: right; min-width: 28px; font-variant-numeric: tabular-nums; }
.hist-bars { flex: 1; display: flex; align-items: flex-end; gap: 2px; overflow-x: auto;
  padding-bottom: 2px; }
.hist-col { flex: 1 1 0; min-width: 10px; display: flex; flex-direction: column; }
/* Полоса всегда занимает полную высоту области, а сам столбец — долю от пика внутри неё:
   так основания всех столбцов лежат на одной линии. */
.hist-stack { height: 160px; display: flex; align-items: flex-end; }
.hist-bar { width: 100%; display: flex; flex-direction: column-reverse; border-radius: 3px 3px 0 0;
  overflow: hidden; background: var(--border); min-height: 1px; }
.hist-seg { width: 100%; }
.hist-x { font-size: 10px; text-align: center; margin-top: 4px; white-space: nowrap;
  overflow: hidden; text-overflow: clip; }
.hist-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }
.hist-key { display: inline-flex; align-items: center; gap: 5px; }
.hist-key i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
/* Палитра различима и в светлой, и в тёмной теме; седьмой цвет — для «прочих». */
.c0, .hist-key i.c0 { background: #2b6cb0; } .c1, .hist-key i.c1 { background: #1f7a4d; }
.c2, .hist-key i.c2 { background: #b7791f; } .c3, .hist-key i.c3 { background: #6b46c1; }
.c4, .hist-key i.c4 { background: #c23b3b; } .c5, .hist-key i.c5 { background: #2c7a7b; }
.c6, .hist-key i.c6 { background: #8a94a6; }
@media (max-width: 860px) {
  .hist-stack, .hist-scale { height: 120px; }
  .hist-x { font-size: 9px; }
}

/* Диагностика: плитки «показатель — значение», без таблицы (значения разной длины). */
.diag-grid { display: grid; gap: .75rem 1.5rem;
             grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.diag-grid > div { display: flex; flex-direction: column; gap: .1rem; }
.diag-trace > td { padding-top: 0; border-top: none; }
.diag-trace pre { max-height: 20em; overflow: auto; font-size: .78rem;
                  background: var(--bg-soft, rgba(127,127,127,.08)); padding: .6rem;
                  border-radius: 6px; white-space: pre-wrap; word-break: break-word; }

/* Вкладки-переключатели (диапазон гистограммы на /admin/activity). Класс был проставлен в
   шаблоне, а стиля к нему не существовало — три ссылки читались как оборванная фраза
   «Месяц Квартал Год». */
.tabs { display: flex; flex-wrap: wrap; gap: 4px; }
.tabs .tab { font-size: 13px; padding: 5px 12px; border: 1px solid var(--border);
  border-radius: 999px; color: var(--muted); white-space: nowrap; }
.tabs .tab:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.tabs .tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Длинный <option> растягивает сам <select>, а тот — всю страницу: на карточке АКБ список из
   72 найденных при обходе листовок раздвигал её до 621px при ширине экрана 390px. */
select { max-width: 100%; }

/* Документные страницы (/readme, /about) — разметка из Markdown, обернуть каждую таблицу
   в .table-scroll там негде, поэтому прокрутку берёт на себя сама таблица.
   Длинные ссылки и куски кода там же переносим: неразрывная строка распирает страницу так же,
   как таблица, и чинится тем же местом. */
.about-doc table, .readme table { display: block; overflow-x: auto; max-width: 100%; }
.about-doc pre, .readme pre { overflow-x: auto; }
.about-doc a, .readme a, .about-doc code, .readme code { overflow-wrap: anywhere; }

@media (max-width: 760px) {
  /* Список пользователей: шесть колонок с формами внутри. В виде таблицы на телефоне кнопка
     «Сохранить» и поле пароля оказывались за правым краем — форму нельзя было отправить, не
     прокрутив её вбок. Поэтому на узком экране строка разворачивается в карточку, а подписи
     колонок подставляются из data-l (в таблице их даёт <thead>, которого здесь уже нет). */
  .stack-rows thead { display: none; }
  .stack-rows, .stack-rows tbody, .stack-rows tr, .stack-rows td { display: block; width: 100%; }
  .stack-rows tr { border: 1px solid var(--border); border-radius: 10px;
    padding: 10px 12px; margin-bottom: 10px; }
  .stack-rows td { border: none; padding: 5px 0; }
  .stack-rows td[data-l]::before { content: attr(data-l); display: block; font-size: 11px;
    text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 3px; }
  .stack-rows td:empty { display: none; }
  /* Галочку из этого правила надо исключать явно: width:100% растягивает сам элемент, и
     Chrome рисует квадратик по центру полосы, выталкивая подпись «активен» за край. */
  .stack-rows .inline-form input:not([type=checkbox]):not([type=radio]),
  .stack-rows .inline-form select { width: 100% !important; }
  .stack-rows .inline-form label.chk { flex: 0 0 auto; }
  .stack-rows .inline-form { gap: 8px; }
  .stack-rows .inline-form > * { flex: 1 1 100%; }
  /* Обёртка вокруг развёрнутой таблицы больше ничего не прокручивает — снимаем и тень. */
  .table-scroll:has(.stack-rows) { overflow-x: visible; background: none; }

  /* Подсказки про колесо мыши и двойной клик на сенсорном экране — мусор, занимающий три
     строки над каждым графиком. */
  .chart-hint { display: none; }

  /* Пальцем в мелкое не попасть. Галочки и переключатели остаются прежнего размера — их
     обрамляет <label>, и нажимается вся строка; увеличиваем то, у чего запаса нет. */
  select { min-height: 34px; }
  label.chk { padding: 4px 0; }
  .x { padding: 4px 9px; line-height: 1; }
}

@media (max-width: 760px) {
  /* Поля с фиксированным min-width в пикселях (в шаблонах их шесть — от 220 до 320px) на узком
     экране распирают всю страницу: список найденных при обходе листовок растягивал карточку АКБ
     до 621px при ширине экрана 390px. Гасим сам минимум одним правилом, а не шестью правками по
     месту: иначе следующее такое поле снова уедет за край, и заметит это опять не автор.
     !important здесь обязателен — inline-стиль стилю из файла иначе не перебить. */
  .card input:not([type=checkbox]):not([type=radio]),
  .card select, .card textarea { min-width: 0 !important; max-width: 100%; }
  /* Раз минимум снят, поле съёживается до умолчания браузера — в формах в строку это выглядит
     оборванным, поэтому отдаём им всю ширину. */
  .inline-form input:not([type=checkbox]):not([type=radio]),
  .inline-form select { width: 100%; }
  .inline-form > label { width: 100%; }
}

/* Подсказка, осмысленная только на узком экране (на десктопе все колонки видны сразу). */
.only-narrow { display: none; }
@media (max-width: 760px) { .only-narrow { display: block; } }

/* Постраничная навигация (_pager.html). Три части в одну строку, на узком экране — в столбик:
   что показано, номера страниц, размер страницы. */
.pager { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.pager-nav { display: flex; flex-wrap: wrap; gap: 4px; }
.pager .pg { min-width: 34px; height: 34px; padding: 0 9px; border: 1px solid var(--border);
  border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; }
.pager .pg:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.pager .pg.cur { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
/* Неактивная стрелка и многоточие — не ссылки: рамка убрана, чтобы не приглашали нажать. */
.pager .pg.off { color: var(--border); border-color: transparent; }
.pager .pg.gap { border-color: transparent; color: var(--muted); min-width: 18px; padding: 0; }
.pager-per { margin-left: auto; }
.pager-per a, .pager-per b { padding: 0 4px; }
@media (max-width: 760px) {
  .pager { flex-direction: column; align-items: stretch; }
  .pager-per { margin-left: 0; }
  .pager-nav { justify-content: center; }
}
