/* ═══════════════════════════════════════════════════════════════
   workspace.css — Data Workspace: canvas + аналитическая панель
   v1.72.0-sample-note

   v1.72.0: Строка «Показано N точек из M — случайная выборка» под легендой
            (`.wc-sample-note`, ТЗ ПОТОЛКИ T2.2). Место и размер те же, что у
            строки о непоказанных точках, цвет приглушённый: это свойство
            картинки, а не поломка.
   v1.71.5: Три списка панели приведены к одному формату (правка владельца):
            одинаковые отступы строки (кружки цветовых меток встали на одну
            вертикаль), кнопки строки видны всегда вполсилы и разгораются на
            наведении — прежде в группах они появлялись только под курсором, а
            в выборках и слоях горели постоянно; каретки заголовков прижаты к
            левому краю, к той же вертикали, что и метки строк.
   v1.71.4: `.wc-hist-btn` — кнопки истории ГРУПП того же вида, что у выборок;
            корзина и «скрыть все» при пустом разделе гаснут, а не исчезают.
            Парная правка — график 1.84.0.
   v1.71.3: Один вертикальный ритм на всю панель: «Источники» и «Статистика»
            носят тот же класс заголовка, что и разделы выше, контейнеры секций
            без собственных отступов, черта между «Классами» и «Группами»
            убрана. Прежде расстояния между списками были разными.
   v1.71.2: Разделы панели идут одним списком: `--flat` снимает собственный
            отступ у контейнеров секций, `--wide` даёт заголовку колонку под
            три-четыре кнопки. Парная правка — график 1.83.0.
   v1.71.1: Строке ГРУППЫ отведено место под четыре кнопки, а не три — иначе
            «→ в выборку» наползает на кнопку тренда. Кнопки истории выборок
            (`.wc-sel-hist`) переехали в строку заголовка: без контура, видны
            всегда, доступность цветом. Парная правка — график 1.82.1.
   v1.71.0: `.wc-chat-action-tosel` — кнопка «→ В выборку» у применённой команды
            модели (T7.2-хр, парная правка к графику 1.81.0).
   v1.70.0: Поле вопроса к модели стало высотой в три строки (было в одну — в
            него не влезала собственная подсказка) и тянется вручную.
   v1.69.0: `.wc-chat-action-undo` — кнопка отмены применённой команды модели.
            Парная правка к графику 1.80.0.
   v1.68.0: Ошибка и предупреждение в сообщениях видны цветом: полоса слева и
            лёгкая заливка. Прежде краснела только рамка, и на тёмном фоне
            алярм читался как обычное сообщение (замечание владельца 17.08).
   v1.67.0: «Источники» и «Статистика» сворачиваются (`.wc-fold`) и по умолчанию
            свёрнуты; оба переехали вниз панели, под «Слои». Правка владельца.
   v1.66.0: Раздел «Источники» в левой панели графика (`.wc-sources`,
            `.wc-src-tech`). Парная правка к графику 1.79.0.
   v1.65.2: Диалог связи прокручивает СЕРЕДИНУ, кнопки прибиты к низу. Прежде
            прокручивался весь диалог, и на невысоком экране кнопка «Создать
            связь» уезжала за край (найдено владельцем сразу после 1.65.1).
   v1.65.1: Подписи над каждым списком в диалоге связи (`.dw-join-kp-field`,
            `.dw-join-kp-cap`) — что это за поле и из какой таблицы колонки.
            Парная правка к канвасу 1.56.13.
   v1.65.0: `.dw-toast--above` — своя полка для липкого сообщения канваса (выше
            обычного на 56px). Парная правка к канвасу 1.56.11: липкий отказ
            связи переехал в отдельный элемент `#dwToastSticky`, потому что в
            общем его затирало рядовое «Сохранено» — и отказ предохранителя не
            доходил до человека ни разу (приёмка волны 5, шаг 3).
   v1.64.0: Полоса свёрнутых окон ПЕРЕНОСИТ плашки на новую строку (`flex-wrap:
            wrap`, ширина до 980px, слот от 170px). Было `nowrap` при жёстких
            55vw: лишние плашки уезжали за край полосы, а затем и за экран —
            свёрнутое окно становилось недостижимым (найдено владельцем 16.08).
   v1.63.0: `.wp-tooltip-head` — заголовок раздела подсказки (имя таблицы), сама
            подсказка шире (460px) и при нужде прокручивается. Парная правка к
            графику 1.76.0: у точки совместного графика за спиной ДВЕ таблицы.
   v1.62.0: `.dw-dialog-overlay--top` — модалка поверх всех окон DWS. Парная
            правка к канвасу 1.56.2: вопрос «Правки уехали в копию» появлялся
            под открытым просмотрщиком, потому что жил внутри слоя канваса со
            своим контекстом наложения.
   v1.61.0: Строка «Не показано точек: N (…)» под легендой (`.wc-hidden-points-note`).
            Парная правка к графику 1.75.0: точки, которых нет на поле, теперь
            названы числом и причиной, а не молчат.
   v1.60.0: ПОСТОЯННАЯ ширина у диалога построения графика (`dw-dialog--fit`),
            остальные диалоги вернулись к прежним 480px. Правка 1.59.0 меняла
            ширину ВСЕХ диалогов по содержимому и раздула выбор проекта, а окно
            осей всё равно гуляло под длину имён колонок — владелец забраковал
            оба эффекта. Ширина <select> задаётся самой длинной строкой списка,
            поэтому «по содержимому» тут и означает «прыгает»; теперь размер
            один и от данных не зависит.
   v1.58.0: селекторы в диалогах перестали вылезать за правый край модалки.
            У флекс-элемента ширина не опускается ниже «естественной», а у
            <select> она задана самой длинной строкой списка — длинные имена
            колонок распирали ряд. Добавлены min-width:0 / max-width:100% /
            box-sizing и запрет растягивать подпись слева.
   v1.57.0: .wtv-error-retry — кнопка повтора в блоке ошибки просмотрщика.
            У отказа обязан быть выход: раньше после запуска rBase таблицу
            приходилось закрывать и открывать заново.
   v1.56.0: .dw-storage-head / .dw-storage-del / .dw-storage-item--already —
            уборка хранилища: корзина у каждой таблицы в диалоге хранилища.
            Строка «уже на канвасе» гасится ЦВЕТОМ, а не прозрачностью:
            прозрачность родителя перемножается с дочерней и погасила бы саму
            корзину. Версия поднята до 1.56.0, чтобы сойтись с `?v=` в app.html —
            заголовок файла отстал от него на несколько правок.
   v1.51.0: .wc-axis-note / .wc-axis-fold-row / .wc-axis-fold-select — раздел
            «Колонки связанных таблиц» в меню оси; max-height меню поднят до
            70vh, иначе до самих колонок приходилось прокручивать вслепую.
            Здесь же .wc-modal-header-actions и .wc-labels-clear — корзина
            «снять все отметки» рядом с крестиком диалога подписей (просьба
            владельца); приглушена, красная только под курсором, иначе рядом с
            закрытием окна она читается как равная ему по весу.
            Здесь же сведены версии: шапка показывала 1.49.1, а `?v=` в
            app.html — 1.50.0.
   v1.49.1: .wc-sel-title-actions — обе кнопки заголовка «Выборки» в одном ряду.
   v1.49.0: .wtv-empty-note — объяснение пустого отбора в просмотрщике.
   v1.48.0: .wc-legend-caret и .wc-legend-section-body — сворачивание секций
            легенды графика (просьба владельца).
   Версия здесь и `?v=` в app.html — одно и то же число (P21/T6.4).
   v1.47.0: .dw-sel-limits — раздел «Пределы» в карточке выборки (T8.2). Строка
            есть у каждого предела, задетый помечен полосой слева.
   v1.46.5: .dw-alg-done — зелёная галочка выполненной операции над выборками
            (просьба владельца на приёмке §9.3).
   v1.46.4: подвал диалогов переносится на вторую строку (flex-wrap), карточка
            выборки расширена до 720px. Шесть кнопок карточки в 560px не
            влезали, и «Операции» уезжала ЗА левый край окна — невидимая и
            ненажимаемая, на глаз «кнопки нет». Найдено владельцем на приёмке
            §9.3 ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS.
   v1.39.0: кнопки окна графика («Свернуть» / «Закрыть») переехали из правой
            панели инструментов в шапку, на уровень вкладок — модификатор
            .wc-header-right.wc-window-controls. Парная правка:
            workspace-chart.js v1.28.0.
   v1.38.0: T3.3 ТЗ_ТРЕЙ_ВЛАДЕНИЕ_И_СТОПКИ_DWS — стиль плашки-группы
            (.dw-min-viewer-pill--group): пунктирная рамка, приглушённые фон и
            иконка. У группы нет своего свёрнутого окна, клик открывает
            карточку заново — она не должна выглядеть как обычная плашка.
   v1.37.0: T1.1 того же ТЗ — z-index трея 9700 → 9750 (просмотрщик документов
            делил с ним 9700 и как более поздний узел DOM накрывал полосу).
            Заголовок файла тогда не бампнули, версия отстала на 1.20-1.36 —
            здесь выправлено до фактического `?v=` в app.html.
   v1.19.0: пояснение к импорту проекта в пикере (T5.1 ТЗ_НАДЁЖНОСТЬ_DWS).
   v1.18.0: блок диагностики ошибки анализа (T6.3 ТЗ_НАДЁЖНОСТЬ_DWS).
   ═══════════════════════════════════════════════════════════════ */

/* ── Overlay & Modal ── */
.dw-overlay {
    position: fixed;
    inset: 0;
    z-index: 9000;
    background: var(--bg, #1c1a20);
    display: flex;
    flex-direction: column;
    font-family: "Inter", system-ui, -apple-system, sans-serif;
    color: var(--text, #e8e3db);
}

/* ── Top toolbar ── */
.dw-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
    height: 42px;
}
.dw-toolbar-title {
    font-size: 0.95rem;
    font-weight: 600;
    margin-right: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}
.dw-toolbar-title input {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text, #e8e3db);
    font-size: 0.95rem;
    font-weight: 600;
    padding: 2px 6px;
    border-radius: 4px;
    width: 260px;
}
.dw-toolbar-title input:hover {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.dw-toolbar-title input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
}
.dw-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    background: transparent;
    color: var(--text-dim, #948e84);
    font-size: 0.82rem;
    cursor: pointer;
    transition: all 0.15s;
    white-space: nowrap;
}
.dw-btn:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    color: var(--text, #e8e3db);
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.dw-btn.active {
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
    border-color: var(--primary, #c9995e);
}
.dw-btn-primary {
    background: var(--primary, #c9995e);
    color: #1c1a20;
    border-color: var(--primary, #c9995e);
    font-weight: 600;
}
.dw-btn-primary:hover {
    background: #d4a76a;
    color: #1c1a20;
}
.dw-btn svg {
    flex-shrink: 0;
}
.dw-separator {
    width: 1px;
    height: 20px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin: 0 4px;
}

/* ── Main body: canvas + panel ── */
.dw-body {
    display: flex;
    flex: 1;
    overflow: hidden;
    position: relative;
}

/* ── Canvas area ── */
.dw-canvas-area {
    flex: 1;
    overflow: auto;
    position: relative;
    background: var(--bg, #1c1a20);
    cursor: default;
}
.dw-canvas-area.hand-mode {
    cursor: grab;
}
.dw-canvas-area.hand-mode.grabbing {
    cursor: grabbing;
}

.dw-canvas-surface {
    position: relative;
    width: 6000px;
    height: 4000px;
    transform-origin: 0 0;
}

/* ── Grid overlay (CSS gradient, canvas-builder style) ── */
.dw-canvas-grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    background-image:
        linear-gradient(rgba(var(--dw-ink, 232, 227, 219), 0.045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(var(--dw-ink, 232, 227, 219), 0.045) 1px, transparent 1px);
    background-size: 20px 20px;
}

/* ── Drop zone overlay ── */
.dw-drop-zone {
    position: absolute;
    inset: 0;
    background: rgba(201, 153, 94, 0.08);
    border: 2px dashed var(--primary, #c9995e);
    border-radius: 10px;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 100;
    pointer-events: none;
}
.dw-drop-zone.active {
    display: flex;
}
.dw-drop-zone-text {
    font-size: 1.1rem;
    color: var(--primary, #c9995e);
    font-weight: 600;
    padding: 16px 24px;
    border-radius: 10px;
    background: rgba(var(--dw-deep, 28, 26, 32), 0.85);
}

/* ── Document Cards ── */
.dw-card {
    position: absolute;
    width: 220px;
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 10px;
    padding: 12px;
    cursor: move;
    user-select: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.dw-card:hover {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.dw-card.selected {
    border-color: var(--primary, #c9995e);
    box-shadow: 0 0 0 1px var(--primary, #c9995e);
}
/* Переход по селектору «Перейти к…»: карточка коротко пульсирует, чтобы её
   было видно среди прочих. Выделение (.selected) остаётся, а подсветка гаснет
   сама — иначе после нескольких переходов канвас в мигающих рамках. */
.dw-card--located {
    animation: dwCardLocated 1.8s ease-out 1;
}
@keyframes dwCardLocated {
    0%   { box-shadow: 0 0 0 1px var(--primary, #c9995e), 0 0 0 10px rgba(201, 153, 94, 0.35); }
    60%  { box-shadow: 0 0 0 1px var(--primary, #c9995e), 0 0 0 18px rgba(201, 153, 94, 0); }
    100% { box-shadow: 0 0 0 1px var(--primary, #c9995e); }
}
@media (prefers-reduced-motion: reduce) {
    .dw-card--located { animation: none; box-shadow: 0 0 0 3px var(--primary, #c9995e); }
}
/* Селектор навигации в панели: выглядит как кнопка рядом с «Добавить». */
.dw-card-nav {
    max-width: 200px;
    padding: 4px 8px;
    appearance: auto;
}
.dw-card-nav:disabled {
    opacity: 0.45;
    cursor: default;
}
/* ТЗ КАРТОЧКИ ГРАФИКОВ, T1.5: визуальное отличие карточек графика/анализа.
   Палитра канваса (тёплая тёмная): --info для графика, --success для анализа. */
.dw-card--chart {
    border-color: rgba(107, 159, 212, 0.28);
}
.dw-card--chart .dw-card-icon {
    background: rgba(107, 159, 212, 0.16);
    color: var(--info, #6b9fd4);
}
.dw-card--analysis {
    border-color: rgba(93, 184, 122, 0.28);
}
.dw-card--analysis .dw-card-icon {
    background: rgba(93, 184, 122, 0.16);
    color: var(--success, #5db87a);
}
.dw-card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}
.dw-card-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
}
.dw-card-title {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}
.dw-card-meta {
    font-size: 0.75rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 6px;
}
.dw-card-columns {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    max-height: 48px;
    overflow: hidden;
    line-height: 1.4;
}
/* Плашка «rBase не отвечает». Держится, пока сервер не ответит: тост тут не
   годится — он гаснет, и со стороны это выглядит как «перетащил файл, а
   карточка не появилась». Поверх канваса, но НИЖЕ модальных диалогов. */
.dw-offline-banner {
    position: absolute;
    top: 56px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9200;
    max-width: 720px;
    width: calc(100% - 48px);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 14px;
    border: 1px solid var(--danger, #d4706a);
    border-radius: 8px;
    background: var(--surface, #1f1f1f);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text, #e8e3db);
}
.dw-offline-text {
    flex: 1;
}
.dw-offline-text b {
    color: var(--danger, #d4706a);
}
.dw-offline-addr {
    display: block;
    margin-top: 2px;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
}
.dw-offline-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

/* ТЗ ВЫБОРКИ, T8.9 — карточка осталась на исходных данных, а правки уехали в
   копию. Молчать здесь нельзя: расхождение иначе видно только по числам. */
.dw-card-note {
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--warn, #c9a227);
    margin-bottom: 6px;
}
/* T8.10 — приписка «копия правок» в списках выбора источника. */
.dw-row-note {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    margin-left: 6px;
}
.dw-chart-table-row--derived,
.dw-storage-item--derived {
    padding-left: 18px;
    border-left: 2px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.14));
}
.dw-card-port {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border: 2px solid var(--bg, #1c1a20);
    cursor: crosshair;
    z-index: 5;
    transition: background 0.15s;
}
.dw-card-port:hover {
    background: var(--primary, #c9995e);
}
.dw-card-port.port-right {
    right: -5px;
    top: 50%;
    transform: translateY(-50%);
}
.dw-card-port.port-left {
    left: -5px;
    top: 50%;
    transform: translateY(-50%);
}
.dw-card-port.port-bottom {
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
}
.dw-card-port.port-top {
    top: -5px;
    left: 50%;
    transform: translateX(-50%);
}

/* ── Connection lines (SVG overlay) ── */
.dw-connections-svg {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}
.dw-connections-svg path {
    fill: none;
    stroke: var(--text-muted, #6b6560);
    stroke-width: 1.5;
    pointer-events: stroke;
    cursor: pointer;
}
.dw-connections-svg path:hover {
    stroke: var(--primary, #c9995e);
    stroke-width: 2;
}
.dw-connections-svg path.conn-exact { stroke: var(--success, #5db87a); }
.dw-connections-svg path.conn-range { stroke: var(--info, #6b9fd4); }
.dw-connections-svg path.conn-fuzzy { stroke: #f59e0b; }
.dw-connections-svg path.conn-reference { stroke: var(--text-muted, #6b6560); stroke-dasharray: 6 4; }
.dw-connections-svg path.conn-group { stroke: var(--text-muted, #6b6560); stroke-dasharray: 2 4; opacity: 0.5; }
/* ТЗ КАРТОЧКИ ГРАФИКОВ, T1.3: производность карточки графика/анализа → источник */
.dw-connections-svg path.conn-derives { stroke: var(--primary, #c9995e); stroke-dasharray: 3 5; opacity: 0.7; }

.dw-conn-label {
    position: absolute;
    font-size: 0.7rem;
    color: var(--text-dim, #948e84);
    background: var(--bg, #1c1a20);
    padding: 1px 5px;
    border-radius: 3px;
    pointer-events: none;
    white-space: nowrap;
    z-index: 2;
}

/* ── Context menu ── */
.dw-context-menu {
    position: fixed;
    z-index: 9500;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 4px 0;
    min-width: 180px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    display: none;
}
.dw-context-menu.visible {
    display: block;
}
.dw-context-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.1s;
}
.dw-context-item:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.dw-context-item.danger {
    color: var(--danger, #d4706a);
}
.dw-context-item.danger:hover {
    background: rgba(212, 112, 106, 0.1);
}
.dw-context-sep {
    height: 1px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin: 4px 0;
}

/* ── Connection type picker dialog ── */
.dw-dialog-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9600;
}
/* Модалка поверх ВСЕХ окон DWS (просмотрщик — 9500, трей — 10001).
   Нужна тем диалогам, которые могут открыться, пока человек смотрит в другое
   окно: «Правки уехали в копию», выбор способа склейки. Работает только вместе
   с монтированием в `document.body` — внутри слоя канваса (9000) любое значение
   осталось бы под соседним окном: там свой контекст наложения. */
.dw-dialog-overlay--top {
    z-index: 10050;
}
.dw-dialog {
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 10px;
    padding: 20px;
    min-width: 360px;
    max-width: 480px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
/* Диалог построения графика: ширина ПОСТОЯННАЯ и от содержимого не зависит
   (требование владельца 15.08 — «размер модалки постоянный», и он же заметил,
   что окно продолжало гулять под длину имён колонок).
   Почему не «по самому широкому содержимому»: ширина <select> задаётся самой
   длинной строкой его списка, а список меняется прямо в этом окне — отметил
   вторую таблицу, и окно дёрнулось под курсором. Здесь взят один размер,
   удобный для длинных имён; сами имена целиком видны в раскрытом списке —
   браузер рисует его поверх окна и в ширину модалки не упирается.
   Общим правилом это делать нельзя: диалог выбора проекта от такой ширины
   только раздувается по своей пояснительной строке. */
.dw-dialog--fit {
    width: min(92vw, 640px);
    max-width: min(92vw, 640px);
}
.dw-dialog-wide {
    min-width: 560px;
    max-width: 640px;
    width: min(640px, 92vw);
}
.dw-dialog-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 14px;
    color: var(--text, #e8e3db);
}
.dw-dialog-title svg {
    flex-shrink: 0;
    color: var(--primary, #c9995e);
}
.dw-dialog textarea {
    width: 100%;
    box-sizing: border-box;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    padding: 8px 10px;
    font-size: 0.85rem;
    font-family: inherit;
    line-height: 1.45;
    resize: vertical;
    min-height: 80px;
    transition: border-color 0.15s;
}
.dw-dialog textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
}
.dw-dialog textarea::placeholder {
    color: var(--text-muted, #6b6560);
}
.dw-dialog-counter {
    display: flex;
    justify-content: flex-end;
    margin-top: 6px;
    margin-bottom: 4px;
    color: var(--text-muted, #6b6560);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}
.dw-dialog-counter.over {
    color: var(--danger, #d9755a);
}
.dw-dialog-note {
    margin: -2px 0 10px;
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(201, 153, 94, 0.12);
    color: var(--text-dim, #948e84);
    font-size: 0.78rem;
    line-height: 1.35;
}
.dw-dialog-note {
    margin-bottom: 10px;
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    color: var(--text-dim, #948e84);
    font-size: 0.78rem;
}
.dw-dialog-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}
.dw-dialog-label {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    min-width: 80px;
}
.dw-dialog select,
.dw-dialog input[type="number"],
.dw-dialog input[type="text"] {
    flex: 1 1 auto;
    /* Без min-width:0 элемент флекса не сжимается ниже своей «естественной»
       ширины, а у <select> она задана САМОЙ ДЛИННОЙ строкой списка. Колонки
       вроде «Глубина по каротажу, м» распирали строку, и селектор вылезал за
       правый край модалки (замечание владельца 15.08). box-sizing нужен, чтобы
       собственные padding и рамка не добавлялись к 100 % ширины. */
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
    background: var(--dw-input-bg, #26232c);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    padding: 6px 10px;
    font-size: 0.82rem;
    color-scheme: dark;
}
/* Та же причина у самой строки: она флекс-элемент диалога и обязана уметь
   сжиматься, иначе длинная подпись слева снова распирает ряд. */
.dw-dialog-row {
    min-width: 0;
}
.dw-dialog-label {
    flex: 0 0 auto;
}
/* Нативный выпадающий список <select>: тёмный фон + светлый текст,
   иначе браузер рендерит опции светлым (светлое-на-светлом). */
.dw-dialog select option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.dw-dialog select optgroup {
    background: var(--dw-surface, #1e1c24);
    color: var(--text-dim, #948e84);
    font-weight: 600;
}
.dw-dialog select:focus,
.dw-dialog input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
/* Кнопки переносятся на вторую строку, а не уезжают за край.
   Без wrap шесть кнопок карточки выборки («Операции», «Повторить правило»,
   «Выгрузить», «Удалить выборку», «Отмена», «Сохранить») не помещались в
   ширину диалога, и при выравнивании вправо ПЕРВАЯ из них оказывалась левее
   белой рамки — то есть поверх затемнения, невидимой и ненажимаемой. Кнопка
   при этом существовала и в разметке была: «функция пропала» на глаз. */
.dw-dialog-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 16px;
}
.dw-radio-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 10px;
}
.dw-radio-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: 6px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: all 0.15s;
    font-size: 0.82rem;
}
.dw-radio-option:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.dw-radio-option.selected {
    border-color: var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
}
.dw-radio-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid var(--text-muted, #6b6560);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.dw-radio-option.selected .dw-radio-dot {
    border-color: var(--primary, #c9995e);
}
.dw-radio-option.selected .dw-radio-dot::after {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--primary, #c9995e);
}
.dw-radio-label { color: var(--text, #e8e3db); }
.dw-radio-desc { font-size: 0.72rem; color: var(--text-muted, #6b6560); margin-left: 22px; margin-top: -2px; }

/* ── Connection settings modal (Эпик 6.3) ── */
.dw-conn-settings-dialog {
    min-width: 560px;
    max-width: 680px;
    width: min(680px, 94vw);
    max-height: 85vh;
    overflow-y: auto;
}
.dw-conn-settings-dialog textarea {
    width: 100%;
    box-sizing: border-box;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    padding: 6px 10px;
    font-size: 0.82rem;
    font-family: inherit;
    resize: vertical;
    min-height: 40px;
}
.dw-conn-settings-dialog textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.dw-conn-section-title {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-dim, #948e84);
    margin: 14px 0 8px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-conn-readonly {
    flex: 1;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    padding: 4px 0;
}
/* ─── Статистика по ключу (модалка связи) ─── */
.dw-conn-stats {
    margin-bottom: 10px;
    padding: 12px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
}
.dw-conn-stats-empty {
    font-size: 0.8rem;
    color: var(--text-muted, #6b6560);
}
.dw-conn-stats-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.dw-conn-stat {
    padding: 9px 11px;
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.045);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.06));
}
.dw-conn-stat-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-dim, #948e84);
    margin-bottom: 5px;
}
.dw-conn-stat-num {
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
    font-variant-numeric: tabular-nums;
}
.dw-conn-stat-num span {
    font-size: 0.82rem;
    font-weight: 400;
    color: var(--text-dim, #948e84);
}
.dw-conn-stat-bar {
    height: 4px;
    border-radius: 2px;
    /* Дорожка прогресс-бара. Литеральный белый в светлой теме сливался с
       подложкой — заполнение висело без «рельса». Через --dw-ink плёнка
       переворачивается в тёмную. */
    background: rgba(var(--dw-ink, 232, 227, 219), 0.10);
    margin: 7px 0 5px;
    overflow: hidden;
}
.dw-conn-stat-bar i {
    display: block;
    height: 100%;
    background: var(--primary, #c9995e);
    transition: width 0.3s;
}
.dw-conn-stat-sub {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
}
.dw-conn-stats-foot {
    margin-top: 10px;
    font-size: 0.8rem;
    color: var(--text-dim, #948e84);
    font-variant-numeric: tabular-nums;
}
.dw-conn-stats-foot b {
    color: var(--text, #e8e3db);
}
.dw-conn-stats-warn {
    margin-top: 8px;
    padding: 7px 9px;
    border-radius: 6px;
    border: 1px solid rgba(217, 117, 90, 0.35);
    background: rgba(217, 117, 90, 0.1);
    color: var(--danger, #e0a08a);
    font-size: 0.76rem;
    line-height: 1.4;
}
.dw-conn-stats-norm {
    margin-top: 8px;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
}
.dw-conn-stats-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}
.dw-conn-stats-actions select {
    flex: 1;
}
.dw-conn-stats-actions .dw-dialog-label {
    min-width: auto;
}
/* ─── Пары колонок составного ключа (диалог связи) ─── */
.dw-join-kp {
    gap: 6px;
    align-items: flex-end;
}
/* Подпись над КАЖДЫМ списком диалога связи (v1.65.1): что это за поле и из
   какой таблицы его колонки. До этого списки не были подписаны вовсе, а в
   режиме Range правый из них молча работал нижней границей интервала —
   владелец искал поле «Min B» и не находил (приёмка волны 5). */
.dw-join-kp-field {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.dw-join-kp-cap {
    font-size: 0.72rem;
    line-height: 1.25;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dw-join-kp select,
.dw-join-kp input[type="number"] {
    flex: 1;
    min-width: 0;
    width: 100%;
}
.dw-join-kp .dw-conn-arrow {
    flex: 0 0 auto;
    margin: 0 2px 8px;
}
.dw-join-kp .dwKpDel {
    margin-bottom: 2px;
}
.dw-join-kp .dwKpDel {
    flex: 0 0 auto;
    padding: 4px 8px;
    line-height: 1;
    font-size: 0.95rem;
    color: var(--text-dim, #948e84);
}
.dw-join-kp .dwKpDel:hover {
    color: var(--danger, #d9755a);
}
.dw-join-keywarn {
    margin: 4px 0 12px;
    padding: 10px 12px;
    border-radius: 6px;
    border: 1px solid rgba(217, 117, 90, 0.4);
    background: rgba(217, 117, 90, 0.1);
    color: var(--danger, #e0a08a);
    font-size: 0.8rem;
    line-height: 1.4;
}
.dw-join-keywarn-title {
    font-weight: 600;
    margin-bottom: 4px;
}
.dw-join-keywarn ul {
    margin: 4px 0 8px;
    padding-left: 18px;
}
.dw-join-keywarn li {
    margin: 2px 0;
}
.dw-join-keywarn-act {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}
.dw-join-keywarn-act .dw-btn {
    font-size: 0.78rem;
    padding: 5px 10px;
}
/* ─── Диалог связи: форма + панель-пояснение справа ─── */
/* Диалог связи: прокручивается СЕРЕДИНА, а заголовок и кнопки стоят на местах
   (v1.65.2). Было `overflow-y` на всём диалоге — при высоком содержимом (длинный
   список колонок, предупреждение о неуникальном ключе, подписи полей 1.65.1)
   кнопки «Создать связь» уезжали вниз вместе с текстом, и на невысоком экране
   до них было не добраться: владелец сообщил это как «модалка стала меньше». */
.dw-join-dialog {
    min-width: 720px;
    max-width: 860px;
    width: min(860px, 95vw);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.dw-join-dialog > .dw-join-layout {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}
.dw-join-dialog > .dw-dialog-actions {
    flex: 0 0 auto;
}
.dw-join-layout {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}
.dw-join-main {
    flex: 1 1 0;
    min-width: 0;
}
.dw-join-help {
    flex: 0 0 300px;
    align-self: stretch;
    padding: 12px 14px;
    border-radius: 8px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text-dim, #948e84);
}
.dw-join-help p {
    margin: 6px 0;
}
.dw-jh-title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
    margin-bottom: 6px;
}
.dw-join-help b {
    color: var(--text, #e8e3db);
    font-weight: 600;
}
.dw-join-help code {
    background: rgba(127, 127, 127, 0.18);
    border-radius: 3px;
    padding: 0 4px;
    font-size: 0.92em;
    color: var(--text, #e8e3db);
}
.dw-jh-ex {
    margin: 8px 0;
    padding: 8px 10px;
    border-radius: 6px;
    background: rgba(127, 127, 127, 0.1);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.06));
    color: var(--text, #e8e3db);
}
.dw-jh-ex-cap {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-dim, #948e84);
    margin-bottom: 4px;
}
.dw-jh-tip {
    margin-top: 8px;
    font-size: 0.78rem;
    color: var(--text-muted, #6b6560);
}
@media (max-width: 760px) {
    .dw-join-layout { flex-direction: column; }
    .dw-join-help { flex-basis: auto; width: 100%; }
}
.dw-conn-arrow {
    color: var(--primary, #c9995e);
    margin: 0 4px;
}
.dw-conn-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
}
.dw-conn-check input[type="checkbox"] {
    width: 14px;
    height: 14px;
    accent-color: var(--primary, #c9995e);
    cursor: pointer;
}
.dw-chart-tables {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 160px;
    overflow-y: auto;
    margin-bottom: 10px;
    padding: 6px 8px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
}
.dw-chart-table-row {
    padding: 3px 2px;
}
.dw-conn-direction-row {
    flex-wrap: wrap;
}
.dw-conn-radio {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 4px;
}
.dw-conn-radio input[type="radio"] {
    accent-color: var(--primary, #c9995e);
    cursor: pointer;
}
.dw-conn-field {
    margin-bottom: 10px;
}
.dw-conn-field label {
    display: block;
    font-size: 0.76rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 4px;
}
.dw-btn-ghost {
    background: transparent;
}
.dw-btn-danger-ghost {
    color: var(--danger, #d9755a);
    border-color: rgba(217, 117, 90, 0.35);
    margin-right: auto;
}
.dw-btn-danger-ghost:hover {
    background: rgba(217, 117, 90, 0.1);
    color: var(--danger, #e08870);
    border-color: rgba(217, 117, 90, 0.6);
}

/* ── Add from storage dialog ── */
.dw-storage-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-storage-tab {
    padding: 8px 16px;
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: all 0.15s;
}
.dw-storage-tab:hover { color: var(--text, #e8e3db); }
.dw-storage-tab.active {
    color: var(--primary, #c9995e);
    border-bottom-color: var(--primary, #c9995e);
}
.dw-storage-list {
    max-height: 300px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.dw-storage-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    transition: background 0.1s;
}
.dw-storage-item:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.dw-storage-item-meta {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    margin-left: auto;
}
/* Уборка хранилища: таблица живёт в движке независимо от карточек канваса, и
   удалить её раньше можно было ТОЛЬКО через карточку — то есть таблица, у
   которой карточку убрали, не удалялась ничем (найдено владельцем 15.08). */
.dw-storage-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 2px 2px 6px;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.10));
    margin-bottom: 2px;
}
.dw-storage-item--already {
    color: var(--text-muted, #6b6560);
    cursor: default;
}
.dw-storage-del {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.1s, background 0.1s, color 0.1s;
}
.dw-storage-item:hover .dw-storage-del,
.dw-storage-del:focus-visible {
    opacity: 1;
}
.dw-storage-del:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    color: var(--danger, #d9694f);
}
.dw-picker-empty {
    padding: 24px 12px;
    text-align: center;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted, #6b6560);
    border: 1px dashed var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.10));
    border-radius: 6px;
}

/* Пояснение к импорту проекта (T5.1 ТЗ_НАДЁЖНОСТЬ_DWS): в файле только
   канвас, данные таблиц остаются в rBase — молчание об этом читалось бы
   как «перенёс проект целиком». */
.dw-picker-import-note {
    margin-top: 10px;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--text-muted, #6b6560);
}

/* ── Minimap ── */
.dw-minimap {
    position: absolute;
    bottom: 12px;
    left: 12px;
    width: 160px;
    height: 100px;
    background: rgba(var(--dw-deep, 28, 26, 32), 0.9);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    overflow: hidden;
    z-index: 50;
}
.dw-minimap-viewport {
    position: absolute;
    border: 1px solid var(--primary, #c9995e);
    background: rgba(201, 153, 94, 0.08);
    border-radius: 2px;
    pointer-events: none;
}
.dw-minimap-card {
    position: absolute;
    background: rgba(var(--dw-ink, 232, 227, 219), 0.15);
    border-radius: 1px;
}

/* ═══════════════════════════════════════════════
   ANALYTICS PANEL (right side)
   ═══════════════════════════════════════════════ */
.dw-panel {
    width: 0;
    overflow: hidden;
    background: var(--dw-surface, #1e1c24);
    border-left: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    display: flex;
    flex-direction: column;
    transition: width 0.25s ease;
    flex-shrink: 0;
    /* якорь для .dw-panel-resizer */
    position: relative;
}
/* Ширину задаёт --dw-panel-w (её пишет _wirePanelResize); 420px — исходная. */
.dw-panel.open {
    width: var(--dw-panel-w, 420px);
}
/* На время перетаскивания края анимация ширины только мешает. */
.dw-panel.dw-panel-resizing {
    transition: none;
}
/* Зона захвата — во всю высоту борта, но НЕВИДИМАЯ: подсвечивать полосой в
   рост панели слишком грубо. Видимая метка — две коротких риски посередине
   высоты, за них и цепляются. Ни фон, ни толщина зоны не меняются ни при
   наведении, ни во время перетаскивания — только яркость рисок. */
.dw-panel-resizer {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 8px;
    cursor: ew-resize;
    z-index: 6;
    background: transparent;
}
.dw-panel-resizer::before,
.dw-panel-resizer::after {
    content: '';
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 2px;
    height: 34px;
    border-radius: 1px;
    background: var(--text-dim, #948e84);
    opacity: 0.45;
    transition: opacity 0.15s ease;
}
.dw-panel-resizer::before { left: 1px; }
.dw-panel-resizer::after { left: 5px; }
.dw-panel-resizer:hover::before,
.dw-panel-resizer:hover::after,
.dw-panel.dw-panel-resizing .dw-panel-resizer::before,
.dw-panel.dw-panel-resizing .dw-panel-resizer::after {
    opacity: 0.9;
}
.dw-panel-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
}
.dw-panel-title {
    font-size: 0.9rem;
    font-weight: 600;
    flex: 1;
}
.dw-panel-close {
    background: none;
    border: none;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    display: flex;
}
.dw-panel-close:hover {
    color: var(--text, #e8e3db);
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.dw-panel-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ── Context block ── */
.dw-ctx-block {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 8px;
    padding: 10px 12px;
}
.dw-ctx-title {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    margin-bottom: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.dw-ctx-item {
    font-size: 0.75rem;
    color: var(--text, #e8e3db);
    padding: 3px 0;
    display: flex;
    align-items: center;
    gap: 6px;
}
.dw-ctx-badge {
    display: inline-block;
    font-size: 0.68rem;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
}

/* ── Task input ── */
.dw-task-input {
    width: 100%;
    min-height: 60px;
    max-height: 140px;
    resize: vertical;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    color: var(--text, #e8e3db);
    padding: 10px;
    font-size: 0.85rem;
    font-family: inherit;
    line-height: 1.5;
}
.dw-task-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.dw-task-input::placeholder {
    color: var(--text-muted, #6b6560);
}
.dw-presets-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.dw-preset-chip {
    font-size: 0.72rem;
    padding: 3px 8px;
    border-radius: 4px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    color: var(--text-dim, #948e84);
    cursor: pointer;
    transition: all 0.15s;
    background: transparent;
}
.dw-preset-chip:hover {
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
}

/* ── Паспорт запроса в карточке «Анализ» (ТЗ ПАСПОРТА) ────────────────────
   Та же строка, что под полем вопроса в окне графика, но своими классами:
   у карточки другая палитра и другие отступы. Свёрнутая строка читается
   одной фразой, форма раскрывается по щелчку. */

.dw-passport-bar {
    display: flex;
    align-items: center;
}

.dw-passport-summary {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 5px 10px;
    font-size: 0.75rem;
    font-family: inherit;
    text-align: left;
    color: var(--text-dim, #948e84);
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.15s;
}

.dw-passport-summary:hover {
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
}

.dw-passport-edit {
    flex-shrink: 0;
    opacity: 0.6;
}

/* Значение, взятое из слов вопроса. Подчёркиванием, а не цветом: цвет в этом
   окне уже занят состоянием наведения. */
.dw-passport-from-q {
    text-decoration: underline dotted;
    text-underline-offset: 2px;
}

.dw-passport-form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 8px 0 2px;
}

.dw-passport-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 120px;
    flex: 1 1 120px;
}

.dw-passport-field > span {
    font-size: 0.7rem;
    color: var(--text-muted, #9b958d);
}

.dw-passport-field select {
    width: 100%;
    padding: 4px 6px;
    font-size: 0.78rem;
    font-family: inherit;
    /* Непрозрачный фон и тёмная схема — иначе часть сборок Chrome рисует
       системную светлую плашку, и светлый текст становится нечитаемым
       (та же ловушка, что была у селектора пресета в чате графика). */
    background-color: var(--bg-2, #2a262e);
    color: var(--text, #e8e3db);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 4px;
    cursor: pointer;
    color-scheme: dark;
}

.dw-passport-field select option {
    background-color: var(--bg-2, #2a262e);
    color: var(--text, #e8e3db);
}

/* Полоса «Кто отвечает / Как отвечать» (base-setup.css) нарисована под светлые
   окна: на тёмной панели DWS подпись выходила тёмной на тёмном, а списки —
   белыми плашками (приёмка 14.10: «плохо читается»). Здесь — в цветах DWS;
   светлая тема DWS возвращает светлую схему ниже, рядом с её правилами. */
.dw-overlay .bs-caption {
    color: var(--text-dim, #948e84);
}
.dw-overlay .bs-select {
    background-color: var(--bg-2, #2a262e);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23b8b2a8'/%3E%3C/svg%3E");
    color: var(--text, #e8e3db);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 7px;
    color-scheme: dark;
}
.dw-overlay .bs-select option {
    background-color: var(--bg-2, #2a262e);
    color: var(--text, #e8e3db);
}

/* ── Steps feed ── */
.dw-steps-feed {
    display: flex;
    flex-direction: column;
    gap: 0;
}
.dw-step {
    display: flex;
    gap: 10px;
    padding: 8px 0;
    position: relative;
}
.dw-step::before {
    content: '';
    position: absolute;
    left: 9px;
    top: 28px;
    bottom: -8px;
    width: 1px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-step:last-child::before { display: none; }

.dw-step-marker {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.68rem;
    margin-top: 1px;
}
.dw-step-marker.pending {
    border: 1.5px solid var(--text-muted, #6b6560);
    color: var(--text-muted, #6b6560);
}
.dw-step-marker.running {
    border: 1.5px solid var(--primary, #c9995e);
    color: var(--primary, #c9995e);
    animation: dw-pulse 1.5s infinite;
}
.dw-step-marker.done {
    background: var(--success, #5db87a);
    color: #1c1a20;
}
.dw-step-marker.error {
    background: var(--danger, #d4706a);
    color: #fff;
}
@keyframes dw-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.dw-step-body { flex: 1; min-width: 0; }
.dw-step-name {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}
.dw-step-detail {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    margin-top: 2px;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s;
}
.dw-step.expanded .dw-step-detail {
    max-height: 300px;
}
.dw-step-toggle {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
    margin-top: 2px;
}
.dw-step-toggle:hover { color: var(--primary, #c9995e); }

/* ── Диагностика ошибки (T6.3 ТЗ_НАДЁЖНОСТЬ_DWS) ──
   Человеческий текст виден всегда (обычный .dw-step-detail схлопнут до
   max-height:0 и раскрывается только по клику — для ошибки это неприемлемо),
   технические подробности живут в сворачиваемом блоке под ним. */
.dw-step-diag .dw-step-detail {
    max-height: none;
    overflow: visible;
    color: var(--text, #e8e3db);
}
.dw-diag-toggle {
    display: inline-block;
    margin-top: 6px;
    padding: 0;
    border: none;
    background: none;
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
}
.dw-diag-toggle:hover { color: var(--primary, #c9995e); }
.dw-diag-body {
    margin-top: 6px;
    padding: 8px;
    border-radius: 6px;
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.08));
}
.dw-diag-row {
    display: flex;
    gap: 8px;
    font-size: 0.7rem;
    line-height: 1.45;
    margin-bottom: 3px;
}
.dw-diag-key {
    flex: 0 0 118px;
    color: var(--text-muted, #6b6560);
}
.dw-diag-val {
    flex: 1;
    min-width: 0;
    color: var(--text-dim, #948e84);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    word-break: break-word;
    white-space: pre-wrap;
}
.dw-diag-copy { margin-top: 8px; font-size: 0.7rem; }

/* ── Result block ── */
.dw-result {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 8px;
    padding: 12px;
}
/* «Копировать» и «Удалить» у пары вопрос — ответ: в правом верхнем углу,
   приглушённо; ярче — при наведении на ответ (приёмка 14.10). */
.dw-answer-tools {
    float: right;
    margin: -4px -4px 4px 10px;
    display: flex;
    gap: 4px;
    opacity: 0.55;
    transition: opacity 150ms ease;
}
.dw-result:hover .dw-answer-tools,
.dw-an-turn-ai:hover .dw-answer-tools,
.dw-answer-tools:focus-within {
    opacity: 1;
}
.dw-answer-tool {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    font: inherit;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
    border-radius: 6px;
    cursor: pointer;
}
.dw-answer-tool:hover {
    color: var(--text, #e8e3db);
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.dw-answer-tool[data-dw-answer="delete"]:hover {
    color: var(--danger, #d4706a);
}
/* Обтекание кнопок не должно протекать за пределы ответа. */
.dw-result::after,
.dw-an-turn-ai::after {
    content: "";
    display: block;
    clear: both;
}
/* Ответы копятся нитью: второй и последующие отделяются линией. */
.dw-result + .dw-result {
    margin-top: 10px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
}
/* Подпись «на какой вопрос это ответ». */
.dw-result-question {
    display: flow-root;   /* рядом с кнопками пары, а не под ними */
    margin-bottom: 10px;
    padding-left: 8px;
    border-left: 2px solid var(--primary, #c9995e);
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--text-dim, #948e84);
}
.dw-result-question-label {
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
}
.dw-result-text {
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text, #e8e3db);
}
.dw-result-text p { margin: 0 0 8px; }
.dw-result-text strong { color: var(--primary, #c9995e); font-weight: 600; }
.dw-result-text code {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 0.8rem;
}
.dw-result-actions {
    display: flex;
    gap: 6px;
    margin-top: 10px;
    flex-wrap: wrap;
}

/* ── AI table_actions feedback (Эпик 6.8) ── */
.dw-result-rejected {
    margin-top: 10px;
    padding: 8px 10px;
    border: 1px solid rgba(234, 179, 8, 0.5);
    background: rgba(234, 179, 8, 0.08);
    border-radius: 6px;
    color: var(--text-primary, #d5d5d6);
    font-size: 0.85rem;
}
.dw-result-rejected ul { margin: 6px 0 0; padding-left: 18px; }
.dw-result-rejected li { margin: 2px 0; color: var(--text-muted, #a5a5a6); }
.dw-result-applied {
    margin-top: 10px;
    padding: 6px 10px;
    background: rgba(93, 184, 122, 0.1);
    border: 1px solid rgba(93, 184, 122, 0.4);
    border-radius: 6px;
    color: var(--text-primary, #d5d5d6);
    font-size: 0.85rem;
}

/* ── Small button variant ── */
.dw-btn-sm {
    padding: 2px 8px;
    font-size: 0.75rem;
    border-radius: 4px;
}

/* ── Inline chart wrapper ── */
.dw-inline-chart-wrap {
    margin-top: 8px;
}

/* ── Inline chart placeholder ── */
.dw-inline-chart {
    width: 100%;
    height: 220px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 8px;
    position: relative;
}
.dw-inline-chart canvas {
    width: 100%;
    height: 100%;
}

/* ── Inline table ── */
.dw-inline-table {
    width: 100%;
    overflow-x: auto;
    margin-top: 8px;
    border-radius: 6px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-inline-table table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
}
.dw-inline-table th {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    padding: 6px 8px;
    text-align: left;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    white-space: nowrap;
}
.dw-inline-table td {
    padding: 5px 8px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.03);
    color: var(--text, #e8e3db);
}
.dw-inline-table tr:hover td {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}

/* ── Progress bar ── */
.dw-progress {
    height: 2px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 1px;
    overflow: hidden;
}
.dw-progress-bar {
    height: 100%;
    background: var(--primary, #c9995e);
    transition: width 0.3s;
    border-radius: 1px;
}

/* ── Status bar ── */
.dw-status-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    flex-shrink: 0;
}

/* ── Empty state ── */
.dw-empty-state {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    pointer-events: none;
}
.dw-empty-icon {
    color: var(--text-muted, #6b6560);
    margin-bottom: 12px;
    opacity: 0.5;
}
.dw-empty-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    margin-bottom: 6px;
}
.dw-empty-desc {
    font-size: 0.82rem;
    color: var(--text-muted, #6b6560);
    max-width: 300px;
}

/* ── Toast notification ── */
.dw-toast {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 10px 18px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    z-index: 9800;
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    pointer-events: none;
}
.dw-toast.visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
/* Ошибку и предупреждение должно быть видно, а не вычислять по оттенку рамки
   (замечание владельца 17.08 на приёмке волны 5: «оно не красное, а обычное»).
   Полоса слева и лёгкая заливка поверх базового фона — фон задан отдельным
   слоем, чтобы не переписывать переменную темы. */
/* T4.5 ТЗ «Панель системных уведомлений»: один смысл — один цвет по ВСЕМУ
   продукту. Полоса сообщения здесь взяла те же токены, что панель уведомлений,
   карточка хода и всплывающие сообщения чата и Аналитика, — раньше «красный в
   чате» и «красный в Аналитике» были два разных красных, а третий жил тут.
   Токены самих данных DWS (--danger/--success на карточках и графиках) не
   трогаются: правило про СООБЩЕНИЯ, а не про оформление канваса. */
.dw-toast.error,
.dw-toast.danger {
    border-color: #c53030;
    border-left: 3px solid #c53030;
    background-image: linear-gradient(rgba(197, 48, 48, 0.12), rgba(197, 48, 48, 0.12));
}
.dw-toast.warn,
.dw-toast.warning {
    border-color: #c05621;
    border-left: 3px solid #c05621;
    background-image: linear-gradient(rgba(192, 86, 33, 0.12), rgba(192, 86, 33, 0.12));
}
.dw-toast.success {
    border-color: #20808D;
    border-left: 3px solid #20808D;
}
/* 87 точек DWS зовут сообщение БЕЗ типа, и полосы у них не было вовсе —
   нейтрально независимо от того, отказ это или сведения. Полоса нейтрального
   уровня есть теперь и у них: «без полосы» — не смысл. */
.dw-toast:not(.error):not(.danger):not(.warn):not(.warning):not(.success) {
    border-left: 3px solid rgba(var(--dw-ink, 232, 227, 219), 0.30);
}
/* Липкий тост: сам не гаснет, закрывается крестиком. Сообщения о смене данных
   по осям несут числа, которые надо успеть прочитать, а 2.5 секунды на это не
   хватает (просьба владельца 2026-08-14). pointer-events возвращаем: у обычного
   тоста они сняты, иначе он перехватывал бы клики по графику под собой. */
.dw-toast.sticky {
    pointer-events: auto;
    max-width: min(560px, 90vw);
    padding-right: 34px;
    text-align: left;
    line-height: 1.45;
}
/* Липкое сообщение канваса стоит на своей полке — выше обычного, чтобы оба
   были читаемы одновременно (v1.65.0). До этого они делили один элемент, и
   рядовое «Сохранено» затирало отказ предохранителя связи. */
.dw-toast--above {
    bottom: 76px;
}
.dw-toast-close {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 9999px;
    background: transparent;
    color: inherit;
    opacity: 0.6;
    cursor: pointer;
    transition: background 150ms ease, opacity 150ms ease, transform 150ms ease;
}
.dw-toast-close:hover {
    background: rgba(var(--dw-ink, 232, 227, 219), 0.10);
    opacity: 1;
}
.dw-toast-close:active {
    transform: scale(0.96);
}
.dw-toast-close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(32, 184, 205, 0.30);
}

/* Кнопка действия в сообщении (T1.6 ТЗ_ХРАНИЛИЩЕ_ГРАФИКА): «Повторить» рядом с
   текстом, а не вместо крестика — закрыть сообщение и повторить попытку это
   разные намерения. */
.dw-toast-action {
    margin-left: 12px;
    padding: 4px 12px;
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.28);
    border-radius: 6px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 150ms ease, border-color 150ms ease;
}
.dw-toast-action:hover {
    background: rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-color: rgba(var(--dw-ink, 232, 227, 219), 0.45);
}
.dw-toast-action:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(32, 184, 205, 0.30);
}

/* ── Scrollbar ── */
.dw-overlay ::-webkit-scrollbar { width: 5px; }
.dw-overlay ::-webkit-scrollbar-thumb { background: rgba(var(--dw-ink, 232, 227, 219), 0.10); border-radius: 3px; }
.dw-overlay ::-webkit-scrollbar-thumb:hover { background: rgba(var(--dw-ink, 232, 227, 219), 0.18); }

/* ─── Свёрнутый Data Workspace: пилюля рядом с AI-Аналитиком ─── */
.dw-minimized-pill {
    position: fixed;
    bottom: 20px;
    right: 240px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    background: var(--bg, var(--dw-surface, #1e1c24));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 24px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
    cursor: pointer;
    z-index: 10001;
    transition: box-shadow 0.2s, transform 0.2s;
    user-select: none;
    font-size: 0.85rem;
    color: var(--text, #e8e3db);
}
.dw-minimized-pill:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.55);
    transform: translateY(-2px);
}
.dw-minimized-pill .dw-pill-icon {
    display: flex;
    align-items: center;
    color: var(--primary, #c9995e);
}
.dw-minimized-pill .dw-pill-icon svg { width: 16px; height: 16px; }
.dw-minimized-pill .dw-pill-label {
    font-weight: 600;
    font-size: 0.82rem;
    white-space: nowrap;
}
.dw-minimized-pill .dw-pill-status {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ─── Полоса свёрнутых внутренних окон (table viewer / doc viewer) ─── */
/* Ширина — по содержимому, а не во всю страницу: полоса живёт поверх окон
   (z выше оверлеев), и растянутая на всю ширину она накрывала поле ввода
   чата в правой панели графика. Прижата к левому нижнему углу, при большом
   числе плашек прокручивается вбок, а не отъедает высоту у окна под собой. */
/* T1.1 ТЗ_ТРЕЙ_ВЛАДЕНИЕ_И_СТОПКИ_DWS (P1): 9750, а не 9700. У просмотрщика
   документов (.dw-doc-viewer-overlay) ровно 9700, он добавляется в DOM позже
   трея и при ничьей выигрывал по порядку документа — непрозрачный inset:0
   накрывал полосу целиком, и с открытым документом свёрнутые окна были
   недостижимы. Держим выше документа, но ниже плавающих пилюль-фолбэков
   (10001), которые живут при закрытом канвасе, когда трея нет вовсе. */
.dw-min-viewers-tray {
    position: fixed;
    left: 0;
    right: auto;
    bottom: 0;
    /* Ширина и ПЕРЕНОС строк (замечание владельца 16.08: «некоторые вкладки
       вылезают за пределы полосы»). Было `nowrap` при жёстких 55vw — плашки
       просто уезжали за правый край: сперва за нарисованный фон полосы, а
       дальше и за экран, то есть свёрнутое окно становилось недостижимым.
       Обрезать нельзя (`overflow` ниже), значит остаётся единственный честный
       выход — переносить на следующую строку: полоса растёт вверх, но не
       теряет ни одной плашки. */
    max-width: min(72vw, 980px);
    z-index: 9750;
    box-sizing: border-box;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 12px;
    background: rgba(var(--dw-deep, 28, 26, 32), 0.96);
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-right: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 0 8px 0 0;
    flex-shrink: 0;
    /* overflow НЕ обрезаем: всплывающий список производных вылезает вверх за
       границы полосы, любой overflow:auto/hidden его бы отрезал. */
    overflow: visible;
    align-items: flex-end;
}
.dw-min-viewers-tray .dw-min-viewer-pill { flex: 0 0 auto; }

/* ── Двухуровневый трей: слот владельца + всплывающая стопка производных ──
   ТЗ_ТРЕЙ_СВЕРНУТЫХ_ОКОН_DWS_2026-07-30 §2. Производные (графики и
   распределения, построенные от таблицы) своей плашки в полосе не имеют —
   они «слайдятся» вверх при наведении на плашку владельца. */
/* Слот задаёт ЕДИНУЮ ширину владельцу и его производным: плашка тянется на
   100% слота, стопка растянута left:0/right:0 — то есть ровно по слоту.
   Из-за этого ни одна из карточек не может оказаться шире другой. */
.dw-min-viewer-slot {
    position: relative;
    display: flex;
    flex: 0 0 auto;
    /* Уже прежних 200px: в строку помещается больше плашек, и полоса реже
       уходит во вторую строку. Имя внутри плашки и так обрезается многоточием,
       а её ширина остаётся одинаковой у владельца и его производных. */
    min-width: 170px;
    max-width: 280px;
}
/* Стопка производных — без своей плашки: ни фона, ни рамки, ни тени.
   Карточки висят над владельцем свободно, разделитель между ними — только
   зазор. Нижний padding держит просвет до плашки владельца. */
.dw-min-viewer-stack {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 5px;
    max-height: 46vh;
    overflow-y: auto;
    padding: 0 0 6px;
    box-sizing: border-box;
    background: none;
    border: 0;
    box-shadow: none;
    /* Скрыта, но не display:none — иначе переход не отработает. */
    opacity: 0;
    transform: translateY(6px);
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
.dw-min-viewer-slot:hover .dw-min-viewer-stack,
.dw-min-viewer-slot:focus-within .dw-min-viewer-stack {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
/* Фон карточек: сплошная подложка + светлая плёнка поверх. Раньше здесь был
   полупрозрачный --bg-card поверх плашки стопки; без неё карточка «поплыла»
   бы прямо по канвасу и стала почти прозрачной. Оба слоя идут от токенов,
   поэтому светлая тема получает белую подложку автоматически. */
.dw-min-viewer-subpill {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 8px;
    box-sizing: border-box;
    width: 100%;
    background:
        linear-gradient(rgba(var(--dw-tint, 255, 250, 243), 0.07),
                        rgba(var(--dw-tint, 255, 250, 243), 0.07)),
        rgba(var(--dw-deep, 28, 26, 32), 0.98);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 6px;
    /* Единственное отличие от плашки владельца: производные висят над
       канвасом, а не на полосе трея, и без тени сливались бы с ним. */
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.30);
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
    transition: background 0.15s, border-color 0.15s;
}
.dw-min-viewer-subpill:hover {
    border-color: var(--primary, #c9995e);
}
.dw-min-viewer-subpill .dw-min-viewer-name {
    flex: 1 1 auto;
    min-width: 0;
    max-width: none;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dw-min-viewer-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--primary, #c9995e);
    color: var(--dw-deep-solid, #1c1a20);
    font-size: 0.68rem;
    font-weight: 600;
    flex-shrink: 0;
}
.dw-min-viewer-pill .dw-min-viewer-name {
    flex: 1 1 auto;
    min-width: 0;
    max-width: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Плашка владельца повторяет геометрию производной карточки: тот же радиус 6px,
   те же отступы, тот же фон и рамка. Прежняя «таблетка» (radius 16px, другой
   padding) выбивалась из стопки, над которой стояла. */
.dw-min-viewer-pill {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px 4px 8px;
    box-sizing: border-box;
    width: 100%;
    max-width: none;
    background:
        linear-gradient(rgba(var(--dw-tint, 255, 250, 243), 0.07),
                        rgba(var(--dw-tint, 255, 250, 243), 0.07)),
        rgba(var(--dw-deep, 28, 26, 32), 0.98);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 6px;
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    user-select: none;
    white-space: nowrap;
}
.dw-min-viewer-pill:hover,
.dw-min-viewer-subpill:hover {
    background:
        linear-gradient(rgba(var(--dw-tint, 255, 250, 243), 0.13),
                        rgba(var(--dw-tint, 255, 250, 243), 0.13)),
        rgba(var(--dw-deep, 28, 26, 32), 0.98);
    border-color: var(--primary, #c9995e);
}
.dw-min-viewer-icon {
    display: inline-flex;
    align-items: center;
    color: var(--primary, #c9995e);
    flex-shrink: 0;
}
.dw-min-viewer-icon svg { width: 14px; height: 14px; }
.dw-min-viewer-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 220px;
}
.dw-min-viewer-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    color: var(--text-dim, #948e84);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
    flex-shrink: 0;
}
.dw-min-viewer-close:hover {
    background: rgba(212, 112, 106, 0.18);
    color: var(--danger, #d4706a);
}

/* Плашка-ГРУППА (T3.3 ТЗ_ТРЕЙ_ВЛАДЕНИЕ_И_СТОПКИ_DWS_2026-08-01).
   У неё нет своего свёрнутого окна: она собрана из карточки-владельца, чьи
   производные свёрнуты, либо предзаполнена снимком вкладок после F5. Клик по
   ней ОТКРЫВАЕТ карточку заново, а не возвращает окно в прежнее состояние —
   поэтому она не должна выглядеть как обычная плашка свёрнутого окна.
   Отличия минимальные и читаемые: пунктирная рамка вместо сплошной («окна за
   ней нет»), фон приглушён, иконка без акцентного цвета. Геометрия та же —
   полоса не должна «прыгать». */
.dw-min-viewer-pill--group {
    background: rgba(var(--dw-deep, 28, 26, 32), 0.82);
    border-style: dashed;
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.16));
    color: var(--text-dim, #948e84);
}
.dw-min-viewer-pill--group .dw-min-viewer-icon {
    color: var(--text-dim, #948e84);
}
/* На наведении группа ведёт себя как обычная плашка: она кликабельна, и это
   должно читаться. Рамка остаётся пунктирной — признак «окна нет» не зависит
   от положения курсора. */
.dw-min-viewer-pill--group:hover {
    color: var(--text, #e8e3db);
    border-color: var(--primary, #c9995e);
}
.dw-min-viewer-pill--group:hover .dw-min-viewer-icon {
    color: var(--primary, #c9995e);
}

/* ─── Fallback-пилюля для свёрнутого WorkspaceTableViewer вне Data Workspace ─── */
.wtv-minimized-pill {
    position: fixed;
    bottom: 20px;
    right: 240px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    background: var(--bg, var(--dw-surface, #1e1c24));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 24px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
    cursor: pointer;
    z-index: 10001;
    user-select: none;
    font-size: 0.85rem;
    color: var(--text, #e8e3db);
}
.wtv-minimized-pill .wtv-pill-icon {
    display: flex;
    align-items: center;
    color: var(--primary, #c9995e);
}
.wtv-minimized-pill .wtv-pill-icon svg { width: 16px; height: 16px; }
.wtv-minimized-pill .wtv-pill-label {
    font-weight: 600;
    font-size: 0.82rem;
}
.wtv-minimized-pill .wtv-pill-status {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ═══════════════════════════════════════════════════════════════
   IKR APPROVAL UI — согласование плана анализа
   ═══════════════════════════════════════════════════════════════ */
.dw-ikr-approval {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 10px;
    padding: 14px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-ikr-header {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
    margin-bottom: 12px;
}
.dw-ikr-section {
    margin-bottom: 12px;
}
.dw-ikr-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    margin-bottom: 6px;
}
.dw-ikr-textarea {
    width: 100%;
    min-height: 70px;
    max-height: 160px;
    resize: vertical;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    color: var(--text, #e8e3db);
    padding: 10px;
    font-size: 0.82rem;
    font-family: inherit;
    line-height: 1.5;
    box-sizing: border-box;
}
.dw-ikr-textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.dw-ikr-entities {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.dw-ikr-entity {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.15s;
}
.dw-ikr-entity:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.dw-ikr-entity input[type="checkbox"] {
    margin-top: 2px;
    accent-color: var(--primary, #c9995e);
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}
.dw-ikr-entity-body {
    flex: 1;
    min-width: 0;
}
.dw-ikr-entity-name {
    display: block;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}
.dw-ikr-entity-desc {
    display: block;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    margin-top: 2px;
    line-height: 1.4;
}
.dw-ikr-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* ═══════════════════════════════════════════════════════════════
   QUESTION UI — интерактивные вопросы агента
   ═══════════════════════════════════════════════════════════════ */
.dw-question-card {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 10px;
    padding: 14px;
    border: 1px solid var(--primary-dim, rgba(201, 153, 94, 0.25));
}
/* T3.1: уточнение модели (ask_user) — спокойный голубой акцент, в
   отличие от золотого «алярма» жёсткого пред-полётного блокера
   data_collection_blockers (палитра «тёплый тёмный», --info). */
.dw-question-card--clarify {
    border-color: rgba(107, 159, 212, 0.30);
}
.dw-question-card--clarify .dw-question-icon,
.dw-question-card--clarify .dw-question-header-label {
    color: var(--info, #6b9fd4);
}
.dw-question-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}
.dw-question-icon {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    flex-shrink: 0;
}
.dw-question-icon svg {
    width: 18px;
    height: 18px;
    color: var(--primary, #c9995e);
}
.dw-question-header-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.dw-question-header-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--primary, #c9995e);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.dw-question-header-from {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
}
.dw-question-text {
    font-size: 0.9rem;
    color: var(--text, #e8e3db);
    margin-bottom: 12px;
    line-height: 1.5;
}
.dw-question-options {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 12px;
}
.dw-question-option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.15s;
}
.dw-question-option:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.dw-question-option.selected {
    border-color: var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.08));
}
.dw-question-option input[type="radio"] {
    display: none;
}
.dw-question-option-radio {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid var(--text-muted, #6b6560);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    margin-top: 1px;
    transition: all 0.15s;
}
.dw-question-option.selected .dw-question-option-radio {
    border-color: var(--primary, #c9995e);
}
.dw-question-option.selected .dw-question-option-radio::after {
    content: '';
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--primary, #c9995e);
}
.dw-question-option-content {
    flex: 1;
    min-width: 0;
}
.dw-question-option-label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text, #e8e3db);
}
.dw-question-option-desc {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    margin-top: 2px;
    line-height: 1.4;
}
.dw-question-input-row {
    display: flex;
    gap: 8px;
    align-items: center;
}
.dw-question-input {
    flex: 1;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    padding: 8px 10px;
    font-size: 0.82rem;
    font-family: inherit;
}
.dw-question-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.dw-question-input::placeholder {
    color: var(--text-muted, #6b6560);
}

/* Кнопка-крестик «очистить поле» (Data Workspace, текст/промпт-поля).
   Обёртка .dwx-wrap ставится JS-декоратором; крестик в правом верхнем
   углу, виден только когда в поле есть текст (класс .has). */
.dwx-wrap { position: relative; }
.dwx-clear {
    position: absolute;
    top: 6px;
    right: 8px;
    width: 18px;
    height: 18px;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(var(--dw-ink, 232, 227, 219), 0.10);
    color: var(--text, #b8b2a8);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    z-index: 3;
    transition: background 0.12s, color 0.12s;
}
.dwx-wrap.has > .dwx-clear { display: flex; }
.dwx-clear:hover { background: rgba(201, 153, 94, 0.30); color: #fff; }

/* ── Status/Error messages ── */
.dw-status-msg {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 8px;
    font-size: 0.85rem;
    color: var(--text-dim, #948e84);
}
.dw-status-msg svg {
    animation: dw-pulse 1.5s infinite;
}
.dw-error-msg {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    background: rgba(212, 112, 106, 0.1);
    border: 1px solid var(--danger, #d4706a);
    border-radius: 8px;
    font-size: 0.85rem;
    color: var(--danger, #d4706a);
}
.dw-success-msg {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    background: rgba(93, 184, 122, 0.1);
    border: 1px solid var(--success, #5db87a);
    border-radius: 8px;
    font-size: 0.85rem;
    color: var(--success, #5db87a);
}


/* ═══════════════════════════════════════════════════════════════
   workspace-table-viewer.js — просмотрщик таблиц
   ═══════════════════════════════════════════════════════════════ */

/* ── Overlay ── */
.wtv-overlay {
    position: fixed;
    inset: 0;
    z-index: 9500;
    background: var(--bg, #1c1a20);
    display: flex;
    flex-direction: column;
    font-family: "Inter", system-ui, -apple-system, sans-serif;
    color: var(--text, #e8e3db);

    /* Фон закреплённой шапки таблицы — обязан быть СПЛОШНЫМ: thead
       `position: sticky`, и полупрозрачная заливка давала просвечивание
       уезжающих под неё строк. Тон подобран как прежний
       rgba(--dw-tint, .04) поверх --bg, чтобы вид шапки не изменился.
       Переопределение светлой темы — там же, где остальные её токены. */
    --wtv-th-bg: #24222a;
    --wtv-th-bg-hover: #2c2a34;
}

/* ── Header ── */
.wtv-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
    min-height: 44px;
}
.wtv-header-left {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.wtv-header-icon {
    color: var(--primary, #c9995e);
    flex-shrink: 0;
    display: flex;
}
.wtv-header-title {
    font-size: 0.95rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 400px;
    display: none; /* replaced by tab bar */
}
.wtv-header-meta {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
}

/* ── Unified view tab bar ── */
.wtv-tab-bar {
    display: flex;
    align-items: center;
    gap: 2px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.wtv-tab-bar::-webkit-scrollbar { display: none; }
.wtv-view-tab {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 6px 6px 0 0;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid transparent;
    border-bottom: none;
    color: var(--text-dim, #948e84);
    font-size: 0.76rem;
    white-space: nowrap;
    max-width: 200px;
    cursor: pointer;
    user-select: none;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    position: relative;
}
.wtv-view-tab:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.07);
    color: var(--text, #e8e3db);
}
.wtv-view-tab.active {
    background: rgba(201, 153, 94, 0.12);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    color: var(--primary, #c9995e);
    font-weight: 600;
}
.wtv-view-tab.active::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--primary, #c9995e);
    border-radius: 2px 2px 0 0;
}
.wtv-view-tab-icon {
    display: flex;
    flex-shrink: 0;
    opacity: 0.7;
}
.wtv-view-tab.active .wtv-view-tab-icon { opacity: 1; }
.wtv-view-tab-name {
    overflow: hidden;
    text-overflow: ellipsis;
}
.wtv-view-tab-close {
    font-size: 13px;
    line-height: 1;
    padding: 0 2px;
    border-radius: 3px;
    opacity: 0;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
    cursor: pointer;
    flex-shrink: 0;
}
.wtv-view-tab:hover .wtv-view-tab-close { opacity: 0.6; }
.wtv-view-tab-close:hover {
    opacity: 1 !important;
    color: var(--danger, #d4706a);
    background: rgba(212, 112, 106, 0.12);
}

/* ── Tab type colors ── */
.wtv-view-tab-table {
    border-left: 2px solid rgba(100, 160, 220, 0.5);
}
.wtv-view-tab-table.active {
    background: rgba(100, 160, 220, 0.1);
    border-color: rgba(100, 160, 220, 0.3);
    border-left: 2px solid rgba(100, 160, 220, 0.8);
    color: var(--info, #7db8e8);
}
.wtv-view-tab-table.active::after {
    background: #7db8e8;
}
.wtv-view-tab-chart.active {
    background: rgba(201, 153, 94, 0.12);
    color: var(--primary, #c9995e);
}
.wtv-view-tab-text {
    border-left: 2px solid rgba(160, 200, 100, 0.5);
}
.wtv-view-tab-text.active {
    background: rgba(160, 200, 100, 0.1);
    border-color: rgba(160, 200, 100, 0.3);
    border-left: 2px solid rgba(160, 200, 100, 0.8);
    color: var(--success, #a0c864);
}
.wtv-view-tab-text.active::after {
    background: #a0c864;
}
.wtv-view-tab.dragging { opacity: 0.4; }
.wtv-view-tab.drag-over { box-shadow: inset 2px 0 0 var(--primary, #c9995e); }

/* ── Tab context menu ── */
.wtv-tab-ctx-menu {
    position: fixed;
    z-index: 100000;
    min-width: 160px;
    padding: 4px 0;
    background: var(--dw-surface, #1e1c24);
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.1);
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
    font-size: 0.8rem;
}
.wtv-tab-ctx-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 14px;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.12s;
    white-space: nowrap;
}
.wtv-tab-ctx-item:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.07);
}
.wtv-tab-ctx-item svg {
    flex-shrink: 0;
    opacity: 0.7;
}
.wtv-tab-ctx-danger {
    color: var(--danger, #d4706a);
}
.wtv-tab-ctx-danger:hover {
    background: rgba(212, 112, 106, 0.12);
}
.wtv-tab-ctx-divider {
    height: 1px;
    margin: 4px 8px;
    background: rgba(var(--dw-ink, 232, 227, 219), 0.08);
}

/* ── Content area ── */
.wtv-content-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.wtv-chart-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.wtv-text-wrap {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: auto;
    padding: 16px;
}
.wtv-text-content {
    white-space: pre-wrap;
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text, #e8e3db);
}

/* ── Embedded chart mode ── */
.wc-overlay.wc-embedded {
    position: relative;
    z-index: auto;
    width: 100%;
    height: 100%;
    border-radius: 0;
}
.wc-overlay.wc-embedded .wc-header-left {
    display: none !important;
}
.wc-overlay.wc-embedded .wc-header {
    display: none !important;
}

.wtv-header-right {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

/* ── Buttons ── */
.wtv-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 12px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    color: var(--text, #e8e3db);
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    white-space: nowrap;
}
.wtv-btn:hover { background: rgba(var(--dw-tint, 255, 250, 243), 0.08); border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13)); }
.wtv-btn:disabled { opacity: 0.4; cursor: default; pointer-events: none; }
.wtv-btn-accent {
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
}
.wtv-btn-accent:hover { background: rgba(201, 153, 94, 0.12); }
.wtv-btn-danger {
    border-color: var(--danger, #d4706a);
    color: var(--danger, #d4706a);
}
.wtv-btn-danger:hover { background: rgba(212, 112, 106, 0.15); }
.wtv-btn-close {
    border: none;
    background: none;
    padding: 5px;
    color: var(--text-dim, #948e84);
}
.wtv-btn-close:hover { color: var(--text, #e8e3db); }
.wtv-btn-sm {
    padding: 3px 8px;
    font-size: 0.72rem;
}

/* ── Columns visibility dropdown ── */
.wtv-cols-wrap {
    position: relative;
    display: inline-block;
}
.wtv-cols-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 100;
    min-width: 180px;
    max-height: 300px;
    overflow-y: auto;
    padding: 8px;
    margin-top: 4px;
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}
.wtv-cols-dropdown.open {
    display: block;
}
.wtv-cols-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 6px;
    border-radius: 4px;
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.12s;
}
.wtv-cols-item:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
}
.wtv-cols-item input[type="checkbox"] {
    accent-color: var(--primary, #c9995e);
    width: 14px;
    height: 14px;
    cursor: pointer;
}

/* ── Filter bar (deprecated, filters are now in column headers) ── */
.wtv-filter-bar {
    display: none;
}
.wtv-filter-item {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}
.wtv-filter-label {
    font-size: 0.7rem;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 140px;
}
.wtv-filter-select {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.75rem;
    padding: 5px 8px;
    width: 100%;
    min-width: 120px;
}
.wtv-filter-select:focus {
    border-color: var(--primary, #c9995e);
    outline: none;
}
.wtv-filter-select option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.wtv-filter-text {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.75rem;
    padding: 5px 8px;
    width: 100%;
    min-width: 140px;
    box-sizing: border-box;
}
.wtv-filter-text:focus {
    border-color: var(--primary, #c9995e);
    outline: none;
}
.wtv-filter-text::placeholder {
    color: var(--text-muted, #6b6560);
    opacity: 0.7;
}
.wtv-filter-num {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.75rem;
    padding: 5px 6px;
    width: 60px;
    flex: 1;
}
.wtv-filter-num:focus {
    border-color: var(--primary, #c9995e);
    outline: none;
}
.wtv-filter-range { min-width: 0; }
.wtv-range-row {
    display: flex;
    align-items: center;
    gap: 4px;
}
.wtv-range-dash {
    color: var(--text-muted, #6b6560);
    font-size: 0.78rem;
}
.wtv-filter-clear {
    align-self: flex-end;
    margin-left: auto;
    color: var(--text-dim, #948e84);
}

/* ── Table wrapper ── */
.wtv-table-wrap {
    flex: 1;
    overflow: auto;
    padding: 0;
    position: relative;
}

/* ── Table ── */
.wtv-table {
    min-width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
}
.wtv-table thead {
    position: sticky;
    top: 0;
    z-index: 2;
}
.wtv-th {
    background: var(--wtv-th-bg, #24222a);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    padding: 6px 10px;
    text-align: left;
    font-weight: 600;
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: background 0.12s;
    vertical-align: top;
}
.wtv-th:hover { background: var(--wtv-th-bg-hover, #2c2a34); }
.wtv-th-sorted { color: var(--primary, #c9995e); }

/* ── Column resize handle ── */
.wtv-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 5px;
    height: 100%;
    cursor: col-resize;
    z-index: 3;
    background: transparent;
    transition: background 0.12s;
}
.wtv-resize-handle:hover,
.wtv-resize-handle:active {
    background: var(--primary, #c9995e);
}

/* ── Column drag-reorder ── */
.wtv-th-dragging {
    opacity: 0.35;
}
.wtv-drag-ghost {
    position: fixed;
    z-index: 10000;
    padding: 4px 10px;
    /* Плашка перетаскиваемой колонки — от токена, иначе в светлой теме над
       белой таблицей летел тёмный прямоугольник. */
    background: rgba(var(--dw-deep, 30, 28, 36), 0.92);
    border: 1px solid var(--primary, #c9995e);
    border-radius: 5px;
    color: var(--primary, #c9995e);
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
}
.wtv-drop-indicator {
    position: fixed;
    z-index: 9999;
    width: 2px;
    background: var(--primary, #c9995e);
    pointer-events: none;
    display: none;
    box-shadow: 0 0 6px rgba(201, 153, 94, 0.5);
}

.wtv-th-num {
    background: var(--wtv-th-bg, #24222a);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    padding: 6px 8px;
    cursor: pointer;
    user-select: none;
    transition: background 0.12s;
    text-align: center;
    font-weight: 400;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    width: 54px;
    min-width: 54px;
}
.wtv-th-num:hover { background: var(--wtv-th-bg-hover, #2c2a34); }
/* Подсветка активной сортировки. Двойной класс обязателен: общий
   `.wtv-th-sorted` объявлен ВЫШЕ по файлу, а `.wtv-th-num` со своим
   приглушённым цветом — ниже, и при равной специфичности перебивал бы его. */
.wtv-th-num.wtv-th-sorted { color: var(--primary, #c9995e); }
.wtv-th-num-inner {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
}
.wtv-th-name {
    margin-right: 4px;
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 3px;
    transition: background 0.12s;
}
.wtv-th-name:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
}
.wtv-th-rename-input {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
    border: 1px solid var(--primary, #c9995e);
    border-radius: 3px;
    color: var(--text, #e8e3db);
    font-size: 0.78rem;
    font-weight: 600;
    padding: 2px 4px;
    width: 100px;
    min-width: 60px;
}
.wtv-th-rename-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
    box-shadow: 0 0 0 2px rgba(201, 153, 94, 0.2);
}
.wtv-th-sort {
    display: inline-flex;
    vertical-align: middle;
    opacity: 0.7;
}

/* ── Header row (name + sort + filter button) ── */
.wtv-th-header {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* ── Filter button in header ── */
.wtv-filter-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    margin-left: auto;
    border: none;
    border-radius: 3px;
    background: transparent;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
    transition: all 0.12s;
    flex-shrink: 0;
}
.wtv-filter-btn:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
    color: var(--text-dim, #948e84);
}
.wtv-filter-btn.active {
    background: rgba(201, 153, 94, 0.15);
    color: var(--primary, #c9995e);
}

/* ── Filter dropdown ── */
.wtv-filter-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 100;
    min-width: 160px;
    padding: 8px;
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    flex-direction: column;
    gap: 6px;
}
.wtv-filter-dropdown.open {
    display: flex;
}
.wtv-th {
    position: relative;
}

/* ── Filter dropdown elements ── */
.wtv-filter-range-info {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    margin-bottom: 2px;
}
.wtv-filter-range-row {
    display: flex;
    align-items: center;
    gap: 4px;
}
.wtv-filter-apply {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px 8px;
    margin-top: 4px;
    border: 1px solid var(--primary, #c9995e);
    border-radius: 4px;
    background: rgba(201, 153, 94, 0.12);
    color: var(--primary, #c9995e);
    font-size: 0.72rem;
    cursor: pointer;
    transition: background 0.12s;
}
.wtv-filter-apply:hover {
    background: rgba(201, 153, 94, 0.2);
}
.wtv-filter-clear-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 3px 6px;
    margin-top: 4px;
    border: none;
    border-radius: 3px;
    background: transparent;
    color: var(--text-muted, #6b6560);
    font-size: 0.68rem;
    cursor: pointer;
    transition: all 0.12s;
}
.wtv-filter-clear-btn:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    color: var(--text-dim, #948e84);
}

.wtv-th-roles {
    display: flex;
    gap: 3px;
    margin-top: 4px;
}

/* ── Role chips (X / Y / Color) ── */
.wtv-role-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: transparent;
    color: var(--text-muted, #6b6560);
    transition: all 0.12s;
    user-select: none;
}
.wtv-role-chip:hover {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
    color: var(--text-dim, #948e84);
}
.wtv-role-chip.active {
    background: rgba(201, 153, 94, 0.15);
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
}

/* ── Color binning dropdown ── */
.wtv-color-dropdown {
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
    min-width: 220px;
    padding: 8px 0;
}
.wtv-color-dropdown-title {
    padding: 6px 12px 8px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin-bottom: 4px;
}
.wtv-color-dropdown-item {
    padding: 8px 12px;
    cursor: pointer;
    transition: background 0.15s;
}
.wtv-color-dropdown-item:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
}
.wtv-color-dropdown-item.active {
    background: rgba(201, 153, 94, 0.1);
}
.wtv-color-dropdown-item.active .wtv-color-method-name {
    color: var(--primary, #c9995e);
}
.wtv-color-method-name {
    display: block;
    font-size: 0.85rem;
    color: var(--text, #e8e3db);
    font-weight: 500;
}
.wtv-color-method-desc {
    display: block;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    margin-top: 2px;
}
.wtv-color-dropdown-bins {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 12px 6px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin-top: 4px;
}
.wtv-bin-count-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.wtv-bin-count-row label {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}
.wtv-color-dropdown-bins input[type="number"] {
    width: 50px;
    padding: 4px 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    text-align: center;
}
.wtv-color-dropdown-bins input[type="number"]:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.wtv-color-checkbox {
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 0.75rem;
    color: var(--text-dim, #948e84);
}
.wtv-color-checkbox input[type="checkbox"] {
    width: 14px;
    height: 14px;
    accent-color: var(--primary, #c9995e);
    cursor: pointer;
}
.wtv-color-checkbox span {
    user-select: none;
}
.wtv-color-dropdown-item.wtv-disabled {
    opacity: 0.35;
    pointer-events: none;
}

/* ── Custom bins modal ── */
.wtv-custom-bins-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10002;
}
.wtv-custom-bins-content {
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 12px;
    width: 520px;
    max-width: 92vw;
    max-height: 85vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.wtv-bins-presets {
    padding: 10px 16px 12px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.015);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.wtv-presets-row {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.wtv-presets-label {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    min-width: 120px;
    flex-shrink: 0;
}
.wtv-preset-btn {
    padding: 4px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.8rem;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}
.wtv-preset-btn:hover {
    background: rgba(201, 153, 94, 0.15);
    border-color: var(--primary, #c9995e);
}
.wtv-preset-btn:active {
    background: rgba(201, 153, 94, 0.25);
}
.wtv-preset-input {
    width: 72px;
    padding: 4px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.8rem;
}
.wtv-preset-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-preset-input::placeholder {
    color: var(--text-muted, #6b6560);
    font-style: italic;
}
.wtv-custom-bins-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}
.wtv-custom-bins-info {
    padding: 10px 16px;
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}
.wtv-custom-bins-info b {
    color: var(--text, #e8e3db);
}
.wtv-custom-bins-list {
    padding: 12px 16px;
    overflow-y: auto;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.wtv-bin-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.wtv-bin-color {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    flex-shrink: 0;
}
.wtv-bin-shape {
    width: 36px;
    padding: 4px 2px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.9rem;
    text-align: center;
    cursor: pointer;
    flex-shrink: 0;
}
.wtv-bin-shape:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-bin-shape option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.wtv-bin-input {
    width: 80px;
    padding: 6px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    text-align: center;
}
.wtv-bin-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-bin-sep {
    color: var(--text-muted, #6b6560);
}
.wtv-bin-delete {
    margin-left: auto;
    opacity: 0.5;
}
.wtv-bin-delete:hover {
    opacity: 1;
}
.wtv-custom-bins-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}

/* ── Body cells ── */
.wtv-td {
    padding: 5px 10px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.04);
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Колонка «#». Ширина ДОЛЖНА совпадать с `.wtv-th-num` — иначе шапка и тело
   расходятся по вертикали (было 54 против 40). И `display:flex` здесь стоять не
   может: ячейка перестаёт быть табличной, и заданная ширина применяется к ней
   буквально, мимо алгоритма ширины колонки. Центрируем обычным текстом, а
   цветную точку разводим отступом. */
.wtv-td-num {
    padding: 5px 8px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.04);
    text-align: center;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    width: 54px;
    min-width: 54px;
    white-space: nowrap;
}
.wtv-td-num .wtv-color-dot {
    margin-right: 3px;
    vertical-align: middle;
}
.wtv-null {
    color: var(--text-muted, #6b6560);
    font-style: italic;
    font-size: 0.75rem;
}
.wtv-table tbody tr:hover td {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
}

/* ── Row color highlighting ── */
.wtv-color-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 4px;
    vertical-align: middle;
    flex-shrink: 0;
}
.wtv-row-colored {
    position: relative;
}
.wtv-row-colored td:first-child {
    position: relative;
}
.wtv-row-colored td:first-child::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--row-color);
    border-radius: 0 2px 2px 0;
}

/* Removed rows (from chart) */
/* T3.5 — строка выделена кликом (набор выборки из таблицы). Отметка та же по
   смыслу, что у строки выборки в панели графика: полоска слева плюс мягкий фон.
   Цвет — акцентный, чтобы не путался с подсветкой команд AI (там цвет свой у
   каждой) и с убранными строками (там красноватый).

   Полоска висит на ПЕРВОЙ ЯЧЕЙКЕ, а не на строке: у таблицы
   `border-collapse: collapse`, а в таком режиме тень на `tr` браузеры не
   рисуют вовсе — отметка осталась бы одним фоном. */
/* T4.2 — строка входит в выборку проекта (связанное выделение).
   Полоска слева цветом выборки, фон не трогаем: строк в выборке бывают тысячи,
   и сплошная заливка сделала бы таблицу нечитаемой. Правила ниже (выделенная
   строка, подсветка команд модели) объявлены ПОСЛЕ и потому перекрывают эту:
   «что происходит сейчас» важнее, чем «чему строка принадлежит». */
.wtv-row-selhit .wtv-td-num {
    box-shadow: inset 3px 0 0 var(--wtv-sel-color, var(--info, #6b9fd4));
}

.wtv-row-picked {
    background-color: rgba(201, 153, 94, 0.14) !important;
}
.wtv-row-picked .wtv-td-num {
    box-shadow: inset 3px 0 0 var(--primary, #c9995e);
}
.wtv-row-picked:hover {
    background-color: rgba(201, 153, 94, 0.2) !important;
}

.wtv-row-removed {
    opacity: 0.5;
    background: rgba(212, 112, 106, 0.08) !important;
}
.wtv-row-removed:hover {
    opacity: 0.7;
    background: rgba(212, 112, 106, 0.12) !important;
}

/* ───────────── AI table-actions (Эпик 6.8) ───────────── */
/* Подсветка строк от table_actions.
   --ai-hl-color задаётся inline в _renderTable. Используем тонкую левую
   полоску + мягкий цветной фон через color-mix, чтобы не перекрывать
   остальную строчную раскраску (_row-color, _row-removed). */
.wtv-row-ai-highlight {
    background-color: color-mix(in srgb, var(--ai-hl-color) 10%, transparent) !important;
}
/* Полоска — на первой ячейке: тень на `tr` при `border-collapse: collapse`
   браузеры не рисуют, и подсветка команд AI оставалась одним фоном. */
.wtv-row-ai-highlight .wtv-td-num {
    box-shadow: inset 3px 0 0 var(--ai-hl-color);
}
.wtv-row-ai-highlight:hover {
    background-color: color-mix(in srgb, var(--ai-hl-color) 18%, transparent) !important;
}

/* Легенда AI-подсветок — горизонтальная полоса над таблицей */
.wtv-highlight-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: rgba(107, 159, 212, 0.08);
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    border-radius: 6px;
    margin-bottom: 8px;
    font-size: 0.84rem;
    color: var(--text-primary, #d5d5d6);
}
.wtv-highlight-legend-title {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: var(--primary, #c9995e);
    margin-right: 4px;
}
.wtv-highlight-legend-title svg { vertical-align: middle; }
.wtv-highlight-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 12px;
    border: 1px solid var(--chip-color, #888);
    background: color-mix(in srgb, var(--chip-color, #888) 15%, transparent);
}
.wtv-highlight-chip-label { font-size: 0.8rem; }
.wtv-highlight-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
    border: 1px solid rgba(0,0,0,0.3);
}
.wtv-highlight-chip-remove {
    background: transparent;
    border: 0;
    color: var(--text-muted, #a5a5a6);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 2px;
}
.wtv-highlight-chip-remove:hover { color: var(--danger, #d4706a); }
.wtv-highlight-legend-clear {
    margin-left: auto;
    background: transparent;
    border: 1px solid var(--border, rgba(255,255,255,0.1));
    color: var(--text-muted, #a5a5a6);
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 0.78rem;
    cursor: pointer;
}
.wtv-highlight-legend-clear:hover {
    color: var(--text-primary, #d5d5d6);
    border-color: var(--danger, #d4706a);
}

/* Pivot-панель (Эпик 6.9 — pivottable.js drag-drop UI) */
.wtv-pivot-panel {
    margin-top: 12px;
    padding: 10px;
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    border-radius: 6px;
    background: rgba(107, 159, 212, 0.04);
}
.wtv-pivot-panel-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}
.wtv-pivot-panel-title {
    font-weight: 600;
    color: var(--primary, #c9995e);
    font-size: 0.9rem;
}
.wtv-pivot-panel-summary {
    flex: 1;
    font-size: 0.78rem;
    color: var(--text-muted, #a5a5a6);
    min-width: 160px;
}
.wtv-pivot-panel-close {
    background: transparent;
    border: 0;
    color: var(--text-muted, #a5a5a6);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
}
.wtv-pivot-panel-close:hover { color: var(--danger, #d4706a); }

/* Полоса «разрезы изменены мышью»: числа посчитаны в браузере поверх уже
   свёрнутых сервером данных и могут врать. Заметная, но не паническая —
   это предупреждение, а не ошибка. */
.wtv-pivot-drift {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 8px;
    padding: 8px 10px;
    border-radius: 5px;
    border: 1px solid rgba(201, 153, 94, 0.45);
    background: rgba(201, 153, 94, 0.10);
}
.wtv-pivot-drift-text {
    flex: 1;
    min-width: 220px;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-primary, #d5d5d6);
}
body.dw-theme-light .wtv-pivot-drift-text { color: var(--text); }

/* Пояснение под сводной, почему исчезли итоги (§9.5) */
.wtv-pivot-note-totals {
    margin-top: 8px;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-muted, #a5a5a6);
    border-left: 2px solid rgba(201, 153, 94, 0.45);
    padding-left: 8px;
}

/* ── Развёрнутая сводная (кнопка «Развернуть» в шапке панели) ──
   Панели сводных лежат в одном скролл-контейнере с таблицей, ниже неё.
   В режиме разворота прячем ВСЕХ соседей — таблицу, легенду цветов, другие
   сводные — и отдаём выбранной панели всю высоту области. `!important`
   нужен: у скрываемых соседей (таблица, легенда) свой `display` в их
   собственных правилах. */
.wtv-table-wrap.wtv-pivot-focus > *:not(.wtv-pivot-panel-expanded) {
    display: none !important;
}
.wtv-pivot-panel.wtv-pivot-panel-expanded {
    margin-top: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
}
/* Штатный потолок высоты сводной (600px) в развёрнутом режиме только мешает
   — он для случая, когда под сводной ещё есть таблица. */
.wtv-pivot-panel-expanded .wtv-pivot-mount {
    max-height: none;
    flex: 1;
}
.wtv-pivot-panel-expanded .wtv-pivot-panel-header {
    position: sticky;
    top: 0;
    z-index: 3;
    margin: -10px -10px 8px;
    padding: 8px 10px;
    background: var(--bg, #1c1a20);
    border-bottom: 1px solid var(--border, rgba(255,255,255,0.08));
}
.wtv-pivot-empty,
.wtv-pivot-note {
    font-size: 0.82rem;
    color: var(--text-muted, #a5a5a6);
    font-style: italic;
    padding: 4px 0;
}
.wtv-pivot-warn {
    color: var(--warning, #eab308);
    background: rgba(234, 179, 8, 0.08);
    border: 1px solid rgba(234, 179, 8, 0.3);
    border-radius: 4px;
    padding: 6px 10px;
    margin-bottom: 8px;
    font-style: normal;
}
.wtv-pivot-tablewrap { overflow-x: auto; max-height: 340px; }
.wtv-pivot-table {
    border-collapse: collapse;
    font-size: 0.84rem;
    width: 100%;
}
.wtv-pivot-table th, .wtv-pivot-table td {
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    padding: 4px 8px;
    text-align: left;
    white-space: nowrap;
}
.wtv-pivot-table thead th {
    background: rgba(107, 159, 212, 0.1);
    position: sticky;
    top: 0;
    font-weight: 600;
}

/* Контейнер, в который монтируется pivottable.js */
.wtv-pivot-mount { overflow: auto; max-height: 600px; }

/* Переопределение тёмной темы для pivottable.js — библиотека приходит с
   светлыми дефолтами, а наш UI — тёмный. */
.wtv-pivot-mount table.pvtTable {
    color: var(--text-primary, #d5d5d6);
    background: transparent;
    font-size: 0.84rem;
}
.wtv-pivot-mount table.pvtTable th.pvtAxisLabel,
.wtv-pivot-mount table.pvtTable th.pvtTotalLabel,
.wtv-pivot-mount table.pvtTable th.pvtColLabel,
.wtv-pivot-mount table.pvtTable th.pvtRowLabel {
    background: rgba(107, 159, 212, 0.12);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.1));
    padding: 4px 8px;
}
.wtv-pivot-mount table.pvtTable td.pvtVal {
    background: transparent;
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    padding: 3px 8px;
    text-align: right;
}
/* Heatmap-виды красят клетки инлайновым background-color по шкале
   БЕЛЫЙ → красный ($.fn.heatmap), и светлый текст тёмной темы на них
   пропадает. Селектор по инлайновому стилю бьёт точно: barchart инлайнит
   padding/text-align, но не background-color. */
.wtv-pivot-mount table.pvtTable td.pvtVal[style*="background-color"],
.wtv-pivot-mount table.pvtTable td.pvtTotal[style*="background-color"] {
    color: #1a1a1a;
}
.wtv-pivot-mount table.pvtTable td.pvtTotal,
.wtv-pivot-mount table.pvtTable td.pvtGrandTotal {
    background: rgba(107, 159, 212, 0.08);
    font-weight: 600;
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.1));
}
.wtv-pivot-mount td.pvtAxisContainer,
.wtv-pivot-mount td.pvtRendererArea {
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    background: rgba(107, 159, 212, 0.04);
    padding: 4px;
    vertical-align: top;
}

/* ── Подписи зон pivotUI ──
   Библиотека не подписывает НИ ОДНУ из своих зон и ни в одной локали: пять
   пустых прямоугольников без единого слова. Подписываем все.

   Делаем ИМЕННО через ::before, а не вставкой элементов: зоны осей — это
   sortable-контейнеры jQuery UI, и любой добавленный в них узел стал бы
   перетаскиваемым наравне с чипами полей. Псевдоэлемент в DOM не попадает,
   поэтому переживает и перерисовки, и перетаскивания.

   Раскладка зон (см. исходники pivotUI): таблица .pvtUi из двух колонок —
   слева «Вид», «Что считаем», «Строки»; справа пул свободных полей,
   «Столбцы» и сама сводная. */
.wtv-pivot-mount td.pvtUnused,
.wtv-pivot-mount td.pvtVals,
.wtv-pivot-mount td.pvtAxisContainer.pvtRows,
.wtv-pivot-mount td.pvtAxisContainer.pvtCols,
.wtv-pivot-mount td.pvtUiCell:not(.pvtAxisContainer):not(.pvtVals) {
    position: relative;
    padding-top: 22px;
}
.wtv-pivot-mount td.pvtUnused::before,
.wtv-pivot-mount td.pvtVals::before,
.wtv-pivot-mount td.pvtAxisContainer.pvtRows::before,
.wtv-pivot-mount td.pvtAxisContainer.pvtCols::before,
.wtv-pivot-mount td.pvtUiCell:not(.pvtAxisContainer):not(.pvtVals)::before {
    position: absolute;
    top: 4px;
    left: 6px;
    right: 6px;
    font-size: 0.68rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-muted, #a5a5a6);
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wtv-pivot-mount td.pvtUnused::before {
    content: "Свободные поля — перетащите в строки или столбцы";
}
/* «Показать метрику», а не «Что считаем»: способ свёртки задаётся в одном
   месте — в диалоге «Настроить», сервером. Здесь остался только выбор, какую
   из уже посчитанных метрик вывести. */
.wtv-pivot-mount td.pvtVals::before { content: "Показать метрику"; }
/* Селектор агрегата остаётся в DOM с единственной опцией (библиотека читает
   из него значение при каждом refresh), но пользователю не показывается —
   выбирать способ свёртки во второй раз, поверх уже свёрнутых данных,
   незачем. */
.wtv-pivot-mount td.pvtVals select.pvtAggregator { display: none; }
.wtv-pivot-mount td.pvtAxisContainer.pvtRows::before { content: "Строки"; }
.wtv-pivot-mount td.pvtAxisContainer.pvtCols::before { content: "Столбцы"; }
.wtv-pivot-mount td.pvtUiCell:not(.pvtAxisContainer):not(.pvtVals)::before {
    content: "Вид";
}

/* ── Пропорции: результат важнее обвязки ──
   `.pvtUi` растянута на 100%, и авто-раскладка HTML-таблицы делила лишнюю
   ширину между колонками поровну — левая колонка с тремя узкими селекторами
   забирала половину экрана, а сводная ютилась в остатке. Прижимаем колонку
   обвязки к содержимому (width:1% — стандартный приём shrink-to-fit), всё
   остальное отдаём области результата. */
.wtv-pivot-mount td.pvtVals,
.wtv-pivot-mount td.pvtAxisContainer.pvtRows,
.wtv-pivot-mount td.pvtUiCell:not(.pvtAxisContainer):not(.pvtVals) {
    width: 1%;
}
.wtv-pivot-mount td.pvtRendererArea {
    width: 100%;
}
.wtv-pivot-mount td.pvtAxisContainer li {
    background: rgba(107, 159, 212, 0.15);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.1));
    padding: 2px 8px;
    margin: 2px;
    border-radius: 3px;
    font-size: 0.78rem;
}
/* `td.pvtVals select` — не лишнее: кроме агрегата библиотека создаёт в этой
   же ячейке селекторы ПОЛЯ (`select.pvtAttrDropdown`), причём динамически, по
   числу аргументов выбранного агрегата. В прежнем списке их не было, и они
   оставались в дефолтном системном виде — рядом со стилизованным агрегатом
   это читалось как контрол из другой подсистемы. */
.wtv-pivot-mount .pvtDropdown,
.wtv-pivot-mount .pvtDropdownCurrent,
.wtv-pivot-mount .pvtAttr,
.wtv-pivot-mount .pvtFilterBox,
.wtv-pivot-mount select.pvtRenderer,
.wtv-pivot-mount select.pvtAggregator,
.wtv-pivot-mount td.pvtVals select {
    background: var(--bg-secondary, #1c1a20);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.12));
}
/* Селекторы «Вид» и «Показать метрику» — один набор правил на оба, иначе
   они выглядят как контролы из разных подсистем. На всю ширину ячейки: под
   метрикой строкой лежат кнопки порядка, и их суммарная ширина равна её
   ширине. */
.wtv-pivot-mount select.pvtRenderer,
.wtv-pivot-mount td.pvtVals select {
    display: block;
    min-width: 160px;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 3px 4px;
    border-radius: 3px;
    font-size: 0.78rem;
}
.wtv-pivot-mount .pvtVals {
    padding: 4px;
    background: rgba(107, 159, 212, 0.06);
    border: 1px solid var(--border, rgba(255,255,255,0.08));
}
/* Кнопки порядка строк и столбцов — строкой ПОД селектором метрики, каждая
   в половину его ширины (контейнер создаёт _annotatePivotControls: в разметке
   библиотеки они стоят в одной строке со скрытым селектором агрегата и
   оказывались над выбором метрики). */
.wtv-pvt-order-row {
    display: flex;
    gap: 4px;
    width: 100%;
    min-width: 160px;
    margin-top: 4px;
}
.wtv-pivot-mount .pvtRowOrder,
.wtv-pivot-mount .pvtColOrder {
    background: rgba(107, 159, 212, 0.12);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.1));
    padding: 3px 6px;
    border-radius: 3px;
    cursor: pointer;
    font-size: 0.78rem;
    margin: 0;
    flex: 1 1 0;
    min-width: 0;
    box-sizing: border-box;
    text-align: center;
    text-decoration: none;
    user-select: none;
}
.wtv-pivot-mount .pvtRowOrder:hover,
.wtv-pivot-mount .pvtColOrder:hover {
    background: rgba(107, 159, 212, 0.22);
}

/* Кнопки в окошке фильтра значений (Применить / Отмена / Выбрать все /
   Снять выделение). Библиотека рисует их голым <button> без класса —
   на фоне остального UI это выглядело как чужой элемент. */
.wtv-pivot-mount .pvtFilterBox button {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    margin: 2px 4px 2px 0;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.16));
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    font-size: 0.78rem;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.wtv-pivot-mount .pvtFilterBox button:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.12);
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.24));
}
/* «Применить» — первая кнопка в своей строке, она же основное действие. */
.wtv-pivot-mount .pvtFilterBox p > button:first-child {
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
}
.wtv-pivot-mount .pvtFilterBox p > button:first-child:hover {
    background: rgba(201, 153, 94, 0.14);
}
.wtv-pivot-mount .pvtFilterBox .pvtSearch {
    background: var(--bg-secondary, #1c1a20);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.12));
    border-radius: 4px;
    padding: 3px 6px;
    font-size: 0.78rem;
    width: 100%;
    box-sizing: border-box;
}
.wtv-pivot-mount .pvtUi { width: 100%; }
.wtv-pivot-mount .pvtFilterBox {
    background: var(--bg-secondary, #1c1a20);
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
    z-index: 10000;
}

/* Диалог "Настроить сводную" (_openPivotConfigDialog) */
/* Размер по умолчанию. Специфичность ДВОЙНАЯ намеренно: базовый
   `.wtv-edit-modal-content` объявлен НИЖЕ по файлу с `width: 440px`, и при
   равной специфичности выигрывал он — сколько здесь ни напиши, диалог
   открывался узким. Потолки (96vw/94vh) приходят из `.wtv-modal-movable`,
   поэтому на маленьком экране окно ужмётся само. */
.wtv-edit-modal-content.wtv-pivot-config-dialog {
    width: 1100px;
    height: 730px;
    max-width: 94vw;
}
/* Две колонки: слева форма, справа справка с примерами и превью видов.
   На узком экране справка уезжает под форму, а не сжимает её в нечитаемое.

   Селектор ДВОЙНОЙ намеренно: базовый `.wtv-edit-modal-body` объявлен ниже
   по файлу и ставит `display: flex; flex-direction: column`. При равной
   специфичности выигрывал он, и справка падала под форму. */
.wtv-edit-modal-body.wtv-pivot-cfg-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
    gap: 16px;
    align-items: start;
}
.wtv-pivot-cfg-form { min-width: 0; }
@media (max-width: 860px) {
    .wtv-edit-modal-body.wtv-pivot-cfg-body { grid-template-columns: minmax(0, 1fr); }
}

/* ── Панель справки ── */
.wtv-pivot-help {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border, rgba(255,255,255,0.12));
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
}
.wtv-pivot-help-sec { min-width: 0; }
.wtv-pivot-help-sec + .wtv-pivot-help-sec {
    border-top: 1px solid var(--border, rgba(255,255,255,0.10));
    padding-top: 10px;
}
.wtv-pivot-help-title {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary, #b5b5b6);
    margin-bottom: 6px;
}
.wtv-pivot-help-title b { color: var(--primary, #c9995e); font-weight: 600; }
.wtv-pivot-help-hint {
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-muted, #a5a5a6);
}
.wtv-pivot-help-note {
    font-size: 0.74rem;
    line-height: 1.4;
    color: var(--text-muted, #a5a5a6);
    margin-top: 6px;
    opacity: 0.85;
}
.wtv-pivot-help-note-warn { color: var(--danger, #d4706a); opacity: 1; }

/* Схема будущей сводной: что окажется по осям и что попадёт в клетку */
.wtv-pivot-help-schema { overflow-x: auto; }
.wtv-pivot-help-schema-table {
    border-collapse: collapse;
    font-size: 0.74rem;
    width: 100%;
}
.wtv-pivot-help-schema-table th,
.wtv-pivot-help-schema-table td {
    border: 1px solid var(--border, rgba(255,255,255,0.14));
    padding: 5px 7px;
    text-align: left;
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wtv-pivot-help-corner {
    background: rgba(201, 153, 94, 0.14);
    color: var(--primary, #c9995e);
    font-weight: 600;
}
.wtv-pivot-help-axis {
    background: rgba(107, 159, 212, 0.12);
    color: var(--text-primary, #d5d5d6);
    font-weight: 500;
}
.wtv-pivot-help-axis-empty { color: var(--text-muted, #a5a5a6); font-style: italic; font-weight: 400; }
.wtv-pivot-help-cell {
    color: var(--text-muted, #a5a5a6);
    font-style: italic;
}

/* Разбор агрегата на живом примере */
.wtv-pivot-help-example { margin-top: 6px; }
.wtv-pivot-help-example-lead {
    font-size: 0.74rem;
    color: var(--text-muted, #a5a5a6);
    margin-bottom: 4px;
}
.wtv-pivot-help-formula {
    font-family: "JetBrains Mono", Consolas, monospace;
    font-size: 0.75rem;
    color: var(--text-primary, #d5d5d6);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border-radius: 4px;
    padding: 5px 7px;
    word-break: break-word;
}

/* Визуальный предпросмотр вида: раскраска — формулами самой pivottable */
.wtv-pivot-help-preview { margin-top: 8px; overflow-x: auto; }
.wtv-pivot-help-preview-table {
    border-collapse: collapse;
    font-size: 0.72rem;
    width: 100%;
}
.wtv-pivot-help-preview-table th,
.wtv-pivot-help-preview-table td {
    border: 1px solid var(--border, rgba(255,255,255,0.14));
    padding: 3px 6px;
    text-align: right;
    color: var(--text-primary, #d5d5d6);
}
.wtv-pivot-help-preview-table th {
    background: rgba(107, 159, 212, 0.12);
    text-align: center;
    font-weight: 500;
}
.wtv-pivot-help-preview-corner { background: transparent !important; border: none !important; }
/* Шкала heatmap в библиотеке идёт от БЕЛОГО к красному — светлый текст
   тёмной темы на такой заливке не читается, поэтому на залитых клетках
   принудительно тёмный. */
.wtv-pivot-help-preview-heat { color: #1a1a1a !important; }
/* Гистограмма: столбик растёт снизу, число под ним — как в pvtVal-клетке */
.wtv-pivot-help-preview-bars td { text-align: center; vertical-align: bottom; padding: 2px 4px; }
.wtv-pivot-help-bar-holder {
    position: relative;
    height: 34px;
    width: 100%;
}
.wtv-pivot-help-bar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: gray;
    border-radius: 1px 1px 0 0;
}
.wtv-pivot-help-bar-num { font-size: 0.68rem; color: var(--text-muted, #a5a5a6); }
.wtv-pivot-cfg-intro {
    font-size: 0.84rem;
    color: var(--text-muted, #a5a5a6);
    margin-bottom: 12px;
}
.wtv-pivot-cfg-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 12px;
}
.wtv-pivot-cfg-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.84rem;
    color: var(--text-secondary, #b5b5b6);
}
/* Шапка списка: подпись слева, крестик очистки прижат вправо. Родитель —
   flex-колонка, поэтому под подпись нужна своя строка-flex. */
.wtv-pivot-cfg-row-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 18px;
}
.wtv-pivot-cfg-clear {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 3px;
    color: var(--text-secondary, #b5b5b6);
    opacity: 0.55;
    cursor: pointer;
}
.wtv-pivot-cfg-clear:hover {
    opacity: 1;
    background: var(--bg-secondary, #1c1a20);
    color: var(--text-primary, #d5d5d6);
}
.wtv-pivot-cfg-clear svg {
    width: 12px;
    height: 12px;
}
.wtv-pivot-cfg-row select {
    min-height: 28px;
    background: var(--bg-secondary, #1c1a20);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.12));
    border-radius: 4px;
    padding: 4px 8px;
}
.wtv-pivot-cfg-values {
    margin-bottom: 12px;
    padding: 8px;
    border: 1px dashed var(--border, rgba(255,255,255,0.12));
    border-radius: 4px;
}
.wtv-pivot-cfg-values-title {
    font-size: 0.84rem;
    color: var(--text-secondary, #b5b5b6);
    margin-bottom: 6px;
    font-weight: 500;
}
.wtv-pivot-cfg-values-hint {
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--text-muted, #a5a5a6);
    margin-bottom: 8px;
}
/* Шапка над списком метрик. Раскладка обязана повторять
   `.wtv-pivot-cfg-value-row` (flex, gap 6px, оба select'а flex:1), иначе
   подписи разъедутся с колонками. */
.wtv-pivot-cfg-values-head {
    display: flex;
    gap: 6px;
    margin-bottom: 4px;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted, #a5a5a6);
}
.wtv-pivot-cfg-values-head > span { flex: 1; min-width: 0; }
.wtv-pivot-cfg-values-head > .wtv-pivot-cfg-values-head-spacer { flex: 0 0 30px; }
.wtv-pivot-cfg-values-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 8px;
}
.wtv-pivot-cfg-value-row {
    display: flex;
    gap: 6px;
    align-items: center;
}
.wtv-pivot-cfg-value-row select {
    flex: 1;
    background: var(--bg-secondary, #1c1a20);
    color: var(--text-primary, #d5d5d6);
    border: 1px solid var(--border, rgba(255,255,255,0.12));
    border-radius: 4px;
    padding: 4px 6px;
    font-size: 0.82rem;
}
.wtv-pivot-cfg-errors {
    margin-top: 8px;
}
.wtv-pivot-cfg-error {
    font-size: 0.82rem;
    color: var(--danger, #d4706a);
    padding: 4px 0;
}

/* Header-кнопка «Команды AI» с бейджем */
.wtv-btn-ai-actions { position: relative; display: inline-flex; align-items: center; gap: 6px; }
.wtv-ai-actions-badge {
    background: var(--primary, #c9995e);
    color: #1c1a20;
    border-radius: 10px;
    padding: 0 6px;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.4;
    min-width: 16px;
    text-align: center;
}

/* Модалка «Команды AI» */
.wtv-ai-actions-dialog { width: 620px; max-width: 92vw; }
.wtv-ai-actions-intro {
    font-size: 0.84rem;
    color: var(--text-muted, #a5a5a6);
    margin-bottom: 10px;
}
.wtv-ai-actions-list { display: flex; flex-direction: column; gap: 6px; max-height: 60vh; overflow-y: auto; }
.wtv-ai-actions-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--border, rgba(255,255,255,0.08));
    border-radius: 6px;
    background: rgba(107, 159, 212, 0.04);
}
.wtv-ai-actions-row-left { flex: 1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wtv-ai-actions-row-right { display: flex; align-items: center; gap: 8px; }
.wtv-ai-actions-kind {
    background: rgba(107, 159, 212, 0.18);
    color: var(--primary, #c9995e);
    border-radius: 4px;
    padding: 2px 6px;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.wtv-ai-actions-row-title { font-weight: 600; color: var(--text-primary, #d5d5d6); font-size: 0.88rem; }
.wtv-ai-actions-row-sub { color: var(--text-muted, #a5a5a6); font-size: 0.8rem; }
.wtv-ai-actions-row-meta { color: var(--text-muted, #a5a5a6); font-size: 0.78rem; font-style: italic; }
.wtv-ai-actions-empty {
    padding: 18px;
    text-align: center;
    color: var(--text-muted, #a5a5a6);
    font-style: italic;
    font-size: 0.86rem;
}

/* Текстовая вкладка для query_result */
.wtv-qr-wrap { padding: 12px; overflow: auto; }
.wtv-qr-header {
    font-weight: 600;
    color: var(--primary, #c9995e);
    margin-bottom: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.wtv-qr-note { color: var(--text-muted, #a5a5a6); font-size: 0.82rem; margin-bottom: 8px; }
.wtv-qr-empty { color: var(--text-muted, #a5a5a6); font-style: italic; }
.wtv-qr-tablewrap { overflow-x: auto; max-height: 68vh; }
.wtv-th-removed {
    color: var(--danger, #d4706a);
    min-width: 80px;
}
.wtv-td-removed {
    color: var(--danger, #d4706a);
    font-size: 0.78rem;
    font-style: italic;
}

/* Custom groups column */
.wtv-th-groups {
    color: var(--info, #6b9fd4);
    min-width: 100px;
}
.wtv-td-groups {
    font-size: 0.78rem;
    line-height: 1.4;
    white-space: normal;
    vertical-align: top;
    max-width: 180px;
}
.wtv-group-tag {
    display: inline-block;
    padding: 1px 6px;
    margin: 1px 0;
    background: rgba(107, 159, 212, 0.12);
    border-radius: 8px;
    color: var(--info, #6b9fd4);
    font-size: 0.72rem;
    white-space: nowrap;
}

.wtv-color-cell {
    position: relative;
    font-weight: 500;
}
.wtv-color-cell::after {
    content: '';
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--cell-color);
}

/* ── Footer / Pagination ── */
.wtv-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 16px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
    min-height: 38px;
}
.wtv-footer-left,
.wtv-footer-center,
.wtv-footer-right {
    display: flex;
    align-items: center;
    gap: 6px;
}
.wtv-footer-info {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}
.wtv-footer-info b {
    color: var(--text, #e8e3db);
    font-weight: 600;
}
.wtv-filtered-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    background: rgba(201, 153, 94, 0.15);
    color: var(--primary, #c9995e);
    margin-left: 4px;
}
/* T3.5 — сколько строк выделено и что с ними можно сделать. Отделено чертой от
   счётчика строк: это про действие пользователя, а не про содержимое таблицы. */
.wtv-sel-info {
    padding-left: 10px;
    margin-left: 4px;
    border-left: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
}
.wtv-page-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    background: transparent;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.wtv-page-btn:hover { background: rgba(var(--dw-tint, 255, 250, 243), 0.06); color: var(--text, #e8e3db); }
.wtv-page-btn:disabled { opacity: 0.3; cursor: default; pointer-events: none; }
.wtv-page-info {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    min-width: 60px;
    text-align: center;
}
.wtv-footer-hint {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
}

/* ── Loading / Error / Empty states ── */
.wtv-loading,
.wtv-error,
.wtv-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    font-size: 0.88rem;
    color: var(--text-dim, #948e84);
}
.wtv-error { color: var(--danger, #d4706a); }

/* ── Scrollbar for table-viewer ── */
.wtv-overlay ::-webkit-scrollbar { width: 5px; height: 5px; }
.wtv-overlay ::-webkit-scrollbar-thumb { background: rgba(var(--dw-ink, 232, 227, 219), 0.10); border-radius: 3px; }
.wtv-overlay ::-webkit-scrollbar-thumb:hover { background: rgba(var(--dw-ink, 232, 227, 219), 0.18); }

/* ── Column Context Menu ── */
.wtv-ctx-menu {
    min-width: 210px;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    animation: wtvCtxFadeIn 0.12s ease;
}
@keyframes wtvCtxFadeIn { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } }
.wtv-ctx-header {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    user-select: none;
}
.wtv-ctx-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    font-size: 0.84rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.12s;
    user-select: none;
}
.wtv-ctx-item:hover {
    background: rgba(201, 153, 94, 0.12);
}
.wtv-ctx-icon {
    font-size: 1rem;
    width: 20px;
    text-align: center;
    flex-shrink: 0;
}
.wtv-ctx-sep {
    height: 1px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin: 3px 0;
}
/* Пометка «создаст копию» / «в копии» у операций, меняющих данные.
   ТЗ ВЫБОРКИ, T8.6: в исходной таблице разграничены запрещённое (правка
   значений, удаление колонки — уходят в копию) и разрешённое (переименование
   колонки — работает по исходной). Пометка приглушённая: это уточнение, а не
   предупреждение. */
.wtv-ctx-note {
    margin-left: auto;
    padding-left: 10px;
    font-size: 0.72rem;
    letter-spacing: 0.01em;
    color: var(--muted, rgba(var(--dw-ink, 232, 227, 219), 0.5));
    white-space: nowrap;
}
.wtv-ctx-item-danger {
    color: var(--danger, #d4706a);
}
.wtv-ctx-item-danger:hover {
    background: rgba(212, 112, 106, 0.15);
}
.wtv-ctx-pos-input {
    width: 48px;
    padding: 2px 5px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.15));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    text-align: center;
    margin-left: 4px;
}
.wtv-ctx-pos-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

/* ── Column Edit Modals ── */
.wtv-edit-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10004;
    animation: wtvCtxFadeIn 0.15s ease;
}
.wtv-edit-modal-content {
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 12px;
    width: 440px;
    max-width: 92vw;
    max-height: 80vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.wtv-edit-modal-wide {
    width: 520px;
}

/* ── Перетаскиваемое и растягиваемое окно диалога (_makeModalMovable) ── */
.wtv-modal-movable {
    resize: both;
    /* Штатные 92vw/80vh здесь стали бы потолком растягивания — поднимаем,
       но не до края экрана, чтобы окно нельзя было «потерять». */
    max-width: 96vw;
    max-height: 94vh;
    min-width: 360px;
    min-height: 200px;
}
.wtv-modal-movable.wtv-modal-placed {
    position: absolute;
    margin: 0;
}
.wtv-modal-movable > .wtv-edit-modal-header {
    cursor: move;
    user-select: none;
}
/* Во время перетаскивания гасим выделение текста — иначе курсор «тащит» за
   собой выделенный заголовок. Глушить `pointer-events` здесь НЕЛЬЗЯ: поток
   pointermove держится на setPointerCapture шапки. */
.wtv-modal-movable.wtv-modal-dragging {
    user-select: none;
}
.wtv-edit-modal-privacy {
    width: 560px;
}
.wtv-edit-modal-footer {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wtv-edit-modal-footer .wtv-spacer {
    flex: 1;
}

/* Эпик 3.1 — «Приватность колонок» modal */
.wtv-privacy-intro {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    line-height: 1.45;
    padding: 2px 0 6px;
}
.wtv-privacy-intro code {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    border-radius: 3px;
    padding: 0 4px;
    font-size: 0.76rem;
    color: var(--text, #e8e3db);
}
.wtv-privacy-summary {
    font-size: 0.82rem;
    color: var(--primary, #c9995e);
    padding: 6px 0;
    border-top: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.08);
    border-bottom: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.08);
    margin-bottom: 4px;
}
.wtv-privacy-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.wtv-privacy-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.wtv-privacy-col {
    font-size: 0.84rem;
    color: var(--text, #e8e3db);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wtv-privacy-hint {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    margin-left: 4px;
}
.wtv-privacy-select {
    width: 220px;
    padding: 5px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.8rem;
    cursor: pointer;
}
.wtv-privacy-select:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-privacy-select option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.wtv-privacy-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: rgba(201, 153, 94, 0.12);
    color: var(--primary, #c9995e);
    border: 1px solid rgba(201, 153, 94, 0.35);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 0.72rem;
    font-weight: 500;
}
.wtv-edit-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}
.wtv-edit-modal-body {
    padding: 14px 16px;
    overflow-y: auto;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.wtv-edit-form-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.wtv-edit-form-row label {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
    min-width: 90px;
}
.wtv-edit-input {
    flex: 1;
    padding: 6px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.84rem;
}
.wtv-edit-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-edit-input-num {
    width: 70px;
    padding: 6px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.84rem;
    text-align: center;
}
.wtv-edit-input-num:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-edit-select {
    flex: 1;
    padding: 6px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    cursor: pointer;
}
.wtv-edit-select:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}
.wtv-edit-select option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.wtv-edit-hint {
    font-size: 0.75rem;
    color: var(--text-muted, #6b6560);
    padding: 2px 0;
}
.wtv-edit-info {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    padding: 6px 0;
}
.wtv-edit-info b {
    color: var(--text, #e8e3db);
}
.wtv-edit-success {
    font-size: 0.88rem;
    color: var(--success, #5db87a);
    padding: 16px 0;
    text-align: center;
}
.wtv-edit-warning {
    font-size: 0.82rem;
    color: #f97316;
    padding: 6px 0;
}
.wtv-edit-error {
    font-size: 0.82rem;
    color: var(--danger, #d4706a);
    padding: 6px 0;
}
.wtv-edit-loading {
    font-size: 0.85rem;
    color: var(--text-dim, #948e84);
    text-align: center;
    padding: 20px 0;
}
.wtv-edit-list {
    max-height: 280px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 0;
}
.wtv-edit-list-item {
    padding: 5px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-radius: 4px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    font-family: monospace;
    word-break: break-all;
}
.wtv-edit-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin-top: 6px;
}
.wtv-edit-preview {
    min-height: 20px;
}
.wtv-edit-preview-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
    margin-top: 4px;
}
.wtv-edit-preview-table th {
    text-align: left;
    padding: 4px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    color: var(--text-dim, #948e84);
    font-weight: 600;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wtv-edit-preview-table td {
    padding: 4px 8px;
    color: var(--text, #e8e3db);
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.03);
    font-family: monospace;
    word-break: break-all;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Edit Tabs ── */
.wtv-edit-tabs {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    padding-bottom: 0;
    margin-bottom: 8px;
    overflow-x: auto;
    scrollbar-width: none;
}
.wtv-edit-tabs::-webkit-scrollbar { display: none; }
.wtv-edit-tab {
    padding: 6px 12px;
    font-size: 0.76rem;
    font-weight: 500;
    color: var(--text-muted, #6b6560);
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    transition: all 0.12s;
    white-space: nowrap;
}
.wtv-edit-tab:hover {
    color: var(--text-dim, #948e84);
}
.wtv-edit-tab.active {
    color: var(--primary, #c9995e);
    border-bottom-color: var(--primary, #c9995e);
}
.wtv-edit-tab-content {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── UX improvements (audit iteration) ── */

/* Filter autocomplete hint under the search input */
.wtv-filter-hint {
    padding: 4px 6px 0;
    font-size: 11px;
    color: var(--muted, #8a8a8a);
    line-height: 1.3;
}

/* Roles summary badge strip in the header */
.wtv-roles-summary {
    display: inline-flex;
    gap: 6px;
    margin-left: 8px;
    flex-wrap: wrap;
    align-items: center;
}
.wtv-role-badge {
    display: inline-block;
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 10px;
    background: rgba(201, 153, 94, 0.15);
    color: var(--fg, #e6e6e6);
    border: 1px solid rgba(201, 153, 94, 0.35);
    white-space: nowrap;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.wtv-role-badge-x { background: rgba(107, 159, 212, 0.18); border-color: rgba(107, 159, 212, 0.45); }
.wtv-role-badge-y { background: rgba(93, 184, 122, 0.18); border-color: rgba(93, 184, 122, 0.45); }
.wtv-role-badge-color { background: rgba(168, 85, 247, 0.18); border-color: rgba(168, 85, 247, 0.45); }

/* Link-style button inside footer (Сбросить все фильтры) */
.wtv-btn-link {
    background: transparent !important;
    border: none !important;
    padding: 2px 6px !important;
    color: var(--primary, #c9995e) !important;
    text-decoration: underline;
    font-size: 12px;
    cursor: pointer;
}
.wtv-btn-link:hover { color: var(--fg, #e6e6e6) !important; }

/* Jump-to-page numeric input inside pagination */
.wtv-page-input {
    width: 52px;
    background: transparent;
    color: inherit;
    /* Белая рамка в светлой теме исчезала — поле «перехода к странице»
       переставало читаться как поле ввода. */
    border: 1px solid var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.15));
    border-radius: 3px;
    text-align: center;
    font-size: inherit;
    padding: 1px 3px;
    margin: 0 2px;
    -moz-appearance: textfield;
}
.wtv-page-input::-webkit-inner-spin-button,
.wtv-page-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.wtv-page-input:focus { outline: none; border-color: var(--primary, #c9995e); }

/* Spinner indicator for quantile fetch on color method item */
.wtv-color-dropdown-item.wtv-loading-inline::after {
    content: '';
    display: inline-block;
    width: 12px; height: 12px;
    margin-left: 8px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: wtv-spin 0.7s linear infinite;
    vertical-align: middle;
}
@keyframes wtv-spin { to { transform: rotate(360deg); } }

/* Inline view-tab rename input */
.wtv-view-tab-rename-input {
    outline: none;
    min-width: 60px;
}

/* Column position quick-apply button */
.wtv-ctx-item-pos { display: flex; align-items: center; gap: 6px; }
.wtv-ctx-pos-apply {
    margin-left: auto;
    padding: 1px 8px;
    font-size: 11px;
    border: 1px solid var(--primary, #c9995e);
    background: transparent;
    color: var(--primary, #c9995e);
    border-radius: 3px;
    cursor: pointer;
}
.wtv-ctx-pos-apply:hover { background: var(--primary, #c9995e); color: #fff; }

/* ── Primary key indicator in table header (Epic 6.2) ── */
.wtv-th-key-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    border-radius: 3px;
    background: transparent;
    cursor: pointer;
    transition: color 0.12s, background 0.12s;
    flex-shrink: 0;
}
.wtv-th-key-btn.active {
    color: var(--primary, #c9995e);
}
.wtv-th-key-btn.active:hover {
    background: rgba(201, 153, 94, 0.15);
}
.wtv-th-key-btn.hint {
    color: var(--text-muted, #6b6560);
    opacity: 0.55;
}
.wtv-th-key-btn.hint:hover {
    color: var(--primary, #c9995e);
    opacity: 1;
    background: rgba(201, 153, 94, 0.08);
}
.wtv-th-primary-key .wtv-th-name {
    color: var(--primary, #c9995e);
    font-weight: 600;
}

/* ── Universal cursor tooltip (shared by chart + table) ── */
.wp-tooltip {
    position: fixed;
    z-index: 10050;
    pointer-events: none;
    background: rgba(var(--dw-deep, 28, 26, 32), 0.94);
    color: var(--text, #e8e3db);
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-radius: 6px;
    padding: 6px 10px;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 11px;
    line-height: 1.45;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
    /* Шире прежних 360px: у точки совместного графика за спиной ДВЕ таблицы, и
       их значения показываются целиком, разделами. Место здесь экономить
       нечего — подсказка живёт под курсором и ничего не загораживает надолго
       (требование владельца 16.08). */
    max-width: 460px;
    max-height: 76vh;
    overflow-y: auto;
    /* Значение, не влезающее в ширину, ПЕРЕНОСИТСЯ на новую строку, а не
       обрезается многоточием. Обрезанное значение — это подсказка, которая не
       подсказывает: длинные бывают ровно те, ради которых её и открыли
       (описание, имя связанной таблицы, причина «нет пары по ключу связи»). */
    white-space: normal;
    opacity: 0;
    transition: opacity 0.08s ease;
}
.wp-tooltip.is-visible { opacity: 1; }
.wp-tooltip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0 8px;
    align-items: baseline;
    margin-bottom: 2px;
}
/* Заголовок раздела подсказки — имя таблицы, из которой идут строки ниже.
   Нужен совместному графику: за его точкой стоят две строки из разных таблиц,
   и без заголовка значения читаются вслепую (имена колонок в соседних
   таблицах часто совпадают). */
.wp-tooltip-head {
    color: var(--primary, #c9995e);
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: 0.01em;
    margin: 8px 0 4px;
    padding-bottom: 3px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.14);
}
.wp-tooltip-head:first-child { margin-top: 0; }
.wp-tooltip-label { color: var(--text-dim, #948e84); font-weight: 500; flex: 0 0 auto; }
.wp-tooltip-value {
    color: var(--text, #e8e3db);
    font-weight: 400;
    flex: 1 1 auto;
    min-width: 0;
    /* Длинное значение переносится по словам, а в крайнем случае — по буквам:
       так не рвётся сама плашка. */
    overflow-wrap: anywhere;
}

/* Error block with collapsible details */
.wtv-error-title {
    font-weight: 500;
    margin-bottom: 4px;
}
/* Кнопка повтора в блоке ошибки: у отказа обязан быть выход, иначе после
   запуска rBase таблицу приходилось закрывать и открывать заново. */
.wtv-error-retry {
    display: inline-block;
    margin-top: 8px;
    padding: 5px 12px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 6px;
    background: transparent;
    color: var(--text, #e8e3db);
    font-size: 12px;
    cursor: pointer;
}
.wtv-error-retry:hover:not(:disabled) {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}
.wtv-error-retry:disabled { opacity: 0.5; cursor: default; }
.wtv-error-details {
    margin-top: 6px;
    font-size: 11px;
}
.wtv-error-details summary {
    cursor: pointer;
    color: var(--muted, #8a8a8a);
    user-select: none;
}
.wtv-error-details summary:hover { color: var(--fg, #e6e6e6); }
.wtv-error-detail-text {
    margin-top: 4px;
    padding: 6px 8px;
    background: rgba(0, 0, 0, 0.25);
    border-radius: 3px;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--muted, #8a8a8a);
    max-height: 180px;
    overflow-y: auto;
}
.wtv-edit-error details { margin-top: 6px; font-size: 11px; }
.wtv-edit-error summary { cursor: pointer; color: var(--muted, #8a8a8a); }
.wtv-edit-error pre {
    margin-top: 4px;
    padding: 6px;
    background: rgba(0, 0, 0, 0.2);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 160px;
    overflow-y: auto;
}


/* ═══════════════════════════════════════════════════════════════
   workspace-chart.js — аналитические графики
   ═══════════════════════════════════════════════════════════════ */

/* ── Overlay ── */
.wc-overlay {
    position: fixed;
    inset: 0;
    z-index: 9600;
    background: var(--bg, #1c1a20);
    display: flex;
    flex-direction: column;
    font-family: "Inter", system-ui, -apple-system, sans-serif;
    color: var(--text, #e8e3db);
}

/* ── Header ── */
.wc-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 14px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
    min-height: 40px;
    gap: 8px;
}
.wc-header-left {
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    flex: 1;
    overflow: hidden;
}
.wc-header-icon {
    color: var(--primary, #c9995e);
    flex-shrink: 0;
    display: flex;
}

/* ── Tab bar ── */
.wc-tab-bar {
    display: flex;
    align-items: center;
    gap: 2px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.wc-tab-bar::-webkit-scrollbar { display: none; }
.wc-tab {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 6px 6px 0 0;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid transparent;
    border-bottom: none;
    color: var(--text-dim, #948e84);
    font-size: 0.76rem;
    white-space: nowrap;
    max-width: 180px;
    cursor: pointer;
    user-select: none;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    position: relative;
}
.wc-tab:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.07);
    color: var(--text, #e8e3db);
}
.wc-tab.active {
    background: rgba(201, 153, 94, 0.12);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    color: var(--primary, #c9995e);
    font-weight: 600;
}
.wc-tab.active::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--primary, #c9995e);
    border-radius: 2px 2px 0 0;
}
.wc-tab-name {
    overflow: hidden;
    text-overflow: ellipsis;
}
.wc-tab-close {
    font-size: 13px;
    line-height: 1;
    padding: 0 2px;
    border-radius: 3px;
    opacity: 0;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
    cursor: pointer;
    flex-shrink: 0;
}
.wc-tab:hover .wc-tab-close { opacity: 0.6; }
.wc-tab-close:hover {
    opacity: 1 !important;
    color: var(--danger, #d4706a);
    background: rgba(212, 112, 106, 0.12);
}
.wc-tab.dragging { opacity: 0.4; }
.wc-tab.drag-over {
    border-left: 2px solid var(--primary, #c9995e);
}
.wc-tab-add {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
    padding: 0;
}
.wc-tab-add:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.07);
    color: var(--text, #e8e3db);
}

/* ── Tab context menu ── */
/* Подложка от токена, а не литералом: пункты меню красятся var(--text), и в
   светлой теме текст становился тёмным на оставшейся тёмной плашке.
   Фолбэк повторяет прежний цвет, поэтому тёмная тема не меняется. */
.wc-tab-context-menu {
    position: fixed;
    z-index: 10002;
    min-width: 160px;
    background: var(--dw-surface-2, #2a2730);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 8px;
    padding: 4px 0;
    box-shadow: 0 6px 24px rgba(0,0,0,0.5);
}
.wc-tab-context-menu .wc-context-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    font-size: 0.8rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.1s;
}
.wc-tab-context-menu .wc-context-item:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
}
.wc-tab-context-menu .wc-context-danger {
    color: var(--danger, #d4706a);
}
.wc-tab-context-menu .wc-context-danger:hover {
    background: rgba(212, 112, 106, 0.1);
}
.wc-tab-context-menu .wc-context-divider {
    height: 1px;
    margin: 4px 8px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* ── Axis column dropdown ── */
.wc-axis-dropdown {
    position: fixed;
    z-index: 100001;
    background: var(--dw-surface-2, #2a2730);
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-radius: 8px;
    padding: 4px 0;
    min-width: 220px;
    max-width: 320px;
    /* 70vh, а не 340px: в меню добавился раздел колонок связанных таблиц с
       охватом связки и выбором свёртки, и на прежней высоте до самих колонок
       приходилось прокручивать почти вслепую. */
    max-height: 70vh;
    overflow-y: auto;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.wc-axis-dropdown-title {
    padding: 6px 12px;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.07);
    margin-bottom: 2px;
}
.wc-axis-dropdown-item {
    padding: 5px 12px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.1s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.wc-axis-dropdown-item:hover {
    background: rgba(201, 153, 94, 0.15);
}
.wc-axis-dropdown-item.active {
    color: var(--primary, #c9995e);
    font-weight: 600;
    background: rgba(201, 153, 94, 0.08);
}
/* Двухуровневый селектор колонок: уровень 1 — название таблицы (JOIN) */
.wc-axis-dropdown-group {
    padding: 6px 12px 3px;
    font-size: 0.74rem;
    color: var(--primary, #c9995e);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.wc-axis-dropdown-group + .wc-axis-dropdown-group,
.wc-axis-dropdown-item + .wc-axis-dropdown-group {
    margin-top: 3px;
    border-top: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.07);
}
/* Уровень 2 — колонка внутри таблицы (отступ-«отсечка») */
.wc-axis-dropdown-item.lvl2 {
    padding-left: 26px;
}

/* ── Колонки связанных таблиц в меню оси ──
   Раздел приходит с сервера уже после показа меню и добавляет к нему охват
   связки, выбор свёртки и список колонок соседней таблицы — поэтому меню и
   стало заметно выше (max-height у .wc-axis-dropdown поднят до 70vh).
   Пояснения набраны мелким приглушённым текстом и переносятся по словам:
   это фразы, а не подписи в одну строку, и обрезать их многоточием нельзя —
   именно в них названы числа охвата и причины потерь. */
.wc-axis-note {
    padding: 3px 12px 5px;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--text-dim, #948e84);
    white-space: normal;
}
.wc-axis-fold-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    font-size: 0.74rem;
    color: var(--text-dim, #948e84);
}
.wc-axis-fold-select {
    flex: 1;
    padding: 3px 5px;
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-radius: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    font-size: 0.75rem;
    outline: none;
    cursor: pointer;
}
.wc-axis-fold-select:focus {
    border-color: var(--primary, #c9995e);
}

/* ── Axis filter row ── */
.wc-axis-filter-row {
    display: flex;
    gap: 4px;
    padding: 4px 10px;
    align-items: center;
}
.wc-axis-filter-row label {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}
.wc-axis-filter-input {
    width: 52px;
    padding: 3px 5px;
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-radius: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    font-size: 0.75rem;
    outline: none;
    transition: border-color 0.12s;
    -moz-appearance: textfield;
    appearance: textfield;
}
.wc-axis-filter-input::-webkit-outer-spin-button,
.wc-axis-filter-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}
.wc-axis-filter-input:focus {
    border-color: var(--primary, #c9995e);
}
.wc-axis-filter-input::placeholder {
    color: var(--text-muted, #6b6560);
}
.wc-axis-rename-input {
    width: 100%;
    flex: 1;
    min-width: 140px;
}
.wc-axis-filter-actions {
    display: flex;
    gap: 6px;
    padding: 4px 12px 6px;
    justify-content: flex-end;
}
.wc-axis-filter-apply,
.wc-axis-filter-clear {
    padding: 3px 0;
    border-radius: 4px;
    font-size: 0.72rem;
    cursor: pointer;
    border: none;
    transition: background 0.12s;
}
.wc-axis-filter-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    border: none;
    cursor: pointer;
    transition: background 0.12s;
    padding: 0;
    flex: none;
}
.wc-axis-filter-apply {
    background: rgba(201, 153, 94, 0.2);
    color: var(--primary, #c9995e);
}
.wc-axis-filter-apply:hover {
    background: rgba(201, 153, 94, 0.35);
}
.wc-axis-filter-clear {
    background: transparent;
    color: var(--text-dim, #948e84);
}
.wc-axis-filter-clear:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
}

/* ── Axis range inputs ── */
.wc-axis-range-input {
    width: 50px;
    padding: 3px 5px;
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.12);
    border-radius: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    font-size: 0.72rem;
    outline: none;
    transition: border-color 0.12s;
    -moz-appearance: textfield;
    appearance: textfield;
}
.wc-axis-range-input::-webkit-outer-spin-button,
.wc-axis-range-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}
.wc-axis-range-input:focus {
    border-color: var(--primary, #c9995e);
}
.wc-axis-range-input::placeholder {
    color: var(--text-muted, #6b6560);
}

.wc-header-right {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    flex-wrap: wrap;
}
/* Кнопки окна графика («Свернуть» / «Закрыть») — в шапке, на уровне вкладок,
   там же, где они у просмотрщика таблиц и документов. Раньше жили в правой
   панели инструментов: это управление ОКНОМ, а не инструмент графика, и вдобавок
   они уезжали вместе с панелью при её сворачивании. Не переносятся на вторую
   строку — вкладки ужимаются сами (.wc-tab-bar со своим overflow). */
.wc-header-right.wc-window-controls {
    flex-wrap: nowrap;
    margin-left: auto;
}
.wc-separator {
    width: 1px;
    height: 18px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin: 0 2px;
}

/* ── Buttons ── */
.wc-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    background: transparent;
    color: var(--text-dim, #948e84);
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    white-space: nowrap;
}
.wc-btn:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
/* Отключённая кнопка обязана ВЫГЛЯДЕТЬ отключённой.
   Вскрыто приёмкой T3.2: «Применить» у конструктора правила выглядела рабочей,
   нажималась и молча ничего не делала — пользователь читает это как поломку, а
   не как запрет. Правило общее, а не для одной кнопки: тем же болели «Сохранить»
   на панели графика (при отсутствии изменений) и «Сохранить» в редакторе
   интервалов. `pointer-events` НЕ гасим — иначе пропадёт подсказка `title`,
   объясняющая, почему нажать нельзя. */
.wc-btn:disabled,
.wc-btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}
.wc-btn:disabled:hover,
.wc-btn[disabled]:hover {
    background: transparent;
    color: var(--text-dim, #948e84);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wc-btn-primary:disabled:hover,
.wc-btn-primary[disabled]:hover {
    /* У основной кнопки фон объявлен через !important — перебиваем тем же,
       иначе наведение подсвечивало бы отключённую кнопку как живую. */
    background: var(--primary, #c9995e) !important;
    color: #1c1a20 !important;
}

.wc-btn-active {
    background: rgba(201, 153, 94, 0.15);
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
}
.wc-btn-close {
    border: none;
    padding: 4px 6px;
}
.wc-btn-close:hover {
    color: var(--danger, #d4706a);
    background: rgba(212, 112, 106, 0.12);
}

/* ── Save button (dirty / clean states) ── */
.wc-btn-save:disabled {
    opacity: 0.5;
    cursor: default;
}
.wc-btn-save:disabled:hover {
    background: transparent;
    color: var(--text-dim, #948e84);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wc-btn-save.wc-btn-dirty {
    background: var(--primary, #c9995e) !important;
    color: #1c1a20 !important;
    border-color: var(--primary, #c9995e) !important;
    animation: wc-save-pulse 2.2s ease-in-out infinite;
}
.wc-btn-save.wc-btn-dirty:hover {
    background: #d4a56a !important;
    border-color: #d4a56a !important;
}
@keyframes wc-save-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(201, 153, 94, 0.45); }
    50%      { box-shadow: 0 0 0 6px rgba(201, 153, 94, 0); }
}

/* ── Confirm modal (несохранённые изменения при закрытии) ── */
.wc-confirm-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 100000;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.wc-confirm-modal {
    background: var(--bg-2, #2a262e);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
    border-radius: 10px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
    min-width: 380px;
    max-width: 520px;
    padding: 20px 22px 18px;
    color: var(--text, #e8e3db);
    font-family: Inter, sans-serif;
}
.wc-confirm-modal-header {
    font-size: 1.0rem;
    font-weight: 600;
    margin-bottom: 10px;
    color: var(--primary, #c9995e);
}
.wc-confirm-modal-body {
    font-size: 0.88rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 18px;
    line-height: 1.45;
}
.wc-confirm-modal-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    flex-wrap: wrap;
}
.wc-confirm-modal-actions .wc-btn {
    padding: 6px 14px;
    font-size: 0.84rem;
}

/* ── Select ── */
.wc-select {
    padding: 4px 8px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    background: transparent;
    color: var(--text-dim, #948e84);
    font-size: 0.78rem;
    cursor: pointer;
    outline: none;
}
.wc-select:hover, .wc-select:focus {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
    color: var(--text, #e8e3db);
}
.wc-select option {
    background: var(--dw-surface-2, #242229);
    color: var(--text, #e8e3db);
}

/* ── Body layout ── */
.wc-body {
    flex: 1;
    display: flex;
    overflow: hidden;
}
.wc-canvas-area {
    flex: 1;
    position: relative;
    overflow: hidden;
}
.wc-canvas-area canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* ── Canvas-area floating tools (top-right) ── */
/* right offset must match PADDING.right in workspace-chart.js so that the
   rightmost button's edge aligns with the plot-area right edge */
.wc-canvas-tools {
    position: absolute;
    top: 8px;
    right: 30px;
    z-index: 2;
    display: flex;
    gap: 6px;
    align-items: center;
}
.wc-canvas-tools .wc-btn,
.wc-canvas-reg-select {
    background: rgba(var(--dw-deep, 28, 26, 32), 0.78);
    backdrop-filter: blur(4px);
}
/* Ховер — как у кнопок боковой панели графика (.wc-btn:hover): светлая плёнка
   от --dw-tint, а не отдельная тёмная плашка #28252e, которая выбивалась из
   ряда и в светлой теме была просто тёмным пятном. Плёнку кладём поверх
   непрозрачной подложки: кнопки этого ряда висят над канвасом, и полностью
   полупрозрачный фон, как у боковых, сделал бы их нечитаемыми. */
.wc-canvas-tools .wc-btn:hover {
    background:
        linear-gradient(rgba(var(--dw-tint, 255, 250, 243), 0.06),
                        rgba(var(--dw-tint, 255, 250, 243), 0.06)),
        rgba(var(--dw-deep, 28, 26, 32), 0.78);
}

/* ── Навигация по полю (видна, пока зажат Ctrl) ── */
/* Правый нижний угол холста: подпись оси X стоит по центру, стат-плашки —
   слева внизу, так что это единственный угол, где панель ничего не закрывает. */
.wc-nav-tools {
    position: absolute;
    right: 12px;
    bottom: 12px;
    z-index: 3;
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 5px 8px;
    border-radius: 8px;
    background: rgba(var(--dw-deep, 28, 26, 32), 0.88);
    border: 1px solid rgba(var(--dw-tint, 255, 250, 243), 0.12);
    backdrop-filter: blur(4px);
}
.wc-nav-tools .wc-btn {
    font-size: 0.95rem;
    line-height: 1;
    padding: 3px 8px;
}
.wc-nav-hint {
    font-size: 0.7rem;
    color: var(--text-dim, #948e84);
    white-space: nowrap;
}

/* ── Right vertical toolbar ── */
.wc-right-toolbar {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    flex-shrink: 0;
    padding: 8px 6px;
    width: 144px;
    border-left: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    overflow-y: auto;
    transition: width 0.15s;
}
.wc-right-toolbar .wc-btn {
    justify-content: flex-start;
    width: 100%;
}
.wc-right-toolbar .wc-select {
    width: 100%;
}
.wc-right-toolbar-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
    margin-bottom: 4px;
}
.wc-right-toolbar.collapsed .wc-right-toolbar-top {
    flex-direction: column;
    align-items: stretch;
}
.wc-toolbar-toggle svg {
    transition: transform 0.15s;
}
.wc-right-toolbar.collapsed .wc-toolbar-toggle svg {
    transform: rotate(180deg);
}
.wc-separator-h {
    height: 1px;
    width: 100%;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin: 4px 0;
}

/* ── Collapsed state: icons only ── */
.wc-right-toolbar.collapsed {
    width: 44px;
}
.wc-right-toolbar.collapsed .wc-btn {
    justify-content: center;
    padding: 4px 4px;
    gap: 2px;
}
.wc-right-toolbar.collapsed .wc-btn-text {
    display: none;
}

.wc-loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.88rem;
    color: var(--text-dim, #948e84);
    background: rgba(var(--dw-deep, 28, 26, 32), 0.8);
    z-index: 2;
}

/* ── Sidebar ── */
.wc-sidebar-resizer {
    width: 5px;
    flex-shrink: 0;
    cursor: ew-resize;
    background: transparent;
    transition: background 0.15s;
    position: relative;
}
.wc-sidebar-resizer::after {
    content: '';
    position: absolute;
    left: 2px;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 40px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 1px;
    opacity: 0;
    transition: opacity 0.15s;
}
.wc-sidebar-resizer:hover {
    background: rgba(201, 153, 94, 0.15);
}
.wc-sidebar-resizer:hover::after,
.wc-sidebar-resizer.active::after {
    opacity: 1;
}
.wc-sidebar-resizer.active {
    background: rgba(201, 153, 94, 0.25);
}
.wc-sidebar {
    width: 240px;
    min-width: 180px;
    max-width: 500px;
    flex-shrink: 0;
    overflow-y: auto;
    padding: 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}
.wc-sidebar-left {
    border-right: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wc-sidebar-section {
    margin-bottom: 14px;
}
.wc-sidebar-title {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 6px;
}

/* ── Legend ── */
/* ЕДИНЫЙ ФОРМАТ СТРОКИ СПИСКА (v1.71.5, правка владельца: «привести все
   элементы управления к единому формату»). Три списка панели — группы, выборки
   и слои — до сих пор жили каждый по своим числам: у групп левый отступ 4px и
   вертикальный 3px, у выборок и слоёв 2px и 4px. Наружу это читалось как
   съехавшие кружки цветовых меток: у групп они стояли правее.
   Отступ задан ЗДЕСЬ и повторён у двух других списков теми же числами. */
.wc-legend-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 4px;
    border-radius: 4px;
    font-size: 0.78rem;
    transition: opacity 0.15s;
}
.wc-legend-row:hover { background: rgba(var(--dw-tint, 255, 250, 243), 0.04); }
.wc-legend-row-active {
    background: rgba(201, 153, 94, 0.18);
    box-shadow: inset 2px 0 0 rgba(201, 153, 94, 0.85);
}
.wc-legend-row-active:hover { background: rgba(201, 153, 94, 0.24); }
.wc-legend-hidden { opacity: 0.35; }
.wc-stat-sub {
    margin-left: 10px;
    color: var(--text-muted, #6b6560);
    font-size: 0.72rem;
}
.wc-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.wc-legend-square {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    flex-shrink: 0;
}
.wc-legend-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text, #e8e3db);
}
.wc-legend-r2 {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}
.wc-legend-overall {
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    margin-bottom: 4px;
    padding-bottom: 5px;
}
.wc-legend-improvement {
    font-size: 0.75rem;
    color: var(--success, #5db87a);
    padding: 4px 0;
    margin-top: 4px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* ── Legend dividers & subtitles ── */
.wc-legend-divider {
    display: flex;
    align-items: center;
    margin: 8px 0 6px 0;
    color: var(--text-dim, #948e84);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.wc-legend-divider::before,
.wc-legend-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.wc-legend-divider::before { margin-right: 8px; }
.wc-legend-divider::after { margin-left: 8px; }

.wc-legend-subtitle {
    font-size: 0.7rem;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 6px 0 4px 0;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-legend-hint {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    font-style: italic;
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* ── Custom group row ── */
/* Строки убранных групп используют ту же раскладку, что и создаваемые
   (тренд + блок действий), поэтому им нужен такой же резерв справа. */
/* Место под блок действий, прижатый вправо абсолютно. Считается по числу
   кнопок: `.wc-btn-icon-sm` это 12px значка плюс 8px отступов, зазор 2px.
   У строки ГРУППЫ кнопок четыре (в выборку, глаз, правка, удалить) — 1.71.1,
   волна 7: с прежними 70px четвёртая кнопка наползала на кнопку тренда. */
.wc-legend-custom {
    position: relative;
    padding-right: 94px;
}
.wc-legend-removed {
    position: relative;
    padding-right: 70px;
}
.wc-legend-row:not(.wc-legend-custom):not(.wc-legend-removed):has(.wc-legend-actions) {
    position: relative;
    padding-right: 36px;
}
/* Кнопки строки ВИДНЫ ВСЕГДА и на наведении разгораются (v1.71.5, правка
   владельца). Прежде они появлялись только на наведении — в выборках и слоях
   при этом были видны постоянно, и один и тот же список вёл себя трояко.
   Появляющийся элемент вдобавок сообщает о себе только тем, кто уже знает, что
   он там есть. */
.wc-legend-actions {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    gap: 2px;
    opacity: 0.45;
    transition: opacity 0.15s;
}
.wc-legend-row:hover .wc-legend-actions,
.wc-legend-row.wc-legend-hidden .wc-legend-actions {
    opacity: 1;
}
.wc-legend-row.wc-legend-active {
    background: rgba(201, 153, 94, 0.16);
    border-left: 3px solid #c9995e;
    padding-left: 5px;
}
.wc-btn-icon-sm {
    background: transparent;
    border: none;
    padding: 2px 4px;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
    border-radius: 3px;
    transition: all 0.15s;
}
.wc-btn-icon-sm:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
}
.wc-btn-icon-sm svg {
    width: 12px;
    height: 12px;
    display: block;
}

/* ── Trend button ── */
.wc-trend-btn {
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    padding: 3px 5px;
    cursor: pointer;
    color: var(--text-muted, #6b6560);
    line-height: 1;
    flex-shrink: 0;
    transition: all 0.15s;
}
.wc-trend-btn:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text-dim, #948e84);
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.wc-trend-btn.active {
    background: rgba(201, 153, 94, 0.15);
    color: var(--primary, #c9995e);
    border-color: var(--primary, #c9995e);
}
.wc-trend-btn svg {
    display: block;
}

/* ── Visibility toggle button (глаз) ── */
.wc-vis-btn {
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    padding: 3px 5px;
    cursor: pointer;
    color: var(--text-muted, #6b6560);
    line-height: 1;
    flex-shrink: 0;
    transition: all 0.15s;
}
.wc-vis-btn:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text-dim, #948e84);
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}
.wc-vis-btn svg {
    display: block;
}

/* ── Trend equation ── */
.wc-legend-equation {
    width: 100%;
    font-size: 0.68rem;
    color: var(--text-dim, #948e84);
    padding: 2px 0 2px 16px;
    font-family: 'SF Mono', 'Consolas', monospace;
    margin-top: 2px;
    border-top: 1px dashed var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* ── Stats ── */
.wc-stat-row {
    font-size: 0.75rem;
    color: var(--text-dim, #948e84);
    padding: 2px 0;
    line-height: 1.4;
}
.wc-stat-row span { color: var(--text-muted, #6b6560); }

/* Раздел «Источники» графика (v1.66.0, парная правка к графику 1.79.0):
   из чего построен ЭТОТ график — таблицы, связь, ключ и оси. Строки те же,
   что у статистики; отдельно приглушено служебное имя представления связи —
   оно нужно при разговоре про сервер и мешает при разговоре про данные. */
.wc-sources .wc-stat-row { word-break: break-word; }

/* Сворачиваемые разделы внизу панели: «Источники» и «Статистика» (v1.67.0).
   Свёрнуты по умолчанию — правка владельца 17.08. Заголовок кликабелен
   целиком, стрелка поворачивается. */
.wc-fold > .wc-fold-body { display: none; }
.wc-fold.open > .wc-fold-body { display: block; }
.wc-fold-title {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
    user-select: none;
}
.wc-fold-caret {
    display: inline-flex;
    transition: transform 120ms ease;
    opacity: 0.7;
}
.wc-fold.open > .wc-fold-title .wc-fold-caret { transform: rotate(90deg); }
.wc-src-tech {
    opacity: 0.65;
    font-size: 0.7rem;
    word-break: break-all;
}

/* ── Адрес строки (T1.2/T1.4 ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS) ──
   Ключ есть → выделение переносится между окнами и переживает перезапрос
   данных; ключа нет → адресация по номеру строки, и это надо ВИДЕТЬ до того,
   как пользователь построит выборку, а не после того, как она съедет. */
.wc-rowkey { word-break: break-word; }
.wc-rowkey-ok { color: var(--text-dim, #948e84); }
.wc-rowkey-ok span { color: var(--text-muted, #6b6560); }
.wc-rowkey-warn {
    color: #e0a94a;
    padding-left: 14px;
    position: relative;
}
.wc-rowkey-warn::before {
    content: '⚠';
    position: absolute;
    left: 0;
    top: 2px;
    font-size: 0.7rem;
}
.wc-rowkey-warn span { color: #e0a94a; opacity: 0.75; }
.wc-rowkey-sub {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    padding-left: 14px;
}

/* ── Grouping ranking ── */
.wc-grouping-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 6px;
    border-radius: 4px;
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 0.12s;
}
.wc-grouping-item:hover { background: rgba(var(--dw-tint, 255, 250, 243), 0.06); }
.wc-grouping-col {
    flex: 1;
    color: var(--text, #e8e3db);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wc-grouping-imp {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    flex-shrink: 0;
}
.wc-grouping-imp.positive { color: var(--success, #5db87a); font-weight: 600; }
.wc-grouping-r2 {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    flex-shrink: 0;
}

/* ── Selection info ── */
.wc-selection-info { font-size: 0.75rem; }

/* Строка про совпадающие точки и ссылка-действие в статистике (2026-08-15). */
.wc-stat-dup { margin-top: 4px; }
.wc-stat-link {
    border: none;
    background: none;
    padding: 0 0 0 4px;
    font: inherit;
    color: #78c8ff;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.wc-stat-link:hover { color: #a8dcff; }
.wc-stat-link:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(32, 184, 205, 0.30);
    border-radius: 3px;
}

/* Подсказка о правке выделения (2026-08-15). Тише счётчика и тише самой
   информации о выделении: она нужна один раз, а мозолить глаза не должна. */
.wc-sel-hint {
    font-size: 0.7rem;
    line-height: 1.35;
    opacity: 0.55;
    margin: 2px 0 6px;
}

/* ── Scrollbar ── */
.wc-overlay ::-webkit-scrollbar { width: 5px; }
.wc-overlay ::-webkit-scrollbar-thumb { background: rgba(var(--dw-ink, 232, 227, 219), 0.10); border-radius: 3px; }
.wc-overlay ::-webkit-scrollbar-thumb:hover { background: rgba(var(--dw-ink, 232, 227, 219), 0.18); }

/* ── Custom Groups Section ── */
.wc-custom-groups-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.wc-custom-groups-empty {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    font-style: italic;
    padding: 8px 0;
}

.wc-custom-group-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    transition: background 0.15s;
}

.wc-custom-group-row:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
}

.wc-custom-group-row.wc-group-hidden {
    opacity: 0.5;
}

.wc-group-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.wc-group-name {
    font-size: 0.78rem;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wc-group-count {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    padding: 2px 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    border-radius: 10px;
}

.wc-group-actions {
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.15s;
}

.wc-custom-group-row:hover .wc-group-actions {
    opacity: 1;
}

.wc-btn-icon-sm {
    background: transparent;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--text-dim, #948e84);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.15s, background 0.15s;
}

.wc-btn-icon-sm:hover {
    color: var(--text, #e8e3db);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
}

.wc-btn-icon-sm:hover svg {
    stroke: currentColor;
}

/* ── Context Menu ── */
/* Подложка идёт от токена, а не от литерала: раньше здесь был захардкоженный
   тёмный rgba(30,28,36), а текст пунктов — от var(--text). В светлой теме текст
   становился тёмным, плашка оставалась тёмной, и меню читать было нечем. */
.wc-context-menu {
    position: absolute;
    z-index: 1000;
    background: rgba(var(--dw-deep, 30, 28, 36), 0.98);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
    border-radius: 8px;
    padding: 4px 0;
    min-width: 180px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(8px);
}
.wc-context-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
    transition: background 0.12s;
}
.wc-context-item:hover {
    background: rgba(201, 153, 94, 0.15);
}
.wc-context-item svg {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    opacity: 0.7;
}
.wc-context-divider {
    height: 1px;
    background: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    margin: 4px 8px;
}

/* ── Removed points ── */
.wc-legend-divider-removed span {
    color: var(--danger, #d4706a);
}
/* Затемнение строки — только в скрытом состоянии (через .wc-legend-hidden),
   как у создаваемых групп. Видимая/активная убранная группа не приглушается. */
.wc-legend-dot-removed {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--text-muted, #6b6560);
    position: relative;
}
.wc-legend-dot-removed::after {
    content: '';
    position: absolute;
    top: 50%;
    left: -1px;
    right: -1px;
    height: 2px;
    background: var(--danger, #d4706a);
    transform: translateY(-50%) rotate(-45deg);
}
.wc-btn-restore {
    color: var(--success, #5db87a) !important;
}
.wc-btn-restore:hover {
    background: rgba(93, 184, 122, 0.15) !important;
}

/* ── Modal Styles ── */
.wc-modal {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
}

.wc-modal-content {
    background: var(--bg-card, var(--dw-surface, #1e1c24));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 12px;
    min-width: 320px;
    max-width: 420px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

.wc-modal-wide {
    min-width: 480px;
    max-width: 600px;
}

.wc-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    font-weight: 600;
    font-size: 0.95rem;
}

/* Несколько кнопок в шапке модалки. Заголовок и кнопки разводит space-between
   у .wc-modal-header, поэтому вторая кнопка, поставленная рядом отдельно,
   уезжает в середину — их обязательно держать одной обёрткой. */
.wc-modal-header-actions {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
/* Корзина «снять все отметки» приглушена: она рядом с закрытием окна, и равный
   вес двух значков превращает её в ловушку. Красной становится под курсором —
   когда намерение уже видно. */
.wc-labels-clear {
    opacity: 0.45;
}
.wc-labels-clear:hover {
    opacity: 1;
    color: var(--danger, #c96a5e);
}

.wc-modal-body {
    padding: 16px;
    max-height: 60vh;
    overflow-y: auto;
}

.wc-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-form-group {
    margin-bottom: 14px;
}

.wc-form-group label {
    display: block;
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 6px;
}

.wc-form-group input[type="text"],
.wc-form-group textarea {
    width: 100%;
    padding: 10px 12px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.88rem;
    font-family: inherit;
    resize: vertical;
}

.wc-form-group input:focus,
.wc-form-group textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-form-info {
    font-size: 0.75rem;
    color: var(--text-muted, #6b6560);
}

/* ── Конструктор правила (T3.2 ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS) ── */

/* Ширина фиксированная, а не «от 480 до 600»: в режиме «по условиям» в строке
   появляется кнопка цвета, и по содержимому диалог стал бы шире. Размер не
   должен зависеть от выбранного режима (запрос владельца). */
#wcRuleModal .wc-modal-content {
    width: min(600px, 92vw);
    max-width: none;
}

.wc-rule-join {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}

.wc-rule-conds {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 10px;
}

.wc-rule-cond {
    display: flex;
    align-items: center;
    gap: 6px;
}

.wc-rule-cond .wc-rule-col {
    flex: 1 1 34%;
    min-width: 0;
}

.wc-rule-cond .wc-rule-op {
    flex: 0 1 30%;
    min-width: 0;
}

.wc-rule-cond .wc-input {
    flex: 1 1 20%;
    min-width: 0;
    padding: 5px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.8rem;
    font-family: inherit;
}

.wc-rule-cond .wc-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-rule-cond textarea.wc-rule-list {
    resize: vertical;
    min-height: 34px;
}

.wc-rule-dash {
    color: var(--text-muted, #6b6560);
    font-size: 0.8rem;
}

.wc-rule-del {
    flex: 0 0 auto;
    opacity: 0.55;
}

.wc-rule-del:hover {
    opacity: 1;
}

/* Цвет условия: задан — условие даёт свою выборку этого цвета (режим
   «по выборке на каждое условие»). Пустой кружок = цвета нет. */
.wc-rule-color {
    flex: 0 0 auto;
}

.wc-rule-color-dot {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 1px solid var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.25));
    background: transparent;
}

.wc-rule-color--none .wc-rule-color-dot {
    border-style: dashed;
}

.wc-rule-color-menu {
    position: absolute;
    z-index: 30;
    right: 0;
    margin-top: 4px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-width: 200px;
    padding: 8px;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

.wc-rule-cond {
    position: relative;
}

/* Режим правила словами. Соединитель, переставший работать, гасится — иначе
   он выглядел бы действующим и врал бы о том, что считается. */
/* Под подпись режима и под предпросмотр отведено по две строки независимо от
   того, сколько там текста сейчас: тексты у режимов разной длины, и без резерва
   диалог менял бы высоту при переключении «Создать» (запрос владельца). */
.wc-rule-mode {
    margin-top: 8px;
    font-size: 0.75rem;
    line-height: 1.35;
    height: 2.7em;
    overflow-y: auto;
}

.wc-rule-mode.per {
    color: var(--primary, #c9995e);
}

/* Класса `.wc-rule-join--off` больше нет: соединитель, не относящийся к режиму,
   не гасится, а не показывается вовсе. Погашенный элемент управления сообщает
   «сломалось», а не «сейчас не применяется». */

.wc-rule-edit {
    padding-bottom: 6px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

/* Предпросмотр «попадёт N строк»: главное число диалога, поэтому крупнее
   остальных подписей. Предупреждение и отказ окрашены — молчаливого усечения
   в этом месте быть не должно (T3.2/T3.3). */
/* Фиксированная высота, а не минимальная: в режиме «по условиям» предпросмотр
   перечисляет счёт по каждому условию, и с ростом их числа диалог полз бы вверх.
   Длинный список прокручивается внутри — числа не теряются, размер не пляшет. */
.wc-rule-preview {
    margin-top: 12px;
    font-size: 0.82rem;
    line-height: 1.35;
    height: 4.1em;
    overflow-y: auto;
}

.wc-rule-preview.ok {
    color: var(--text, #e8e3db);
    font-weight: 600;
}

.wc-rule-preview.warn {
    color: var(--warning, #d9a441);
}

/* ── Color Picker ── */
.wc-color-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.wc-color-swatch {
    width: 28px;
    height: 28px;
    border-radius: 6px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: transform 0.15s, border-color 0.15s;
}

.wc-color-swatch:hover {
    transform: scale(1.1);
}

.wc-color-swatch.selected {
    border-color: #fff;
    box-shadow: 0 0 0 2px var(--bg, #1c1a20), 0 0 0 4px currentColor;
}

/* «Без цвета» — активная выборка, выглядящая как обычные данные. Ячейка
   заливки не имеет намеренно: цвет здесь именно отсутствует. */
.wc-color-swatch--none {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.9rem;
    color: var(--text-dim, #948e84);
    border: 2px dashed var(--border, #d9d2c7);
}

/* ── Legend section header (above CLASS groups) ── */
/* Mirrors .wc-legend-row right-padding so its action buttons sit on the same vertical
 * line as the toggle/edit buttons of group rows below. */
.wc-legend-section-header {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 8px 0 4px;
    padding: 4px 4px 4px 4px;
    padding-right: 36px;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.wc-legend-section-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ЕДИНЫЙ ВЕРТИКАЛЬНЫЙ РИТМ ПАНЕЛИ (v1.71.3, правка владельца: «расстояние
   между списками не одинаково»). Все заголовки разделов — «Классы», «Группы»,
   «Выборки», «Слои», «Источники», «Статистика» — носят один класс, поэтому
   расстояние между соседними задаётся ЗДЕСЬ и ровно один раз. Контейнеры
   секций своих отступов не имеют (`--flat`), иначе к этому числу добавлялись бы
   ещё их собственные — так ритм и разъезжался. */
.wc-fold-title.wc-legend-section-header {
    gap: 6px;
}
.wc-fold-title > .wc-fold-caret {
    width: 16px;
    height: 16px;
    align-items: center;
    justify-content: flex-start;
    color: var(--text-dim, #948e84);
    opacity: 1;
}

/* Заголовок с тремя-четырьмя кнопками справа («Классы», «Пользовательские
   группы», «Выборки»): колонка под них шире базовых 36px, иначе название
   наползает на кнопки. Считается так же, как у строк групп (v1.71.2). */
.wc-legend-section-header--wide {
    padding-right: 94px;
}

/* Разделы панели идут ОДНИМ списком, без собственных отступов у каждого
   контейнера: их ритм задают отступы заголовков. Иначе «Выборки» и «Слои»
   читаются как отдельные блоки, а не как соседние разделы (волна 7). */
.wc-sidebar-section--flat {
    margin-bottom: 0;
}

/* Пустой результат отбора в просмотрщике (2026-08-13). Пустое поле под шапкой
   читается как «таблица сломалась» — объяснение стоит на его месте. */
.wtv-empty-note {
    margin: 24px auto;
    max-width: 560px;
    padding: 16px 18px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.14));
    border-radius: 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    text-align: left;
}
.wtv-empty-note-title {
    font-size: 0.92rem;
    color: var(--text, #e8e3db);
    margin-bottom: 6px;
}
.wtv-empty-note-text {
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--text-dim, #948e84);
}
.wtv-empty-note-btn {
    margin-top: 12px;
    padding: 6px 12px;
    font-size: 0.8rem;
    color: var(--primary, #c9995e);
    background: transparent;
    border: 1px solid var(--primary, #c9995e);
    border-radius: 6px;
    cursor: pointer;
}
.wtv-empty-note-btn:hover {
    background: rgba(201, 153, 94, 0.12);
}

/* Сворачивание секции легенды (просьба владельца 2026-08-13). Заголовок сам
   служит кнопкой, поэтому курсор указывает на это на всей его ширине; каретка
   поворачивается стилем, второй иконки для свёрнутого состояния нет. */
.wc-legend-section-header {
    cursor: pointer;
}
/* Каретка прижата к ЛЕВОМУ краю своей коробки (v1.71.5): по центру она стояла
   правее цветных кружков в строках под собой, и заголовок выглядел сдвинутым
   относительно собственного списка. */
.wc-legend-caret {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    width: 16px;
    height: 16px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    transition: transform 0.15s, color 0.15s;
}
.wc-legend-caret:hover {
    color: var(--text, #e8e3db);
}
.wc-legend-caret.collapsed {
    transform: rotate(-90deg);
}
.wc-legend-section-body {
    display: block;
}

/* Отдельной черты между разделами больше нет (v1.71.3): пока «Классы» и
   «Группы» были двумя половинами одного блока, она их разделяла; теперь все
   разделы панели равны, и одна линия посередине ломала бы ритм. Правило
   оставлено пустым намеренно — класс мог остаться в чужой разметке. */
.wc-legend-section-header.wc-legend-section-header-divider {
    margin-top: 8px;
}

.wc-legend-edit-bins,
.wc-legend-toggle-all {
    flex-shrink: 0;
    color: var(--text-dim, #948e84);
}

.wc-legend-edit-bins:hover,
.wc-legend-toggle-all:hover {
    color: var(--primary, #c9995e);
}

/* Always-visible variant of .wc-legend-actions — used for the section header
 * and the "Все данные" row, where the buttons must not be gated on hover. */
.wc-legend-actions.wc-legend-actions-always {
    opacity: 1 !important;
}

/* Заголовок секции «Группы» — та же раскладка, что у строк легенды и
   секционных заголовков. display:flex объявлен ЗДЕСЬ, а не на .wc-sidebar-title:
   тот же класс носят «Статистика» и «Выделено точек: <span>», и flex разбил бы
   их текст на отдельные флекс-элементы, съев пробел перед числом.
   padding-right резервирует колонку под кнопку, как в .wc-legend-section-header. */
.wc-legend-title {
    position: relative;
    display: flex;
    align-items: center;
    padding-right: 36px;
}
.wc-legend-title .wc-legend-actions {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    gap: 2px;
}

/* Section header uses the same absolute-right positioning as group rows,
 * so its actions stack lines up on the same vertical with group toggles. */
.wc-legend-section-header .wc-legend-actions {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    gap: 2px;
}

/* ── Bins Editor (CLASS-range editor in chart sidebar) ── */
.wc-bins-editor-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.wc-bin-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.08));
    border-radius: 6px;
    transition: opacity 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.wc-bin-row.wc-bin-row-focus {
    border-color: var(--primary, #c9995e);
    box-shadow: 0 0 0 1px var(--primary, #c9995e);
}

.wc-bin-row.wc-bin-row-dragging {
    opacity: 0.45;
}

.wc-bin-row.wc-bin-row-dropzone {
    border-color: var(--primary, #c9995e);
    box-shadow: inset 0 2px 0 var(--primary, #c9995e);
}

.wc-bin-row-handle {
    flex-shrink: 0;
    width: 14px;
    text-align: center;
    color: var(--text-muted, #6b6560);
    font-size: 12px;
    line-height: 1;
    cursor: grab;
    user-select: none;
    letter-spacing: -2px;
}

.wc-bin-row-handle:active { cursor: grabbing; }

.wc-bin-row-order {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex-shrink: 0;
}

.wc-bin-row-up,
.wc-bin-row-down {
    width: 18px;
    height: 14px;
    padding: 0 !important;
    line-height: 1;
    font-size: 8px;
    color: var(--text-dim, #948e84);
}

.wc-bin-row-up:hover,
.wc-bin-row-down:hover {
    color: var(--primary, #c9995e);
}

.wc-bin-row-up:disabled,
.wc-bin-row-down:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.wc-bin-row-color {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 4px;
    cursor: pointer;
    /* Контрастный кант вокруг произвольного цвета образца: в тёмной теме
       светлый, в светлой — тёмный. Литеральный белый на белом пропадал,
       и светлые образцы теряли границу. */
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.18);
    transition: transform 0.15s;
}

.wc-bin-row-color:hover { transform: scale(1.08); }

.wc-bin-row-name {
    flex: 1 1 auto;
    min-width: 80px;
    padding: 6px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
}

.wc-bin-row-num {
    width: 80px;
    flex-shrink: 0;
    padding: 6px 8px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
}

.wc-bin-row-name:focus,
.wc-bin-row-num:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-bin-row-sep {
    color: var(--text-muted, #6b6560);
    font-size: 0.78rem;
}

.wc-bin-row-shape {
    flex-shrink: 0;
    padding: 5px 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 4px;
    color: var(--text, #e8e3db);
    font-size: 0.78rem;
}

.wc-bin-row-del {
    flex-shrink: 0;
    color: var(--text-muted, #6b6560);
}

.wc-bin-row-del:hover {
    color: var(--danger, #e87a5d);
}

.wc-inline-color-pop {
    position: fixed;
    z-index: 10010;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px;
    background: var(--bg-card, var(--dw-surface, #1e1c24));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.12));
    border-radius: 6px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
    max-width: 220px;
}

/* ── Button Styles ── */
.wc-btn-primary {
    background: var(--primary, #c9995e) !important;
    color: #1c1a20 !important;
}

.wc-btn-primary:hover {
    background: #d4a56a !important;
}

.wc-btn-icon {
    padding: 6px !important;
    min-width: auto !important;
}

/* ── Analysis Modal ── */
.wc-groups-select-title {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 8px;
}

.wc-selected-points-info {
    background: rgba(201, 153, 94, 0.08);
    border: 1px solid rgba(201, 153, 94, 0.2);
    border-radius: 8px;
    padding: 12px 14px;
    margin-bottom: 12px;
}

.wc-selected-points-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--primary, #c9995e);
    margin-bottom: 6px;
}

.wc-selected-points-badge svg {
    width: 16px;
    height: 16px;
}

.wc-selected-points-details {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    line-height: 1.5;
}

.wc-groups-select-subtitle {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-top: 12px;
    margin-bottom: 6px;
    padding-top: 8px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-group-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.82rem;
    transition: background 0.15s;
}

.wc-group-checkbox:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
}

.wc-group-checkbox input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--primary, #c9995e);
}

.wc-analysis-presets {
    margin-top: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.wc-preset-label {
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
    margin-right: 4px;
}

.wc-preset-btn {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    transition: all 0.15s;
}

.wc-preset-btn:hover {
    background: rgba(201, 153, 94, 0.15);
    border-color: var(--primary, #c9995e);
    color: var(--text, #e8e3db);
}

.wc-analysis-response {
    margin-top: 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    padding-top: 12px;
}

.wc-analysis-response-header {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 8px;
}

.wc-analysis-response-content {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-radius: 8px;
    padding: 12px;
    font-size: 0.85rem;
    line-height: 1.5;
    max-height: 200px;
    overflow-y: auto;
}

.wc-analysis-loading {
    color: var(--text-dim, #948e84);
    font-style: italic;
}

.wc-analysis-error {
    color: var(--danger, #d4706a);
    padding: 12px;
    background: rgba(212, 112, 106, 0.1);
    border-radius: 8px;
    border: 1px solid rgba(212, 112, 106, 0.2);
}

/* Таймлайн шагов анализа — тот же визуальный язык, что «режим Агента»
   (.agent-timeline / .at-* в style.css): вертикальная линия + точки-состояния
   (готово = зелёная, идёт = синяя пульсирующая, ожидание = серая). Цвета через
   токены DWS с dark-фолбэками, поэтому работает и в тёмной, и в светлой теме. */
.wc-analysis-steps {
    margin-bottom: 16px;
    display: flex;
    flex-direction: column;
    gap: 0;
    border-top: 1px solid var(--border, rgba(232, 227, 219, 0.12));
    padding-top: 8px;
}

.wc-tl-step {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 2px 0 4px;
    font-size: 0.78rem;
    line-height: 1.3;
    transition: opacity 0.2s;
}

.wc-tl-marker {
    position: relative;
    display: flex;
    justify-content: center;
    width: 12px;
    flex-shrink: 0;
    padding-top: 3px;
}

/* Соединительная линия между маркерами (кроме последнего шага). Галочка и
   активная точка занимают по 12px, «ожидание» — 8px, отсюда две геометрии. */
.wc-tl-step:not(:last-child) .wc-tl-marker::after {
    content: '';
    position: absolute;
    top: 15px;
    left: 50%;
    transform: translateX(-50%);
    width: 1px;
    height: calc(100% + 3px);
    background: var(--border, rgba(232, 227, 219, 0.12));
}

.wc-tl-step.wc-tl-pending:not(:last-child) .wc-tl-marker::after {
    top: 11px;
    height: calc(100% + 7px);
}

.wc-tl-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    /* 2px-кольцо цветом поверхности «отрезает» точку от линии (как в агенте). */
    border: 2px solid var(--dw-surface, #1e1c24);
    box-shadow: 0 0 0 1px var(--border, rgba(232, 227, 219, 0.2));
}

.wc-tl-step.wc-tl-pending .wc-tl-dot { background: var(--text-muted, #6b6560); }

/* Выполненный шаг — зелёная галочка вместо точки (глиф из CSS, разметка та же).
   Держим в одном виде с .at-step.at-done в style.css: карточка анализа
   сознательно повторяет визуальный язык чата, и правки идут парой. */
.wc-tl-step.wc-tl-done .wc-tl-dot {
    width: 12px;
    height: 12px;
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--success, #5db87a);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

.wc-tl-step.wc-tl-done .wc-tl-dot::before { content: '\2713'; }

/* Точка «идёт сейчас» — сплошной цвет без обводки и дышащий ореол вместо
   угасания; margin добивает бокс до 12px галочки ради общего правила линии.
   Ореол задан фиксированной rgba (а не токеном): box-shadow нельзя собрать из
   var(--info) с прозрачностью, а полупрозрачный синий читается и в тёмной,
   и в светлой теме DWS. */
.wc-tl-step.wc-tl-active .wc-tl-dot {
    width: 10px;
    height: 10px;
    margin: 1px 0;
    background: var(--info, #6b9fd4);
    border: none;
    box-shadow: 0 0 0 3px rgba(107, 159, 212, 0.28);
    animation: wc-tl-pulse 1.4s ease-in-out infinite;
}

.wc-tl-body { flex: 1; min-width: 0; }

.wc-tl-line {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.wc-tl-text { flex: 1; min-width: 0; }
.wc-tl-step.wc-tl-done .wc-tl-text { color: var(--text-dim, #948e84); }
.wc-tl-step.wc-tl-active .wc-tl-text { color: var(--text, #e8e3db); }
.wc-tl-step.wc-tl-pending .wc-tl-text { color: var(--text-dim, #948e84); }

.wc-tl-duration {
    flex-shrink: 0;
    color: var(--text-muted, #6b6560);
    font-size: 0.72rem;
    font-family: 'SF Mono', monospace;
}

.wc-tl-detail {
    color: var(--text-muted, #6b6560);
    font-size: 0.75rem;
    margin-top: 2px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@keyframes wc-tl-pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(107, 159, 212, 0.28); }
    50%      { box-shadow: 0 0 0 6px rgba(107, 159, 212, 0.08); }
}

/* Thinking block */
.wc-thinking {
    margin: 12px 0;
    padding: 12px;
    background: rgba(107, 159, 212, 0.08);
    border: 1px solid rgba(107, 159, 212, 0.2);
    border-radius: 8px;
}

.wc-thinking-header {
    font-size: 0.78rem;
    color: var(--info, #6b9fd4);
    margin-bottom: 6px;
    font-weight: 500;
}

.wc-thinking-content {
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
    font-style: italic;
    line-height: 1.5;
}

/* Loading spinner */
.wc-analysis-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px;
    color: var(--text-dim, #948e84);
}

.wc-loading-spinner {
    width: 32px;
    height: 32px;
    border: 3px solid rgba(201, 153, 94, 0.2);
    border-top-color: var(--primary, #c9995e);
    border-radius: 50%;
    animation: wc-spin 0.8s linear infinite;
}

.wc-analysis-answer {
    color: var(--text, #e8e3db);
    line-height: 1.6;
    padding: 12px 0;
}

.wc-analysis-answer code {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
    padding: 2px 6px;
    border-radius: 4px;
    font-family: 'SF Mono', monospace;
    font-size: 0.82rem;
}

.wc-analysis-answer strong {
    color: var(--primary, #c9995e);
}

.wc-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid transparent;
    border-top-color: currentColor;
    border-radius: 50%;
    animation: wc-spin 0.8s linear infinite;
    margin-right: 4px;
}

@keyframes wc-spin {
    to { transform: rotate(360deg); }
}

/* ═══════════════════════════════════════════════════════════════
   IKR APPROVAL — согласование плана анализа
   ═══════════════════════════════════════════════════════════════ */

.wc-ikr-approval {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 10px;
    padding: 16px;
    max-width: 600px;
}

.wc-ikr-header {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--primary, #c9995e);
    font-weight: 600;
    margin-bottom: 16px;
    font-size: 0.95rem;
}

.wc-ikr-section {
    margin-bottom: 14px;
}

.wc-ikr-label {
    display: block;
    color: var(--text-dim, #948e84);
    font-size: 0.8rem;
    margin-bottom: 6px;
    font-weight: 500;
}

.wc-ikr-textarea {
    width: 100%;
    padding: 10px 12px;
    background: var(--bg, #1c1a20);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.9rem;
    font-family: inherit;
    resize: vertical;
    min-height: 60px;
    box-sizing: border-box;
}

.wc-ikr-textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-ikr-input {
    width: 100%;
    padding: 8px 10px;
    background: var(--bg, #1c1a20);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.85rem;
    font-family: inherit;
    box-sizing: border-box;
}

.wc-ikr-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-ikr-entities {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.wc-ikr-entity {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    background: var(--bg, #1c1a20);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.15s;
}

.wc-ikr-entity:hover {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}

.wc-ikr-entity input[type="checkbox"] {
    margin-top: 3px;
    accent-color: var(--primary, #c9995e);
}

.wc-ikr-entity-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.wc-ikr-entity-name {
    color: var(--text, #e8e3db);
    font-weight: 500;
    font-size: 0.88rem;
}

.wc-ikr-entity-desc {
    color: var(--text-dim, #948e84);
    font-size: 0.8rem;
    line-height: 1.35;
}

.wc-ikr-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 16px;
}

.wc-ikr-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.15s;
    font-family: inherit;
}

.wc-ikr-btn:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}

.wc-ikr-btn-primary {
    background: var(--primary, #c9995e);
    border-color: var(--primary, #c9995e);
    color: #1c1a20;
    font-weight: 500;
}

.wc-ikr-btn-primary:hover {
    background: #d4a46a;
    border-color: #d4a46a;
}

/* ═══════════════════════════════════════════════════════════════
   CHAT DIALOG — прикреплённая панель AI-анализа (справа)
   ═══════════════════════════════════════════════════════════════ */

/* Docked right panel inside wc-body */
.wc-chat-panel {
    flex-shrink: 0;
    width: 420px;
    min-width: 300px;
    max-width: 700px;
    border-left: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: var(--bg-card, var(--dw-surface, #1e1c24));
}

/* Chat resizer between canvas and chat panel */
.wc-chat-resizer {
    width: 5px;
    flex-shrink: 0;
    cursor: ew-resize;
    background: transparent;
    transition: background 0.15s;
    position: relative;
}

.wc-chat-modal {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.wc-chat-modal .wc-modal-header {
    flex-shrink: 0;
}

.wc-chat-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.wc-chat-clear-btn {
    font-size: 0.72rem !important;
    color: var(--text-muted, #6b6560) !important;
    opacity: 0.7;
    transition: opacity 0.15s;
}

.wc-chat-clear-btn:hover {
    opacity: 1;
    color: var(--danger, #d4706a) !important;
}

.wc-chat-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0 !important;
    max-height: none !important;
}

/* ═══ AI sidebar accordion sections (Context / Plan / Dialog) ═══ */
.wc-ai-section {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    min-height: 0;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-ai-section-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    cursor: pointer;
    font-size: 0.8rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--text-dim, #948e84);
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border-top: 1px solid rgba(var(--dw-tint, 255, 250, 243), 0.05);
    user-select: none;
    transition: color 0.15s, background 0.15s;
    flex-shrink: 0;
}

.wc-ai-section:first-child > .wc-ai-section-header {
    border-top: none;
}

.wc-ai-section-header:hover {
    color: var(--text, #e8e3db);
    background: rgba(201, 153, 94, 0.08);
}

.wc-ai-section.open > .wc-ai-section-header {
    color: var(--text, #e8e3db);
    background: rgba(201, 153, 94, 0.1);
    border-left: 2px solid var(--primary, #c9995e);
    padding-left: 14px;
}

.wc-ai-section.open > .wc-ai-section-header:hover {
    background: rgba(201, 153, 94, 0.14);
}

.wc-ai-section-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wc-ai-section-icon {
    font-size: 0.72rem;
    transition: transform 0.2s ease;
    display: inline-block;
    width: 10px;
    text-align: center;
}

.wc-ai-section.open > .wc-ai-section-header > .wc-ai-section-icon {
    transform: rotate(90deg);
}

.wc-ai-section-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.25s ease;
    min-height: 0;
}

.wc-ai-section.open > .wc-ai-section-body {
    grid-template-rows: 1fr;
}

.wc-ai-section-inner {
    overflow: hidden;
    min-height: 0;
}

.wc-ai-section.open > .wc-ai-section-body > .wc-ai-section-inner {
    overflow-y: auto;
    padding: 2px 16px 12px;
}

/* Dialog section expands to fill remaining panel height when open */
.wc-ai-section-dialog.open {
    flex: 1 1 auto;
    min-height: 0;
}

.wc-ai-section-dialog.open > .wc-ai-section-body {
    flex: 1 1 auto;
    min-height: 0;
}

.wc-ai-section-dialog.open > .wc-ai-section-body > .wc-ai-section-inner {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

/* Chat messages area */
.wc-chat-messages {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
}

/* Welcome screen */
.wc-chat-welcome {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px 16px;
    flex: 1;
}

.wc-chat-welcome-icon {
    color: var(--primary, #c9995e);
    opacity: 0.5;
    margin-bottom: 12px;
}

.wc-chat-welcome-icon svg {
    width: 32px;
    height: 32px;
}

.wc-chat-welcome-text {
    font-size: 0.88rem;
    color: var(--text-dim, #948e84);
    margin-bottom: 16px;
    text-align: center;
}

.wc-chat-welcome .wc-analysis-presets {
    justify-content: center;
    margin-top: 0;
}

/* Chat message bubbles */
.wc-chat-msg {
    display: flex;
    flex-direction: column;
    gap: 4px;
    animation: wc-fade-in 0.2s ease;
}

.wc-chat-msg.user {
    align-items: flex-end;
}

.wc-chat-msg.assistant {
    align-items: flex-start;
}

.wc-chat-msg-bubble {
    /* Раньше было 85% — слева/справа оставались широкие пустые поля,
       таблицы и длинные ответы тратили место зря. 98% оставляют только
       минимальный визуальный отступ от края, чтобы было видно границу
       баббла, не превращая его в полосу во всю ширину. */
    max-width: 98%;
    padding: 10px 14px;
    border-radius: 12px;
    font-size: 0.88rem;
    line-height: 1.6;
    word-break: break-word;
}

.wc-chat-msg.user .wc-chat-msg-bubble {
    background: var(--primary, #c9995e);
    color: #1c1a20;
    border-bottom-right-radius: 4px;
}

.wc-chat-msg.assistant .wc-chat-msg-bubble {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    color: var(--text, #e8e3db);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-bottom-left-radius: 4px;
}

/* Fallback-плашка: backend вернул пустой ответ или SSE 'done' пришёл без content.
   См. Docs/PLAN_AI_аналитик_пустой_ответ.md, задача A2. */
.wc-chat-msg.wc-chat-fallback-empty .wc-chat-msg-bubble {
    background: rgba(220, 170, 60, 0.10);
    border-color: rgba(220, 170, 60, 0.45);
    color: var(--text, #f4e6c8);
}

.wc-chat-msg-bubble code {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.1);
    padding: 1px 5px;
    border-radius: 3px;
    font-family: 'SF Mono', 'Consolas', monospace;
    font-size: 0.82rem;
}

/* Markdown-таблицы из ответов агента (render — _formatMarkdown).
   Чарт-агент часто отдаёт сводки в виде GFM-таблиц («Топ-5 по разнице», и т.п.) —
   raw-markdown в чате нечитаем, поэтому рендерим как настоящую HTML-таблицу. */

/* Враппер: ограничивает ширину бабла и даёт горизонтальный скролл, если
   контент таблицы всё равно не помещается. Без него длинные ячейки распирают
   bubble и весь ответ вываливается за границы диалога. */
.wc-chat-msg-bubble .wc-chat-table-wrap {
    max-width: 100%;
    overflow-x: auto;
    margin: 8px 0;
    /* Тонкая полоса прокрутки в духе тёмной темы */
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--dw-ink, 232, 227, 219), 0.20) transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.10));
    border-radius: 6px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
}
.wc-chat-msg-bubble .wc-chat-table-wrap::-webkit-scrollbar {
    height: 6px;
}
.wc-chat-msg-bubble .wc-chat-table-wrap::-webkit-scrollbar-thumb {
    background: rgba(var(--dw-ink, 232, 227, 219), 0.20);
    border-radius: 3px;
}

.wc-chat-msg-bubble .wc-chat-table {
    border-collapse: collapse;
    width: 100%;
    /* table-layout: auto оставляем (auto = браузер сам распределяет колонки
       по контенту); fixed не даёт нужного сжатия для разноширинных ячеек. */
    font-size: 0.78rem;
    line-height: 1.4;
}
.wc-chat-msg-bubble .wc-chat-table th,
.wc-chat-msg-bubble .wc-chat-table td {
    padding: 5px 8px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    text-align: left;
    vertical-align: top;
    /* Длинные значения (составные многословные категории) рвутся по словам,
       очень длинные неразрывные строки тоже могут рваться — иначе раздуют
       таблицу и пробьют враппер. */
    word-break: break-word;
    overflow-wrap: anywhere;
}
.wc-chat-msg-bubble .wc-chat-table th {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.06);
    font-weight: 600;
    color: var(--primary, #c9995e);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    /* nowrap убран: для длинных заголовков лучше перенос, чем растяжка
       таблицы за пределы бабла. Короткие заголовки не страдают. */
    white-space: normal;
}
/* Числовые ячейки лучше выравнивать вправо — но мы не знаем тип
   автоматически. Если markdown указал align (`---:` / `:---:`), inline
   style="text-align:..." применяется выше, в _formatMarkdown. Тут ничего. */
.wc-chat-msg-bubble .wc-chat-table tbody tr:last-child td {
    border-bottom: none;
}
.wc-chat-msg-bubble .wc-chat-table tbody tr:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
}

/* Заголовки внутри ответа агента (### / ## / # рендерятся как h4/h3/h2). */
.wc-chat-msg-bubble h2,
.wc-chat-msg-bubble h3,
.wc-chat-msg-bubble h4 {
    color: var(--primary, #c9995e);
    margin: 10px 0 4px;
    line-height: 1.3;
}
.wc-chat-msg-bubble h2 { font-size: 1rem; }
.wc-chat-msg-bubble h3 { font-size: 0.95rem; }
.wc-chat-msg-bubble h4 { font-size: 0.88rem; font-weight: 600; }
.wc-chat-msg-bubble h2:first-child,
.wc-chat-msg-bubble h3:first-child,
.wc-chat-msg-bubble h4:first-child { margin-top: 0; }

.wc-chat-msg-bubble strong {
    color: var(--primary, #c9995e);
}

.wc-chat-msg.assistant .wc-chat-msg-bubble strong {
    color: var(--primary, #c9995e);
}

.wc-chat-msg.user .wc-chat-msg-bubble strong {
    color: inherit;
}

/* Эпик 3.1 — PII privacy note under the user's outgoing message */
.wc-chat-privacy-note {
    font-size: 0.7rem;
    color: rgba(var(--dw-ink, 232, 227, 219), 0.7);
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.2);
    font-style: italic;
}

/* Эпик 4.2 — плашка «⚡ Ответ из кеша», показывается внутри assistant-баббла
   когда ответ восстановлен из клиентского кеша (Map, TTL 5 мин). */
.wc-chat-cache-note {
    font-size: 0.7rem;
    color: rgba(201, 153, 94, 0.85);
    margin-top: 4px;
    padding-top: 4px;
    border-top: 1px dashed rgba(201, 153, 94, 0.35);
    font-style: italic;
}

/* Эпик 3.2 — plashka under assistant's message with list of rejected
   chart_actions (валидатор actions-schema.js отбросил невалидные команды) */
.wc-chat-rejected-actions {
    margin-top: 8px;
    padding: 6px 10px;
    background: rgba(241, 196, 15, 0.08);
    border: 1px solid rgba(241, 196, 15, 0.28);
    border-radius: 6px;
    font-size: 0.72rem;
    color: rgba(var(--dw-ink, 232, 227, 219), 0.82);
}
.wc-chat-rejected-title {
    font-weight: 600;
    color: var(--warning, #f1c40f);
    margin-bottom: 4px;
}
.wc-chat-rejected-list {
    margin: 0;
    padding-left: 18px;
    list-style: disc;
}
.wc-chat-rejected-list li {
    margin: 2px 0;
    line-height: 1.35;
    word-break: break-word;
}

/* Эпик 3.3 — «Попросить переформатировать». Показывается когда LLM вернула
   команды без корректного ```chart_actions``` блока. */
.wc-chat-reformat-wrap {
    margin-top: 8px;
    padding: 8px 10px;
    background: rgba(52, 152, 219, 0.06);
    border: 1px dashed rgba(52, 152, 219, 0.35);
    border-radius: 6px;
    font-size: 0.72rem;
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
}
.wc-chat-reformat-hint {
    color: var(--text-muted, #6b6560);
    line-height: 1.35;
}
.wc-chat-reformat-btn {
    cursor: pointer;
    font-size: 0.72rem;
    padding: 4px 10px;
    border-radius: 4px;
    background: #3498db;
    color: #fff;
    border: 1px solid #2980b9;
    transition: background 0.15s ease;
}
.wc-chat-reformat-btn:hover:not(:disabled) {
    background: #2980b9;
}
.wc-chat-reformat-btn:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

/* Эпик 6.11 — кнопка «Записать как эталон» под ассистент-сообщением */
.wc-chat-etalon-btn {
    display: inline-block;
    margin-top: 8px;
    cursor: pointer;
    font-size: 0.72rem;
    padding: 4px 10px;
    border-radius: 4px;
    background: transparent;
    color: var(--primary, #c9995e);
    border: 1px dashed rgba(201, 153, 94, 0.5);
    transition: background 0.15s ease;
}
.wc-chat-etalon-btn:hover:not(:disabled) {
    background: rgba(201, 153, 94, 0.1);
}
.wc-chat-etalon-btn:disabled { cursor: not-allowed; opacity: 0.55; }

/* Timestamp */
.wc-chat-msg-time {
    font-size: 0.65rem;
    color: var(--text-muted, #6b6560);
    padding: 0 4px;
}
.wc-chat-msg-time-row {
    display: flex;
    align-items: center;
    gap: 4px;
}
.wc-chat-delete-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    border-radius: 3px;
    background: transparent;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s, color 0.15s, background 0.15s;
}
.wc-chat-msg:hover .wc-chat-delete-btn {
    opacity: 1;
}
.wc-chat-delete-btn:hover {
    color: var(--danger, #d4706a);
    background: rgba(212, 112, 106, 0.12);
}

/* Streaming/loading message */
.wc-chat-msg-loading {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
}

.wc-chat-msg-loading .wc-loading-spinner {
    width: 16px;
    height: 16px;
    border-width: 2px;
}

/* Steps inside assistant message */
.wc-chat-msg-steps {
    margin-bottom: 8px;
}

/* Chart actions badge */
/* Кнопка отмены применённой команды модели (v1.69.0, парная правка к графику
   1.80.0). Нейтральный, приглушённый вид: отмена — выход, а не второе главное
   действие, и спорить за внимание с самой командой она не должна. */
.wc-chat-action-undo {
    background: transparent !important;
    border-color: rgba(var(--dw-ink, 232, 227, 219), 0.20) !important;
    color: var(--text-dim, #948e84) !important;
    margin-left: 6px;
}
.wc-chat-action-undo:hover {
    border-color: var(--danger, #d4706a) !important;
    color: var(--danger, #d4706a) !important;
}
.wc-chat-action-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 8px;
    padding: 4px 10px;
    background: rgba(201, 153, 94, 0.12);
    border: 1px solid rgba(201, 153, 94, 0.25);
    border-radius: 16px;
    font-size: 0.72rem;
    color: var(--primary, #c9995e);
    cursor: pointer;
    transition: all 0.15s;
}

.wc-chat-action-badge:hover {
    background: rgba(201, 153, 94, 0.2);
}

.wc-chat-action-badge.applied {
    background: rgba(93, 184, 122, 0.12);
    border-color: rgba(93, 184, 122, 0.25);
    color: var(--success, #5db87a);
}
.wc-chat-action-badge.applied:hover {
    background: rgba(212, 112, 106, 0.15);
    border-color: rgba(212, 112, 106, 0.3);
    color: var(--danger, #d4706a);
}

.wc-chat-action-badge-group {
    background: rgba(107, 159, 212, 0.12);
    border-color: rgba(107, 159, 212, 0.25);
    color: var(--info, #6b9fd4);
    margin-left: 4px;
}

.wc-chat-action-badge-group:hover {
    background: rgba(107, 159, 212, 0.25);
}

/* T7.2-хр (график 1.81.0) — «→ В выборку» рядом с применённой командой модели.
   Цвет тот же, что у «Создать группу»: обе кнопки делают из отмеченного набора
   объект, который живёт дольше графика, и разными их красить не за что. */
.wc-chat-action-tosel {
    background: rgba(107, 159, 212, 0.12);
    border-color: rgba(107, 159, 212, 0.25);
    color: var(--info, #6b9fd4);
    margin-left: 4px;
}

.wc-chat-action-tosel:hover {
    background: rgba(107, 159, 212, 0.25);
}

/* T7.3 — вопрос о разрушительной команде модели. Выделен предупреждающим
   цветом намеренно: он стоит между командой и её применением, и потеряться
   среди обычных сообщений чата не должен. */
.wc-guard-prompt .wc-chat-msg-bubble {
    border: 1px solid rgba(212, 158, 106, 0.45);
    background: rgba(212, 158, 106, 0.10);
}

.wc-chat-msg-note {
    margin-top: 6px;
    font-size: 0.72rem;
    color: var(--text-muted, #9b958d);
}

/* Chat toolbar (style selector above input) */
.wc-chat-toolbar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px 6px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}

.wc-style-label {
    font-size: 0.75rem;
    color: var(--text-muted, #9b958d);
    white-space: nowrap;
}

.wc-style-select {
    flex: 1;
    padding: 4px 8px;
    /* Непрозрачный тёмный фон — иначе на некоторых рендерах <select> тянет
       системную светлую плашку, и светлый текст становится нечитаемым. */
    background-color: var(--bg-2, #2a262e);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.8rem;
    font-family: inherit;
    cursor: pointer;
    /* Принудительно тёмная цветовая схема для нативных элементов формы:
       стрелка-открывашка и popup-список options тоже становятся тёмными. */
    color-scheme: dark;
}

.wc-style-select:hover {
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.28));
}

.wc-style-select:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

/* Раскрывающийся список <option>: явно задаём тёмный фон и светлый текст,
   иначе браузер берёт системные дефолты (белый фон + унаследованный светлый
   текст из .wc-style-select → нечитаемо). */
.wc-style-select option {
    background-color: var(--bg-2, #2a262e);
    color: var(--text, #e8e3db);
}
.wc-style-select option:checked,
.wc-style-select option:hover {
    background-color: var(--primary, #c9995e);
    color: #1c1a20;
}

/* ── Паспорт запроса (T4.2 ТЗ ПАСПОРТА) ───────────────────────────────────
   Встаёт на место выпадающего «Стиль ответа», в ту же .wc-chat-toolbar —
   отступы, фон и разделительная линия наследуются от неё. Свёрнутая строка
   читается одной фразой; форма раскрывается по щелчку. */

.wc-passport-summary {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 6px;
    color: var(--text-dim, #948e84);
    font-size: 0.75rem;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: all 0.15s;
}

.wc-passport-summary:hover {
    background: rgba(201, 153, 94, 0.15);
    border-color: var(--primary, #c9995e);
    color: var(--text, #e8e3db);
}

.wc-passport-edit {
    flex-shrink: 0;
    opacity: 0.6;
}

/* Поле, значение которого взято из слов вопроса. Подчёркиванием, а не
   цветом: цвет в этой панели уже занят состоянием наведения. */
.wc-passport-from-q {
    text-decoration: underline dotted;
    text-underline-offset: 2px;
}

.wc-passport-form {
    flex-shrink: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 8px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}

.wc-passport-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 120px;
    flex: 1 1 120px;
}

.wc-passport-field > span {
    font-size: 0.7rem;
    color: var(--text-muted, #9b958d);
}

.wc-passport-field .wc-style-select {
    flex: none;
    width: 100%;
}

/* ── Строка «что применилось» и «Переспросить» (T4.4) ────────────────────
   Живёт под готовым ответом. Кнопки — по образцу .wc-preset-btn (готовые
   вопросы): тот же вид покоя, тот же радиус, та же реакция на наведение. */

.wc-applied-passport {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-applied-passport-line {
    font-size: 0.72rem;
    color: var(--text-muted, #9b958d);
    margin-bottom: 6px;
}

.wc-applied-passport-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Недоступность показываем приглушением, а не исчезновением: пропавшая
   кнопка читается как поломка, погашенная — как «уже применено». */
.wc-reask-btn:disabled {
    opacity: 0.4;
    cursor: default;
}

.wc-reask-btn:disabled:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    color: var(--text-dim, #948e84);
}

/* Chat input area */
.wc-chat-input-area {
    flex-shrink: 0;
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 8px 16px 12px 16px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}

.wc-chat-input-area textarea {
    flex: 1;
    padding: 10px 12px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 8px;
    color: var(--text, #e8e3db);
    font-size: 0.88rem;
    font-family: inherit;
    /* v1.70.0 — поле было высотой в ОДНУ строку (40px вместе с отступами), и
       собственная подсказка «Задайте вопрос или попросите выделить точки на
       графике…» в него не влезала: вторая строка обрезалась на середине
       (замечание владельца 17.08). Поле, в котором не видно даже приглашения,
       читается как сломанное. Три строки по умолчанию, до шести с прокруткой,
       и разрешено тянуть вручную — вопросы к модели бывают длинными. */
    resize: vertical;
    max-height: 180px;
    min-height: 76px;
    line-height: 1.4;
}

.wc-chat-input-area textarea:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-chat-send-btn {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    padding: 0 !important;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px !important;
}

.wc-chat-send-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Range highlight overlays on canvas */
.wc-range-overlay {
    pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════
   IKR SETTINGS — настройки плана анализа в модальном окне
   ═══════════════════════════════════════════════════════════════ */

.wc-ikr-settings {
    /* accordion section owns its own chrome; no top border needed here */
}

.wc-ikr-toggle {
    margin-bottom: 12px;
}

.wc-toggle-label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    color: var(--text-dim, #948e84);
    font-size: 0.85rem;
}

.wc-toggle-label input[type="checkbox"] {
    accent-color: var(--primary, #c9995e);
}

.wc-ikr-content {
    animation: wc-fade-in 0.2s ease;
}

@keyframes wc-fade-in {
    from { opacity: 0; transform: translateY(-5px); }
    to { opacity: 1; transform: translateY(0); }
}

.wc-ikr-hint {
    font-size: 0.75rem;
    color: var(--text-muted, #6b6560);
    margin-top: 4px;
}

.wc-entities-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 10px;
}

.wc-entity-item {
    display: flex;
    gap: 8px;
    align-items: center;
}

.wc-entity-input {
    flex: 1;
    padding: 8px 10px;
    background: var(--bg, #1c1a20);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    color: var(--text, #e8e3db);
    font-size: 0.85rem;
    font-family: inherit;
}

.wc-entity-input:focus {
    outline: none;
    border-color: var(--primary, #c9995e);
}

.wc-entity-remove {
    padding: 4px 8px !important;
    min-width: auto !important;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--text-muted, #6b6560);
}

.wc-entity-remove:hover {
    color: var(--danger, #d4706a);
}

.wc-btn-sm {
    padding: 6px 12px;
    font-size: 0.8rem;
}


/* ═══════════════════════════════════════════════════════════════
   TEXT DOCUMENT VIEWER — просмотрщик текстовых документов
   ═══════════════════════════════════════════════════════════════ */

.dw-doc-viewer-overlay {
    position: fixed;
    inset: 0;
    z-index: 9700;
    background: var(--bg, #1c1a20);
    display: flex;
    flex-direction: column;
    font-family: "Inter", system-ui, -apple-system, sans-serif;
    color: var(--text, #e8e3db);
    width: 100%;
    height: 100%;
}

.dw-doc-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    flex-shrink: 0;
}

.dw-doc-title {
    font-size: 0.95rem;
    font-weight: 600;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dw-doc-nav {
    display: flex;
    align-items: center;
    gap: 4px;
}

.dw-doc-nav-btn {
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 4px;
    padding: 4px 8px;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    font-size: 0.75rem;
    display: flex;
    align-items: center;
    gap: 4px;
    transition: all 0.15s;
}

.dw-doc-nav-btn:hover:not(:disabled) {
    border-color: var(--primary, #c9995e);
    color: var(--primary, #c9995e);
}

.dw-doc-nav-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.dw-doc-nav-info {
    font-size: 0.75rem;
    color: var(--text-dim, #948e84);
    padding: 0 8px;
}

.dw-doc-body {
    flex: 1;
    display: flex;
    overflow: hidden;
    min-height: 0; /* Fix flexbox overflow */
}

.dw-doc-content {
    flex: 1;
    overflow-y: auto;
    padding: 20px 24px;
    line-height: 1.7;
    font-size: 0.92rem;
    min-height: 0; /* Fix flexbox overflow */
}

.dw-doc-sidebar {
    width: 280px;
    border-left: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    display: flex;
    flex-direction: column;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
}

.dw-doc-sidebar-header {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
}

.dw-doc-matches {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}

.dw-doc-match {
    padding: 10px 12px;
    border-radius: 6px;
    margin-bottom: 6px;
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    cursor: pointer;
    transition: all 0.15s;
    border: 1px solid transparent;
}

.dw-doc-match:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    border-color: var(--border-hover, rgba(var(--dw-ink, 232, 227, 219), 0.13));
}

.dw-doc-match.active {
    border-color: var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.1));
}

.dw-doc-match-text {
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    line-height: 1.5;
}

.dw-doc-match-score {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    margin-top: 4px;
}

/* Highlight in document */
.dw-highlight {
    background: rgba(201, 153, 94, 0.25);
    padding: 1px 2px;
    border-radius: 2px;
}

.dw-highlight.active {
    background: var(--primary, #c9995e);
    color: #1c1a20;
}


/* ═══════════════════════════════════════════════════════════════
   CARD STATE INDICATORS — индикация состояния карточек
   ═══════════════════════════════════════════════════════════════ */

/* Карточка в контексте анализа */
.dw-card.in-context {
    border-color: var(--primary, #c9995e);
    box-shadow: 0 0 0 2px rgba(201, 153, 94, 0.2);
}

/* Карточка использована в последнем ответе */
.dw-card.used-in-answer {
    border-color: var(--success, #5db87a);
}

.dw-card.used-in-answer::after {
    content: '';
    position: absolute;
    top: -4px;
    right: -4px;
    width: 10px;
    height: 10px;
    background: var(--success, #5db87a);
    border-radius: 50%;
    border: 2px solid var(--bg, #1c1a20);
}

/* Badge с количеством строк/символов */
.dw-card-badge {
    position: absolute;
    bottom: 6px;
    right: 6px;
    font-size: 0.65rem;
    padding: 2px 5px;
    border-radius: 3px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.08);
    color: var(--text-muted, #6b6560);
}

/* Hover preview */
.dw-card-preview-popup {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 6px;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    z-index: 100;
    display: none;
    max-height: 200px;
    overflow-y: auto;
}

.dw-card:hover .dw-card-preview-popup {
    display: block;
}

.dw-card-preview-row {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 2px 0;
}

.dw-card-preview-col {
    color: var(--text, #e8e3db);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dw-card-preview-type {
    color: var(--text-muted, #6b6560);
    flex-shrink: 0;
}


/* ═══════════════════════════════════════════════════════════════
   CONNECTION TOOLTIP & CONTEXT MENU — связи между карточками
   ═══════════════════════════════════════════════════════════════ */

.dw-conn-tooltip {
    position: fixed;
    z-index: 9600;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 0.78rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
    pointer-events: none;
    min-width: 180px;
    max-width: 300px;
}

.dw-conn-tooltip-title {
    font-weight: 600;
    color: var(--text, #e8e3db);
    margin-bottom: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.dw-conn-tooltip-type {
    display: inline-block;
    font-size: 0.68rem;
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
}

.dw-conn-tooltip-row {
    display: flex;
    justify-content: space-between;
    color: var(--text-dim, #948e84);
    padding: 2px 0;
}

.dw-conn-tooltip-value {
    color: var(--text, #e8e3db);
}

/* Connection context menu */
.dw-conn-context-menu {
    position: fixed;
    z-index: 9700;
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 4px 0;
    min-width: 160px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}

/* Connection line styles по типам */
.dw-connections-svg path.conn-exact {
    stroke: var(--success, #5db87a);
    stroke-width: 2;
}

.dw-connections-svg path.conn-range {
    stroke: var(--info, #6b9fd4);
    stroke-width: 2;
}

.dw-connections-svg path.conn-fuzzy {
    stroke: #f59e0b;
    stroke-width: 2;
    stroke-dasharray: 6 3;
}


/* ═══════════════════════════════════════════════════════════════
   CONTEXT PREVIEW — превью контекста перед анализом
   ═══════════════════════════════════════════════════════════════ */

.dw-context-preview {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 12px;
}

.dw-context-preview-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.dw-context-preview-title {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
}

.dw-context-preview-toggle {
    font-size: 0.72rem;
    color: var(--primary, #c9995e);
    cursor: pointer;
    text-decoration: underline;
}

.dw-context-source {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 5px;
    margin-bottom: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    border: 1px solid transparent;
    cursor: pointer;
    transition: all 0.15s;
}

.dw-context-source:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}

.dw-context-source input[type="checkbox"] {
    accent-color: var(--primary, #c9995e);
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

.dw-context-source-icon {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
    flex-shrink: 0;
}

.dw-context-source-name {
    flex: 1;
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dw-context-source-meta {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    flex-shrink: 0;
}


/* ═══════════════════════════════════════════════════════════════
   GROUP COMPARISON — сравнение двух групп после lasso
   ═══════════════════════════════════════════════════════════════ */

.wc-compare-panel {
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--dw-surface-2, #242229);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 10px;
    padding: 14px 18px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
    z-index: 100;
    min-width: 320px;
    max-width: 500px;
}

.wc-compare-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.wc-compare-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}

.wc-compare-close {
    background: none;
    border: none;
    color: var(--text-dim, #948e84);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    display: flex;
}

.wc-compare-close:hover {
    color: var(--text, #e8e3db);
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}

.wc-compare-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.wc-compare-group {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 6px;
    padding: 10px 12px;
}

.wc-compare-group-header {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
}

.wc-compare-group-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}

.wc-compare-group-name {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}

.wc-compare-group-count {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
    margin-left: auto;
}

.wc-compare-stat {
    display: flex;
    justify-content: space-between;
    font-size: 0.75rem;
    padding: 2px 0;
    color: var(--text-dim, #948e84);
}

.wc-compare-stat-value {
    color: var(--text, #e8e3db);
    font-weight: 500;
}

.wc-compare-actions {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-compare-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.78rem;
    margin-top: 6px;
}

.wc-compare-table th,
.wc-compare-table td {
    padding: 4px 6px;
    text-align: right;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}

.wc-compare-table th:first-child,
.wc-compare-table td:first-child {
    text-align: left;
    color: var(--text-dim, #948e84);
}

.wc-compare-table thead th {
    font-weight: 600;
    color: var(--text-dim, #948e84);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.wc-compare-table .wc-compare-sel {
    color: var(--primary, #c9995e);
}

.wc-compare-table .wc-compare-oth {
    color: var(--text-muted, #6b6560);
}

.wc-compare-table tbody td {
    color: var(--text, #e8e3db);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.76rem;
}

.wc-compare-table .wc-compare-group-header td {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
    color: var(--text, #e8e3db);
    font-weight: 600;
    padding: 6px;
    font-family: inherit;
}

.wc-btn-compare {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: center;
    margin-top: 8px;
    width: 100%;
    padding: 6px 10px;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
    border: 1px solid var(--primary, #c9995e);
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.15s ease;
}

.wc-btn-compare:hover {
    background: var(--primary, #c9995e);
    color: var(--bg, #1c1a20);
}


/* ═══════════════════════════════════════════════════════════════
   GROUPINGS PANEL — панель найденных группировок
   ═══════════════════════════════════════════════════════════════ */

.dw-groupings-panel {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border-radius: 8px;
    padding: 12px;
    margin-top: 10px;
}

.dw-groupings-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.dw-groupings-title {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
}

.dw-grouping-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    margin-bottom: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    cursor: pointer;
    transition: all 0.15s;
}

.dw-grouping-item:hover {
    background: var(--bg-hover, rgba(var(--dw-tint, 255, 250, 243), 0.07));
}

.dw-grouping-item.active {
    border: 1px solid var(--primary, #c9995e);
    background: var(--primary-dim, rgba(201, 153, 94, 0.1));
}

.dw-grouping-col {
    flex: 1;
    font-size: 0.78rem;
    color: var(--text, #e8e3db);
}

.dw-grouping-improvement {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--success, #5db87a);
}

.dw-grouping-improvement.negative {
    color: var(--danger, #d4706a);
}

.dw-grouping-r2 {
    font-size: 0.68rem;
    color: var(--text-muted, #6b6560);
}


/* ═══════════════════════════════════════════════════════════════
   ONBOARDING HINTS — подсказки для пустого canvas
   ═══════════════════════════════════════════════════════════════ */

.dw-onboarding {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    pointer-events: none;
    max-width: 460px;
    z-index: 40;
}

.dw-onboarding-icon {
    color: var(--text-muted, #6b6560);
    margin-bottom: 16px;
    opacity: 0.6;
}

.dw-onboarding-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-dim, #948e84);
    margin-bottom: 8px;
}

.dw-onboarding-desc {
    font-size: 0.88rem;
    color: var(--text-muted, #6b6560);
    line-height: 1.6;
    margin-bottom: 20px;
}

.dw-onboarding-steps {
    text-align: left;
    display: inline-block;
}

.dw-onboarding-step {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px 0;
    font-size: 0.82rem;
    color: var(--text-dim, #948e84);
}

.dw-onboarding-step-num {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    color: var(--primary, #c9995e);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: 600;
    flex-shrink: 0;
}

.dw-onboarding-step-text {
    flex: 1;
    line-height: 1.4;
    padding-top: 2px;
}

.dw-onboarding-step svg {
    color: var(--text-muted, #6b6560);
    flex-shrink: 0;
    margin-top: 2px;
}

/* ─────────────────── Эпик 6.11 — «Лаборатория аналитика» ─────────────────── */

.al-fab {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 9990;
    background: var(--primary, #c9995e);
    color: var(--dw-surface, #1e1c24);
    border: none;
    border-radius: 999px;
    padding: 10px 16px 10px 12px;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.al-fab:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}
.al-fab:active { transform: translateY(0); }
.al-fab-text { font-size: 0.85rem; }

.al-modal {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.65);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10005;
    animation: wtvCtxFadeIn 0.12s ease;
}
.al-modal-content {
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 12px;
    width: 1100px;
    max-width: 96vw;
    height: 90vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.al-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.al-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text, #e8e3db);
    display: flex;
    align-items: center;
    gap: 8px;
}
.al-title-icon { font-size: 1.1rem; }
.al-btn-icon {
    background: transparent;
    border: none;
    color: var(--text-muted, #6b6560);
    font-size: 1.2rem;
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 4px;
}
.al-btn-icon:hover { color: var(--text, #e8e3db); background: rgba(var(--dw-tint, 255, 250, 243),0.06); }

.al-tabs {
    display: flex;
    gap: 0;
    padding: 0 12px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    background: rgba(0,0,0,0.18);
}
.al-tab {
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-muted, #6b6560);
    padding: 10px 14px;
    font-size: 0.85rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.al-tab:hover { color: var(--text, #e8e3db); }
.al-tab.active {
    color: var(--primary, #c9995e);
    border-bottom-color: var(--primary, #c9995e);
}
.al-tab-count {
    background: rgba(var(--dw-tint, 255, 250, 243),0.06);
    border-radius: 999px;
    padding: 1px 7px;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6560);
}
.al-tab.active .al-tab-count { background: var(--primary, #c9995e); color: var(--dw-surface, #1e1c24); }

.al-toolbar {
    display: flex;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    align-items: center;
}
.al-search { flex: 1; }
.al-search, .al-filter-profile, .al-filter-status {
    padding: 6px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243),0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.84rem;
    color-scheme: dark;
}
.al-filter-profile option,
.al-filter-status option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
.al-btn {
    padding: 6px 14px;
    background: var(--primary, #c9995e);
    color: var(--dw-surface, #1e1c24);
    border: none;
    border-radius: 5px;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
}
.al-btn:hover { filter: brightness(1.07); }
.al-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.al-btn-primary { background: var(--primary, #c9995e); color: var(--dw-surface, #1e1c24); }
.al-btn-ghost {
    background: transparent;
    color: var(--text, #e8e3db);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
}
.al-btn-ghost:hover { background: rgba(var(--dw-tint, 255, 250, 243),0.05); }
.al-btn-danger-ghost {
    background: transparent;
    color: var(--danger, #d96b6b);
    border: 1px solid rgba(217, 107, 107, 0.4);
}
.al-btn-danger-ghost:hover { background: rgba(217, 107, 107, 0.1); }

.al-body {
    flex: 1;
    display: flex;
    overflow: hidden;
    min-height: 0;
}
.al-list-section {
    width: 38%;
    min-width: 280px;
    max-width: 460px;
    border-right: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    overflow-y: auto;
    padding: 6px 0;
}
.al-editor-section {
    flex: 1;
    overflow-y: auto;
    padding: 14px 18px;
}
.al-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--text-muted, #6b6560);
    font-size: 0.85rem;
    line-height: 1.5;
}
.al-empty-editor p { margin: 6px 0; }
.al-empty-hint { font-size: 0.78rem; color: var(--text-dim, #948e84); }
.al-empty-disabled {
    /* Орчестратор отключён в config.json — пользователю нужна понятная плашка,
       а не пустой список «нет кейсов». */
    background: rgba(217, 184, 107, 0.08);
    border: 1px solid rgba(217, 184, 107, 0.25);
    border-radius: 6px;
    color: var(--warning, #f0d4a0);
    margin: 10px;
    padding: 14px 18px;
    line-height: 1.5;
    text-align: left;
}

.al-case-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.al-case-item {
    padding: 8px 16px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.04);
    cursor: pointer;
    transition: background 0.1s ease;
}
.al-case-item:hover { background: rgba(var(--dw-tint, 255, 250, 243),0.04); }
.al-case-item.active { background: rgba(201, 153, 94, 0.12); }
.al-case-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.al-case-status {
    font-size: 0.65rem;
    width: 8px;
    text-align: center;
}
.al-status-pass { color: var(--success, #6bd96b); }
.al-status-fail { color: var(--danger, #d96b6b); }
.al-status-not_run { color: var(--text-muted, #6b6560); }
.al-case-title {
    flex: 1;
    font-size: 0.86rem;
    color: var(--text, #e8e3db);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.al-case-profile {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    background: rgba(var(--dw-tint, 255, 250, 243),0.06);
    padding: 1px 6px;
    border-radius: 3px;
}
.al-case-meta {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-top: 4px;
    padding-left: 16px;
}
.al-case-meta-dim {
    font-size: 0.7rem;
    color: var(--text-muted, #6b6560);
    font-style: italic;
}
.al-tag-chip {
    font-size: 0.7rem;
    color: var(--text-dim, #948e84);
    background: rgba(var(--dw-tint, 255, 250, 243),0.05);
    border-radius: 3px;
    padding: 1px 6px;
}

/* Editor */
.al-editor { display: flex; flex-direction: column; gap: 14px; }
.al-editor-header { display: flex; flex-direction: column; gap: 8px; }
.al-editor-title-row { display: flex; gap: 8px; }
.al-input, .al-select, .al-textarea {
    padding: 6px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243),0.04);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.1));
    border-radius: 5px;
    color: var(--text, #e8e3db);
    font-size: 0.86rem;
    font-family: inherit;
    width: 100%;
    box-sizing: border-box;
    color-scheme: dark;
}
.al-select option,
.al-input-profile option {
    background: var(--dw-surface, #1e1c24);
    color: var(--text, #e8e3db);
}
/* Native datepicker / number-spinner на тёмной теме (для будущих use-case'ов) */
.al-input::-webkit-calendar-picker-indicator,
.al-input::-webkit-inner-spin-button {
    filter: invert(0.7);
}
.al-textarea { resize: vertical; min-height: 56px; }
.al-input-title { flex: 1; }
.al-input-profile { width: 160px; }
.al-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
}
.al-label {
    display: block;
    font-size: 0.78rem;
    color: var(--text-muted, #6b6560);
    margin-bottom: 4px;
}
.al-editor-section-block {}
.al-grid-two {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.al-editor-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-top: 8px;
    border-top: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.06);
}
.al-spacer { flex: 1; }
.al-editor-errors {
    background: rgba(217, 107, 107, 0.1);
    border: 1px solid rgba(217, 107, 107, 0.35);
    border-radius: 5px;
    padding: 8px 12px;
    color: var(--danger, #f0a0a0);
    font-size: 0.82rem;
}
.al-editor-errors ul { margin: 0; padding-left: 18px; }

/* Result panel */
.al-result-panel {
    margin-top: 12px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 6px;
    padding: 12px;
    background: rgba(0,0,0,0.18);
}
.al-result-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.86rem;
    color: var(--text, #e8e3db);
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.07);
    margin-bottom: 8px;
}
.al-result-badge {
    font-size: 0.72rem;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 4px;
}
.al-result-pass .al-result-badge { background: #6bd96b; color: var(--dw-surface, #1e1c24); }
.al-result-fail .al-result-badge { background: #d96b6b; color: var(--dw-surface, #1e1c24); }
.al-result-section { margin-bottom: 8px; }
.al-result-section-title {
    font-size: 0.78rem;
    color: var(--text-muted, #6b6560);
    margin-bottom: 4px;
}
.al-result-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.al-result-items li {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
}
.al-result-bullet { width: 14px; text-align: center; }
.al-result-ok { color: var(--text, #e8e3db); }
.al-result-ok .al-result-bullet { color: var(--success, #6bd96b); }
.al-result-bad { color: var(--danger, #f0a0a0); }
.al-result-bad .al-result-bullet { color: var(--danger, #d96b6b); }
.al-result-detail {
    font-size: 0.74rem;
    color: var(--text-muted, #6b6560);
    margin-left: auto;
}
.al-result-actual {
    margin-top: 12px;
    border-top: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.07);
    padding-top: 8px;
}
.al-result-actual summary {
    font-size: 0.78rem;
    color: var(--text-muted, #6b6560);
    cursor: pointer;
}
.al-result-actual-text, .al-result-actions-json {
    background: rgba(0,0,0,0.3);
    border-radius: 4px;
    padding: 8px;
    color: var(--text-dim, #948e84);
    font-size: 0.76rem;
    max-height: 240px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}
.al-result-actions-title { margin-top: 6px; font-size: 0.78rem; color: var(--text-muted, #6b6560); }

/* Suite bar / report */
.al-suite-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.al-suite-info { color: var(--text-muted, #6b6560); font-size: 0.82rem; }
.al-suite-bar .al-suite-run { margin-left: auto; }

.al-suite-report {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10010;
}
.al-suite-report-content {
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    border-radius: 12px;
    width: 760px;
    max-width: 92vw;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.al-suite-report-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.al-suite-report-title { font-size: 1rem; font-weight: 600; color: var(--text, #e8e3db); }
.al-suite-report-body { padding: 16px 18px; overflow-y: auto; }
.al-suite-summary {
    display: flex;
    gap: 18px;
    padding-bottom: 12px;
    border-bottom: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.07);
    margin-bottom: 12px;
}
.al-suite-stat {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
.al-suite-stat-num { font-size: 1.6rem; font-weight: 700; color: var(--text, #e8e3db); }
.al-suite-stat-label { font-size: 0.74rem; color: var(--text-muted, #6b6560); margin-top: 2px; }
.al-suite-stat-pass .al-suite-stat-num { color: var(--success, #6bd96b); }
.al-suite-stat-fail .al-suite-stat-num { color: var(--danger, #d96b6b); }

.al-suite-regress {
    border-radius: 5px;
    padding: 8px 12px;
    margin-bottom: 8px;
    font-size: 0.82rem;
}
.al-suite-regress-bad {
    background: rgba(217, 107, 107, 0.12);
    border: 1px solid rgba(217, 107, 107, 0.35);
    color: var(--danger, #f0a0a0);
}
.al-suite-regress-good {
    background: rgba(107, 217, 107, 0.12);
    border: 1px solid rgba(107, 217, 107, 0.35);
    color: var(--success, #a0d8a0);
}
.al-suite-missing {
    background: rgba(var(--dw-tint, 255, 250, 243),0.06);
    border-radius: 5px;
    padding: 6px 10px;
    margin-bottom: 8px;
    color: var(--text-muted, #6b6560);
    font-size: 0.8rem;
}
.al-suite-fails-title {
    font-size: 0.84rem;
    color: var(--text, #e8e3db);
    margin-bottom: 6px;
}
.al-suite-fails-empty { color: var(--text-muted, #6b6560); font-size: 0.84rem; padding: 4px 0; }
.al-suite-fail-item {
    margin-bottom: 8px;
    padding: 8px 10px;
    background: rgba(var(--dw-tint, 255, 250, 243),0.04);
    border-left: 2px solid #d96b6b;
    border-radius: 0 4px 4px 0;
}
.al-suite-fail-item strong { color: var(--primary, #c9995e); }
.al-suite-reasons {
    margin: 4px 0 0;
    padding-left: 18px;
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}
.al-suite-error {
    margin-top: 4px;
    color: var(--danger, #f0a0a0);
    font-size: 0.76rem;
}

/* Toast */
.al-toast {
    position: fixed;
    right: 20px;
    bottom: 80px;
    background: var(--dw-surface, #1e1c24);
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.18));
    color: var(--text, #e8e3db);
    padding: 10px 14px;
    border-radius: 6px;
    font-size: 0.82rem;
    z-index: 10020;
    box-shadow: 0 4px 12px rgba(0,0,0,0.5);
    animation: wtvCtxFadeIn 0.18s ease;
}
.al-toast-error {
    border-color: rgba(217, 107, 107, 0.45);
    color: var(--danger, #f0a0a0);
}

/* ── Multi-version selector в Suite-bar (Эпик 8.4) ─────────────────── */
.al-suite-bar { flex-wrap: wrap; }
.al-suite-versions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
}
.al-suite-vers-block {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}
.al-suite-vers-prof {
    color: var(--text-muted, #6b6560);
    font-size: 0.78rem;
    margin-right: 4px;
}
.al-suite-vers-hint {
    color: var(--text-dim, #948e84);
    font-size: 0.76rem;
    font-style: italic;
}
.al-suite-vers-chk {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    border-radius: 4px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.08);
    font-size: 0.8rem;
    color: var(--text, #e8e3db);
    cursor: pointer;
}
.al-suite-vers-chk:hover { background: rgba(var(--dw-tint, 255, 250, 243), 0.08); }
.al-suite-vers-chk-active {
    border-color: rgba(107, 217, 107, 0.4);
    background: rgba(107, 217, 107, 0.08);
}
.al-suite-vers-name { font-weight: 500; }
.al-suite-vers-badge {
    color: var(--success, #6bd96b);
    font-size: 0.68rem;
    margin-left: 2px;
}

/* ── «Сделать активной» в отчёте (Эпик 8.5/8.8) ────────────────────── */
.al-suite-active-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.07);
}
.al-suite-active-tag {
    color: var(--text-muted, #6b6560);
    font-size: 0.84rem;
}
.al-suite-active-tag strong { color: var(--text, #e8e3db); }
.al-suite-active-marker {
    color: var(--success, #6bd96b);
    font-size: 0.84rem;
    font-weight: 600;
}
.al-btn-make-active {
    font-size: 0.78rem;
    padding: 4px 10px;
}

/* ── Эпик 8.10: прогресс, эталон, пропуски, подсказки ─────────────── */

/* Прогресс-бар фонового прогона (POST /test-suite/run-async + поллинг). */
.al-progress {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 16px 12px;
    border-top: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.08);
}
.al-progress-track {
    flex: 1 1 auto;
    height: 6px;
    min-width: 120px;
    border-radius: 3px;
    background: rgba(var(--dw-ink, 232, 227, 219), 0.10);
    overflow: hidden;
}
.al-progress-fill {
    height: 100%;
    width: 0%;
    border-radius: 3px;
    background: var(--accent, #c9995e);
    transition: width 240ms ease;
}
.al-progress-label {
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
    white-space: nowrap;
}
.al-progress-current {
    font-size: 0.78rem;
    color: var(--text-muted, #6b6560);
    max-width: 320px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.al-progress-cancel { font-size: 0.78rem; padding: 4px 10px; }

/* Закреплённый эталонный прогон. */
.al-baseline-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding-bottom: 10px;
    margin-bottom: 10px;
    border-bottom: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.07);
}
.al-baseline-tag { font-size: 0.82rem; color: var(--text-muted, #6b6560); }
.al-baseline-none { font-size: 0.82rem; color: var(--text-dim, #948e84); font-style: italic; }
.al-btn-pin-baseline,
.al-btn-unpin-baseline { font-size: 0.78rem; padding: 4px 10px; }

/* Технические аварии и отмена — жёлтые, а не красные: это не провал промпта. */
.al-suite-regress-warn {
    background: rgba(217, 184, 107, 0.08);
    border: 1px solid rgba(217, 184, 107, 0.25);
    color: var(--warning, #f0d4a0);
    border-radius: 6px;
    padding: 8px 12px;
    margin-bottom: 10px;
    font-size: 0.84rem;
}
.al-suite-stat-err .al-suite-stat-num { color: var(--warning, #f0d4a0); }
.al-suite-stat-skip .al-suite-stat-num { color: var(--text-muted, #6b6560); }
.al-suite-active-locked {
    color: var(--text-muted, #6b6560);
    font-weight: 500;
}

/* Пропущенная ячейка матрицы: «не прогонялся» ≠ «провалился». */
.al-mx-cell-skip {
    background: rgba(var(--dw-ink, 232, 227, 219), 0.04);
    color: var(--text-dim, #948e84);
}
.al-mx-vh-extra { color: var(--text-dim, #948e84); }

/* Подсказка по синтаксису ожиданий в редакторе кейса. */
.al-hint {
    margin-top: 4px;
    font-size: 0.75rem;
    line-height: 1.45;
    color: var(--text-muted, #6b6560);
}
.al-hint code {
    background: rgba(var(--dw-ink, 232, 227, 219), 0.08);
    border-radius: 3px;
    padding: 1px 4px;
    font-size: 0.72rem;
}
.al-from-dialog { font-size: 0.8rem; }
.al-from-dialog:disabled { opacity: 0.45; cursor: not-allowed; }
.al-btn-copy { font-size: 0.8rem; }

/* ── Matrix отчёт (Эпик 8.4) ──────────────────────────────────────── */
.al-suite-report-content-matrix {
    width: 1100px;
    max-width: 96vw;
}
.al-suite-regress-stable {
    background: rgba(180, 180, 180, 0.08);
    border: 1px solid rgba(180, 180, 180, 0.25);
    color: var(--text-muted, #b8b3aa);
}
.al-mx-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    padding-bottom: 12px;
    border-bottom: 1px dashed rgba(var(--dw-ink, 232, 227, 219), 0.07);
    margin-bottom: 12px;
}
.al-mx-summary-block {
    min-width: 180px;
    padding: 8px 12px;
    background: rgba(var(--dw-tint, 255, 250, 243), 0.03);
    border-radius: 6px;
}
.al-mx-summary-name {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--text, #e8e3db);
    margin-bottom: 4px;
}
.al-mx-summary-line {
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
}
.al-mx-summary-pass { color: var(--success, #6bd96b); font-weight: 700; }
.al-mx-summary-faint { color: var(--text-muted, #6b6560); font-size: 0.74rem; }

.al-mx-delta { margin-bottom: 12px; }

.al-mx-grid-wrap {
    overflow-x: auto;
    margin-top: 8px;
}
.al-mx-grid {
    border-collapse: collapse;
    width: 100%;
}
.al-mx-grid th,
.al-mx-grid td {
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.1);
    padding: 8px 10px;
    text-align: left;
    vertical-align: top;
}
.al-mx-case-h {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    color: var(--text, #e8e3db);
    width: 28%;
}
.al-mx-vh {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.05);
    color: var(--text, #e8e3db);
    text-align: center;
    min-width: 130px;
}
.al-mx-vh-name { font-weight: 600; font-size: 0.84rem; margin-bottom: 4px; }
.al-mx-vh-stat { font-size: 0.72rem; color: var(--text-muted, #6b6560); margin-bottom: 6px; }
.al-mx-vh-active { display: flex; justify-content: center; }
.al-mx-vh-active .al-btn-make-active-col {
    font-size: 0.72rem;
    padding: 3px 8px;
}

.al-mx-case {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.02);
    color: var(--text, #e8e3db);
}
.al-mx-case-id { font-size: 0.82rem; margin-bottom: 2px; }
.al-mx-case-id strong { color: var(--primary, #c9995e); }
.al-mx-case-title { font-size: 0.78rem; color: var(--text-muted, #6b6560); margin-bottom: 4px; }
.al-mx-case-tags { display: flex; flex-wrap: wrap; gap: 2px; }

.al-mx-cell {
    text-align: center;
    cursor: pointer;
    transition: background 0.1s;
}
.al-mx-cell:hover { filter: brightness(1.15); }
.al-mx-cell-pass {
    background: rgba(107, 217, 107, 0.18);
    color: var(--success, #b3eab3);
}
.al-mx-cell-fail {
    background: rgba(217, 107, 107, 0.18);
    color: var(--danger, #f0a0a0);
}
.al-mx-cell-warn {
    background: rgba(217, 184, 107, 0.18);
    color: var(--warning, #f0d4a0);
}
.al-mx-cell-icon { font-size: 1.1rem; line-height: 1; }
.al-mx-cell-score { font-size: 0.72rem; margin-top: 2px; opacity: 0.9; }

.al-mx-detail-row td { padding: 0; background: rgba(0, 0, 0, 0.18); }
.al-mx-detail {
    padding: 10px 14px;
    font-size: 0.82rem;
    color: var(--text, #e8e3db);
}
.al-mx-detail-head { margin-bottom: 6px; color: var(--text-muted, #b8b3aa); }
.al-mx-detail-head strong { color: var(--text, #e8e3db); }
.al-mx-detail-err { color: var(--danger, #f0a0a0); margin-bottom: 4px; }
.al-mx-detail-reasons {
    margin: 4px 0 8px;
    padding-left: 18px;
    color: var(--text-dim, #948e84);
    font-size: 0.78rem;
}
.al-mx-detail-actual { margin-top: 6px; }
.al-mx-detail-actual summary {
    cursor: pointer;
    color: var(--text-muted, #6b6560);
    font-size: 0.78rem;
}
.al-mx-detail-actual-text {
    margin: 6px 0 0;
    padding: 8px 10px;
    background: rgba(0, 0, 0, 0.25);
    border-radius: 4px;
    font-family: monospace;
    font-size: 0.74rem;
    color: var(--text, #e8e3db);
    white-space: pre-wrap;
    max-height: 280px;
    overflow-y: auto;
}
.al-mx-detail-actions {
    margin: 6px 0 0;
    padding: 8px 10px;
    background: rgba(0, 0, 0, 0.2);
    border-radius: 4px;
    font-family: monospace;
    font-size: 0.7rem;
    color: var(--text-muted, #b8b3aa);
}

/* ═══ Distribution mode (workspace-chart) ═══ */
.wc-dist-toggles {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 6px;
    padding-left: 8px;
    border-left: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.15);
}
.wc-dist-toggles .wc-btn {
    font-size: 11px;
    padding: 4px 8px;
}
.wc-dist-method-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    padding: 4px 0;
}
.wc-radio-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 12px;
    color: var(--text, #d8d3ca);
    user-select: none;
}
.wc-radio-label input[type="radio"] {
    cursor: pointer;
    accent-color: var(--primary, #c9995e);
    margin: 0;
}
#wcDistRangesList {
    max-height: 240px;
    overflow-y: auto;
    margin-bottom: 6px;
}
#wcDistColInfo {
    margin-top: 4px;
    color: var(--text-dim, #948e84);
    font-size: 11px;
}

/* Per-bar color picker popover */
.wc-dist-color-picker {
    position: fixed;
    z-index: 10000;
    background: var(--dw-surface, #1c1a20);
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.18);
    border-radius: 6px;
    padding: 10px 12px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    min-width: 240px;
    color: var(--text, #e8e3db);
    font-size: 12px;
}
.wc-dist-color-picker-title {
    font-weight: 500;
    margin-bottom: 8px;
    color: var(--text, #d8d3ca);
    font-size: 11px;
    border-bottom: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.07);
    padding-bottom: 6px;
}
.wc-dist-color-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 4px;
    margin-bottom: 8px;
}
.wc-dist-color-swatch {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 3px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: border-color 0.1s;
}
.wc-dist-color-swatch:hover {
    border-color: rgba(var(--dw-ink, 232, 227, 219), 0.45);
}
.wc-dist-color-swatch.active {
    border-color: var(--text, #e8e3db);
}
.wc-dist-color-row {
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.wc-dist-color-row input[type="color"] {
    width: 32px;
    height: 22px;
    padding: 0;
    border: 1px solid rgba(var(--dw-ink, 232, 227, 219), 0.18);
    border-radius: 3px;
    cursor: pointer;
    background: transparent;
}
.wc-dist-color-actions {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

/* ── ТЗ КАРТОЧКИ ГРАФИКОВ, Этап 4: окно-модалка карточки анализа ── */
.dw-analysis-modal {
    width: min(720px, 94vw);
    max-width: 720px;
    max-height: 88vh;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.dw-analysis-modal .dw-dialog-title {
    margin-bottom: 0;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-analysis-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.dw-analysis-modal .dw-status-bar {
    flex-shrink: 0;
    border-top: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
}
.dw-analysis-modal .dw-context-preview {
    max-height: 200px;
    overflow-y: auto;
}
.dw-an-history {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.dw-an-turn {
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 0.84rem;
    line-height: 1.5;
}
.dw-an-turn-user {
    background: var(--primary-dim, rgba(201, 153, 94, 0.15));
    border: 1px solid rgba(201, 153, 94, 0.25);
    color: var(--text, #e8e3db);
}
.dw-an-turn-ai {
    background: var(--bg-card, rgba(var(--dw-tint, 255, 250, 243), 0.04));
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.07));
    color: var(--text, #e8e3db);
}
.dw-an-turn-tag {
    display: block;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-dim, #948e84);
    margin-bottom: 4px;
}
.dw-an-turn-ai .dw-result-text strong { color: var(--primary, #c9995e); }

/* ── Оркестратор-фикс: карточка-источник без живой DuckDB-таблицы ── */
.dw-card--broken {
    border-color: var(--danger, #d9755a) !important;
    box-shadow: 0 0 0 1px rgba(217, 117, 90, 0.45);
}
.dw-card--broken::after {
    content: "источник недоступен";
    position: absolute;
    left: 8px;
    right: 8px;
    bottom: 6px;
    font-size: 0.64rem;
    color: var(--danger, #d9755a);
    background: rgba(217, 117, 90, 0.14);
    border-radius: 4px;
    padding: 2px 6px;
    text-align: center;
    pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   СВЕТЛАЯ ТЕМА Data Workspace
   Класс .dw-theme-light висит на <body>, но добавляется/снимается строго
   синхронно с видимостью DWS-оверлея (см. _applyDwTheme в workspace-canvas.js),
   поэтому переопределение токенов не протекает в основной чат.

   • Палитра шрифтов согласована с основной темой сайта (#2d3748 / #718096).
   • Акцент — фирменная бронза DWS, затемнённая до #b07d3f для контраста на белом.
   • Полупрозрачные «осветляющие» заливки (--dw-tint / --dw-ink) переведены
     в «затемняющие», глубокие тёмные поверхности (--dw-deep) — в светлые.
   ═══════════════════════════════════════════════════════════════════════ */
/* Второй селектор — полоса свёрнутых окон. Она живёт в document.body и
   остаётся на экране, когда оверлей DWS свёрнут: класс с <body> в этот момент
   снимается (иначе токены протекают в чат), поэтому трей носит его на себе и
   получает те же токены самостоятельно. */
body.dw-theme-light,
.dw-min-viewers-tray.dw-theme-light {
    /* — базовые токены DWS — */
    --bg: #eceff3;
    --bg-card: #ffffff;
    --bg-hover: rgba(45, 55, 72, 0.05);
    --text: #2d3748;
    --text-dim: #718096;
    --text-muted: #a0aec0;
    --border: rgba(45, 55, 72, 0.16);
    --border-hover: rgba(45, 55, 72, 0.28);
    --primary: #b07d3f;
    --primary-dim: rgba(176, 125, 63, 0.15);
    --success: #2f9e6b;
    --info: #3182ce;
    --danger: #c53030;
    --warning: #c2410c;

    /* — RGB-каналы для полупрозрачных заливок (см. var-изацию) — */
    --dw-tint: 45, 55, 72;     /* было светлое осветление → стало тёмное затемнение */
    --dw-ink: 45, 55, 72;      /* границы / сетка / разделители / скроллбары */
    --dw-deep: 255, 255, 255;  /* минимапа / тултипы / тулбары графика / бейджи */

    /* — сплошные приподнятые поверхности — */
    --dw-surface: #ffffff;     /* диалоги, панель, меню, выпадашки */
    --dw-surface-2: #ffffff;   /* контекстные меню, тосты */
    --dw-input-bg: #ffffff;    /* поля ввода диалогов */

    /* — legacy-имена из инлайн-диалогов и бейджей table-viewer/canvas — */
    --surface: #ffffff;
    --muted: #718096;
    --fg: #2d3748;          /* var(--fg) в .wtv-role-badge (сводка осей X/Y/CLASS) и т.п. */
}

/* Тулбары — чистый белый для отделения от холста */
body.dw-theme-light .dw-toolbar,
body.dw-theme-light .wtv-toolbar,
body.dw-theme-light .wc-toolbar {
    background: #ffffff;
}

/* Primary-кнопка: белый текст на бронзе + насыщенный hover (вместо светлого тана) */
body.dw-theme-light .dw-btn-primary,
body.dw-theme-light .wc-btn-primary {
    color: #ffffff;
}
body.dw-theme-light .dw-btn-primary:hover,
body.dw-theme-light .wc-btn-primary:hover {
    background: #9c6c34;
    color: #ffffff;
}

/* Маркеры шагов / done — белый текст на зелёном */
body.dw-theme-light .dw-step-marker.done {
    color: #ffffff;
}

/* Предупреждения связей/JOIN — светло-коралловый текст не читается на белом */
body.dw-theme-light .dw-conn-stats-warn,
body.dw-theme-light .dw-join-keywarn {
    color: #b45309;
}

/* Тосты/контекстные меню/выпадашки на белом — тонкая рамка для отделения */
body.dw-theme-light .dw-toast,
body.dw-theme-light .dw-context-menu,
body.dw-theme-light .wtv-ctx-menu,
body.dw-theme-light .wtv-color-dropdown,
body.dw-theme-light .wc-select {
    border: 1px solid var(--border);
}

/* Активная кнопка-переключатель темы */
body.dw-theme-light .dw-btn.dw-theme-toggle {
    color: var(--primary);
}

/* ── Таблица: на белом исходные границы (alpha 0.04) не видны — усиливаем
      и добавляем вертикальную сетку для читаемости столбцов ── */
body.dw-theme-light .wtv-td,
body.dw-theme-light .wtv-td-num {
    border-bottom-color: rgba(45, 55, 72, 0.14);
    border-right: 1px solid rgba(45, 55, 72, 0.07);
}
body.dw-theme-light .wtv-th,
body.dw-theme-light .wtv-th-num {
    border-bottom: 1px solid rgba(45, 55, 72, 0.28);
    border-right: 1px solid rgba(45, 55, 72, 0.10);
}
/* Сплошной фон закреплённой шапки в светлой теме (см. --wtv-th-bg в
   .wtv-overlay). Задаём на том же элементе, что и тёмный дефолт, — иначе
   объявление на .wtv-overlay, как более близкое к узлу, перебило бы токен
   темы с body. */
body.dw-theme-light .wtv-overlay {
    --wtv-th-bg: #e2e6ec;
    --wtv-th-bg-hover: #d6dbe3;
}
body.dw-theme-light .wtv-table tbody tr:hover td {
    background: rgba(45, 55, 72, 0.05);
}
body.dw-theme-light .dw-inline-table td {
    border-bottom-color: rgba(45, 55, 72, 0.10);
}

/* ── Активные вкладки представлений: бледные тинты на белом плохо читаются ── */
body.dw-theme-light .wtv-view-tab-table.active {
    background: rgba(49, 130, 206, 0.12);
    border-color: rgba(49, 130, 206, 0.35);
}
body.dw-theme-light .wtv-view-tab-text.active {
    background: rgba(47, 158, 107, 0.13);
    border-color: rgba(47, 158, 107, 0.35);
}
body.dw-theme-light .wtv-view-tab.active {
    border-color: rgba(45, 55, 72, 0.18);
}

/* ── Чипы ролей осей X/Y/CLASS в шапке: неактивные на --text-muted (#a0aec0)
      слишком бледные на белом. Активные оставляем бронзовыми (:not(.active)). ── */
body.dw-theme-light .wtv-role-chip:not(.active) {
    color: var(--text-dim);
}

/* ── Нативные <select> и поля ввода: цветовая схема формы ───────────────
      В тёмной теме на них выставлен color-scheme: dark — браузер рисует
      тёмными и стрелку-открывашку, и popup-список, и его скроллбар.
      На белом фоне это выглядит чужеродно, а в части сборок Chrome ещё и
      перекрашивает текст опций в светлый (светлое-на-белом = нечитаемо). ── */
body.dw-theme-light .dw-dialog select,
body.dw-theme-light .dw-dialog input[type="number"],
body.dw-theme-light .dw-dialog input[type="text"],
body.dw-theme-light .wc-style-select,
body.dw-theme-light .al-input,
body.dw-theme-light .al-select,
body.dw-theme-light .al-textarea,
body.dw-theme-light .al-search,
body.dw-theme-light .al-filter-profile,
body.dw-theme-light .al-filter-status {
    color-scheme: light;
}

/* ── Селектор пресета промпта в чате графика ────────────────────────────
      Опирался на var(--bg-2), которого в светлой теме нет → браузер брал
      захардкоженный тёмный фолбэк #2a262e, а текст шёл от var(--text)
      = #2d3748 → тёмное на тёмном, не читалось ни в поле, ни в списке. ── */
body.dw-theme-light .wc-style-select,
body.dw-theme-light .wc-style-select option {
    background-color: var(--dw-surface);
    color: var(--text);
}
body.dw-theme-light .wc-style-select option:checked,
body.dw-theme-light .wc-style-select option:hover {
    background-color: var(--primary);
    color: #ffffff;
}

/* ── Паспорт запроса в светлой теме (T4.2 ТЗ ПАСПОРТА) ──────────────────
      Та же ловушка, что была у селектора пресета выше: фолбэки в базовых
      правилах тёмные, и на белом фоне строка настройки читалась бы серым по
      светло-серому. Перечисляем явно, а не полагаемся на наследование. */
body.dw-theme-light .wc-passport-summary {
    background: var(--dw-surface);
    border-color: var(--border);
    color: var(--text);
}
body.dw-theme-light .wc-passport-summary:hover {
    background: rgba(201, 153, 94, 0.12);
    border-color: var(--primary);
    color: var(--text);
}
body.dw-theme-light .wc-passport-field > span,
body.dw-theme-light .wc-applied-passport-line {
    color: var(--text-secondary, #5a6472);
}
body.dw-theme-light .wc-reask-btn:disabled:hover {
    background: var(--dw-surface);
    border-color: var(--border);
    color: var(--text);
}

/* Паспорт запроса в карточке «Анализ» — светлая тема. Фолбэки в базовых
   правилах тёмные, на белом фоне строка читалась бы серым по светло-серому. */
body.dw-theme-light .dw-passport-summary {
    background: var(--dw-surface);
    border-color: var(--border);
    color: var(--text);
}
body.dw-theme-light .dw-passport-summary:hover {
    background: rgba(201, 153, 94, 0.12);
    border-color: var(--primary);
    color: var(--text);
}
body.dw-theme-light .dw-passport-field > span {
    color: var(--text-secondary, #5a6472);
}
body.dw-theme-light .dw-passport-field select,
body.dw-theme-light .dw-passport-field select option {
    background-color: var(--dw-surface);
    color: var(--text);
    color-scheme: light;
}
body.dw-theme-light .dw-overlay .bs-select,
body.dw-theme-light .dw-overlay .bs-select option {
    background-color: var(--dw-surface);
    color: var(--text);
    color-scheme: light;
}
body.dw-theme-light .dw-overlay .bs-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%235a6478'/%3E%3C/svg%3E");
}

/* ── Сводная таблица (pivot) и её диалог настройки ──────────────────────
      Здесь используются var(--bg-secondary) / var(--text-primary) /
      var(--text-secondary) — токены, которых нет ни в базовой палитре DWS,
      ни в светлой. Работали только тёмные фолбэки (#1c1a20 / #d5d5d6),
      поэтому выпадающие списки «Вид», «Строки», «Столбцы» и метрики
      оставались тёмными плашками с серым текстом посреди белого диалога. ── */
body.dw-theme-light .wtv-pivot-mount .pvtDropdown,
body.dw-theme-light .wtv-pivot-mount .pvtDropdownCurrent,
body.dw-theme-light .wtv-pivot-mount .pvtAttr,
body.dw-theme-light .wtv-pivot-mount .pvtFilterBox,
body.dw-theme-light .wtv-pivot-mount select.pvtRenderer,
body.dw-theme-light .wtv-pivot-mount select.pvtAggregator,
body.dw-theme-light .wtv-pivot-cfg-row select,
body.dw-theme-light .wtv-pivot-cfg-value-row select {
    background: var(--dw-surface);
    color: var(--text);
    border-color: var(--border);
    color-scheme: light;
}
body.dw-theme-light .wtv-pivot-mount select.pvtRenderer option,
body.dw-theme-light .wtv-pivot-mount select.pvtAggregator option,
body.dw-theme-light .wtv-pivot-cfg-row select option,
body.dw-theme-light .wtv-pivot-cfg-value-row select option {
    background: var(--dw-surface);
    color: var(--text);
}
body.dw-theme-light .wtv-pivot-mount .pvtRowOrder,
body.dw-theme-light .wtv-pivot-mount .pvtColOrder {
    color: var(--text);
}
body.dw-theme-light .wtv-pivot-cfg-clear {
    color: var(--text-dim);
}
body.dw-theme-light .wtv-pivot-cfg-clear:hover {
    background: var(--dw-surface);
    color: var(--text);
}
body.dw-theme-light .wtv-pivot-cfg-row,
body.dw-theme-light .wtv-pivot-cfg-values-title,
body.dw-theme-light .wtv-pivot-cfg-values-hint,
body.dw-theme-light .wtv-pivot-cfg-values-head,
body.dw-theme-light .wtv-pivot-cfg-intro {
    color: var(--text-dim);
}
/* Закреплённая шапка развёрнутой сводной — фон обязан быть сплошным и
   в светлой теме, иначе сводная просвечивает под ней при прокрутке. */
body.dw-theme-light .wtv-pivot-panel-expanded .wtv-pivot-panel-header {
    background: var(--bg);
    border-bottom-color: var(--border);
}

/* Панель справки диалога сводной на белом */
body.dw-theme-light .wtv-pivot-help {
    background: rgba(45, 55, 72, 0.03);
    border-color: var(--border);
}
body.dw-theme-light .wtv-pivot-help-title,
body.dw-theme-light .wtv-pivot-help-hint,
body.dw-theme-light .wtv-pivot-help-note,
body.dw-theme-light .wtv-pivot-help-example-lead,
body.dw-theme-light .wtv-pivot-help-bar-num {
    color: var(--text-dim);
}
body.dw-theme-light .wtv-pivot-help-formula,
body.dw-theme-light .wtv-pivot-help-schema-table th,
body.dw-theme-light .wtv-pivot-help-schema-table td,
body.dw-theme-light .wtv-pivot-help-preview-table th,
body.dw-theme-light .wtv-pivot-help-preview-table td {
    color: var(--text);
    border-color: var(--border);
}
body.dw-theme-light .wtv-pivot-help-formula {
    background: rgba(45, 55, 72, 0.06);
}
body.dw-theme-light .wtv-pivot-help-cell,
body.dw-theme-light .wtv-pivot-help-axis-empty {
    color: var(--text-dim);
}
body.dw-theme-light .wtv-pivot-mount .pvtFilterBox {
    box-shadow: 0 2px 8px rgba(45, 55, 72, 0.18);
}

/* ── Прочие потребители несуществующих токенов ──────────────────────────
      Тот же дефект вне селекторов: модалка подтверждения графика брала
      тёмный #2a262e под тёмный текст, а плашки результата table_actions —
      светло-серый #d5d5d6 на белом. ── */
body.dw-theme-light .wc-confirm-modal {
    background: var(--dw-surface);
    box-shadow: 0 12px 40px rgba(45, 55, 72, 0.22);
}
body.dw-theme-light .dw-result-rejected,
body.dw-theme-light .dw-result-applied,
body.dw-theme-light .wtv-ai-actions-row-title {
    color: var(--text);
}

/* Плавающие карточки производных: чёрная тень 0.30 на белом канвасе слишком
   тяжёлая — смягчаем до фирменного синевато-серого. */
body.dw-theme-light .dw-min-viewer-subpill,
.dw-min-viewers-tray.dw-theme-light .dw-min-viewer-subpill {
    box-shadow: 0 4px 12px rgba(45, 55, 72, 0.16);
}

/* Всплывающие меню графика: подложки уже идут от токенов (белые), но чёрные
   тени под ними на белом фоне выглядят грязным пятном. */
body.dw-theme-light .wc-context-menu,
body.dw-theme-light .wc-tab-context-menu,
body.dw-theme-light .wc-axis-dropdown,
body.dw-theme-light .wc-dist-color-picker {
    box-shadow: 0 8px 24px rgba(45, 55, 72, 0.18);
}
body.dw-theme-light .wc-context-item svg {
    opacity: 0.85;
}
/* Раздел связанных таблиц в меню оси: пояснения и селектор свёртки берут цвет
   от токенов, а вот подложка поля ввода на белом фоне пропадала — обводка ниже
   единственное, чем селектор виден. */
body.dw-theme-light .wc-axis-fold-select {
    background: #ffffff;
    border-color: rgba(45, 55, 72, 0.18);
    color: #2d3748;
}

/* ── Легаси-имена токенов ───────────────────────────────────────────────
      --bg-2 / --bg-secondary / --text-primary / --text-secondary остались от
      ранних версий просмотрщика и графика. В палитре DWS их нет вообще, поэтому
      всегда работали захардкоженные ТЁМНЫЕ фолбэки (#1c1a20 / #2a262e /
      #d5d5d6 / #b5b5b6): в светлой теме это давало тёмные плашки и светло-серый
      текст на белом. Точечные перекрытия ниже уже закрывали сводную таблицу и
      модалку графика — здесь закрываем остальное разом.

      Объявляем на КОРНЯХ компонентов, а не на <body>: те же имена использует
      основной чат (style.css), причём со СВЕТЛЫМИ значениями и местами вообще
      без фолбэка, и объявление на body переопределило бы их под оверлеем.
      AI-Аналитик не задет — он держит свою палитру на #orchestratorModal. ── */
body.dw-theme-light .dw-overlay,
body.dw-theme-light .wtv-overlay,
body.dw-theme-light .wc-overlay {
    --bg-2: #ffffff;
    --bg-secondary: #ffffff;
    --text-primary: #2d3748;
    --text-secondary: #4a5568;
}

/* ══ Выборки (ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS, волна 2: T2.2, T2.3, T2.5) ══════
   Цвета — только через токены палитры DWS: захардкоженные значения ломали бы
   светлую тему (см. memory: project_dws_light_theme). Единственное исключение
   — --dw-selection-color: это цвет САМОЙ выборки, выбранный пользователем, и
   он одинаков в обеих темах по смыслу. */

/* ── Карточка выборки на канвасе ── */
.dw-card--selection {
    border-color: rgba(201, 153, 94, 0.28);
}
.dw-card--selection .dw-card-icon {
    background: rgba(201, 153, 94, 0.16);
    color: var(--primary, #c9995e);
}
/* Полоса цвета выборки. Цвета может не быть вовсе (выборка точки не
   перекрашивает) — тогда переменная не задана и полоса не рисуется. */
.dw-card--selection[style*="--dw-selection-color"]::before {
    content: '';
    position: absolute;
    left: 0;
    top: 8px;
    bottom: 8px;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--dw-selection-color);
}

/* ── Диалог свойств выборки ── */
/* Карточка выборки — самый плотный диалог DWS: шесть кнопок в подвале,
   происхождение, правила отображения и оба уровня §0.6 в примечаниях. На 560px
   кнопки не помещались в одну строку. Ширина по окну, чтобы на узком экране
   диалог не вылезал за него. */
.dw-selection-dialog {
    width: min(720px, 92vw);
    max-width: 720px;
}
/* Подтверждение выполненной операции над выборками: галочка на месте
   предпросмотра. Диалог, который просто закрылся, оставлял вопрос «сработало
   или я промахнулся» — тост в углу уезжает (приёмка §9.3). */
.dw-alg-done {
    color: var(--success, #5db87a);
    font-weight: 600;
}
.dw-sel-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
}
.dw-sel-swatch {
    width: 20px;
    height: 20px;
    border-radius: 5px;
    cursor: pointer;
    border: 2px solid transparent;
    box-sizing: border-box;
}
.dw-sel-swatch.selected {
    border-color: var(--text, #e8e3db);
    box-shadow: 0 0 0 1px var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.2));
}
.dw-sel-swatch-none {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    color: var(--text-dim, #948e84);
    background: transparent;
    border: 1px dashed var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.25));
}
.dw-sel-states {
    display: flex;
    gap: 4px;
    flex: 1;
}
.dw-sel-state {
    flex: 1;
    padding: 5px 8px;
    font-size: 0.78rem;
    font-family: inherit;
    cursor: pointer;
    color: var(--text-dim, #948e84);
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.14));
    border-radius: 6px;
}
.dw-sel-state:hover {
    color: var(--text, #e8e3db);
    border-color: var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.28));
}
.dw-sel-state.active {
    color: var(--primary, #c9995e);
    border-color: var(--primary, #c9995e);
    background: rgba(201, 153, 94, 0.12);
}
.dw-sel-prov {
    max-height: 140px;
    overflow-y: auto;
}
.dw-sel-prov-row {
    display: flex;
    gap: 8px;
    align-items: baseline;
    font-size: 0.8rem;
    padding: 3px 0;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.05));
}
.dw-sel-prov-origin {
    flex-shrink: 0;
    color: var(--primary, #c9995e);
}
.dw-sel-prov-detail {
    flex: 1;
    color: var(--text-dim, #948e84);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dw-sel-prov-size {
    flex-shrink: 0;
    color: var(--text-dim, #948e84);
    font-variant-numeric: tabular-nums;
}

/* ── Пределы выборки в её карточке (T8.2) ──
   Строка есть у каждого предела, а не только у задетого: «где мой потолок»
   спрашивают до того, как в него упрутся. Задетый помечен цветом и полосой
   слева — иначе он теряется среди соседних строк того же вида. */
.dw-sel-limits {
    max-height: 190px;
    overflow-y: auto;
}
.dw-sel-limit-row {
    display: flex;
    gap: 8px;
    align-items: baseline;
    font-size: 0.78rem;
    line-height: 1.45;
    padding: 4px 0 4px 6px;
    border-left: 2px solid transparent;
    border-bottom: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.05));
}
.dw-sel-limit-row.hit {
    border-left-color: var(--primary, #c9995e);
}
.dw-sel-limit-label {
    flex: 0 0 140px;
    color: var(--text, #e8e3db);
}
.dw-sel-limit-text {
    flex: 1;
    color: var(--text-dim, #948e84);
}
.dw-sel-limit-row.hit .dw-sel-limit-text {
    color: var(--text, #e8e3db);
}

/* ── Раздел «Выборки» в левой панели графика ── */
/* Отступы те же, что у строки группы (v1.71.5) — иначе цветные кружки двух
   списков стоят на разной вертикали. */
.wc-sel-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 4px;
    border-radius: 4px;
    cursor: pointer;
}
.wc-sel-row:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
}
.wc-sel-row.wc-sel-row--dim .wc-sel-name {
    opacity: 0.5;
}
/* Выборка, временно не применяемая к этому графику (глазок выключен). Строка
   остаётся читаемой: настройки при ней сохранены, и по ним видно, что вернётся
   при включении. Кнопка глазка не гасится — ею и включают обратно. */
.wc-sel-row.wc-sel-row--off .wc-sel-dot,
.wc-sel-row.wc-sel-row--off .wc-sel-name,
.wc-sel-row.wc-sel-row--off .wc-sel-count,
.wc-sel-row.wc-sel-row--off .wc-sel-states,
.wc-sel-row.wc-sel-row--off .wc-trend-btn {
    opacity: 0.4;
}
.wc-sel-row.wc-sel-row--off .wc-sel-name {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}
.wc-sel-dot {
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.3));
}
.wc-sel-dot--none {
    background: transparent;
    border-style: dashed;
}
.wc-sel-name {
    flex: 1;
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wc-sel-count {
    flex-shrink: 0;
    font-size: 0.74rem;
    color: var(--text-dim, #948e84);
    font-variant-numeric: tabular-nums;
}
.wc-sel-states {
    display: flex;
    gap: 2px;
    flex-shrink: 0;
}
.wc-sel-state {
    width: 20px;
    height: 18px;
    font-size: 0.68rem;
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
    color: var(--text-dim, #948e84);
    background: transparent;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.14));
    border-radius: 3px;
}
.wc-sel-state.active {
    color: var(--primary, #c9995e);
    border-color: var(--primary, #c9995e);
    background: rgba(201, 153, 94, 0.14);
}
/* Выборка целиком вошла в текущее выделение (Ctrl+клик по строке). Видно, из
   чего набрано выделение, прежде чем сохранять его новой выборкой. */
.wc-sel-row--picked {
    background: rgba(201, 153, 94, 0.14);
    box-shadow: inset 2px 0 0 var(--primary, #c9995e);
}
/* T3.4 — выборка сейчас показана поверх столбцов распределения. Отметка та же
   по смыслу, что у строки группы в легенде (wc-legend-active): нажатие в
   режиме распределения включает показ, а не выделение точек. */
.wc-sel-row--overlay {
    background: rgba(201, 153, 94, 0.16);
    box-shadow: inset 3px 0 0 var(--primary, #c9995e);
}

/* Кнопки строки выборки — по общему правилу списков (v1.71.5): видны всегда
   вполсилы, разгораются на наведении. Прежде корзина стояла на 0.35, а глазок
   на полной яркости — в одной строке две разные громкости. */
.wc-sel-del,
.wc-sel-row .wc-sel-eye {
    flex-shrink: 0;
    opacity: 0.45;
    transition: opacity 0.15s;
}
.wc-sel-row:hover .wc-sel-del,
.wc-sel-row:hover .wc-sel-eye {
    opacity: 1;
}
.wc-sel-hint {
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    padding: 4px 2px 0;
    line-height: 1.35;
}

/* Точки, которых нет на поле: число и причина. Приглушённая строка под
   легендой — постоянное свойство текущего вида, а не событие. Цвет предупреждения,
   а не ошибки: данные целы, их просто не видно. */
.wc-hidden-points-note {
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--warning, #d9a441);
    padding: 4px 2px 0;
    opacity: 0.9;
}

/* Строка «Показано N точек из M — случайная выборка» (T2.1/T2.2 ТЗ ПОТОЛКИ).
   То же место и тот же размер, что у строки о непоказанных точках, но цвет
   приглушённый, а не предупреждающий: это не проблема и не потеря данных, а
   свойство картинки, о котором человек обязан знать. Жёлтым тут было бы
   «что-то сломалось». */
.wc-sample-note {
    color: var(--text-dim, #948e84);
}

/* Отмена и повтор операций с выборками (v1.71.1, правка владельца на приёмке
   волны 7). Прежде это была строка широких кнопок с контуром ВНУТРИ списка, и
   появлялась она только когда отменять есть что. Теперь обе кнопки стоят в
   строке заголовка «Выборки», выглядят как корзина рядом (без контура) и видны
   ВСЕГДА — доступность показана цветом, а не появлением и исчезновением. */
/* v1.71.4: тот же класс носят кнопки истории ГРУПП — правка владельца «для
   групп нужны такие же элементы управления, как для выборок». Один вид на обе
   истории; какая именно история за кнопкой, говорит её подсказка. */
.wc-sel-hist,
.wc-hist-btn {
    opacity: 0.4;
}
.wc-sel-hist:disabled,
.wc-hist-btn:disabled {
    opacity: 0.25;
    cursor: default;
}
.wc-sel-hist.is-on,
.wc-hist-btn.is-on {
    opacity: 1;
    color: var(--primary, #c9995e);
}
.wc-sel-hist.is-on:hover,
.wc-hist-btn.is-on:hover {
    color: var(--text, #e8e3d9);
}
/* Корзина при пустом разделе не исчезает, а гаснет — по тому же правилу, что
   и кнопки истории: пропадающий элемент сдвигает соседей. */
.wc-sel-clear:disabled,
.wc-legend-toggle-all:disabled {
    opacity: 0.25;
    cursor: default;
}
.wc-sel-clear:disabled:hover,
.wc-legend-toggle-all:disabled:hover {
    color: var(--text-muted, #6b6560);
    background: transparent;
}

/* T2.6 — переключатель показа происхождения в подсказке. Живёт в заголовке
   секции, поэтому прижат вправо и не мешает названию. */
/* Блок кнопок в заголовке «Выборки»: прижат вправо целиком, кнопки идут в
   ряд. Поодиночке (каждая со своим float) вторая падала под заголовок —
   найдено владельцем 2026-08-13. */
.wc-sel-title-actions {
    float: right;
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
.wc-sel-clear {
    opacity: 0.4;
}
.wc-sel-clear:hover {
    opacity: 1;
    color: var(--danger, #c96a5e);
}
.wc-sel-prov-toggle {
    opacity: 0.4;
}
.wc-sel-prov-toggle:hover {
    opacity: 0.8;
}
.wc-sel-prov-toggle.active {
    opacity: 1;
    color: var(--primary, #c9995e);
}

/* Категория, поднятая в список приоритета. Отличима от выборки, но не
   выглядит второсортной: права у строк одинаковые, разное только
   происхождение — выборка набрана руками, категория пришла из раскраски. */
.wc-sel-row--cat {
    border-left: 2px dashed var(--border, #d9d2c7);
    padding-left: 4px;
}

/* ═══ Слои графика — T5.1-T5.4 ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS (волна 6) ═══
   Раскладка повторяет строку выборки: две похожие сущности в одной панели с
   разной геометрией читались бы как разные механики. */
/* Отступы те же, что у строк групп и выборок (v1.71.5). */
.wc-layer-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 4px;
    border-radius: 4px;
    flex-wrap: wrap;
}
/* Кнопки строки слоя — по общему правилу: видны всегда, разгораются на
   наведении. Прежде они горели в полную силу постоянно, а в группах не были
   видны вовсе (v1.71.5). */
.wc-layer-row .wc-btn-icon-sm {
    opacity: 0.45;
    transition: opacity 0.15s;
}
.wc-layer-row:hover .wc-btn-icon-sm {
    opacity: 1;
}
.wc-layer-row:hover {
    background: rgba(var(--dw-tint, 255, 250, 243), 0.04);
}
/* Основной источник графика: та же строка, но без действий — его нельзя убрать
   с собственного графика, и кнопка, которая ничего не делает, здесь лишняя. */
.wc-layer-row--base {
    border-left: 2px solid var(--border, rgba(232, 227, 219, 0.2));
    padding-left: 4px;
}
/* Слой скрыт: строка остаётся читаемой — по ней видно, что вернётся. */
.wc-layer-row--off .wc-layer-dot,
.wc-layer-row--off .wc-layer-name,
.wc-layer-row--off .wc-layer-count {
    opacity: 0.4;
}
.wc-layer-dot {
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    border: 1px solid var(--border, rgba(var(--dw-ink, 232, 227, 219), 0.3));
}
.wc-layer-name {
    flex: 1;
    min-width: 60px;
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wc-layer-count {
    flex-shrink: 0;
    font-size: 0.74rem;
    color: var(--text-dim, #948e84);
    font-variant-numeric: tabular-nums;
}
/* «Объединять» — участие слоя в общем тренде. Пока выключено, знак приглушён:
   включённое состояние обязано отличаться с одного взгляда. */
.wc-layer-combine {
    opacity: 0.4;
    font-weight: 600;
}
.wc-layer-combine.active {
    opacity: 1;
    color: var(--primary, #c9995e);
}
.wc-layer-error {
    flex-basis: 100%;
    color: var(--danger, #d4706a);
}
/* Чем этот источник лёг на оси — ВИДНОЙ строкой, а не подсказкой при наведении.
   Подпись оси на поле одна на весь график (она от основного источника), и у
   слоя там свои колонки: не сказать этого прямо — значит оставить вопрос «а что
   у слоя на осях?» без ответа (§0.6 запрещает объяснять только наведением). */
.wc-layer-axes-line {
    flex-basis: 100%;
    padding-left: 16px;
    font-size: 0.72rem;
    color: var(--text-dim, #948e84);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Диалог слоя: две оси рядом — сопоставление читается парой, а не двумя
   независимыми вопросами. */
.wc-layer-axes {
    display: flex;
    gap: 12px;
}
.wc-layer-axes .wc-form-group {
    flex: 1;
    min-width: 0;
}
.wc-layer-axis-base {
    color: var(--text-dim, #948e84);
    font-size: 0.72rem;
}
.wc-layer-warn {
    color: var(--warning, #c9995e);
}
/* Заголовок группы показателей: слои считаются по отдельности, и без подписи
   было бы неясно, чьи это числа. */
.wc-stat-head {
    font-size: 0.74rem;
    color: var(--text-dim, #948e84);
    margin-top: 6px;
}

/* ═══ Подписи у точек — T5.5 ТЗ_ВЫБОРКИ_И_ВЫДЕЛЕНИЕ_DWS (волна 6) ═══ */
.wc-label-cols {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    max-height: 160px;
    overflow-y: auto;
    padding: 4px 2px;
}
.wc-label-col {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 0.8rem;
    cursor: pointer;
}
/* Колонки связанных таблиц идут теми же флажками, что и свои: три ответа из
   четырёх («откуда», «по чему здесь», «по чему там») уже даны связью на
   канвасе, и переспрашивать про них значит выдавать устройство за работу. */

/* T5.6 — выбор связанных таблиц в конструкторе правила. Стоит НАД строкой
   «Создать»: сначала решают, чьи колонки нужны, потом набирают условия. */
.wc-rule-linked {
    padding: 6px 0;
    border-bottom: 1px solid var(--border, rgba(232, 227, 219, 0.07));
    margin-bottom: 8px;
}
.wc-rule-linked-title {
    font-size: 0.78rem;
    color: var(--text-dim, #948e84);
}
.wc-rule-linked .wc-label-cols {
    max-height: 92px;
}
/* Связь по составному ключу условием пока не становится — флажок выключен, и
   почему, сказано подсказкой строки, а не молчанием. */
.wc-rule-linked .wc-label-col input:disabled + span {
    opacity: 0.45;
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

/* Зоны переноса: пока строку тащат, видно, куда её можно бросить. Без этого
   перетаскивание между двумя списками — угадывание. */
.wc-selections.wc-sel-drop,
#wcLegend.wc-legend-drop {
    outline: 2px dashed var(--primary, #c9995e);
    outline-offset: 2px;
    border-radius: 6px;
}
