/* ========================================
   easy3D — стили модуля
   [2026-09-22] Причина: предэтап 0.6 ТЗ заводит страницу модуля easy3D. Цвета, размеры, радиусы,
   тени и переходы берутся ТОЛЬКО токенами из styles/themes.css (ТЗ §6.1).
   Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §6.1, §6.2. Chat: easy3d-impl-2026-09-22.

   [2026-09-23] Вторая редакция — раскладка как у оригинала (снимок PO 2026-09-23: «пока ещё хаос
   из кнопок во фронте», оригинал рядом). Файл переписан целиком: первая редакция копила слои
   правок поверх правок (две разные раскладки ленты, три правила `.easy3d-ribbon-group`, рамки групп,
   перенос групп на четыре строки, список выпадающей кнопки с `display: flex`, перебивавшим атрибут
   `hidden`, — списки стояли открытыми поверх соседей). Теперь: шапка (меню, вкладки, быстрые
   команды), лента одной строкой с прокруткой вбок, группы разделены линией, а не рамкой; боковая
   колонка слева, область просмотра во всю остальную ширину, строка состояния внизу. Размеров-
   литералов нет вовсе: всё — токенами `--space-*`, `--font-size-*`, `--radius-*` и их кратными
   через `calc()`; линии — ключевым словом `thin`.
   Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §3.5, §6.1, §6.2, §6.3. Chat: easy3d-port-ui-2026-09-23.
   ======================================== */

/* Страница не скроллится — скроллится содержимое панелей (DESIGN.md «Лэйаут страницы»). */
body.easy3d-page {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow: hidden;
    background: var(--bg-primary);
}

.easy3d-root {
    /* [2026-09-24] Опора для стартового экрана (`.easy3d-landing`, position: absolute; inset: 0):
       экран закрывает рабочую область порта, а не случайного предка.
       Ref: docs/easy3d/PARITY_CHILI3D.md (Стартовый экран). Chat: easy3d-port-ui-2026-09-23. */
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: var(--text-primary);
    font-size: var(--font-size-sm);
}

/* Значок библиотеки поставки. Видимость значков держит правило тем
   `html:not(.material-icons-loaded) .material-symbols-outlined { visibility: hidden }` — замок
   снимает config.js после загрузки шрифтов; страница обязана его подключать (см. port.html). */
.easy3d-icon {
    line-height: 1;
    color: inherit;
}

/* Общая кнопка-значок: быстрые команды, тулбар дерева, органы вида. */
.easy3d-icon-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.easy3d-icon-button:hover,
.easy3d-icon-button:focus-visible {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.easy3d-icon-button .easy3d-icon {
    font-size: var(--font-size-xl);
}

/* ===== Шапка: меню (ТЗ §6.4), вкладки ленты, быстрые команды ===== */
/* [2026-09-25] Третья вкладка ленты («Plugin», рус. «Расширения») удлинила строку шапки: на странице
   модуля шириной 1129 точек по-русски быстрые команды уходили за правый край окна (живая проверка
   visibility-paths, путь after-language). Шапка теперь переносит быстрые команды на вторую строку,
   когда места нет, — ни одна кнопка не уходит за окно; на тесном окне меню и вкладки уплотняются.
   Ref: .unlazy/easy3d/gates/leaf-1.9.md G7; docs/easy3d/PARITY_CHILI3D.md (Вкладка Plugin).
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-topbar {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0 var(--space-4);
    padding: 0 var(--space-3);
    border-bottom: thin solid var(--border-color);
    background: var(--bg-secondary);
}

.easy3d-menubar {
    display: flex;
    align-items: center;
}

.easy3d-menu {
    position: relative;
}

.easy3d-menu-button {
    padding: var(--space-2) var(--space-3);
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.easy3d-menu-button:hover,
.easy3d-menu-button[aria-expanded='true'] {
    background: var(--bg-hover);
}

.easy3d-menu-panel {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: var(--z-dropdown);
    min-width: calc(var(--space-20) * 3);
    max-height: 60vh;
    overflow-y: auto;
    padding: var(--space-1);
    border: thin solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    box-shadow: var(--shadow-md);
}

.easy3d-menu-item {
    display: block;
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    text-align: left;
    cursor: pointer;
}

.easy3d-menu-item:hover,
.easy3d-menu-item:focus-visible {
    background: var(--bg-hover);
}

.easy3d-menu-separator {
    margin: var(--space-1) 0;
    border: 0;
    border-top: thin solid var(--border-color);
}

.easy3d-tabs {
    display: flex;
    align-items: stretch;
    gap: var(--space-1);
}

.easy3d-tab {
    padding: 0 var(--space-3);
    border: 0;
    border-bottom: medium solid transparent;
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.easy3d-tab[aria-selected='true'] {
    border-bottom-color: var(--brand-primary);
    color: var(--text-primary);
}

.easy3d-quick {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    margin-left: auto;
}

/* [2026-09-25] Вкладки открытых документов — в середине шапки, как у оригинала (вкладка: имя и
   крестик, рядом «+» нового документа). Полоса сжимается первой и прокручивается вбок, если
   документов много, — быстрые команды справа не уходят за окно.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Документ и оболочка: вкладки документов).
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-doc-tabs {
    display: flex;
    flex: 1 1 0;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    min-width: 0;
}

/* [2026-09-25] Вкладки НЕ сжимаются до многоточия: в тесной шапке (русское меню, окно 1266 точек)
   две вкладки сжимались до «Доку…» каждая. Полоса вкладок прокручивается вбок (колесом тоже),
   текущая вкладка всегда в поле зрения, «+» — сразу за полосой и не уезжает. Полоса прокрутки
   скрыта: высота шапки не меняется. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-doc-tab-list {
    display: flex;
    flex: 0 1 auto;
    gap: var(--space-1);
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.easy3d-doc-tab-list::-webkit-scrollbar {
    display: none;
}

.easy3d-doc-new {
    flex: 0 0 auto;
}

.easy3d-doc-tab {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: var(--space-1);
    max-width: calc(var(--space-20) * 3);
    /* [2026-09-25] Левое поле — space-2, крестик без полей: в русской шапке окна 1266 точек имя
       «Документ 27» обрезалось до «Докум…» (снимок страницы модуля). Chat: easy3d-port-ui-2026-09-23. */
    padding: 0 0 0 var(--space-2);
    border: thin solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    white-space: nowrap;
    cursor: pointer;
}

.easy3d-doc-tab:hover {
    background: var(--bg-hover);
}

.easy3d-doc-tab[aria-selected='true'] {
    border-color: var(--primary-color);
    color: var(--text-primary);
}

.easy3d-doc-tab-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.easy3d-doc-tab-close {
    padding: 0;
}

/* [2026-09-25] Тесное окно: меню, вкладки и промежутки шапки уплотняются (см. .easy3d-topbar выше).
   Правило стоит ПОСЛЕ правил кнопок меню и вкладок — иначе они перебивали бы его. Chat: easy3d-port-ui-2026-09-23. */
@media (max-width: 1400px) {
    .easy3d-topbar {
        column-gap: var(--space-2);
    }

    .easy3d-menu-button,
    .easy3d-tab {
        padding-inline: var(--space-2);
    }

    /* [2026-09-25] Тесное окно: вкладки документов — ОТДЕЛЬНОЙ строкой шапки во всю ширину, быстрые
       команды остаются справа в первой строке. Прежде (уплотнённое меню, одна строка) в русской
       шапке окна 1266 точек помещалась одна вкладка, вторая обрезалась до «До…» (снимок страницы
       модуля). Строка постоянная, а не по числу вкладок: вид не прыгает под курсором, когда
       открывается второй документ. Порядок — свойством `order`, разметка шапки не меняется.
       Ref: docs/easy3d/UI_EASY3D.md (Вкладки документов в шапке). Chat: easy3d-port-ui-2026-09-23. */
    .easy3d-quick {
        order: 1;
    }

    .easy3d-doc-tabs {
        order: 2;
        flex-basis: 100%;
        justify-content: flex-start;
        padding-bottom: var(--space-1);
    }
}

/* ===== Лента (ТЗ §6.3): одна строка групп, как у оригинала; тесное окно прокручивает её вбок ===== */
.easy3d-ribbon {
    flex: 0 0 auto;
    border-bottom: thin solid var(--border-color);
    background: var(--bg-secondary);
}

.easy3d-tab-panel {
    display: flex;
    align-items: stretch;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}

.easy3d-tab-panel[hidden] {
    display: none;
}

.easy3d-ribbon-group {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    padding: var(--space-1) var(--space-1) 0;
    border-right: thin solid var(--border-color);
}

.easy3d-ribbon-row {
    flex: 1;
    display: flex;
    align-items: flex-start;
    gap: var(--space-1);
}

.easy3d-ribbon-caption {
    display: flex;
    align-items: center;
    justify-content: center;
    padding-bottom: var(--space-1);
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
    white-space: nowrap;
}

/* Кнопка инструмента: большая — значок над словом, малая — значок слева от слова. */
.easy3d-tool {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-xs);
    line-height: var(--line-height-tight);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.easy3d-tool:hover,
.easy3d-tool:focus-visible {
    background: var(--bg-hover);
}

.easy3d-tool .easy3d-icon {
    color: var(--brand-primary);
}

.easy3d-tool-large {
    flex-direction: column;
    justify-content: flex-start;
    min-width: var(--space-12);
    padding: var(--space-1) var(--space-2);
}

.easy3d-tool-large .easy3d-icon {
    font-size: var(--font-size-3xl);
}

.easy3d-tool-small {
    flex-direction: row;
    justify-content: flex-start;
    height: var(--space-6);
    padding: 0 var(--space-2);
}

.easy3d-tool-small .easy3d-icon {
    font-size: var(--font-size-base);
}

.easy3d-stack {
    display: flex;
    flex-direction: column;
}

/* Выпадающая кнопка: кнопка и стрелка под словом, список — по стрелке. */
.easy3d-split {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

.easy3d-split > .easy3d-tool-large {
    padding-bottom: 0;
}

.easy3d-dropdown-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    line-height: 1;
    cursor: pointer;
}

.easy3d-dropdown-toggle:hover,
.easy3d-dropdown-toggle[aria-expanded='true'] {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.easy3d-dropdown-toggle .easy3d-icon {
    font-size: var(--font-size-lg);
}

/* Список стоит на координатах своей стрелки (их ставит лента): прокрутка ленты его не обрезает. */
.easy3d-dropdown {
    position: fixed;
    z-index: var(--z-dropdown);
    display: flex;
    flex-direction: column;
    min-width: calc(var(--space-20) * 2);
    padding: var(--space-1);
    border: thin solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    box-shadow: var(--shadow-md);
}

.easy3d-dropdown[hidden] {
    display: none;
}

.easy3d-dropdown .easy3d-tool-small {
    width: 100%;
}

/* ===== Рабочая область: боковая колонка и область просмотра ===== */
.easy3d-workspace {
    flex: 1;
    min-height: 0;
    display: flex;
}

.easy3d-sidebar {
    flex: 0 0 calc(var(--space-20) * 4.5);
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-right: thin solid var(--border-color);
    background: var(--bg-primary);
}

.easy3d-panel {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.easy3d-panel + .easy3d-panel {
    border-top: thin solid var(--border-color);
}

.easy3d-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2) var(--space-1) var(--space-4);
    background: var(--bg-secondary);
}

.easy3d-panel-title {
    margin: 0;
    padding: var(--space-1) 0;
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

.easy3d-project-toolbar {
    display: flex;
    gap: var(--space-1);
}

.easy3d-panel-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--space-1) var(--space-2);
}

.easy3d-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

/* Строка перечня. Перечень сущностей — СТРОКАМИ, а не кнопками (канон PO): строка кликабельна
   целиком. Длинная подпись переносится, а не обрезается. */
.easy3d-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-normal);
    overflow-wrap: anywhere;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.easy3d-row:hover {
    background-color: var(--bg-hover);
}

.easy3d-empty {
    margin: var(--space-2) var(--space-2) 0;
    color: var(--text-tertiary);
    font-size: var(--font-size-xs);
}

/* Область просмотра: сцена во всю зону, подпись режима слева сверху (правее куба ориентации,
   который сцена рисует в левом верхнем углу), органы вида столбиком справа, форма шага — поверх. */
.easy3d-viewport {
    position: relative;
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    background: var(--bg-tertiary);
}

.easy3d-viewport canvas {
    flex: 1;
    min-width: 0;
    min-height: 0;
    width: 100%;
    height: 100%;
    display: block;
}

/* [2026-09-24] Имя привязки у знака под курсором (как подпись привязки у оригинала): мелкая
   подпись справа снизу от точки, мимо курсора, щелчки не перехватывает. Только токены темы.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Строка состояния: 9 привязок). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-snap-label {
    position: absolute;
    z-index: var(--z-sticky);
    transform: translate(var(--space-3), var(--space-3));
    padding: 0 var(--space-1);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: var(--font-size-xs);
    pointer-events: none;
    white-space: nowrap;
}

.easy3d-snap-label[hidden] {
    display: none;
}

/* [2026-09-24] Подсказка шага и поле ввода у курсора при рисовании щелчками — как плавающая
   подсказка и поле ввода у оригинала (ui/viewport/flyout). Подсказка щелчки не перехватывает,
   поле ввода — перехватывает (в него набирают). Только токены темы.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Ввод команд); замечание PO 2026-09-24.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-draw-tip {
    position: absolute;
    z-index: var(--z-sticky);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    /* [2026-09-24] Подсказка у правого и нижнего края области просмотра переходит на другую сторону
       курсора: иначе её обрезал край (снимок живого переноса щелчками — «Pick next point, E…»).
       Ref: docs/easy3d/PARITY_CHILI3D.md (Ввод команд). Chat: easy3d-port-ui-2026-09-23. */
    --easy3d-tip-x: var(--space-4);
    --easy3d-tip-y: var(--space-4);
    transform: translate(var(--easy3d-tip-x), var(--easy3d-tip-y));
    pointer-events: none;
}

.easy3d-draw-tip.easy3d-draw-tip-left {
    --easy3d-tip-x: calc(-100% - var(--space-4));
}

.easy3d-draw-tip.easy3d-draw-tip-up {
    --easy3d-tip-y: calc(-100% - var(--space-4));
}

.easy3d-draw-tip[hidden] {
    display: none;
}

.easy3d-draw-prompt {
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: var(--font-size-xs);
    white-space: nowrap;
    box-shadow: var(--shadow-sm);
}

.easy3d-draw-input {
    width: calc(var(--space-20) * 2);
    pointer-events: auto;
}

/* [2026-09-25] Размеры измерений в виде, как у оригинала (threeView.module.css .htmlText): слой
   подписей поверх полотна не мешает щелчкам по виду, подпись — число в рамке, крестик виден при
   наведении и убирает размер. Только токены темы.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Measure). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-measure-layer {
    position: absolute;
    top: 0;
    left: 0;
    z-index: var(--z-sticky);
    pointer-events: none;
}

.easy3d-measure-label {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    /* [2026-09-25] Толщина рамки словом `thin`, как у соседних правил модуля: размеры — только
       токенами (ТЗ §6.1). Chat: easy3d-port-ui-2026-09-23. */
    border: thin solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: var(--font-size-xs);
    white-space: nowrap;
    opacity: 0.9;
    pointer-events: auto;
}

.easy3d-measure-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    visibility: hidden;
}

.easy3d-measure-close .material-symbols-outlined {
    font-size: var(--font-size-sm);
}

.easy3d-measure-label:hover .easy3d-measure-close {
    visibility: visible;
}

.easy3d-measure-close:hover {
    color: var(--color-error);
}

/* [2026-09-25] Сумма Select в углу вида, как у оригинала (measure/select.module.css .selectSum):
   вид величины, «+ значение» по элементам со скроллом длинного перечня и «= сумма». Под подписью
   режима отображения, чтобы не закрывать её. Только токены темы.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Measure: Select). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-select-sum {
    position: absolute;
    top: var(--space-12);
    left: var(--space-4);
    z-index: var(--z-sticky);
    display: flex;
    flex-direction: column;
    min-width: calc(var(--space-16) * 2);
    border: thin solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    color: var(--text-primary);
    overflow: hidden;
}

.easy3d-select-sum-title {
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-size-base);
    font-weight: 600;
    text-align: center;
}

.easy3d-select-sum-list {
    margin: 0;
    padding: 0;
    list-style: none;
    max-height: calc(var(--space-20) * 5);
    overflow-y: auto;
    background: var(--bg-secondary);
    font-size: var(--font-size-sm);
}

.easy3d-select-sum-row {
    display: flex;
    justify-content: space-between;
    padding: var(--space-1) var(--space-3);
}

.easy3d-select-sum-row::before {
    content: '+';
    color: var(--text-secondary);
}

.easy3d-select-sum-total {
    display: flex;
    justify-content: space-between;
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.easy3d-select-sum-total::before {
    content: '=';
    color: var(--text-secondary);
}

.easy3d-draw-input[hidden] {
    display: none;
}

/* [2026-09-24] Подпись режима и раскрывающийся перечень режимов СТРОКАМИ — как у оригинала
   (viewport.module.css .viewModeControl / .viewModeMenu): перечень под подписью, выбранная строка
   отмечена, закрытый перечень скрыт. Только токены темы.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Область просмотра). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-view-mode-control {
    position: absolute;
    top: var(--space-2);
    left: var(--space-16);
    z-index: var(--z-sticky);
}

.easy3d-view-mode-menu {
    position: absolute;
    top: 100%;
    left: 0;
    margin: var(--space-1) 0 0;
    padding: var(--space-1);
    list-style: none;
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    box-shadow: var(--shadow-sm);
}

.easy3d-view-mode-menu[hidden] {
    display: none;
}

.easy3d-view-mode-row {
    padding: var(--space-2);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}

.easy3d-view-mode-row:hover,
.easy3d-view-mode-row:focus-visible {
    background: var(--bg-hover);
}

.easy3d-view-mode-row[aria-checked='true'] {
    background: var(--bg-tertiary);
    color: var(--brand-primary);
}

.easy3d-view-mode {
    padding: var(--space-1) var(--space-2);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.easy3d-view-mode:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

/* [2026-09-24] Знак осей справа сверху, как у оригинала (viewGizmo.ts: 100 точек, круглый, фон
   под указателем): холст 200×200 показан вдвое меньше — кружки чёткие на плотных экранах. Фон под
   указателем — токен затемнения, а не литерал. Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §6.2;
   docs/easy3d/PARITY_CHILI3D.md (Область просмотра). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-view-gizmo {
    position: absolute;
    top: var(--space-2);
    right: var(--space-3);
    z-index: var(--z-sticky);
    width: calc(var(--space-20) + var(--space-5));
    height: calc(var(--space-20) + var(--space-5));
    border-radius: 50%;
    cursor: pointer;
    user-select: none;
}

.easy3d-view-gizmo:hover {
    background: var(--bg-overlay);
}

.easy3d-view-gizmo canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* [2026-09-24] Органы вида — столбиком справа ПОД знаком осей (100 точек от верхнего края +
   отступ), как панель вида у оригинала.
   Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §6.2. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-view-controls {
    position: absolute;
    top: calc(var(--space-20) + var(--space-8));
    right: var(--space-3);
    z-index: var(--z-sticky);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* [2026-09-24] Органы вида двумя группами, как у оригинала (.viewControls .border): камера и
   действия — каждая своей плашкой. Нажатая кнопка (вид камеры, включённый Toggle ленты) показывает
   себя, как `.actived`/`.checked` у оригинала: до этой правки состояние Toggle стояло только в
   `aria-pressed` и классе, у которых не было ни одного правила, — на экране его не было видно.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Область просмотра, Working Plane). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-view-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-1);
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    box-shadow: var(--shadow-sm);
}

.easy3d-icon-button[aria-pressed='true'],
.easy3d-tool[aria-pressed='true'] {
    background: var(--bg-tertiary);
    color: var(--brand-primary);
    outline: thin solid var(--brand-primary);
}

.easy3d-form-host {
    position: absolute;
    top: var(--space-10);
    left: var(--space-3);
    z-index: var(--z-sticky);
    width: calc(var(--space-20) * 4);
    max-height: calc(100% - var(--space-12));
    overflow-y: auto;
}

.easy3d-form-host:empty {
    display: none;
}

/* [2026-09-24] Полоса сохранённых видов камеры («Act») — плитки внизу области просмотра, как у
   оригинала; пустая полоса скрыта. Только токены дизайн-системы: ни одного литерала размера или
   цвета, рамка — ключевым словом `thin`.
   Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §3.5, §6.3. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-acts {
    position: absolute;
    left: var(--space-3);
    right: var(--space-3);
    bottom: var(--space-3);
    z-index: var(--z-sticky);
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    overflow-x: auto;
}

.easy3d-acts[hidden] {
    display: none;
}

.easy3d-act {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: thin solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: var(--font-size-xs);
    cursor: pointer;
}

.easy3d-act:hover {
    background: var(--bg-hover);
}

.easy3d-act-name {
    white-space: nowrap;
}

.easy3d-act-input {
    width: calc(var(--space-20) * 2);
}

.easy3d-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
    border: thin solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    box-shadow: var(--shadow-md);
}

.easy3d-form-title {
    margin: 0;
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

.easy3d-form-summary {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
}

.easy3d-field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.easy3d-field-label {
    flex: 0 0 45%;
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
}

/* [2026-09-24] Метка активного шага формы: видно, куда попадёт следующий щелчок в области
   просмотра. Только токены — ни размеров, ни цветов числами. Ref: ТЗ §5.6, §6.3.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-field-active {
    outline: thin solid var(--brand-primary);
    border-radius: var(--radius-sm);
}

.easy3d-field-note {
    color: var(--text-tertiary);
    font-size: var(--font-size-xs);
}

.easy3d-point {
    display: flex;
    gap: var(--space-1);
    min-width: 0;
}

/* [2026-09-24] Шаг «точка», «вектор», «плоскость»: подпись строкой сверху, тройки осей — во всю
   ширину формы. Рядом с подписью на поле оставалось четыре знака, координата обрезалась (снимок
   порта: «11.» вместо «11.984»). Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §6.3.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-field-point {
    flex-wrap: wrap;
}

.easy3d-field-point .easy3d-field-label {
    flex: 1 0 60%;
}

.easy3d-field-point .easy3d-point {
    flex: 1 0 100%;
}

.easy3d-input {
    min-width: 0;
    width: 100%;
    padding: var(--space-1) var(--space-2);
    border: thin solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: var(--font-size-xs);
}

/* [2026-09-24] Выключенный необязательный шаг формы виден выключенным: без этого поля с
   умолчаниями выглядели заполненными (снимок формы «Length»). Ref: ТЗ §6.3.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-input:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.easy3d-step-toggle {
    margin: 0 var(--space-1) 0 0;
    accent-color: var(--brand-primary);
}

/* [2026-09-23] Поля шагов «набор тел» и «набор точек» (форма шага команды): флажки тел столбиком,
   поле точек — несколько строк. Ref: docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md §6.3.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-shapes {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.easy3d-shape-item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--font-size-xs);
}

.easy3d-shape-item .easy3d-input {
    width: auto;
}

textarea.easy3d-input {
    min-height: var(--space-16);
    resize: vertical;
    font-family: var(--font-family-mono);
}

.easy3d-form-actions {
    display: flex;
    gap: var(--space-2);
    justify-content: flex-end;
}

/* ===== Строка состояния, как у оригинала: подсказка и статус слева, привязки флажками справа ===== */
.easy3d-statusbar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-1) var(--space-3);
    border-top: thin solid var(--border-color);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
}

.easy3d-status-text {
    display: flex;
    gap: var(--space-3);
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* [2026-09-25] Статус и подсказка сжимаются с многоточием, а не обрезаются посреди слова: при
   видимых координатах курсора в русском окне 1266 точек статус отказа (343 точки) резался рамкой
   строки на 185 точках, и середина статуса уходила за край (живой прогон страницы модуля: «статус
   не виден на месте»). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-hint,
.easy3d-status {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.easy3d-status {
    color: var(--text-primary);
}

.easy3d-status:empty {
    display: none;
}

.easy3d-snap-row {
    flex: 0 0 auto;
    display: flex;
    gap: var(--space-3);
}

/* [2026-09-25] Координаты курсора (ТЗ §6.9 п.2): цифры одной ширины — столбцы не прыгают при
   движении мыши; пустое поле места не занимает. Ref: .unlazy/easy3d/gates/leaf-1.9.md G13.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-cursor {
    flex: 0 0 auto;
    margin-left: auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

.easy3d-cursor:empty {
    display: none;
}

/* [2026-09-25] Занятость ядра в ленте (ТЗ §6.3 п.5, §6.9 п.3): бегущая полоса по нижнему краю
   ленты, пока идёт тяжёлая операция; окно не блокируется. Ref: .unlazy/easy3d/gates/leaf-1.9.md G13.
   Chat: easy3d-port-ui-2026-09-23. */
.easy3d-ribbon {
    position: relative;
}

.easy3d-ribbon[data-easy3d-busy='true']::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--space-1);
    background-image: linear-gradient(90deg, transparent, var(--brand-primary), transparent);
    background-size: 40% 100%;
    background-repeat: no-repeat;
    animation: easy3d-busy-sweep var(--spinner-duration) linear infinite;
}

@keyframes easy3d-busy-sweep {
    from {
        background-position: -40% 0;
    }
    to {
        background-position: 140% 0;
    }
}

/* [2026-09-25] Отчёт проверки тела в окне сервиса (ТЗ §6.7): итог строкой, дефекты — перечнем
   строк. Ref: .unlazy/easy3d/gates/leaf-1.9.md G12. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-check-overall {
    margin: 0 0 var(--space-2);
    color: var(--text-primary);
}

.easy3d-check-overall[data-easy3d-check='invalid'] {
    color: var(--color-error);
}

.easy3d-check-list {
    max-height: calc(var(--space-20) * 3);
    margin: 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
    border-top: thin solid var(--border-color);
}

.easy3d-check-row {
    padding: var(--space-1) 0;
    border-bottom: thin solid var(--border-color);
}

.easy3d-snap {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    white-space: nowrap;
    cursor: pointer;
}

.easy3d-snap input {
    margin: 0;
    accent-color: var(--brand-primary);
}

/* Панель сведений: справка, состав поставки, список клавиш — на странице, не окном. */
.easy3d-info {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    z-index: var(--z-popover);
    max-width: calc(var(--space-20) * 5);
    max-height: 70vh;
    overflow-y: auto;
    padding: var(--space-4);
    border: thin solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-primary);
    box-shadow: var(--shadow-md);
}

.easy3d-info-title {
    margin: 0 0 var(--space-2);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

.easy3d-info-row {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-normal);
}

/* ===== Тесное окно: колонка уже, привязки — без подписей; ещё уже — колонка над сценой ===== */
@media (max-width: 1100px) {
    .easy3d-sidebar {
        flex-basis: calc(var(--space-20) * 3.5);
    }

    .easy3d-snap span {
        display: none;
    }
}

@media (max-width: 820px) {
    .easy3d-workspace {
        flex-direction: column;
    }

    .easy3d-sidebar {
        flex: 0 0 40%;
        border-right: 0;
        border-bottom: thin solid var(--border-color);
    }

    .easy3d-statusbar {
        flex-wrap: wrap;
    }
}

/* ===== Дерево модели и свойства узла: отступ по глубине, выделение, скрытие, поля ввода ===== */
/* [2026-09-24] Причина: строки дерева и свойств не имели ни отступа по глубине, ни признака
   выделения и скрытия — иерархию документа и выбор строки на экране видно не было.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Документ и оболочка: дерево, свойства);
   цель PO 2026-09-24 «100 % функционала оригинала». Chat: easy3d-port-ui-2026-09-23. */
.easy3d-tree-row {
    padding-left: calc(var(--space-2) + var(--easy3d-depth, 0) * var(--space-4));
    gap: var(--space-1);
}

.easy3d-row-selected {
    background-color: var(--bg-tertiary);
    box-shadow: inset var(--space-1) 0 0 var(--primary-color);
}

.easy3d-tree-hidden .easy3d-tree-name {
    color: var(--text-tertiary);
}

/* [2026-09-24] Перенос узла мышью: цель подсвечивается только когда перенос допустим, и
   подсветка собрана из токенов темы — своих цветов у модуля нет.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Дерево: перенос узла мышью). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-tree-drop-target {
    background-color: var(--bg-tertiary);
    outline: var(--space-1) solid var(--primary-color);
    outline-offset: calc(var(--space-1) * -1);
}

.easy3d-tree-dragging {
    opacity: 0.6;
}

.easy3d-tree-name {
    flex: 1;
    min-width: 0;
}

.easy3d-tree-spacer {
    display: inline-block;
    width: calc(var(--space-1) * 2 + var(--font-size-xl));
}

.easy3d-tree-input,
.easy3d-prop-input {
    flex: 1;
    min-width: 0;
}

.easy3d-prop-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* [2026-09-24] Отменённая команда в истории приглушена: её вернёт «Повтор», а новая команда снимет.
   Ref: docs/easy3d/DOC_MODEL_EASY3D.md §Отмена и повтор. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-history-undone {
    color: var(--text-tertiary);
}

/* ===== Стартовый экран (ТЗ §3.5): новый документ, открытие, настройки, недавние проекты ===== */
/* [2026-09-24] Причина: у порта не было стартового экрана оригинала — он открывался в пустую
   область проектирования. Экран лежит поверх области, столбцами: слева действия и настройки,
   справа приветствие и перечень недавних. Цвета — только токенами, линии — ключевым словом `thin`.
   Ref: docs/easy3d/PARITY_CHILI3D.md (Стартовый экран); docs/TZ_EASY3D_INDEPENDENT_CAD_2026-09-22.md
   §3.5. Chat: easy3d-port-ui-2026-09-23. */
.easy3d-landing {
    position: absolute;
    inset: 0;
    /* [2026-09-24] Проверка по живому снимку: органы вида (метка режима, кнопки масштаба —
       --z-sticky) рисовались ПОВЕРХ стартового экрана. Слой экрана — токеном выше них
       (--z-fixed), но ниже подсказок и окон. Chat: easy3d-port-ui-2026-09-23. */
    z-index: var(--z-fixed);
    display: flex;
    background: var(--bg-primary);
    overflow: hidden;
}

.easy3d-landing[hidden] {
    display: none;
}

/* [2026-09-25] Общее окно Open (ActivityDocumentBrowser, подложка `.document-browser-overlay`) несёт
   в общем файле z-index 1000 — ниже слоёв порта (--z-sticky 1020, --z-dropdown 1025) и стартового
   экрана (--z-fixed 1030). Снимок фронта 2026-09-25: окно открывалось ПОД стартовым экраном и не
   принимало нажатий. Слой окна на странице модуля — токеном окон (--z-modal), как задумано выше
   («ниже подсказок и окон»); общий файл окна не трогается — от него живут Word, PDF и Fish.
   Ref: docs/easy3d/UI_EASY3D.md (Модуль-страница easykawa и окно Open). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-page .document-browser-overlay {
    z-index: var(--z-modal);
}

.easy3d-landing-left {
    flex: 0 0 calc(var(--space-20) * 3.5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-6);
    border-right: thin solid var(--border-color);
    overflow-y: auto;
}

.easy3d-landing-right {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-6);
    overflow-y: auto;
}

.easy3d-landing-brand {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.easy3d-landing-action {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-2);
    width: 100%;
}

/* [2026-09-25] Общий `.btn-secondary` (styles/modal.css) несёт внешний отступ справа для ряда кнопок
   футера окна; кнопке столбца на всю его ширину он даёт лишние 8 px, и снимок фронта 2026-09-25
   показал полосу прокрутки вбок под левым столбцом. Кнопки столбца отступов наружу не имеют.
   Ref: docs/easy3d/UI_EASY3D.md (Модуль-страница easykawa и окно Open). Chat: easy3d-port-ui-2026-09-23. */
.easy3d-landing .easy3d-landing-action {
    margin: 0;
}

.easy3d-landing-settings {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

.easy3d-landing-setting {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.easy3d-landing-setting-caption {
    color: var(--text-secondary);
    font-size: var(--font-size-xs);
}

.easy3d-landing-title {
    margin: 0;
    font-size: var(--font-size-3xl);
    color: var(--text-primary);
}

.easy3d-landing-subtitle {
    margin: 0;
    font-size: var(--font-size-base);
    color: var(--text-secondary);
}

.easy3d-landing-recent-title {
    margin: var(--space-2) 0 0;
    font-size: var(--font-size-xl);
    color: var(--text-primary);
}

.easy3d-landing-recent {
    gap: var(--space-1);
}

.easy3d-recent-row {
    gap: var(--space-3);
    padding: var(--space-2);
}

.easy3d-recent-image {
    flex: 0 0 auto;
    width: calc(var(--space-20) * 0.8);
    height: calc(var(--space-20) * 0.6);
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--bg-tertiary);
    color: var(--text-tertiary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.easy3d-recent-name {
    flex: 1;
    min-width: 0;
}

.easy3d-recent-date {
    color: var(--text-tertiary);
    font-size: var(--font-size-xs);
}

.easy3d-recent-delete {
    margin-left: auto;
}

.easy3d-recent-question {
    flex: 1;
    min-width: 0;
    color: var(--text-primary);
}

.easy3d-recent-confirm {
    background-color: var(--bg-tertiary);
    box-shadow: inset var(--space-1) 0 0 var(--primary-color);
}

@media (max-width: 820px) {
    .easy3d-landing {
        flex-direction: column;
    }

    .easy3d-landing-left {
        flex: 0 0 auto;
        border-right: 0;
        border-bottom: thin solid var(--border-color);
    }
}
