/* 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 */
    /* Насыщенный синий ТОЛЬКО для подмешивания выделения к смысловым фонам
       (зелёный edited, розовые diff): сам tableSelectionBg слишком бледный —
       смесь с ним почти не отличалась от исходного цвета (пожелание, июль 2026) */
    --selection-mix-blue: #4d7fe6;
    --active-filter-bg: #bebebe;         /* activeFilterButtonBg */
    --edited-cell-bg: #c8ffc8;           /* editedCellBg — зелёная подсветка загруженного файла */
    /* Подсветка паразитных символов (MVP1). Дефолты --marker-bg и --lang-hl-bg
       переопределяются из настроек «Паразитные символы» (MVP25, reloadParasiticSettings) */
    --issue-bg: #ffe0e0;
    --issue-border: #e08080;
    --marker-bg: #d04040;
    --lang-hl-bg: #ffeb50;               /* mixedLanguageCharBg — фон «разных языков» */
    /* Цвета валидности полей — 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;
}

/* Надпись приватности (MVP29): кликабельна — открывает окно-объяснение */
.app-title {
    margin-left: auto;
    font-size: 11px;
    color: #999;
    padding-bottom: 4px;
    cursor: pointer;
}

.app-title:hover {
    color: #555;
    text-decoration: underline;
}

/* ==================== Контейнеры вкладок (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; }

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

.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: 660px;               /* ×1.5 от прежних 440 — шире для длинных значений/истории */
    min-width: 440px;
    max-width: 96vw;
    resize: horizontal;         /* окно можно растягивать по горизонтали */
    overflow: auto;
    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;
}

/* Секция истории изменений (MVP13a, §6.6): все записи журнала (id, column) сверху вниз,
   моноширинно, свежая — первая; клик по строке копирует её текст */
.cell-popup .history {
    font-family: Consolas, monospace;
    font-size: 12px;
    border: 1px solid #ccc;
    max-height: 140px;
    overflow: auto;
}

.cell-popup .history-row {
    padding: 2px 6px;
    white-space: pre;
    cursor: pointer;
}

.cell-popup .history-row:hover {
    background: #eef4ff;
}

.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; цвет — из настроек MVP25) */
.lang-hl {
    background: var(--lang-hl-bg);
    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);
}

/* Выделенная ИЗМЕНЁННАЯ ячейка — зелёный с насыщенным синим: видно и факт
   правки, и выделение (доработка сверх десктопа). Маркеры/подсветка паразитных
   внутри ячейки не затрагиваются — красный остаётся как есть. */
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) 65%, var(--selection-mix-blue));
}

/* ==================== Кросс-выделение Мёржера (MVP30, §5.15) ==================== */

/* Сопоставленная строка другой таблицы — заметно бледнее .sel (тот же тон, разбавленный
   белым): читается как выделение, но отличимо от настоящего. Специфичность 0-4-3,
   как у .sel — побеждает зебру (0-3-3). */
tbody tr:nth-child(even) td.sel-mirror:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.sel-mirror:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, var(--table-selection-bg) 45%, #fff);
}

/* Изменённая ячейка под кросс-выделением: зелёный факт правки доминирует, выделение
   подмешано бледным тоном (мягче насыщенного синего у .edited.sel — 0-5-3 у обоих,
   маркеры паразитных внутри ячейки не затрагиваются). */
tbody tr:nth-child(even) td.edited.sel-mirror:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.edited.sel-mirror:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, var(--edited-cell-bg) 65%, 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;
}

/* Итог сохранения (MVP22): имя файла — моноширинным жирным, длинное имя переносится */
.id-confirm .sr-name {
    font-family: Consolas, 'Courier New', monospace;
    font-weight: 600;
    word-break: break-word;
}

.id-confirm .sr-error {
    word-break: break-word;
}

/* Примечание к успешному сохранению (MVP13a: журнал записан — форматирование потеряно) */
.id-confirm .sr-note {
    color: #a05a00;
    font-size: 12px;
}

/* Окно-объяснение приватности (MVP29): текст пунктами, при избытке — прокрутка */
.id-confirm.privacy-dialog {
    width: 640px;
}

.privacy-dialog .privacy-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow-y: auto;
    max-height: 50vh;
    font-size: 13px;
    line-height: 1.45;
}

.privacy-dialog .privacy-item code {
    background: #f2f2f2;
    padding: 0 3px;
    border-radius: 2px;
}

/* ==================== Окно подтверждения сохранения (MVP31, §2.3.2) ==================== */
/* Клон десктопного EditConfirmDialog: шапка-счётчик, список правок, метаданные, кнопки */

.id-confirm.save-confirm {
    width: 700px;
}

.save-confirm .scd-header {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-weight: 600;
}

.save-confirm .scd-file {
    color: #5a5a5a;
    text-align: right;
    word-break: break-word;
}

/* Список правок — моноширинный (как JTextPane десктопа), при избытке прокрутка */
.save-confirm .scd-list {
    flex: 1 1 auto;
    min-height: 60px;
    overflow-y: auto;
    border: 1px solid #ccc;
    padding: 6px 8px;
    font-family: Consolas, 'Courier New', monospace;
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-word;
}

.save-confirm .scd-id {
    font-weight: 600;
    border-bottom: 1px solid #bbb;
    margin: 8px 0 4px;
}

.save-confirm .scd-id:first-child {
    margin-top: 0;
}

.save-confirm .scd-change {
    margin-bottom: 6px;
}

/* Предупреждение об откате к пересборке (листа метаданных в файле нет) */
.save-confirm .scd-warning {
    color: #a05a00;
    font-size: 12px;
}

/* Блок метаданных журнала — рамка с заголовком (TitledBorder десктопа), поля в одну линию */
.save-confirm .scd-meta {
    border: 1px solid #bbb;
    border-radius: 3px;
    padding: 6px 8px 8px;
}

.save-confirm .scd-meta-title {
    font-size: 12px;
    color: #444;
    margin-bottom: 4px;
}

.save-confirm .scd-meta-row {
    display: flex;
    gap: 12px;
}

.save-confirm .scd-meta-row label {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.save-confirm .scd-meta-row input {
    flex: 1;
    min-width: 60px;
    font-size: 13px;
    padding: 2px 4px;
}

/* ==================== Окно отчёта автомёржа (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 */
}

/* Выделенная различающаяся ячейка: различие доминирует, выделение подмешивается
   насыщенным синим (бледный tableSelectionBg в смеси был почти неразличим;
   отход от десктопного blend(diffBg, selectionBg, 0.75) — пожелание, июль 2026). */
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 65%, var(--selection-mix-blue));
}

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 65%, var(--selection-mix-blue));
}

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 65%, var(--selection-mix-blue));
}

/* Различающаяся ячейка под КРОСС-выделением (MVP30, §5.15): градация различия
   доминирует, выделение подмешано бледным tableSelectionBg (мягче синего у .sel —
   кросс-выделение вторично). Специфичность 0-5-3 — побеждает одиночные diff-* и
   .sel-mirror независимо от порядка объявления. */
tbody tr:nth-child(even) td.diff-minor.sel-mirror:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-minor.sel-mirror:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, #fdeeee 65%, var(--table-selection-bg));
}

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

tbody tr:nth-child(even) td.diff-major.sel-mirror:not(.rownum):not(.reveal-strip),
tbody tr:nth-child(odd) td.diff-major.sel-mirror:not(.rownum):not(.reveal-strip) {
    background: color-mix(in srgb, #f0a8a8 65%, 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;
}

/* ==================== Вкладка «Настройки» (MVP24, §6) ==================== */

/* Экран настроек — колонка секций, прокрутка при нехватке высоты */
.settings-view {
    padding: 8px 4px;
    gap: 10px;
    overflow-y: auto;
    max-width: 640px;
}

/* Секция — рамка с надписью, как TitledBorder десктопа (см. .merger-panel) */
.settings-section {
    margin: 0;
    padding: 4px 12px 10px;
    border: 1px solid #bbb;
    border-radius: 3px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

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

/* Чекбокс с подписью */
.settings-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    cursor: pointer;
    user-select: none;
    align-self: flex-start;
}

.settings-check input {
    margin: 0;
    cursor: pointer;
}

/* Зарезервированная (недоступная) опция — затемнена, курсор обычный */
.settings-check.disabled {
    color: #999;
    cursor: default;
}

.settings-check.disabled input {
    cursor: default;
}

/* Пояснение под контролом */
.settings-hint {
    font-size: 12px;
    color: #777;
}

/* Строка «чекбокс + значок ?»: держит их на одной линии (MVP13a) */
.settings-check-help {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Подпись поля с значком «?» */
.settings-row-label {
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Значок «?» в кружке — открывает информационное окно */
.help-badge {
    width: 18px;
    height: 18px;
    padding: 0;
    border: 1px solid #999;
    border-radius: 50%;
    background: #f4f4f4;
    font-size: 12px;
    font-weight: 600;
    color: #555;
    line-height: 1;
    cursor: pointer;
}

.help-badge:hover {
    background: #e6e6e6;
}

/* Список сохранённых пар «левое имя → правое имя» */
.pair-history {
    font-size: 13px;
    border: 1px solid #ddd;
    border-radius: 3px;
    background: #fafafa;
    padding: 6px 8px;
    max-height: 180px;
    overflow-y: auto;
}

.pair-history.empty {
    color: #999;
}

.pair-history .pair-row {
    padding: 1px 0;
    word-break: break-word;
}

/* Кнопки действий секции/экрана */
.settings-actions button {
    font-size: 12px;
    padding: 3px 12px;
    cursor: pointer;
    align-self: flex-start;
}

.settings-actions button:disabled {
    color: #999;
    cursor: default;
}

/* Текст информационного окна «?» — абзацы без лишних отступов */
.settings-help-text p {
    margin: 0 0 8px;
}

.settings-help-text p:last-child {
    margin-bottom: 0;
}

/* ==================== Разделы «Мёржер» и формат даты (MVP26) ==================== */

/* Строка «подпись + числовое поле порога» */
.settings-number-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
}

.settings-number-row input[type="number"] {
    width: 64px;
    font-size: 13px;
    padding: 1px 4px;
    border: 1px solid #bbb;
    border-radius: 2px;
}

/* Некорректное значение порога — не применяется, поле подсвечено до исправления */
.settings-number-row input.invalid {
    border-color: #c00;
    background: #fff0f0;
}

/* Radio-группа формата даты — варианты в строку */
.settings-radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 18px;
}

/* Строка «подпись + текстовое поле» (имя листа метаданных, MVP13a) */
.settings-text-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
}

.settings-text-row input[type="text"] {
    width: 140px;
    font-size: 13px;
    padding: 1px 4px;
    border: 1px solid #bbb;
    border-radius: 2px;
}

/* ==================== Раздел «Паразитные символы» (MVP25) ==================== */

/* Строка «подпись + color-контрол» */
.settings-color-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
}

.settings-color-row input[type="color"] {
    width: 44px;
    height: 22px;
    padding: 1px;
    border: 1px solid #999;
    border-radius: 3px;
    background: #fff;
    cursor: pointer;
}

/* Сворачиваемая таблица символов (раздел длинный — по умолчанию свёрнут) */
.marker-details summary {
    font-size: 13px;
    cursor: pointer;
    user-select: none;
    padding: 2px 0;
}

.marker-details .settings-hint {
    margin: 4px 0 6px;
}

/* Грид строк символов — несколько колонок, как три колонки настроек десктопа */
.marker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 3px 14px;
}

/* Строка символа: [отслеживать][текст маркера][тип] */
.marker-row {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    min-width: 0;
}

.marker-row input[type="checkbox"] {
    margin: 0;
    flex: none;
    cursor: pointer;
}

.marker-row .marker-text {
    width: 46px;
    flex: none;
    font: 11px Consolas, monospace;
    padding: 1px 3px;
    border: 1px solid #bbb;
    border-radius: 2px;
}

/* Ключ типа символа — подпись строки (обрезается с многоточием при нехватке места) */
.marker-row .marker-type {
    color: #666;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
