/* ExcelMerger Web — стили вкладки «Редактор» (клон десктопной таблицы).
   Цвета взяты из ui.util.ColorScheme десктопного приложения. */

:root {
    /* ColorScheme десктопа */
    --table-header-bg: #f0f0f0;          /* tableHeaderBg */
    --table-even-row-bg: #ffffff;        /* tableEvenRowBg */
    --table-odd-row-bg: #f5f5fa;         /* tableOddRowBg */
    --table-selection-bg: #b8cfe5;       /* tableSelectionBg */
    --active-filter-bg: #bebebe;         /* activeFilterButtonBg */
    --edited-cell-bg: #c8ffc8;           /* editedCellBg — зелёная подсветка загруженного файла */
    /* Подсветка паразитных символов (MVP1) */
    --issue-bg: #ffe0e0;
    --issue-border: #e08080;
    --marker-bg: #d04040;
    /* Цвета валидности полей — ViewConstants.defaultOKColor/defaultErrorColor десктопа */
    --valid-ok-bg: rgb(230, 253, 230);
    --valid-error-bg: rgb(253, 230, 230);
}

body {
    font-family: "Segoe UI", Tahoma, sans-serif;
    margin: 0;
    padding: 12px 20px;
    background: #fafafa;
    color: #222;
    display: flex;
    flex-direction: column;
    height: calc(100vh - 24px);
}

/* ==================== Вкладки приложения ==================== */

.app-tabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    border-bottom: 1px solid #bbb;
    margin-bottom: 8px;
}

.app-tab {
    font-size: 13px;
    padding: 5px 16px;
    border: 1px solid #bbb;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    background: #e8e8e8;
    color: #444;
    cursor: pointer;
}

.app-tab:hover {
    background: #dcdcdc;
}

.app-tab.active {
    background: #fff;
    color: #111;
    font-weight: 600;
    position: relative;
    top: 1px;               /* «сливается» с содержимым, перекрывая линию таб-бара */
    border-bottom: 1px solid #fff;
}

.app-title {
    margin-left: auto;
    font-size: 11px;
    color: #999;
    padding-bottom: 4px;
}

/* ==================== Контейнеры вкладок (MVP14) ==================== */

/* Вид вкладки занимает всё место под таб-баром; скрытый — полностью убран
   (правило с [hidden] ниже flex-правила, иначе display:flex перебил бы hidden) */
.app-view {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.app-view[hidden] {
    display: none;
}

/* ==================== Тулбар: ↓ ID из БО + файл + лист ==================== */

.toolbar {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
}

.toolbar button {
    font-size: 13px;
    height: 26px;
    padding: 0 12px;
    cursor: pointer;
}

.vsep {
    width: 1px;
    height: 22px;
    background: #ccc;
    margin: 0 4px;
}

/* Поле «пути» к файлу: широкое, растягивается; зелёное, когда файл загружен.
   .file-field — те же поля в тулбарах Мёржера (MVP14). */
#filePathField,
.toolbar .file-field {
    flex: 1 1 auto;
    min-width: 180px;
    height: 22px;
    font-size: 13px;
    padding: 1px 6px;
    border: 1px solid #aaa;
    border-radius: 2px;
    color: #333;
    background: #fff;
}

/* Поле зеленеет после загрузки файла — и у Редактора, и в тулбарах Мёржера (MVP15) */
#filePathField.loaded,
.file-field.loaded {
    background: var(--edited-cell-bg);
}

.toolbar label.sheet-label {
    font-size: 13px;
    color: #333;
    margin-left: 4px;
}

#sheetSelect,
.toolbar .sheet-select {
    font-size: 13px;
    min-width: 140px;
    height: 26px;
}

#sheetSelect:disabled,
.toolbar .sheet-select:disabled {
    color: #999;
}

/* ==================== Вкладка «Мёржер» (MVP14 — оболочка) ==================== */

/* Две панели таблиц рядом, делят ширину пополам (JSplitPane с resizeWeight 0.5) */
/* Верхний тулбар и нижняя панель действий Мёржера — три зоны в grid 1fr auto 1fr:
   центральная колонка (auto) всегда геометрически по центру фрейма, потому что боковые
   колонки (1fr и 1fr) забирают равный остаток. Так центральная кнопка держится по центру
   при любой ширине окна и любом размере боковых групп (как CenteredMergerToolbarPanel). */
.merger-top,
.merger-actionbar {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
    padding: 4px;
}

.mtb-zone,
.mab-zone {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;              /* позволяет боковым группам сжиматься, не ломая центр */
}

/* Левая группа примыкает к левому краю, правая — начинается сразу справа от центра
   (для верхнего тулбара) либо прижата к правому краю (для нижних Трим/Норм). */
.mtb-left  { justify-content: flex-start; }
.mtb-right { justify-content: flex-start; }
.mab-left  { justify-content: flex-start; }
.mab-right { justify-content: flex-end; }

/* Резиновое поле пути — тянется в своей зоне, как inline-файлчузер десктопа */
.mtb-zone .file-field {
    flex: 1 1 auto;
    min-width: 80px;
}

.mtb-zone .sheet-select {
    min-width: 90px;
    flex: 0 0 auto;
}

.merger-tables {
    display: flex;
    gap: 8px;
    flex: 1 1 auto;
    min-height: 0;
}

/* Панель таблицы — рамка с надписью, как TitledBorder десктопа */
.merger-panel {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 2px 8px 8px;
    border: 1px solid #bbb;
    border-radius: 3px;
}

.merger-panel legend {
    font-size: 12px;
    font-weight: 600;
    color: #555;
    padding: 0 5px;
}

/* Тулбар файла внутри панели — компактнее общего (в панели меньше места) */
.merger-toolbar {
    margin-bottom: 6px;
}

.merger-toolbar .file-field {
    min-width: 80px;
}

.merger-toolbar .sheet-select {
    min-width: 90px;
}

/* Плейсхолдер области таблицы: виден до загрузки, после — скрывается (MVP15) */
.merger-placeholder {
    flex: 1 1 auto;
    min-height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #ccc;
    background: #fff;
    color: #999;
    font-size: 14px;
}

/* display:flex выше перебил бы браузерное [hidden] — прячем явно (как .app-view[hidden]) */
.merger-placeholder[hidden] {
    display: none;
}

/* Статус-строка панели — компактный формат Редактора (§7), пока нули */
.merger-status {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    color: #444;
    padding: 4px 2px 0;
    white-space: nowrap;
}

.merger-status .ssep {
    width: 1px;
    height: 14px;
    background: #ccc;
}

/* Блок «=/☰ X/A» крупнее остальных — как #displayedStatus Редактора */
.merger-status .rows {
    font-size: 15px;
}

/* Счётчик «↯ N/M» в статусе панелей Мёржера — те же цвета, что в .statusbar (MVP15) */
.merger-status .bad { color: #b02020; font-weight: 600; }
.merger-status .ok  { color: #208040; font-weight: 600; }

#mergerHideMaskField {
    height: 22px;
    font-size: 13px;
    padding: 1px 4px;
    border: 1px solid #aaa;
    border-radius: 2px;
}

/* ==================== Таблица ==================== */

.table-wrap {
    overflow: auto;
    flex: 1 1 auto;
    border: 1px solid #ccc;
    background: #fff;
}

table {
    border-collapse: collapse;
    font-size: 13px;
}

th, td {
    border: 1px solid #ddd;
    padding: 2px 8px;
    white-space: pre;       /* ведущие/хвостовые пробелы видны как есть */
    max-width: 420px;
    overflow: hidden;
    text-overflow: ellipsis;
}

thead th {
    background: var(--table-header-bg);
    position: sticky;
    top: 0;
    z-index: 2;
    font-weight: 600;
    color: #444;
    text-align: left;
}

/* Шапка из двух рядов (как в десктопе): сверху экспресс-поля с [▼], под ними заголовки.
   Ряд заголовков липнет ниже ряда фильтров (высота задаётся из app.js). */
thead tr.head-row th {
    top: var(--filter-row-h, 27px);
}

/* Заголовок с активным Фильтром столбца */
thead th.filtered {
    background: #e2e2e2;
}

.th-title {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Сортировка по клику на заголовок (MVP9) ---- */

thead tr.head-row th.sortable {
    cursor: pointer;
}

/* У активного столбца справа резервируется место под стрелку направления */
thead tr.head-row th.sorted {
    padding-right: 18px;
}

/* Стрелка ▲/▼ — маленькая, в правом краю заголовка (th — sticky, т.е. positioned) */
.sort-arrow {
    position: absolute;
    right: 3px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 9px;
    color: #555;
}

/* ---- Ряд экспресс-фильтров ---- */

thead tr.filter-row th.filter-cell {
    padding: 2px 3px;
}

.filter-inner {
    display: flex;
    align-items: center;
    gap: 3px;
}

/* Поле экспресс-фильтра тянется по ширине своей колонки */
.express-input {
    flex: 1 1 auto;
    width: 100%;
    min-width: 40px;
    box-sizing: border-box;
    font-size: 12px;
    height: 20px;
    padding: 1px 4px;
    border: 1px solid #aaa;
    border-radius: 2px;
}

.express-input.active {
    background: var(--active-filter-bg);
}

/* Кнопка большого Фильтра [▼] — как в десктопе, красится при активном фильтре */
.filter-btn {
    flex: 0 0 auto;
    font-size: 9px;
    line-height: 1;
    width: 17px;
    height: 17px;
    padding: 0;
    border: 1px solid #999;
    border-radius: 2px;
    background: #f8f8f8;
    color: #555;
    cursor: pointer;
}

.filter-btn:hover {
    background: #e8e8e8;
}

.filter-btn.active {
    background: var(--active-filter-bg);
}

td.rownum, th.rownum {
    background: var(--table-header-bg);
    color: #888;
    text-align: right;
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 34px;
}

thead th.rownum {
    z-index: 3;
}

tbody tr:nth-child(even) td:not(.rownum):not(.reveal-strip) {
    background: var(--table-odd-row-bg);
}

tbody tr:nth-child(odd) td:not(.rownum):not(.reveal-strip) {
    background: var(--table-even-row-bg);
}

/* Ячейка, изменённая пользователем (MVP4, как RevealCellRenderer / editedCellBg).
   Селектор с :not(...) как у зебры (0-4-3 против 0-3-3) — иначе фон зебры
   специфичнее и перекрывает зелёный. Выделение .sel побеждает это правило
   порядком (равная специфичность, объявлено позже). */
tbody tr:nth-child(even) td.edited:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.edited:not(.rownum):not(.reveal-strip) {
    background: var(--edited-cell-bg);
}

/* Инлайн-редактор ячейки (MVP4): поле ввода на всю ячейку */
td.editing {
    padding: 0;
}

.cell-editor {
    width: 100%;
    min-width: 80px;
    box-sizing: border-box;
    font: inherit;
    border: 2px solid #4a7ab5;
    border-radius: 0;
    padding: 0 6px;
    margin: 0;
    background: #fff;
}

/* Паразитные символы (MVP1): фон ячейки НЕ заливаем (§3.2) — только маркеры невидимых
   символов и подсветка самих проблемных участков (пробелы). */
.hl {
    background: #f6b0b0;
    border-radius: 2px;
}

.marker {
    display: inline-block;
    background: var(--marker-bg);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    border-radius: 3px;
    padding: 0 3px;
    margin: 0 1px;
    vertical-align: baseline;
}

/* ==================== Нижняя панель действий ==================== */

.actionbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 0 2px;
}

.actions-left,
.actions-right {
    display: flex;
    align-items: center;
    gap: 8px;
}

.actionbar button,
.merger-top button,
.merger-actionbar button {
    font-size: 13px;
    height: 26px;
    padding: 0 14px;
    cursor: pointer;
}

.actionbar button:disabled,
.merger-top button:disabled,
.merger-actionbar button:disabled {
    color: #999;
    cursor: default;
}

/* Отступ между группой операций и «Сохранить» (как strut 30 в EditorPanel) */
.actions-gap {
    width: 30px;
}

#hideMaskField {
    height: 22px;
    font-size: 13px;
    padding: 1px 4px;
    border: 1px solid #aaa;
    border-radius: 2px;
}

/* Валидность маски скрытия (MVP8): зелёный — есть что скрыть, розовый — нечего.
   Цвета — те же, что у поля выбора файла (ViewConstants десктопа). */
#hideMaskField.ok {
    background: var(--valid-ok-bg);
}

#hideMaskField.bad {
    background: var(--valid-error-bg);
}

/* ==================== Скрытые столбцы (MVP8) ==================== */

/* Полоска-раскрывалка на месте скрытых столбцов: тонкая, но заметная
   (эталон — узкий столбец-разделитель десктопа). Даблклик/ПКМ — раскрыть. */
th.reveal-strip, td.reveal-strip {
    width: 7px;
    min-width: 7px;
    max-width: 7px;
    padding: 0;
    background: repeating-linear-gradient(135deg, #b8b8c8 0 3px, #d8d8e2 3px 6px);
    border-left: 1px solid #9898a8;
    border-right: 1px solid #9898a8;
    cursor: pointer;
}

th.reveal-strip:hover, td.reveal-strip:hover {
    background: repeating-linear-gradient(135deg, #8faccd 0 3px, #c2d4e8 3px 6px);
}

/* Контекстное меню («Скрыть»/«Раскрыть») — в стиле поповера фильтра */
.ctx-menu {
    position: fixed;
    z-index: 180;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 8px rgba(0, 0, 0, 0.25);
    padding: 3px;
    display: flex;
    flex-direction: column;
    min-width: 120px;
}

.ctx-menu .ctx-item {
    font-size: 13px;
    text-align: left;
    padding: 4px 14px;
    border: none;
    background: none;
    cursor: pointer;
}

.ctx-menu .ctx-item:hover:not(:disabled) {
    background: #eef3fa;
}

.ctx-menu .ctx-item:disabled {
    color: #999;
    cursor: default;
}

/* ==================== Статус-строка ==================== */

.statusbar {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12px;
    color: #444;
    padding: 4px 2px 0;
    white-space: nowrap;
}

.statusbar .ssep {
    width: 1px;
    height: 14px;
    background: #ccc;
}

/* Блок «=/☰ X/A» — крупнее остальных, как в TableStatusPanel (+4 к размеру) */
#displayedStatus {
    font-size: 15px;
}

.statusbar .op {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #333;
}

.statusbar .bad { color: #b02020; font-weight: 600; }
.statusbar .ok  { color: #208040; font-weight: 600; }

.privacy {
    font-size: 11px;
    color: #999;
}

/* ==================== Тост-заглушка ==================== */

.toast {
    position: fixed;
    left: 50%;
    bottom: 48px;
    transform: translateX(-50%);
    background: rgba(40, 40, 40, 0.92);
    color: #fff;
    font-size: 13px;
    padding: 8px 18px;
    border-radius: 4px;
    z-index: 200;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    transition: opacity 0.3s;
}

.toast.hide {
    opacity: 0;
}

/* ==================== Окно просмотра ячейки (MVP6) ==================== */

.cell-popup {
    position: fixed;
    z-index: 150;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 8px rgba(0, 0, 0, 0.25);
    padding: 8px;
    width: 440px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
}

.cell-popup .title {
    font-weight: 600;
    color: #444;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Крупное моноширинное превью значения (как JEditorPane с Consolas в десктопе) */
.cell-popup .preview {
    font-family: Consolas, monospace;
    font-size: 16px;
    white-space: pre-wrap;   /* пробелы видны как есть, длинное значение переносится */
    word-break: break-all;
    border: 1px solid #ccc;
    padding: 6px 8px;
    min-height: 44px;
    max-height: 180px;
    overflow: auto;
}

/* Маркеры в окне крупнее табличных — под размер превью */
.cell-popup .preview .marker {
    font-size: 12px;
}

.cell-popup .footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

/* Отчёт о последней операции — приглушённый, как reportLabel десктопа */
.cell-popup .report {
    flex: 1 1 auto;
    color: #666;
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cell-popup .buttons {
    display: flex;
    gap: 6px;
}

.cell-popup button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

.cell-popup button:disabled {
    color: #999;
    cursor: default;
}

/* ==================== Отчёт о качестве (MVP11) ==================== */

/* Немодальное окно (§3.12): таблицу под ним видно, работа с ней не блокируется */
.quality-window {
    position: fixed;
    z-index: 140;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 760px;
    height: 480px;
    min-width: 520px;
    min-height: 300px;
    max-width: 96vw;
    max-height: 90vh;
    resize: both;
    overflow: hidden;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 12px rgba(0, 0, 0, 0.3);
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    box-sizing: border-box;
}

.quality-window .qr-header {
    display: flex;
    justify-content: space-between;
    gap: 12px;
}

.quality-window .qr-file {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.quality-window .qr-summary {
    color: #444;
    white-space: pre;
}

.quality-window .qr-table-wrap {
    flex: 1 1 auto;
    overflow: auto;
    border: 1px solid #ccc;
}

.quality-window .qr-table-wrap table {
    width: 100%;
}

/* Колонка «Значение (с маркерами)» — моноширинно, как Consolas в десктопе;
   многоточие при нехватке ширины — только визуальное (в модели полный текст) */
.quality-window td.qr-value {
    font-family: Consolas, monospace;
    font-size: 12px;
    max-width: 420px;
}

.quality-window td.qr-num {
    text-align: center;
}

.quality-window .qr-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.quality-window .qr-toggle {
    display: flex;
}

.quality-window button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

/* Активный режим — «нажат» и недоступен для повторного нажатия (§3.12) */
.quality-window .qr-toggle button.active:disabled {
    background: var(--active-filter-bg);
    color: #222;
    cursor: default;
}

/* Жёлтый фон нерусских букв в режиме «Разные языки» (mixedLanguageCharBg) */
.lang-hl {
    background: #ffeb50;
    border-radius: 2px;
}

/* ==================== Поповер Фильтра столбца ==================== */

.filter-popup {
    position: absolute;
    z-index: 100;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 8px rgba(0, 0, 0, 0.25);
    padding: 6px;
    /* 350px: строка «По одной строке на значение · скрыто дублей: NNN»
       помещается целиком, счётчик не обрезается (MVP17) */
    width: 350px;
    display: flex;
    flex-direction: column;
    font-size: 13px;
}

.filter-popup .search-row {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 4px;
}

.filter-popup .search-row input {
    flex: 1 1 auto;
    font-size: 13px;
    padding: 2px 4px;
}

.filter-popup .specials {
    display: flex;
    flex-direction: column;
    padding: 2px 0 4px;
}

.filter-popup label.check-row {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 1px 2px;
    cursor: pointer;
    white-space: pre;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-popup label.check-row:hover {
    background: #eef3fa;
}

.filter-popup .values-list {
    height: 240px;
    overflow: auto;
    border: 1px solid #ccc;
    padding: 2px;
}

.filter-popup .empty-label {
    font-style: italic;
    color: #666;
}

.filter-popup .buttons {
    display: flex;
    justify-content: space-between;
    margin-top: 6px;
}

.filter-popup .buttons .right {
    display: flex;
    gap: 4px;
}

.filter-popup button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

/* ==================== Выделение ячеек (MVP10) ==================== */

/* Браузерное текстовое выделение в данных отключено — работает собственное
   прямоугольное выделение протягиванием ЛКМ (копирование по Ctrl+C) */
tbody {
    user-select: none;
}

/* Внутри инлайн-редактора текст выделяется как обычно */
.cell-editor {
    user-select: text;
}

/* Выделенные ячейки — цвет выделения десктопной таблицы (tableSelectionBg).
   Селектор с :not(...) как у «зебры» — иначе зебра (0-3-3) специфичнее и её фон
   перекрывает выделение; здесь 0-4-3 — побеждает зебру и зелёный .edited. */
tbody tr:nth-child(even) td.sel:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.sel:not(.rownum):not(.reveal-strip) {
    background: var(--table-selection-bg);
}

/* Выделенная ИЗМЕНЁННАЯ ячейка — смесь зелёного и синего 50/50: видно и факт
   правки, и выделение (доработка сверх десктопа). Маркеры/подсветка паразитных
   внутри ячейки не затрагиваются — красный остаётся как есть. */
tbody tr:nth-child(even) td.edited.sel:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.edited.sel:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, var(--edited-cell-bg) 50%, var(--table-selection-bg));
}

/* ==================== Окно «↓ ID из БО» (MVP12, §4.2) ==================== */

/* Модальный оверлей: пока окно открыто, таблица недоступна (в десктопе диалог модальный) */
.id-confirm-overlay {
    position: fixed;
    inset: 0;
    z-index: 180; /* выше отчёта о качестве (140), ниже тоста (200) */
    background: rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Окно подтверждения (эталон — ClipboardIdConfirmDialog: зелёные/красные ID + счётчики) */
.id-confirm {
    width: 560px;
    max-width: 92vw;
    max-height: 70vh;
    overflow: hidden;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 12px rgba(0, 0, 0, 0.3);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 13px;
    box-sizing: border-box;
}

.id-confirm .idc-title {
    font-weight: 600;
}

/* Строки ID: переносятся по словам, при избытке — прокрутка */
.id-confirm .idc-ids {
    overflow-y: auto;
    max-height: 20vh;
    word-break: break-word;
}

.id-confirm .idc-found {
    color: #2E7D32; /* найдены в первом столбце — как в десктопном диалоге */
}

.id-confirm .idc-missing {
    color: #C62828; /* не найдены — будут пропущены */
}

.id-confirm .idc-counters {
    color: #444;
}

.id-confirm .idc-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.id-confirm button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

.id-confirm button:disabled {
    cursor: default;
}

/* ==================== Окно отчёта автомёржа (MVP19, §5.11) ==================== */
/* Модальный слой — общий .id-confirm-overlay (затемнение, клик мимо/Esc закрывают) */

.auto-merge-report {
    max-width: 92vw;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 12px rgba(0, 0, 0, 0.3);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 13px;
    box-sizing: border-box;
}

.auto-merge-report .amr-title {
    font-weight: 600;
}

/* Моноширинный отчёт: числа групп выровнены в колонку (клон buildAutoMergeReportLine) */
.auto-merge-report .amr-text {
    margin: 0;
    font-family: Consolas, 'Courier New', monospace;
    font-size: 12px;
    white-space: pre;
    overflow-x: auto;
}

.auto-merge-report .amr-buttons {
    display: flex;
    justify-content: flex-end;
}

.auto-merge-report button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

/* ==================== Окно «Сопоставление столбцов» (MVP16, §5.5) ==================== */

/* Текст последней операции в статусе панели Мёржера — как .statusbar .op Редактора */
.merger-status .op {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #333;
}

/* Модальный оверлей — как окно «↓ ID из БО» (в десктопе диалог модальный) */
.mapping-overlay {
    position: fixed;
    inset: 0;
    z-index: 180; /* выше отчёта о качестве (140), ниже тоста (200) */
    background: rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Окно сопоставления (эталон — ColumnMappingDialog: 650×550 в десктопе) */
.mapping-dialog {
    width: 650px;
    max-width: 92vw;
    max-height: 80vh;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 12px rgba(0, 0, 0, 0.3);
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 13px;
    box-sizing: border-box;
}

.mapping-dialog .md-title {
    font-weight: 600;
}

.mapping-dialog .md-hint {
    color: #444;
}

/* Таблица пар: имя левого столбца + <select> правых; прокрутка при избытке строк */
.mapping-dialog .md-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 12px;
    align-items: center;
    overflow-y: auto;
    padding: 4px 2px;
    border-top: 1px solid #ddd;
}

.mapping-dialog .md-head {
    font-weight: 600;
    padding-bottom: 2px;
    border-bottom: 1px solid #ddd;
}

.mapping-dialog .md-left {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 260px;
}

.mapping-dialog select {
    font-size: 13px;
    padding: 2px 4px;
    border: 1px solid #aaa;
    border-radius: 2px;
    min-width: 0;
}

/* Несопоставленный столбец — красная рамка (клон updateComboBorder) */
.mapping-dialog select.unmapped {
    border: 2px solid #dc5050;
    padding: 1px 3px; /* компенсация толщины рамки — строки не «прыгают» */
}

/* Ошибка валидации «Применить» (правый столбец выбран дважды) */
.mapping-dialog .md-error {
    color: #b02020;
    min-height: 1em;
}

.mapping-dialog .md-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.mapping-dialog button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

/* ==================== Diff-фон правой таблицы Мёржера (MVP17, §5.8.1) ==================== */

/* Розовая градация различия пары ячеек (клон DiffCellRenderer.getSimilarityBg;
   цвета — дефолты ColorScheme). Специфичность 0-4-3 как у зебры/.edited/.sel,
   объявлено ПОЗЖЕ них — diff-фон побеждает зебру и зелёный порядком объявления.
   Красные маркеры паразитных — спаны ПОВЕРХ фона (приоритет «паразиты > diff»). */
tbody tr:nth-child(even) td.diff-minor:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-minor:not(.rownum):not(.reveal-strip) {
    background: #fdeeee; /* малое различие: sim > 0.98 */
}

tbody tr:nth-child(even) td.diff-moderate:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-moderate:not(.rownum):not(.reveal-strip) {
    background: #f8d0d0; /* среднее различие: 0.80 <= sim <= 0.98 */
}

tbody tr:nth-child(even) td.diff-major:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-major:not(.rownum):not(.reveal-strip) {
    background: #f0a8a8; /* сильное различие: sim < 0.80 */
}

/* Выделенная различающаяся ячейка: различие доминирует, выделение мягко
   подмешивается (клон ColorScheme.blend(diffBg, selectionBg, 0.75)). */
tbody tr:nth-child(even) td.diff-minor.sel:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-minor.sel:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, #fdeeee 75%, var(--table-selection-bg));
}

tbody tr:nth-child(even) td.diff-moderate.sel:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-moderate.sel:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, #f8d0d0 75%, var(--table-selection-bg));
}

tbody tr:nth-child(even) td.diff-major.sel:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-major.sel:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, #f0a8a8 75%, var(--table-selection-bg));
}

/* Счётчик скрытых дублей у чекбокса «По одной строке на значение» (MVP17):
   серый курсив справа; под число зарезервировано 3 знака, чтобы строка
   не скакала по горизонтали при изменении значения. */
.filter-popup .dedupe-hint {
    margin-left: auto;
    padding-left: 10px;
    color: #888;
    font-style: italic;
}

.filter-popup .dedupe-num {
    display: inline-block;
    min-width: 3ch;
    text-align: right;
}

/* ==================== Посимвольный diff (MVP18, §5.8.1) ==================== */

/* «Лишние» символы значения относительно парного — синий текст (ColorScheme.diffCharFg);
   различия только регистра — magenta (caseDiffFg). Паразитные маркеры приоритетны:
   их спаны (.marker/.hl) строятся вместо diff-окраски в renderHighlighted. */
.diff-ch {
    color: #0000c8;
}

.case-ch {
    color: #ff00ff;
}

/* ==================== Окно «МержЯчеек» (MVP18, §5.9, §5.10) ==================== */

/* Немодальное singleton-окно (клон CellMergeDialog): габариты ~1200×352 десктопа,
   на узких экранах ужимается до вьюпорта. Ниже поповера фильтра/окна ячейки (150). */
.cell-merge-window {
    position: fixed;
    z-index: 145;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(1200px, calc(100vw - 32px));
    height: 352px;
    min-height: 304px;
    background: #fff;
    border: 1px solid #999;
    border-radius: 3px;
    box-shadow: 2px 3px 12px rgba(0, 0, 0, 0.3);
    padding: 8px 10px 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 12px;
}

.cell-merge-window .cmw-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: 600;
    color: #444;
}

.cell-merge-window .cmw-x {
    border: none;
    background: none;
    font-size: 14px;
    color: #666;
    cursor: pointer;
    padding: 0 4px;
}

.cell-merge-window .cmw-x:hover {
    color: #000;
}

/* Сетка 5 рядов × N пар: горизонтальная прокрутка при множестве пар; ширина
   колонки ~200px (ресайза колонок в вебе нет — граница MVP18) */
.cell-merge-window .cmw-grid-wrap {
    flex: 1 1 auto;
    overflow: auto;
    border: 1px solid #ccc;
}

.cell-merge-window table {
    border-collapse: collapse;
    table-layout: fixed;
}

.cell-merge-window td {
    border: 1px solid #d0d0d0;
    width: 200px;
    min-width: 80px;
    max-width: 200px;
    height: 32px;
    box-sizing: border-box;
    padding: 2px 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Ряды 1 и 5 — заголовки столбцов: фон и цвет как у шапок таблиц */
.cell-merge-window td.cmw-head {
    background: #f0f0f0;
    color: rgb(50, 50, 80);
    text-align: center;
    font-weight: 600;
}

/* Ряды 2 и 4 — значения: моноширинно, как ячейки таблиц; фоны — через классы
   .edited (зелёный левой) и .diff-minor/.diff-moderate/.diff-major (розовые правой),
   их правила объявлены выше и работают в этой таблице так же */
.cell-merge-window td.cmw-value {
    font-family: Consolas, monospace;
    background: #fff;
    white-space: pre;       /* как у ячеек таблиц: крайние пробелы-паразиты не схлопываются */
}

/* Ряд 3 — псевдокнопка переноса (клон TransferButtonCellRenderer) */
.cell-merge-window td.cmw-btn-cell {
    padding: 0;
}

.cell-merge-window .cmw-transfer {
    display: block;
    width: 100%;
    height: 100%;
    font-weight: 700;
    font-size: 12px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cell-merge-window .cmw-transfer.on {
    background: #e6f5e6;
    color: #006e00;
    border: 2px outset #d8ecd8;
    cursor: pointer;
}

.cell-merge-window .cmw-transfer.on:hover {
    background: #daf2da;
    border: 1px solid #469646;
}

.cell-merge-window .cmw-transfer.off {
    background: #ececec;
    color: #969696;
    border: 2px inset #e0e0e0;
    cursor: default;
}

/* Низ окна: чекбоксы слева, навигация по центру, «Закрыть» справа */
.cell-merge-window .cmw-footer {
    display: flex;
    align-items: center;
    gap: 12px;
}

.cell-merge-window .cmw-checks {
    display: flex;
    align-items: center;
    gap: 12px;
    white-space: nowrap;
}

.cell-merge-window .cmw-checks .check-row {
    display: flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}

.cell-merge-window .cmw-nav {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.cell-merge-window .cmw-info {
    min-width: 200px;
    text-align: center;
    color: #333;
}

.cell-merge-window .cmw-nav button,
.cell-merge-window .cmw-close button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
}

.cell-merge-window .cmw-nav button:disabled {
    color: #999;
    cursor: default;
}
