/* ListMatcher — стили страницы. Вид — по десктопу DOP_Helper2 (Swing): эталон вида, не копия.
   Раскладка — колонка во всю высоту окна: шапка, вкладки, содержимое вкладки, системная панель.
   Содержимое вкладки забирает всю оставшуюся высоту (как таблицы десктопа) — место для таблиц на 100 000 строк.
   Окно ниже панелей кнопок — страница прокручивается целиком (как минимальная высота окна десктопа), таблицы
   при этом ужимаются. Окно уже — сначала сужаются таблицы, до заголовка с итогами; панели кнопок не сжимаются;
   уже этого предела — прокрутка страницы вбок (body не уже своего min-content). Мобильной вёрстки нет. */

:root {
    /* Цвета десктопа (CommonUtils ViewConstants): defaultOKColor — общие строки, найденное фильтром;
       defaultErrorColor — фильтр не нашёл */
    --ok-bg: rgb(230, 253, 230);
    --error-bg: rgb(253, 230, 230);
    --unique-bg: #ffffff;
    --selection-bg: #b8cfe5;
    /* Найденное экспресс-фильтром: HighlightStyle.defaults() CommonUtils — Color.YELLOW фон, Color.RED текст */
    --found-bg: rgb(255, 255, 0);
    --found-text: rgb(255, 0, 0);
    --panel-bg: #f0f0f0;
    --border: #c8c8c8;
    --text: #222222;
    --text-muted: #666666;
    --font: "Segoe UI", Tahoma, system-ui, sans-serif;
    --mono: Consolas, "DejaVu Sans Mono", "Courier New", monospace;
    /* Высота строки таблицы — постоянная: app.js (ListTable) читает её и по ней находит видимые строки */
    --row-height: 20px;
    /* Кнопки ColoredButton CommonUtils (CustomButtonUI): обычный цвет, под мышью, нажата */
    --blue-bg: rgb(204, 229, 255);
    --blue-hover: rgb(51, 153, 255);
    --blue-pressed: rgb(0, 102, 204);
    --violet-bg: rgb(250, 230, 250);
    --violet-hover: rgb(240, 200, 240);
    --violet-pressed: rgb(230, 190, 255);
    --green-bg: rgb(229, 255, 229);
    --green-hover: rgb(179, 255, 179);
    --green-pressed: rgb(51, 255, 51);
    --yellow-bg: rgb(255, 255, 204);
    --yellow-hover: rgb(255, 255, 102);
    --yellow-pressed: rgb(255, 255, 51);
    /* «Выделить найденные» (ExpressFilterPanel): красный текст на жёлтом */
    --select-found-bg: rgb(255, 255, 153);
    --select-found-hover: rgb(255, 255, 51);
    --select-found-pressed: rgb(204, 204, 0);
}

* {
    box-sizing: border-box;
}

html, body {
    height: 100%;
}

body {
    margin: 0;
    /* Не уже содержимого: панели кнопок целиком и таблицы не уже своего заголовка; окно уже — прокрутка вбок,
       шапка, вкладки и системная панель тянутся на всю прокручиваемую ширину */
    min-width: min-content;
    display: flex;
    flex-direction: column;
    font-family: var(--font);
    font-size: 14px;
    color: var(--text);
    background: #fafafa;
}

button, input, select, textarea {
    font: inherit;
    color: inherit;
}

/* ==================== Шапка: приватность и версия — одной строкой ==================== */

.app-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 12px;
    padding: 5px 16px;
    background: var(--panel-bg);
    border-bottom: 1px solid var(--border);
}

.app-version {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 12px;
    white-space: nowrap;
}

.privacy-note {
    margin: 0;
    font-size: 12px;
    color: #2e6b2e;
    cursor: help;
}

/* ==================== Вкладки (LMW-6, как MainTabPanel десктопа) ==================== */

.app-tabs {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding: 6px 16px 0;
    background: var(--panel-bg);
    border-bottom: 1px solid #b0b0b0;
}

.app-tab {
    padding: 5px 16px;
    border: 1px solid #b0b0b0;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    background: #e4e4e4;
    color: #444;
    cursor: pointer;
}

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

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

/* ==================== Содержимое вкладок ==================== */

/* Высота содержимого не меньше его панелей кнопок (min-height по умолчанию — auto): окно ниже — страница
   прокручивается. Таблицы в этот минимум не входят (contain: size у прокрутки) — длинная таблица прокручивается
   внутри себя, а не растягивает страницу */
.app-views {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.app-view {
    flex: 1;
    padding: 8px 12px;
}

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

/* ==================== Общие элементы: кнопки, блоки с рамкой-титулом, галочки ==================== */

.app-view button {
    padding: 3px 6px;
    border: 1px solid #a8a8a8;
    border-radius: 3px;
    background: linear-gradient(#fdfdfd, #e6e6e6);
    cursor: pointer;
    white-space: nowrap;
}

.app-view button:hover {
    background: linear-gradient(#ffffff, #dcebf7);
    border-color: #7a9cc0;
}

.app-view button:active {
    background: #c9dcee;
}

.app-view button:disabled {
    color: #999;
    background: #eeeeee;
    border-color: #c8c8c8;
    cursor: default;
}

.app-view button:focus-visible {
    outline: 2px solid #5b9bd5;
    outline-offset: -2px;
}

/* Переключатель (JToggleButton): нажатый — утоплен */
.app-view button.toggle[aria-pressed="true"] {
    background: linear-gradient(#cfd8e2, #dfe6ee);
    border-color: #7a8ea4;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.25);
}

/* Цветные кнопки ColoredButton CommonUtils */
.app-view button.colored.blue { background: var(--blue-bg); }
.app-view button.colored.blue:hover { background: var(--blue-hover); }
.app-view button.colored.blue:active { background: var(--blue-pressed); color: #fff; }
.app-view button.colored.violet { background: var(--violet-bg); }
.app-view button.colored.violet:hover { background: var(--violet-hover); }
.app-view button.colored.violet:active { background: var(--violet-pressed); }
.app-view button.colored.green { background: var(--green-bg); }
.app-view button.colored.green:hover { background: var(--green-hover); }
.app-view button.colored.green:active { background: var(--green-pressed); }
.app-view button.colored.yellow { background: var(--yellow-bg); }
.app-view button.colored.yellow:hover { background: var(--yellow-hover); }
.app-view button.colored.yellow:active { background: var(--yellow-pressed); }

/* Блок с рамкой-титулом (TitledBorder) */
.app-view fieldset {
    margin: 0;
    padding: 2px 6px 6px;
    border: 1px solid #c4c4c4;
    border-radius: 3px;
}

.app-view legend {
    padding: 0 3px;
    font-size: 13px;
    color: #333;
}

/* «Удалить» — заголовок красный, как в десктопе */
.delete-block legend {
    color: #d00000;
}

.check {
    display: flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    user-select: none;
}

.check input {
    margin: 0;
}

/* ==================== «Сравнить множества» ==================== */

.view-compare {
    display: flex;
    gap: 8px;
}

/* Панели управления: ширина постоянная и не сжимаются — содержимое целиком (шрифт шире — панель шире: min-width),
   блоки прижаты к верху (как bottomGlue десктопа). Сужается окно — сужаются таблицы */
.control-panel {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: max-content;
}

.left-control {
    width: 300px;
}

.right-control {
    width: 128px;
}

/* LoadPanel: [Разбить по: …] [↘+] [↘]; кнопки загрузки — на всю высоту блока, крупным шрифтом */
.load-block {
    display: flex;
    gap: 3px;
    padding: 3px;
    border: 1px solid #c4c4c4;
    border-radius: 3px;
    min-height: 80px;
}

.app-view .breakdown-block {
    flex: 1;
    min-width: 0;
    padding: 2px 4px 6px;
}

.breakdown-buttons {
    display: flex;
}

.breakdown-buttons button {
    flex: 1 1 auto;
    padding: 2px 2px;
    font-size: 13px;
    border-radius: 0;
}

.breakdown-buttons button:first-child {
    border-radius: 3px 0 0 3px;
}

.breakdown-buttons button:last-child {
    border-radius: 0 3px 3px 0;
}

.breakdown-buttons button + button {
    margin-left: -1px;
}

.app-view button.load-button {
    padding: 2px 5px;
    font-size: 20px;
    line-height: 1;
}

.match-mode {
    padding: 0 2px;
    font-size: 13px;
}

/* Левые «Копировать строки» и «Удалить строки»: [Все] [Уникальные] [Общие] / . [Выбранные] [Дубли] */
.grid-block {
    display: grid;
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
        "all unique common"
        ".   selected duplicates";
    gap: 2px;
}

.grid-block .cell-all { grid-area: all; }
.grid-block .cell-unique { grid-area: unique; }
.grid-block .cell-common { grid-area: common; }
.grid-block .cell-selected { grid-area: selected; }
.grid-block .cell-duplicates { grid-area: duplicates; }

/* Правые «Копировать» и «Удалить»: столбиком на всю ширину */
.column-block {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.right-load-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3px;
}

.app-view .right-load-row button.load-button {
    padding: 6px 4px;
}

/* Экспресс-фильтр */
.filter-block {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.filter-field {
    width: 100%;
    padding: 3px 5px;
    border: 1px solid #a8a8a8;
    border-radius: 2px;
    background: #fff;
}

/* Цвет поля по запросу (DOP-27): текст есть в левой таблице — зелёный, нет — розовый, пустой — обычный */
.filter-field.found {
    background: var(--ok-bg);
}

.filter-field.not-found {
    background: var(--error-bg);
}

.filter-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

.filter-row .check {
    font-size: 13px;
}

.app-view button.clear-filter {
    padding: 0 10px;
    font-size: 16px;
    font-weight: 600;
}

.app-view button.invert-selection {
    padding: 0 16px;
    font-size: 18px;
    line-height: 1.2;
}

.app-view button.select-found {
    padding: 4px 10px;
    color: #e00000;
    background: var(--select-found-bg);
}

.app-view button.select-found:hover {
    background: var(--select-found-hover);
}

.app-view button.select-found:active {
    background: var(--select-found-pressed);
}

/* История: «↶ Назад» и «Вперёд ↷» в один ряд, одной ширины */
.history-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2px;
}

/* Таблица (TablePanel): кнопки сортировки постоянной высоты, высоту окна забирает только таблица. Таблицы делят
   ширину поровну и сужаются первыми; предел — min-width: auto, то есть min-content: кнопки ↑ ⊙ ☽ и заголовок с
   итогами целиком (не меньше образца с трёхзначными числами — .list-header::after). Строки на ширину не влияют
   (contain: strict у прокрутки) */
.table-panel {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sort-buttons {
    flex: none;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}

.sort-buttons button {
    border-radius: 0;
    font-size: 15px;
    line-height: 1.2;
}

.sort-buttons button + button {
    margin-left: -1px;
}

/* Одна колонка строк: заголовок-итоги и прокрутка. Прокрутка — без своего размера (contain: size): высоту ей
   даёт вкладка, строки (LMW-7 рисует только видимые) на размер страницы не влияют */
.list-table {
    flex: 1 1 0;
    min-height: 120px;
    display: flex;
    flex-direction: column;
    border: 1px solid #a8a8a8;
    background: var(--unique-bg);
}

.list-header {
    flex: none;
    padding: 3px 6px;
    border-bottom: 1px solid #b8b8b8;
    background: linear-gradient(#fbfbfb, #e8e8e8);
    font-size: 13px;
    text-align: center;
    /* Итоги «Σ 120  ⊙ 80  ☽ 37  ≡ 3» — пары через два пробела, как в десктопе: пробелы не схлопывать */
    white-space: pre;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
}

/* Образец ширины: итоги с трёхзначными числами не обрезаются, даже если сейчас числа короче, — таблица не уже его.
   Невидим и без высоты; итоги длиннее образца расширяют таблицу сами (свой min-content) */
.list-header::after {
    content: "Σ 999  ⊙ 999  ☽ 999  ≡ 999";
    display: block;
    height: 0;
    overflow: hidden;
    visibility: hidden;
}

.list-viewport {
    flex: 1 1 0;
    position: relative;
    overflow-x: hidden;
    overflow-y: auto;
    contain: strict;
}

/* Строки (ListTable в app.js): .list-rows — высотой со все строки (даёт полосу прокрутки), в нём .list-window —
   только видимые строки, сдвинутые к месту прокрутки. Длинная строка — троеточием, полный текст — в подсказке */
.list-rows {
    position: relative;
    overflow: hidden;
}

.list-window {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

.list-row {
    height: var(--row-height);
    padding: 0 4px;
    border-bottom: 1px solid #ececec;
    font-size: 13px;
    line-height: calc(var(--row-height) - 1px);
    white-space: pre;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
    user-select: none;
}

/* Раскраска сравнения (ArrayComporatorTableCellRenderer десктопа): общая — зелёный фон defaultOKColor, уникальная —
   белый фон таблицы, дубль — жирный */
.list-row.common {
    background: var(--ok-bg);
}

.list-row.duplicate {
    font-weight: bold;
}

/* Выделенная строка (LMW-10) — синий фон выделения JTable поверх раскраски; жирный дубля остаётся */
.list-row.selected {
    background: var(--selection-bg);
}

/* Найденное экспресс-фильтром (LMW-10) — HighlightStyle CommonUtils по умолчанию: жёлтый фон, красный текст */
.list-row mark.found {
    padding: 0;
    background: var(--found-bg);
    color: var(--found-text);
}

.list-viewport:focus-visible {
    outline: 2px solid #5b9bd5;
    outline-offset: -2px;
}

/* Подсказка пустой таблицы (вместо демо-данных десктопа) */
.list-empty {
    padding: 24px 12px;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

.list-empty p {
    margin: 0 0 6px;
}

.list-empty-title {
    font-size: 14px;
    font-weight: 600;
}

.list-empty[hidden] {
    display: none;
}

/* ==================== «Операции с текстом» ==================== */

/* Столбик кнопок одной ширины (GridLayout десктопа); слева место, как у распорки десктопа */
.view-text {
    display: flex;
}

.view-text::before {
    content: "";
    flex: 2 1 150px;
}

.view-text::after {
    content: "";
    flex: 1 1 0;
}

.text-operations {
    flex: none;
    width: 320px;
    display: grid;
    grid-auto-rows: auto;
    gap: 4px;
    align-content: start;
}

.app-view .text-operations button {
    padding: 6px 4px;
}

/* ==================== «Исправить кодировку» ==================== */

/* Сверху вниз; таблица файлов и предпросмотр делят высоту поровну и ужимаются вместе */
.view-encoding {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.view-encoding.drag-over {
    outline: 2px dashed #5b9bd5;
    outline-offset: -4px;
}

.encoding-choose-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.encoding-drop-hint {
    color: var(--text-muted);
    font-size: 13px;
}

/* Основа 90px, а не 0, — общая с предпросмотром: у его поля свои отступы, и основа 0 дала бы ему на них больше */
.encoding-files {
    flex: 1 1 90px;
    min-height: 90px;
    overflow: auto;
    contain: size;
    border: 1px solid #a8a8a8;
    background: #fff;
}

.files-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 13px;
}

.files-table th {
    position: sticky;
    top: 0;
    padding: 3px 6px;
    border-right: 1px solid #b8b8b8;
    border-bottom: 1px solid #b8b8b8;
    background: linear-gradient(#fbfbfb, #e8e8e8);
    font-weight: normal;
    text-align: left;
}

/* «Кодировка» узкая (по ширине названий кодировок), имя файла забирает остальное */
.files-table .encoding-column {
    width: 120px;
}

/* Строки файлов: длинное имя — троеточием (полное — в подсказке), выбранная — фоном выделения, как в таблицах */
.files-table td {
    padding: 2px 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: default;
    user-select: none;
}

.files-table tr.selected td {
    background: var(--selection-bg);
}

.encoding-files:focus-visible {
    outline: 2px solid #5b9bd5;
    outline-offset: -2px;
}

.labeled-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.labeled-row select {
    padding: 2px 4px;
}

.app-view button.recode-button {
    padding: 4px 12px;
}

.encoding-preview {
    flex: 1 1 90px;
    min-height: 90px;
    contain: size;
    resize: none;
    padding: 4px 6px;
    border: 1px solid #a8a8a8;
    font-family: var(--mono);
    font-size: 13px;
    white-space: pre;
    overflow: auto;
}

/* ==================== «О программе» ==================== */

.view-about {
    overflow: auto;
}

.about {
    max-width: 760px;
    line-height: 1.45;
}

.about h2 {
    margin: 4px 0 8px;
    font-size: 18px;
}

.about h3 {
    margin: 14px 0 4px;
    font-size: 15px;
}

.about p, .about ul {
    margin: 0 0 6px;
}

/* «Скачать офлайн-версию (.HTML)» (LMW-16) — под пояснением */
.about button {
    margin: 2px 0 6px;
}

.about-version {
    margin-top: 14px;
    color: var(--text-muted);
}

/* ==================== Системная панель ==================== */

.system-panel {
    flex: none;
    border-top: 1px solid var(--border);
    background: var(--panel-bg);
}

/* Область буфера обмена — 3 строки, только чтение (PanelSystem десктопа) */
.clipboard-area {
    display: block;
    width: 100%;
    margin: 0;
    padding: 3px 16px;
    border: none;
    border-bottom: 1px solid var(--border);
    background: #fff;
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.35;
    resize: none;
    white-space: pre;
    overflow: auto;
}

.clipboard-area::placeholder {
    color: #9a9a9a;
    font-family: var(--font);
    white-space: normal;
}

/* Строка состояния — итог последнего действия (printStateLine десктопа); длинный текст — троеточием, полный — в подсказке */
.statusbar {
    padding: 4px 16px;
    min-height: 26px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Длинный итог не расширяет страницу (body — по min-content): он обрезается троеточием */
    contain: inline-size;
}

.statusbar.error {
    background: var(--error-bg);
    color: #a00000;
}
