@font-face {
  font-family: 'Carlito';
  src: url('assets/fonts/Carlito-Regular.ttf') format('truetype');
  font-weight: 400;
}
@font-face {
  font-family: 'Carlito';
  src: url('assets/fonts/Carlito-Bold.ttf') format('truetype');
  font-weight: 700;
}

:root {
  --ink: #0a0a0a;
  --tint: #fafaf9;
  --mid: #737373;
  --hair: #dcdcdc;
  --subband: #ededed;
  --rust: #ab4b0e;
  --ok: #2f7a3d;
  --issue: #b3271e;
  --r: 9px;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  background: #f1f0ee;
  color: var(--ink);
  font-family: 'Carlito', 'Calibri', Arial, sans-serif;
  -webkit-tap-highlight-color: transparent;
}
button { font-family: inherit; }

#app { min-height: 100vh; display: flex; flex-direction: column; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: var(--ink); color: #fff;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
}
.topbar img.logo { height: 28px; }
.topbar .title { font-weight: 700; font-size: 15px; flex: 1; }
.topbar .sub { font-size: 12px; color: #cfcfcf; }
.topbar button {
  background: var(--rust); color: #fff; border: none; border-radius: 7px;
  padding: 9px 14px; font-size: 14px; font-weight: 700; cursor: pointer;
}
.topbar button.ghost {
  background: transparent; border: 1px solid #555; color: #eee;
}
.progress-wrap { width: 100%; height: 4px; background: #333; }
.progress-bar { height: 100%; background: var(--rust); transition: width .2s; }

/* ---------- home / list ---------- */
.container { max-width: 980px; margin: 0 auto; padding: 20px 16px 80px; width: 100%; }
.card {
  background: var(--tint); border: 1px solid var(--hair); border-radius: var(--r);
  overflow: hidden; margin-bottom: 16px;
}
.card-head {
  background: var(--ink); color: #fff; font-weight: 700; letter-spacing: .02em;
  padding: 10px 14px; font-size: 13px; text-transform: uppercase;
}
.card-body { padding: 12px 14px; }
.big-cta {
  display: block; width: 100%; text-align: center; background: var(--rust); color: #fff;
  border: none; border-radius: var(--r); padding: 18px; font-size: 18px; font-weight: 700;
  cursor: pointer; margin-bottom: 20px;
}
.insp-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 4px; border-bottom: 1px solid var(--hair); cursor: pointer;
}
.insp-row:last-child { border-bottom: none; }
.insp-row .who { font-weight: 700; }
.insp-row .meta { color: var(--mid); font-size: 13px; }
/* Статус + кнопка PDF в правой части строки осмотра (2026-09-08). */
.insp-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.pdf-btn {
  padding: 6px 10px; font-size: 12px; font-weight: 700; font-family: inherit;
  border-radius: 7px; border: 1px solid var(--ok); background: #fff; color: var(--ok);
  cursor: pointer; letter-spacing: .02em;
}
.pdf-btn:active { background: #eef6f0; }
.badge {
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 20px;
  text-transform: uppercase;
}
.badge.in_progress { background: #fdeecb; color: #8a5a00; }
.badge.finished { background: #dcf0de; color: var(--ok); }

/* ---------- intake form ---------- */
.field-row { margin-bottom: 12px; }
.field-row label { display: block; font-size: 12px; color: var(--mid); margin-bottom: 4px; }
.field-row input, .field-row select {
  width: 100%; padding: 12px; border: 1px solid var(--hair); border-radius: 7px;
  font-size: 16px; font-family: inherit; background: #fff;
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }


/* ---------- вкладка «Автомобили» ---------- */
.search-box { margin-bottom: 12px; }
.search-box input {
  width: 100%; padding: 12px; border: 1px solid var(--hair); border-radius: 7px;
  font-size: 16px; font-family: inherit; background: #fff;
}

/* ---------- checklist fill ---------- */
/* Шапка + лента блоков -- один прилипающий контейнер (2026-09-08). Раньше
   это были два независимых sticky: .topbar на top:0 и .section-nav на
   жёстком top:45px. Реальная высота шапки (padding 10+10, логотип 28px,
   полоска прогресса 4px) -- около 52px, поэтому при прокрутке лента
   заезжала под шапку и верх кнопок срезался (жалоба Александра). Липнет
   вся группа целиком, подгонять смещение под высоту шапки больше не нужно;
   внутренние элементы делаем static, иначе они прилипали бы ещё и внутри
   контейнера. На остальных экранах .topbar по-прежнему sticky сам по себе. */
.sticky-head { position: sticky; top: 0; z-index: 20; }
.sticky-head .topbar, .sticky-head .section-nav { position: static; }
.section-nav {
  position: sticky; top: 45px; z-index: 15; background: #f1f0ee;
  display: flex; gap: 6px; overflow-x: auto; padding: 8px 12px;
  border-bottom: 1px solid var(--hair);
}
.section-nav button {
  flex: none; background: #fff; border: 1px solid var(--hair); border-radius: 20px;
  padding: 7px 13px; font-size: 12.5px; white-space: nowrap; cursor: pointer;
}
.section-nav button .cnt { color: var(--rust); font-weight: 700; margin-left: 4px; }
.section-nav button.active .cnt { color: #ffb385; }
/* Подсветка статуса блока (см. blockProgressState()/updateFillChrome() в
   app.js) -- теперь заливка ВСЕЙ кнопки, а не только текста/рамки, по
   прямой просьбе Александра (2026-09): так нагляднее видно, что заполнено,
   а что нет, особенно раз переход между блоками теперь свободный (никакой
   последовательной блокировки больше нет -- любой блок можно открыть в
   любой момент, см. goToBlock()). Три состояния (2026-09-07, уточнение
   Александра): зелёная заливка -- блок полностью заполнен, красная --
   начали, но остались пустые пункты, серая -- к блоку ещё вообще не
   притрагивались. Какой блок сейчас ОТКРЫТ показывает отдельная тёмная
   рамка-обводка (.active) поверх заливки, а не сама заливка -- она занята
   статусом заполненности. */
.section-nav button.nav-complete { background: var(--ok); color: #fff; border-color: var(--ok); }
.section-nav button.nav-incomplete { background: var(--issue); color: #fff; border-color: var(--issue); }
.section-nav button.nav-empty { background: var(--mid); color: #fff; border-color: var(--mid); }
.section-nav button.active { box-shadow: 0 0 0 2px var(--ink); font-weight: 700; }
/* Все блоки, кроме открытого, показываются приглушённо (Александр,
   2026-09-08: «блоки, которые сейчас не активны, все кроме того, в котором
   сейчас находишься, нужно делать более блёклыми, чтобы активный блок
   выделить визуально; цвета при этом остаются как есть»). Именно opacity,
   а не другой набор цветов: так зелёный остаётся зелёным, красный красным,
   серый серым -- меняется только насыщенность, и статус заполненности
   по-прежнему читается по всей ленте. Открытый блок остаётся в полную силу
   и вместе с тёмной обводкой (.active выше) сразу выделяется. */
.section-nav button { opacity: .5; transition: opacity .12s ease; }
.section-nav button.active { opacity: 1; }
/* Раздел, недоступный, пока КОМПЛЕКТАЦИЯ не заполнена целиком (см.
   complSectionsUnlocked() в app.js) -- по замечанию Александра, 2026-09-07,
   такая кнопка должна быть вообще не кликабельна (pointer-events:none --
   вторая линия защиты поверх того, что onclick на ней и не вешается) и
   визуально выглядеть неактивной. */
   Приглушён он сильнее, чем просто неоткрытый блок (.5 выше): «сюда пока
   нельзя» должно отличаться от «сюда можно, но ты не здесь». */
.section-nav button.nav-locked { opacity: .3; cursor: not-allowed; pointer-events: none; }

.subhead {
  background: var(--subband); font-weight: 700; font-size: 12.5px;
  padding: 8px 14px; letter-spacing: .02em; text-transform: uppercase; color: #444;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap;
}
/* Заголовок подраздела -- сам по себе flex-элемент без ограничения по
   ширине по умолчанию не сжимается (min-width:auto) и не переносится по
   словам, из-за чего длинный заголовок вместе с кнопкой «Пропустить» мог
   вылезти за границы карточки на узком экране. flex-wrap выше даёт кнопке
   уйти на следующую строку, если места не хватает, а min-width:0 здесь --
   чтобы сам заголовок при этом мог сжаться и перенестись по словам, а не
   продолжал настаивать на своей полной однострочной ширине. */
.subhead > span:first-child { min-width: 0; overflow-wrap: break-word; }
/* Пропуск подраздела, которого физически нет на этой машине (второй АКБ,
   МКПП vs АКПП и т.п.) — см. toggleSkipSubsection() в app.js. */
.skip-btn {
  flex: none; border: 1px solid var(--hair); background: #fff; color: var(--mid);
  border-radius: 20px; padding: 4px 10px; font-size: 11px; font-weight: 700;
  text-transform: none; letter-spacing: 0; cursor: pointer; white-space: nowrap;
}
.skip-btn.active { background: var(--mid); color: #fff; border-color: var(--mid); }
.skip-note {
  padding: 10px 14px; font-size: 12.5px; color: var(--mid); font-style: italic;
  border-bottom: 1px solid var(--hair); background: #fafafa;
}
/* Обязательное заполнение блока перед «Далее»/«Завершить» — см.
   isBlockComplete()/incompleteItemsOf() в app.js. */
.big-cta.disabled { opacity: .4; cursor: not-allowed; }
.block-warning {
  background: #fff4e5; border: 1px solid var(--rust); border-radius: var(--r);
  padding: 10px 14px; margin-top: 10px; font-size: 12.5px; color: #7a3b00;
}
.block-warning-list { color: var(--rust); font-weight: 700; }
.item-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--hair); background: #fff;
}
.item-row:last-child { border-bottom: none; }
.item-row .lbl { flex: 1; font-size: 13px; }
.item-row .lbl .note-flag { color: var(--rust); font-size: 11px; margin-left: 6px; }

/* ---------- checkboxes (same visual language as the printed blank —
   see vendor/gen_checklist_html.py's .box/.box.checked: thin ink border,
   small radius, solid ink fill + white glyph when checked) ----------
   Размер и пропорции — 1:1 как у .cm-box в карточке КОМПЛЕКТАЦИЯ (18×18,
   рамка 1.5px, радиус 4px, шрифт глифа 13px) -- по замечанию Александра,
   2026-09-07: чекбоксы во всех остальных разделах были заметно крупнее
   (34px, местами 28px в таблицах) и выбивались из общего стиля. */
.cbx {
  width: 18px; height: 18px; flex: none; border-radius: 4px; border: 1.5px solid var(--ink);
  background: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; line-height: 1; color: transparent; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cbx.active { background: var(--ink); color: #fff; }
/* Норма -> тёмно-зелёный, замечание -> тёмно-красный (по просьбе
   Александра, 2026-09-07) -- перекрывает общее правило выше за счёт
   большей специфичности (три класса против двух). */
.cbx.cbx-ok.active { background: var(--ok); }
.cbx.cbx-issue.active { background: var(--issue); }
.cbx-unit {
  display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 4px 2px;
  -webkit-tap-highlight-color: transparent;
}
.cbx-unit .cbx-label { font-size: 12px; color: var(--mid); white-space: nowrap; }
.cbx-unit.active .cbx-label { color: var(--ink); font-weight: 700; }
.cbx-row { display: flex; gap: 18px; flex: none; }
.dash-icon { width: 26px; height: 26px; flex: none; }
.field-value input {
  width: 130px; padding: 8px; border: 1px solid var(--hair); border-radius: 6px; font-size: 13px;
}

/* ---------- print-style tables ("полная переверстка под таблицы PDF",
   выбор Александра, 2026-09) -- пункты single/dash_icon/field собраны в
   настоящие <table>, повторяющие форму печатных table.single/
   table.dash-icons/table.field из vendor/gen_checklist_html.py: те же
   пропорции столбцов, тонкие линии-разделители между строками, общие
   подписи столбцов в шапке таблицы (как у table.pairs в печати) вместо
   подписи у каждого чекбокса отдельно. См. groupItemRuns()/
   renderChecklistTable()/renderFieldTable() в app.js. ---------- */
.pv-table { width: 100%; border-collapse: collapse; background: #fff; }
.pv-table thead td {
  font-size: 10px; text-transform: uppercase; letter-spacing: .03em; color: var(--mid);
  font-weight: 700; text-align: center; padding: 6px 4px 4px; border-bottom: 1px solid var(--hair);
}
.pv-table thead td.pv-th-lbl { text-align: left; padding-left: 14px; }
.pv-table tbody tr.pv-row { border-bottom: 1px solid var(--hair); }
.pv-table tbody tr.pv-row:last-child { border-bottom: none; }
.pv-table td.pv-lbl { font-size: 13px; padding: 9px 8px 9px 14px; }
.pv-table td.pv-icon { width: 34px; padding: 9px 0 9px 12px; }
.pv-table td.pv-icon .dash-icon { width: 22px; height: 22px; }
/* Ширина/паддинги колонки чекбокса подогнаны под уменьшенный (18px, как в
   КОМПЛЕКТАЦИИ) размер .cbx выше -- раньше колонка была рассчитана под
   крупный 28px чекбокс и с новым размером выглядела бы пусто. */
.pv-table td.pv-chk-cell { width: 40px; text-align: center; padding: 9px 4px; }
.pv-table td.pv-chk-cell .cbx-unit { justify-content: center; padding: 3px; }
.pv-table tr.pv-detail-row td { padding: 0; }
/* table.field -- печатный «прочерк для записи»: нижняя линия вместо рамки
   поля ввода (см. vendor/gen_checklist_html.py's table.field/.field-fill).
   Колонка ввода — фиксированные 92px, ровно как колонка переключателей
   (.pv-chk-cell--tri), а сама «строка для записи» внутри — 62px, ровно
   ширина переключателя (.tri-seg). Просьба Александра, 2026-09-08:
   «ширина полей для ручного ввода должна быть равна ширине слайдера».
   Так линия ввода встаёт точно под переключателями соседних таблиц (в
   блоках АКБ/ГЕНЕРАТОР они идут вперемешку), и правый край страницы
   читается одной вертикалью. От печатных пропорций 74%/26% это отступает
   сознательно: на A4 доли работают, на 390px телефона — нет, ровно та же
   причина, что и у колонки дефектов выше. table-layout:fixed обязателен --
   без него ширины на <td> в auto-режиме игнорируются в пользу содержимого
   (проверено: было 62/38 вместо заданного). */
.pv-table--field { table-layout: fixed; }
.pv-table--field td.pv-field-cell { width: 92px; padding: 6px 6px; }
.pv-field-cell-inner { display: flex; justify-content: center; }
/* Блок «черта + единица» шириной ровно с переключатель (62px). Сама черта
   короче блока и НЕ проходит под единицей: единица стоит после неё через
   пробел, за пределами черты (Александр, 2026-09-08: «черта рукописного
   ввода короче и её характеристика написана через пробел, не на черте»).
   Черта фиксированной ширины, а не резиновой, -- иначе у «°C» она была бы
   заметно короче, чем у «В», и колонка выглядела бы рваной; сейчас все
   черты одинаковой длины и начинаются с одного места, единицы -- тоже.
   Выравнивание по нижнему краю сохранено: единица сидит на уровне черты
   («вольты, амперы, проценты по нижнему краю»). Черта тонкая, 1px
   («линию ввода не делай болдом» -- была 1.5px). */
.pv-field-box { display: flex; align-items: flex-end; gap: 5px; width: 62px; flex: none; }
.pv-field-input {
  width: 46px; flex: none; border: none; border-bottom: 1px solid var(--ink);
  border-radius: 0; padding: 2px 1px; font-size: 13px; font-family: inherit;
  background: transparent; text-align: right;
}
.pv-field-input:focus { outline: none; border-bottom-color: var(--rust); }
/* Единица измерения (А/В/°C/%) -- см. FIELD_UNIT_CONFIG в app.js,
   2026-09-07. Мельче и светлее значения: это подпись, а не данные. */
.pv-field-unit { flex: none; font-size: 11px; color: var(--mid); white-space: nowrap; line-height: 1.45; }

/* ---------- table.pairs -- та же форма, что и в печати (см.
   vendor/gen_checklist_html.py::render_pair_table()) -- см.
   renderPairTable() в app.js. Раньше здесь был сворачиваемый блок-кнопка
   на каждую сторону (не таблица вообще) -- заменено по замечанию
   Александра, 2026-09-08 («верстка ровно как в PDF, не выдумывай своё»).
   Комбинированный селектор (.pv-chk-cell.pv-chk-cell--pair) специально
   более специфичен, чем общее правило .pv-table td.pv-chk-cell выше --
   иначе от порядка правил в файле зависело бы, какая ширina победит. */
.pv-table--pair td.pv-th-side { width: 76px; }
.pv-table td.pv-chk-cell.pv-chk-cell--pair { width: 76px; padding: 9px 4px; }
.pv-chk-cell-inner { display: flex; justify-content: center; gap: 2px; }
.pv-chk-cell-inner .cbx-unit { padding: 3px 2px; }
.pv-detail-side-tag { font-size: 11px; font-weight: 700; color: var(--mid); padding: 6px 14px 0; }

/* .detail-panel / .chip / .note-input удалены 2026-09-08: панели под
   строкой больше нет — дефект выбирается прямо в строке (см. .pv-st-cell
   в строке), а поле «Комментарий мастера» убрано целиком. */

/* ---------- КОМПЛЕКТАЦИЯ (LC80) ----------
   Вёрстка повторяет печатный бланк (vendor/gen_checklist_html.py,
   build_compl_card()) -- те же сгруппированные таблицы с объединением
   ячейки группы по rowspan (ДВС над своими КПП, part-time/full-time над
   своими раздатками, «Оригинальная»/«Тюнинг» над размерами лифта),
   пунктирная линия между строками ОДНОЙ группы (.cm-sub) и обычная
   сплошная -- между группами, плюс чекбокс-квадрат вместо круглых чипов
   (тот же .box/.box.checked, что и в PDF). Раньше значения были россыпью
   плавающих "таблеток" без видимой структуры -- по просьбе Александра
   2026-09-07 сделано наглядно, как в печатном чек-листе. Кликабельна вся
   строка целиком (не только чекбокс) -- удобнее на телефоне. */
/* Одна последовательная колонка, как во всех остальных блоках (Александр,
   2026-09-08). Две колонки остались только в печатном бланке -- там они
   экономят бумагу; на экране они заставляли прыгать глазами влево-вправо,
   а на узких экранах всё равно схлопывались в одну. Заголовки разделов --
   те же полосы .subhead, что и подразделы в остальных блоках, поэтому
   padding у тела карточки нулевой (полоса идёт во всю ширину), а таблицы
   получают собственные горизонтальные отступы. */
.compl-body { padding: 0 0 4px; }
.compl-table-wrap { padding: 8px 14px 12px; }

table.cm-matrix, table.compl-lock { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.cm-matrix col.cm-engine { width: 40%; }
table.cm-matrix col.cm-trans { width: 42%; }
table.cm-matrix col.cm-chk { width: 18%; }
/* Блокировки: три варианта (Электро / Пневмо / Нет). Раньше колонки были
   по 18% при подписях в одну букву («Э»/«П»); 2026-09-08 подписи стали
   словами по просьбе Александра, поэтому 20% на вариант, а название оси
   отдаёт лишнее (было 46%). */
table.compl-lock col.cl-chk { width: 20%; }
table.compl-lock col.cl-axle { width: 40%; }
/* Тормоза (дисковые/барабанные) и ABS (есть/нет) -- те же таблицы, но
   вариантов два, а не три, поэтому колонкам достаётся больше ширины. */
table.compl-lock.compl-2col col.cl-axle { width: 44%; }
table.compl-lock.compl-2col col.cl-chk { width: 28%; }
/* table-layout:fixed держит ширину колонки жёстко по проценту, но сам
   текст внутри по умолчанию не переносится посреди длинного слова --
   на узком экране («ОТСУТСТВУЕТ» в заголовке колонки блокировок, узкие
   43%/44% колонки ДВС/КПП) это вылезало за границы ячейки/карточки.
   overflow-wrap здесь заставляет такое слово переноситься внутри своей
   ячейки вместо того, чтобы вылезать наружу. */
table.cm-matrix td, table.compl-lock td, table.compl-lock th {
  font-size: 13px; color: var(--ink); padding: 9px 8px; border-bottom: 1px solid var(--hair); vertical-align: middle;
  overflow-wrap: break-word; word-break: break-word;
}
table.cm-matrix tr, table.compl-lock tbody tr { cursor: pointer; }
table.cm-matrix tr:active, table.compl-lock tbody tr:active { background: var(--tint); }
table.cm-matrix tr.cm-sub td { border-bottom: 1px dotted var(--hair); }
table.cm-matrix td.cm-engine {
  font-weight: 700; vertical-align: middle; border-right: 1px solid var(--hair);
}
table.cm-matrix tr.cm-sub td.cm-engine { border-bottom: 1px solid var(--hair); }
table.cm-matrix td.cm-chk, table.compl-lock td.cl-chk {
  text-align: center; border-left: 1px solid var(--hair);
}
/* Подсветка выбранной строки — в том же зелёном семействе, что и всё
   «выбрано» в приложении (бледный фон невыбранной зелёной зоны
   переключателя — #e8f3ea; здесь ещё светлее, чтобы не спорить с самой
   галочкой). Раньше был рыжеватый #fff8f0 из фирменной палитры бланка —
   заменено 2026-09-08 вместе с зелёными чекбоксами. */
table.cm-matrix tr.cm-active td, table.compl-lock tr.cm-active td { background: #f1f8f3; }
/* Сам выбор — зелёным текстом, а не только зелёной галочкой: подсвечивается
   и значение (КПП, код раздатки, размер лифта, тип блокировки/тормозов), и
   НАЗВАНИЕ ГРУППЫ, к которой оно относится — двигатель, Part-time/Full-time,
   Оригинальная/Тюнинг, ось. Просьба Александра, 2026-09-08: «если ты зелёным
   подсвечиваешь выбранную КПП, то и ДВС подсвечивай, и раздатку тоже, и
   тюнинг». Важный частный случай: ячейка названия группы объединяет строки
   через rowspan и принадлежит первой из них, поэтому фоном строки она
   подсвечивалась только при выборе ПЕРВОГО варианта группы — класс cm-pick
   ставится по всей группе (см. complMatrixTable() в app.js). */
table.cm-matrix td.cm-pick, table.compl-lock td.cm-pick { color: var(--ok); font-weight: 700; }
table.compl-lock th {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: var(--mid); text-align: center; padding: 4px 4px 6px; border-bottom: 1px solid var(--hair);
}
table.compl-lock th:first-child { text-align: left; }
table.compl-lock td.cl-axle { font-size: 13px; }
/* "Потухшие" варианты, пока в этой группе (таблице -- у ДВС/КПП, раздатки,
   подвески; строке оси -- у блокировок) уже что-то выбрано (см.
   complMatrixTable()/complLockTable() в app.js, 2026-09-07): не кликается
   и приглушено, пока не снят текущий выбор. */
/* Приглушение — по ЯЧЕЙКАМ, а не по всей строке: ячейка с названием группы
   объединяет строки через rowspan и принадлежит первой из них, а она чаще
   всего не выбрана. При opacity на <tr> зелёная подсветка выбранной группы
   («1HD-T», «Full-time», «Тюнинг») гасла вместе с ней до 35%. Поэтому
   выбранное (.cm-pick) остаётся в полную силу. */
table.cm-matrix tr.cm-locked { pointer-events: none; }
table.cm-matrix tr.cm-locked td { opacity: .35; }
table.cm-matrix tr.cm-locked td.cm-pick { opacity: 1; }
table.compl-lock td.cl-locked { opacity: .35; pointer-events: none; }

/* Чекбокс-квадрат карточки КОМПЛЕКТАЦИЯ. Раньше он повторял печатный
   бланк (пустой квадрат -> залитый ЧЁРНЫМ с галочкой), но во всём
   остальном приложении «выбрано и в порядке» -- это зелёная заливка с
   белой галочкой (.tri-cell.cell-ok.active). Александр, 2026-09-08:
   «раздел комплектация по визуалу приведи ко всем остальным -- чекбоксы
   зелёные». Поэтому фон/рамка выбранного = var(--ok), а пустой квадрат
   держит ту же светло-серую рамку (var(--hair)), что и рамка
   переключателя. На печать это не влияет: PDF рисует свои .box сам. */
.cm-box {
  display: inline-block; width: 18px; height: 18px; border: 1.5px solid var(--hair);
  border-radius: 4px; vertical-align: middle; position: relative; background: #fff;
}
.cm-box.checked { background: var(--ok); border-color: var(--ok); }
.cm-box.checked::after {
  content: "✓"; position: absolute; inset: 0; color: #fff; font-size: 13px;
  line-height: 15px; text-align: center;
}

.finish-bar {
  position: sticky; bottom: 0; background: #fff; border-top: 1px solid var(--hair);
  padding: 10px 16px;
}
/* Подвал: ОДИН элемент вместо прежней пары «Назад»/«Далее» (Александр,
   2026-09-08). Он меняет не только текст, но и роль -- и это главное в
   раскладке: пока делать нечего, это ПЛОСКАЯ СЕРАЯ ПЛАШКА без тени и без
   курсора-руки (её и не хочется нажимать), а как только осмотр заполнен
   целиком -- она становится настоящей зелёной кнопкой. Так в подвале
   никогда не висит «мёртвая» кнопка, которую жмут и ничего не происходит,
   и наоборот: если что-то выглядит нажимаемым, оно работает.
   Счётчик пунктов блока -- тут же справа, мелким и приглушённым: он
   уточняет статус, а не спорит с ним. */
.footer-state {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 12px 16px; border-radius: 9px; font-size: 15px; font-weight: 700;
  text-align: center; user-select: none;
}
.footer-state-count { font-size: 13px; font-weight: 400; opacity: .75; }
/* «Осмотр не окончен» и «Осмотрено» -- оба серые: разница между ними в
   тексте, а не в цвете. Зелёный в приложении означает «готово», и красить
   им закрытый БЛОК, пока осмотр в целом не закрыт, было бы обещанием,
   которого экран не выполняет. */
.footer-state--pending { background: #f1f1f1; color: var(--mid); }
.footer-state--done { background: #ededed; color: #5c5c5c; }
.footer-state--ready {
  background: var(--ok); color: #fff; cursor: pointer;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .08);
}
.footer-state--ready:active { filter: brightness(.94); }

/* ---------- report ---------- */
.report-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.report-head img { height: 40px; }
.report-head h1 { font-size: 20px; margin: 0; }
.report-meta { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px 20px; font-size: 13.5px; margin-bottom: 18px; }
.report-meta div span { display:block; color: var(--mid); font-size: 11px; }
.defect-row { display:flex; justify-content:space-between; padding: 9px 0; border-bottom: 1px solid var(--hair); }
.defect-row .path { color: var(--mid); font-size: 12px; }
.defect-row .status { color: var(--issue); font-weight: 700; }
.ok-summary { color: var(--mid); font-size: 13px; margin-top: 10px; }
.print-btn, .export-btn {
  background: var(--ink); color: #fff; border: none; border-radius: 7px; padding: 10px 16px;
  font-weight: 700; cursor: pointer; margin-right: 8px;
}
@media print {
  .topbar, .no-print { display: none !important; }
  body { background: #fff; }
}
.empty-hint { color: var(--mid); text-align: center; padding: 40px 10px; }

/* ======================================================================
   ПЕРЕКЛЮЧАТЕЛЬ «ЗАМЕЧАНИЕ / НЕ ПРОВЕРЕНО / НОРМА» — один контрол на пункт
   вместо двух отдельных чекбоксов (окончательный выбор Александра,
   2026-09-08, после сравнения трёх вариантов вживую).
   Три равные зоны в одной рамке: слева «замечание» (красная), по центру
   «не проверено» (серая), справа «норма» (зелёная) — зелёный справа, как и
   было выбрано. Выбранная зона заливается своим цветом, бегунка внутри
   нет. Геометрия: трек 62x23px + рамка 1px -> внутри ровно 60px = 3 x 20px.
   Радиус и рамка — как у обычных чекбоксов приложения (.cbx/.cm-box).
   Неактивные зоны держат бледный фон и бледный значок (! / · / ✓), чтобы
   было видно назначение каждой зоны до первого нажатия.
   ====================================================================== */
.tri-seg {
  display: inline-flex; width: 62px; height: 23px;
  border: 1px solid var(--hair); border-radius: 5px; background: #fff;
  overflow: hidden; cursor: pointer; flex: none; user-select: none;
  touch-action: manipulation;
}
.tri-cell {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center;
  border-right: 1px solid var(--hair); pointer-events: none;
  font-size: 12px; font-weight: 700; line-height: 1;
}
.tri-cell:last-child { border-right: none; }
/* бледные (невыбранные) состояния */
.tri-cell.cell-issue { background: #fbe9e7; color: #e3a49e; }
.tri-cell.cell-none { background: #f1f1f1; color: #c4c4c4; }
.tri-cell.cell-ok { background: #e8f3ea; color: #94c2a0; }
/* выбранная зона -- насыщенная заливка и белый значок. Средняя («не
   проверено») светлее остальных серых: этим состоянием помечено
   большинство пунктов, пока осмотр идёт, и тёмная заливка делала весь
   список визуально тяжёлым. */
.tri-cell.cell-issue.active { background: var(--issue); color: #fff; }
.tri-cell.cell-none.active { background: #d5d5d5; color: #767676; }
.tri-cell.cell-ok.active { background: var(--ok); color: #fff; }

/* Колонка под переключатель: одна на пункт (раньше их было две -- под
   отдельные чекбоксы «норма»/«замечание»). */
.pv-table--tri td.pv-th-tri {
  color: var(--mid); text-align: center; white-space: nowrap; width: 92px;
  padding: 5px 6px 3px;
}
/* Подсказка в шапке -- только стрелки, слов «замечание»/«норма» нет
   (просьба Александра, 2026-09-08). Блок стрелок ровно той же ширины,
   что и сам переключатель (.tri-seg = 62px), и делится на те же три
   равные доли, поэтому «←» стоит точно над красной зоной, «→» -- над
   зелёной; ячейки шапки и строки центрируют содержимое одинаково, так
   что стрелки выровнены по столбцу переключателей. */
.tri-hint { display: inline-flex; width: 62px; font-size: 12px; line-height: 1; }
.tri-hint span { flex: 1 1 0; text-align: center; }
.pv-table td.pv-chk-cell--tri { width: 92px; padding: 7px 6px; }
/* У пар колонка стороны -- ТАКИЕ ЖЕ 92px, как и одиночная колонка
   переключателей. Раньше было 82px, и правый переключатель пары стоял на
   5px правее, чем переключатель одиночного пункта под ним: в блоке
   ФОНАРИ/«Подсветка номера» это читалось как «слайдер уехал» (замечание
   Александра, 2026-09-08). При равной ширине колонок обе таблицы прижаты к
   правому краю карточки, поэтому все переключатели документа стоят на
   одной вертикали. */
.pv-table--tri.pv-table--pair td.pv-th-side { width: 92px; }
.pv-table td.pv-chk-cell--pair.pv-chk-cell--tri { width: 92px; }

/* ======================================================================
   ВЫБОР ТИПА НЕИСПРАВНОСТИ (2026-09-08)
   Колонка дефектов — на том же месте, где список напечатан в бланке
   (в PDF это средняя колонка table.single s-st 39% / table.pairs c-st 37%:
   мелкий серый текст, выровненный вправо). Пока дефект не выбран, здесь
   бледно перечислены ВОЗМОЖНЫЕ — экран читается как бумага; выбранный
   становится тёмным.
   ====================================================================== */
/* Ширина колонки — по содержимому, а не фиксированной долей: приём
   `width:1%` + `nowrap` заставляет браузер сжать её до самого длинного
   списка дефектов в этой таблице, а всё остальное место отдать названию
   пункта. Фиксированные 34% (как доля s-st в печатном бланке) на телефоне
   ломали длинные названия на две-три строки — на A4 те же 39% помещаются,
   на 390px уже нет. На совсем узких экранах разрешаем перенос. */
.pv-table td.pv-st-cell, .pv-table td.pv-th-st { width: 1%; white-space: nowrap; }
.pv-table td.pv-st-cell {
  text-align: right; padding: 6px 8px 6px 0; font-size: 11px;
  line-height: 1.35; color: var(--mid); vertical-align: middle;
}
@media (max-width: 340px) {
  .pv-table td.pv-st-cell, .pv-table td.pv-th-st { white-space: normal; }
}
.pv-st-word { color: var(--mid); }
/* Выбранный дефект — ТОЛЬКО красный жирный текст, без плашки и рамки
   (просьба Александра, 2026-09-08). Кликабельность не подсвечивается
   отдельно: то, что пункт отмечен «замечанием», уже видно по красному
   переключателю справа. */
.pv-st-word.picked { color: var(--issue); font-weight: 700; }
.pv-st-cell--pick .pv-st-word { cursor: pointer; }
.pv-st-sep { color: #c9c9c9; margin: 0 3px; }

/* Сообщение о том, что сервер сделал с карточкой автомобиля при сохранении:
   нашлась ли машина по VIN, как записались номер и VIN после нормализации,
   предупреждения о формате. См. buildVehicleNotice()/renderFill() в app.js.
   Не диалог: мастер работает дальше, сообщение закрывается крестиком. */
.vehicle-notice {
  position: relative;
  background: #eef5ee; border: 1px solid var(--ok); border-radius: var(--r);
  padding: 10px 34px 10px 14px; margin-bottom: 10px;
  font-size: 12.5px; color: #1f4f28; line-height: 1.45;
}
.vehicle-notice div { margin: 2px 0; }
.vehicle-notice-close {
  position: absolute; top: 4px; right: 6px;
  border: none; background: none; cursor: pointer;
  font-size: 18px; line-height: 1; color: var(--mid); padding: 4px 6px;
}

/* Специалист в шапке незаконченного чек-листа: тот же список, что и при
   заведении, но компактный — он живёт в строке подзаголовка. См.
   technicianControl() в app.js. */
.tech-select {
  font-family: inherit; font-size: 12px; color: inherit;
  background: rgba(255,255,255,.15); border: 1px solid rgba(255,255,255,.35);
  border-radius: 5px; padding: 1px 4px; max-width: 160px;
}

/* ---------- согласие ---------- */
/* Две дороги одного размера: бумажная — не «запасной выход», а вторая
   постоянная. См. renderConsentGate() в app.js. */
.consent-lead { margin: 0 0 12px; font-size: 13.5px; line-height: 1.5; }
.consent-roads { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .consent-roads { grid-template-columns: 1fr 1fr; } }
.consent-road {
  border: 1px solid var(--hair); border-radius: var(--r);
  background: #fff; padding: 12px 14px;
}
.consent-road-title { font-weight: 700; font-size: 13px; margin-bottom: 6px; }
.consent-road-text { font-size: 12.5px; color: var(--mid); line-height: 1.45; margin-bottom: 10px; }
.consent-btn {
  display: block; width: 100%; border: 1px solid var(--ok); background: #fff;
  color: var(--ok); border-radius: 7px; padding: 12px; font-size: 14px;
  font-weight: 700; font-family: inherit; cursor: pointer;
}
.consent-btn:active { background: #eef6f0; }
.consent-btn:disabled { opacity: .55; cursor: default; }
.consent-error { margin-top: 8px; font-size: 12.5px; color: var(--issue); }
.consent-stub {
  margin-top: 14px; padding: 10px 12px; border-radius: var(--r);
  border: 1px dashed var(--mid); font-size: 12px; color: var(--mid);
}
.consent-stub .consent-btn { margin-top: 8px; border-color: var(--mid); color: var(--mid); }
.consent-badge {
  margin-bottom: 10px; padding: 7px 12px; border-radius: var(--r);
  background: #eef5ee; border: 1px solid var(--ok); color: #1f4f28;
  font-size: 12.5px;
}

.consent-token { margin-top: 10px; }
.consent-link {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; word-break: break-all; line-height: 1.5;
  background: #fff; border: 1px solid var(--hair); border-radius: 7px;
  padding: 8px 10px; margin-bottom: 8px; user-select: all;
}
.consent-copy { padding: 8px; font-size: 13px; }
.consent-qr { margin-top: 10px; text-align: center; }
.consent-qr svg { width: 180px; height: 180px; }
