/* Файл: client/js/Widgets/Table.css
   Визуальный стиль виджета Table (см. Widgets/Table.js) — карточка с тенью, как и в
   Cerberus/admin (см. Widgets/Group.css: .group-card) и в самом Cerberus (.users-db-card,
   client/cerberus.html) — везде один и тот же рецепт padding/radius/shadow, продублирован
   намеренно (каждый виджет отвечает за свой внешний вид сам, без общего базового файла).
   Заголовок таблицы (caption) — жирный, главное на карточке; заголовки колонок —
   вспомогательная информация, поэтому подчёркнуто скромнее (без фона, серым, мельче). */

/* display:flex + gap (2026-09-30) — расстояние между заголовком/Toolbox/содержимым таблицы теперь
   через gap этого контейнера, не через margin-bottom самих .canvas-table-caption/.toolbox (см. их
   правила). Сентинел бесконечного скролла НЕ страдает от этого — он всегда обёрнут вместе с
   таблицей/карточками в один div (.canvas-table-scroll/.canvas-table-content, см. Widgets/Table.js),
   а не является отдельным прямым ребёнком .canvas-table.
   Без собственного margin (нашли и убрали 2026-10-03): родитель (форма/модалка/Group) уже даёт
   gap:var(--spacing) своим детям через orientationStyle() (Widgets/Group.js) — тот же принцип, что
   уже применён к .field-group/.field-caption. Старый margin-top/bottom здесь поверх этого gap давал
   двойной отступ между соседними таблицами (10+10+10=30px вместо 10px) — реальный баг, найден на
   Doc_Tickets.Element (пустота между Participants и Messages). */
.canvas-table {
    display: flex;
    flex-direction: column;
    gap: var(--spacing, 10px);
}

/* BorderVisibility (см. Table.js::renderElementTable, тот же принцип, что и у Group —
   Widgets/Group.css) — NoBorder не добавляет ни один из этих классов (плоский контейнер),
   NormalBorder добавляет .canvas-table-bordered, StrongBorder — оба класса сразу (усиленная тень). */
.canvas-table-bordered {
    padding: var(--spacing, 10px);
    border-radius: 8px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    background: white;
}
.canvas-table-bordered.canvas-table-bordered-strong {
    box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}

/* margin-bottom убран (2026-09-30) — расстояние до Toolbox/содержимого теперь даёт gap родителя
   (.canvas-table, см. выше). */
.canvas-table-caption {
    font-size: calc(var(--font-size, 14px) + 2px);
    font-weight: bold;
    color: #000;
}

/* Grid-режим (не cards) — 2026-10-11, перевод с настоящего <table> на CSS Grid (один
   .canvas-table-grid с grid-template-columns, инлайн-ширины те же columnWidthStyle, что раньше
   собирали <col>; реальный инцидент — узкая колонка с кнопкой (свой padding 10px/15px) наезжала
   на соседнюю Stock, потому что у table-layout:fixed нет штатного способа "подрезать" содержимое
   ячейки без явного overflow:hidden, которого раньше просто нигде не было). Строка —
   .canvas-table-datarow с display:contents (её дети становятся прямыми grid-item'ами родителя и
   выстраиваются в те же колонки, что и у соседних строк), сам DOM-узел строки никуда не девается —
   весь код, завязанный на класс .canvas-table-datarow (выбор строки, dblclick->Open, фильтры,
   довставка по скроллу), продолжает работать без изменений, см. Widgets/Table.js. */
.canvas-table-grid {
    display: grid;
    font-size: var(--font-size, 14px);
}

.canvas-table-th {
    font-weight: normal;
    color: #000;
    background: none;
    font-size: var(--font-size, 14px);
    /* padding:6px -> var(--spacing) (обсуждение 2026-10-11, см. память feedback_universal_spacing_rule) —
       заголовок колонки визуально не совпадал по горизонтальному отступу с данными под ним
       (.canvas-table-td даёт var(--spacing), заголовок был захардкожен на 6px). */
    padding: var(--spacing, 10px);
    text-align: left;
    border-bottom: 1px solid #eee;
    /* overflow:hidden + min-width:0 — та самая структурная гарантия "ячейка никогда не наедет на
       соседнюю колонку", которой раньше не было: ни длинная подпись без пробелов (DeletionMark),
       ни кнопка со своим padding (см. комментарий выше) не могут вылезти за границы своего трека. */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    min-width: 0;
}

.canvas-table-td {
    /* И вертикальный, и горизонтальный padding — один и тот же --spacing (обсуждение 2026-09-30,
       "все отступы" — единообразно, без исключений). RowSpacing (--row-spacing) по-прежнему может
       переопределить ТОЛЬКО вертикаль (расстояние между записями) для конкретной таблицы —
       горизонталь у него своего смысла не имеет, эту ось всегда решает общий --spacing формы. */
    padding: var(--row-spacing, var(--spacing, 10px)) var(--spacing, 10px);
    cursor: pointer;
    overflow: hidden;
    min-width: 0;
}

/* RowBorderVisibility (см. Table.js::renderTableRowsHtml) — раньше border-bottom между строками
   был жёстко зашит и не регулировался; теперь NoBorder — разделителя нет вообще, NormalBorder —
   .row-border (как раньше), StrongBorder — оба класса (заметнее). Дочерний комбинатор (> .canvas-
   table-td) работает даже через display:contents родителя — тот не убирает элемент из DOM-дерева
   для целей селекторов, только из модели боксов (см. спецификацию display:contents). */
.row-border > .canvas-table-td {
    border-bottom: 1px solid #eee;
}
.row-border.row-border-strong > .canvas-table-td {
    border-bottom: 2px solid #999;
}

/* .canvas-table-datarow сам display:contents — у него нет собственного бокса и красить фон
   напрямую бессмысленно (ничего не нарисуется), поэтому выделение/hover строки красит каждую её
   ячейку по отдельности через дочерний комбинатор. :hover на display:contents элементе по-прежнему
   срабатывает, пока курсор над любым его ребёнком — вся "строка" подсвечивается как одно целое. */
.canvas-table-datarow.selected > .canvas-table-td,
.canvas-table-datarow.selected-row > .canvas-table-td {
    background-color: #cce8ff;
}
.canvas-table-datarow:hover > .canvas-table-td {
    background-color: #f7f7f7;
}

.table-load-sentinel {
    height: 1px;
}

.canvas-table-scroll {
    overflow-y: auto;
}
.canvas-table-scroll .canvas-table-header-row > .canvas-table-th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: #fff;
}

/* Layout:"cards" (см. Table.js::renderElementTable) — одна запись = один блок вместо строки
   таблицы, поля друг под другом с подписями. Для узких экранов, где обычная таблица с большим
   числом колонок либо сжимается до нечитаемости (table-layout:fixed выше), либо требует
   горизонтальной прокрутки. */
.canvas-table-cards {
    display: flex;
    flex-direction: column;
    /* RowSpacing (см. Table.js::renderElementTable, --row-spacing) — тот же смысл, что и
       вертикальный padding у .canvas-table td в grid-режиме: расстояние между записями. Тот же
       фолбэк на общий --spacing формы, что и в grid-режиме выше (обсуждение 2026-09-30). */
    gap: var(--row-spacing, var(--spacing, 10px));
}
.canvas-table-cards-empty {
    text-align: center;
    padding: var(--spacing, 10px);
    color: #888;
    font-size: var(--font-size, 14px);
}
/* display:flex + gap (2026-09-30) — расстояние МЕЖДУ полями/группами карточки теперь через gap
   этого контейнера, не через margin-bottom самих .card-field/.card-group (см. их правила ниже —
   margin-bottom убран, включая больше не нужный .card-field:last-child override). */
.canvas-table-card {
    display: flex;
    flex-direction: column;
    gap: var(--spacing, 10px);
    border-radius: 6px;
    padding: var(--spacing, 10px);
    cursor: pointer;
}
/* RowBorderVisibility в cards-режиме (см. Table.js::renderTableCardsRowsHtml) — то же свойство,
   что даёт .row-border у <tr> в grid-режиме, просто в другом layout рисуется иначе (граница
   карточки, а не строки). Отдельно от BorderVisibility самой таблицы: можно, например, оставить
   обычную рамку у таблицы целиком, но выделить каждую карточку внутри неё сильнее. NoBorder —
   ни один класс не добавляется. */
.canvas-table-card.card-border {
    border: 1px solid #eee;
}
.canvas-table-card.card-border.card-border-strong {
    border: 2px solid #999;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.canvas-table-card.selected-row {
    background-color: #cce8ff;
    border-color: #7ab8f5;
}
/* margin-bottom убран, gap добавлен (2026-09-30) — то же единое правило, что и у .field-group
   (client-form.css): расстояние до следующего card-field/card-group даёт gap у .canvas-table-card
   (выше), расстояние между ЕГО ЖЕ label и value — gap самого .card-field. :last-child override
   больше не нужен — gap никогда не добавляет отступ после последнего ребёнка. */
.card-field {
    display: flex;
    flex-direction: column;
    gap: var(--spacing, 10px);
}
.card-field-label {
    display: block;
    font-size: calc(var(--font-size, 14px) - 1px);
    color: #888;
}
/* :not(.stepper-input) — реальный инцидент (2026-10-11, Agent, обнаружен на 320px): по CSS-
   специфичности `.card-field-value input` (класс+тег) перебивает `.stepper-input { width:48px }`
   (Widgets/Stepper.css, только класс) независимо от порядка подключения файлов — число внутри
   степпера растягивалось на 100% ширины карточки ЦЕЛИКОМ, а рядом ещё стояли свои −/+ кнопки,
   сумма вылезала за карточку (и за саму модалку выбора товара). Степпер — компактный виджет под
   тесную ячейку по дизайну (см. комментарий в Stepper.css), а не поле, которое должно
   растягиваться на всю ширину карточки. */
.card-field-value input:not(.stepper-input),
.card-field-value select,
.card-field-value textarea {
    width: 100%;
}
/* .field-plaintext (PlainText-режим readonly поля, Widgets/Field.js) — тот же span, что рисуется
   и ВНЕ таблицы, сюда не попадал: width:100% на инлайновом <span> браузер вообще игнорирует
   (width применяется только к block/inline-block), а без display:block элемент остаётся ровно по
   размеру своего текста — alignTextHorizontal (text-align, см. Widgets/Field.js/utils.js) физически
   нечего двигать внутри такого span (места под текстом ровно столько же, сколько самого текста).
   Снаружи это выглядело так, будто text-align молча не работает именно в cards-режиме (обнаружено
   вживую на Ref_Products.Picker/Price: с обычным <input> — работало, стоило включить PlainText —
   текст "уезжал" обратно влево, обсуждение 2026-10-11). */
.card-field-value .field-plaintext {
    display: block;
    width: 100%;
}
/* captionPosition:left/right колонки (см. Widgets/Table.js::fieldBlockHtml) — тот же приём, что
   .field-group-row у обычных полей вне таблицы (client-form.css): порядок left/right решает JS
   порядком кусков HTML (label/value меняются местами в разметке), не flex-direction:row-reverse —
   визуальный порядок остаётся равен DOM/Tab-порядку. Работает только в card-режиме — в grid-режиме
   caption уходит в заголовок колонки (общий на все строки), позиционировать там нечего. */
.card-field-row {
    flex-direction: row;
    align-items: center;
}
.card-field-row > .card-field-label {
    flex: 0 0 auto;
}
.card-field-row > :not(.card-field-label) {
    flex: 1;
    min-width: 0;
}
/* margin-bottom убран, gap добавлен (2026-09-30) — та же логика, что у .card-field выше: расстояние
   до следующего соседа даёт .canvas-table-card, расстояние между СВОИМИ caption и внутренней
   строкой полей — свой же gap. */
.card-group {
    display: flex;
    flex-direction: column;
    gap: var(--spacing, 10px);
}
.card-group-caption {
    font-size: calc(var(--font-size, 14px) - 1px);
    color: #888;
    font-weight: bold;
}
.card-group .card-field {
    flex: 1;
    min-width: 100px;
}
.card-group .card-field-button {
    flex: 0 0 auto;
    min-width: 0;
}
/* Колонка верхнего уровня (не внутри tablecolumngroup) — родитель тут .canvas-table-card
   (column flex), не .card-group (row flex), поэтому ось, которую нужно гасить, другая: в row
   flex:0 0 auto гасит растяжение по ГЛАВНОЙ оси (ширина), а в column flex ширина — это ПОПЕРЕЧНАЯ
   ось, её контролирует align-self, не flex. Без этого правила кнопка/label верхнего уровня
   растягивались на всю ширину карточки (align-items:normal/stretch родителя по умолчанию) —
   реальный случай: RowDeleteBtn (Doc_Orders.Element, не в группе) превращался в полноширинную
   синюю плашку вместо компактной кнопки (обсуждение 2026-10-11/12). */
.canvas-table-card > .card-field-button {
    align-self: flex-start;
    min-width: 0;
}

/* Grid-режим (не cards) — та же пара правил, что card-field/card-field-button выше, для
   TableColumnGroup внутри обычной <tr> (см. Widgets/Table.js::renderTableRowsHtml). Без flex:1
   и min-width:0 поля с width:100% (form-control) при orientation:horizontal не сжимаются
   (см. ".form-container *, .modal-body * { flex-shrink: 0; }" в client-form.css) и вылезают
   друг на друга — например, Body вылезал поверх колонки с кнопками в Doc_Tickets.Element. */
/* Ячейка группы сама по себе — обычный <div>, не <td>, поэтому по умолчанию не растягивается
   на высоту строки, даже если сосед-колонка (напр. кнопки) её выше — height:100% отталкивается от
   родительской <td>, у которой высота уже определена высотой строки таблицы. Без этого дочернему
   полю (см. node.height в Widgets/Field.js) не от чего было бы взять "100%". */
.tcg-cell {
    height: 100%;
}
.tcg-cell > .tcg-item {
    flex: 1 1 0;
    min-width: 0;
}
/* .tcg-item сам стал flex-контейнером (2026-10-10, Widgets/Table.js — align-items для центрирования
   по высоте, см. тот файл). Побочный эффект: раньше .tcg-item был обычным блоком, и его единственный
   ребёнок (строка поля, например .lookup-select-row) занимал 100% ширины автоматически — обычное
   поведение блочных детей. Внутри flex-контейнера дети ТАК не делают — без flex:1 они сжимаются до
   размера своего содержимого (а <input> без явной ширины схлопывается к браузерному дефолту
   ~193px), вместо того чтобы заполнить доступные 104px — реальный баг, найденный вживую на
   Doc_Orders.List/Doc_Invoices.List (Client "вылезал" в соседнюю колонку DocumentDate). */
.tcg-item > * {
    flex: 1 1 auto;
    min-width: 0;
}
.tcg-cell > .tcg-item-button {
    flex: 0 0 auto;
}
/* Обёртка .tcg-item-button растягивается по кросс-оси на всю ширину группы (align-items:stretch
   по умолчанию), но сама кнопка внутри — inline-block по размеру своего текста ("Open" уже
   "Delete message"), поэтому визуально были разной ширины несмотря на одинаковые обёртки.
   width:100% — кнопка занимает всю обёртку, все кнопки одной группы становятся одной ширины. */
.tcg-cell > .tcg-item-button > .form-button {
    width: 100%;
}

/* Кнопка как ПРЯМАЯ колонка таблицы (не через TableColumnGroup — обычная button-колонка вроде
   ViewBtn/AddToCartBtn в Ref_Products.List, 2026-10-11). Ячейка (.canvas-table-td) уже даёт padding
   var(--spacing) со всех сторон — тот же самый, что получает любое другое содержимое любой другой
   колонки (текст, число — что угодно). Кнопка не добавляет свой ВТОРОЙ, независимый padding
   (.form-button, 10px/15px) поверх — иначе два отступа складываются и в узкой колонке съедают
   почти всё место под иконку (реальный инцидент: 10px ячейки + 15px кнопки = 25px с каждой стороны
   в колонке 48px, кнопка обрезалась). padding:0 + width:100% — кнопка по ширине занимает всю уже
   отступленную область ячейки целиком, единственный источник горизонтального отступа — сама
   ячейка, как и у любой другой колонки. Высоту НЕ растягиваем (height:100% пробовали и убрали —
   в высокой строке, например рядом с большим фото, кнопка превращалась в длинный столбик): по
   высоте кнопка, как и раньше под <table>, остаётся в своём естественном размере — .canvas-table-td
   как grid-item сам растягивается на всю строку (align-items:stretch по умолчанию), но НЕ-grid
   ребёнок внутри него (сама кнопка) это наследование не получает, если явно не попросить. */
.canvas-table-td > .form-button {
    width: 100%;
    /* padding:0 убрано (обсуждение 2026-10-11) — эмодзи/текст кнопки прижимался прямо к её
       собственному фону без всякого зазора (отступ ячейки снаружи кнопки не помогал — он между
       кнопкой и соседними колонками, а не внутри самой кнопки). Теперь используется обычный
       padding .form-button (Button.css, "10px 15px"), как у любой другой кнопки. Риск, ради
       которого раньше стоял padding:0 (реальный инцидент: узкая кнопка-колонка наезжала на
       соседний Stock) — структурно закрыт позже миграцией grid-режима на CSS Grid
       (overflow:hidden + min-width:0 на ячейках по умолчанию, см. Widgets/Table.js) — теперь
       кнопка шире своей колонки обрежется внутри своей же ячейки, а не наедет на соседнюю. */
}

/* Попап поиска по колонке (см. Widgets/Table.js::showTableSearchPopup) и его баннер активного
   фильтра рисуют свою разметку сами (не через Field.js/Button.js) — своя независимая копия
   .field-caption/.form-control/.form-button, не обязана меняться вместе с формой. */
/* margin-bottom убран (2026-09-30) — расстояние до контрола теперь даёт gap родителя
   (.field-group, см. client-form.css), а не собственный отступ подписи. */
.field-caption {
    display: block;
    font-size: var(--font-size, 14px);
    font-weight: normal;
    color: #000;
}

.form-control {
    width: 100%;
    padding: calc(var(--spacing, 10px) / 2);
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    font-family: inherit;
    font-size: var(--font-size, 14px);
    font-weight: normal;
    color: #000;
}

/* margin-right убран (2026-09-30) — расстояние до соседней кнопки теперь даёт gap родителя
   (тут — .table-search-banner/попап поиска, см. Widgets/Table.js), а не собственный отступ кнопки. */
.form-button {
    padding: 10px 15px;
    background-color: #0078d7;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.form-button:hover {
    background-color: #005a9e;
}
.form-button:disabled {
    background-color: #aaa;
    cursor: not-allowed;
    opacity: 0.7;
}

/* Popup поиска по ref-колонке использует тот же combobox-паттерн, что и Widgets/Combobox.js —
   своя копия классов (см. комментарий в Combobox.css). */
.combobox-control {
    position: relative;
}

.combobox-input-row {
    display: flex;
    gap: var(--spacing, 10px);
    align-items: center;
}

.combobox-input-row .combobox-display {
    flex: 1;
}

.combobox-clear {
    padding: 4px 8px;
    background: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    cursor: pointer;
    color: #666;
    font-size: calc(var(--font-size, 14px) + 2px);
    line-height: 1;
    flex-shrink: 0;
}
.combobox-clear:hover { background: #f0f0f0; }

.combobox-select-btn {
    padding: 4px 8px;
    background: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    cursor: pointer;
    color: #666;
    font-size: calc(var(--font-size, 14px) + 2px);
    line-height: 1;
    flex-shrink: 0;
}
.combobox-select-btn:hover { background: #f0f0f0; }

.combobox-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-top: none;
    border-radius: 0 0 4px 4px;
    max-height: 220px;
    overflow-y: auto;
    z-index: 1000;
    box-shadow: 0 4px 8px rgba(0,0,0,0.12);
}
.combobox-dropdown.open { display: block; }

.combobox-dropdown.drop-up {
    top: auto;
    bottom: 100%;
    border-top: 1px solid #ccc;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    box-shadow: 0 -4px 8px rgba(0,0,0,0.12);
}

.combobox-item {
    padding: 6px 10px;
    cursor: pointer;
    font-size: var(--font-size, 14px);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.combobox-item:hover,
.combobox-item.active { background: #e8f0fe; color: #1a56db; }

.combobox-empty {
    padding: 6px 10px;
    color: #888;
    font-size: var(--font-size, 14px);
    font-style: italic;
}
