/* Файл: 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) — TableColumnGroup внутри обычной <tr> (см.
   Widgets/Table.js::renderTableRowsHtml). Переведено на CSS Grid 2026-10-18 (завершение миграции,
   начатой для основной таблицы 2026-10-11) — раньше здесь был flex, и единственная жёсткая граница
   "не вылезай за свои пределы" стояла только на самой внешней .canvas-table-td; сама кнопка и
   .tcg-item/.tcg-item-button были overflow:visible — реальный повторяющийся баг (найдено вживую:
   Doc_Tickets.Element, узкая icon-only кнопка 🗑️ обрезалась по границе ячейки, потому что padding
   самой кнопки не оставлял места на сам символ). Теперь КАЖДЫЙ уровень вложенности — не только
   внешняя ячейка — имеет свою жёсткую границу (overflow:hidden+min-width:0 ниже), а не только
   самый внешний grid-item. grid-template-columns/rows задаёт сам Table.js (columnGridTrack для
   обычных полей, max-content для кнопок — трек кнопки всегда ровно по её реальному размеру, не
   делит место с соседями поровну, как раньше flex:0 0 auto пытался сделать внутри уже готового
   flex-контейнера). */
/* Ячейка группы сама по себе — обычный <div>, не <td>, поэтому по умолчанию не растягивается
   на высоту строки, даже если сосед-колонка (напр. кнопки) её выше — height:100% отталкивается от
   родительской <td>, у которой высота уже определена высотой строки таблицы. Без этого дочернему
   полю (см. node.height в Widgets/Field.js) не от чего было бы взять "100%". */
.tcg-cell {
    height: 100%;
}
/* overflow:hidden+min-width:0 — та же гарантия, что у .canvas-table-td (см. выше по файлу), теперь
   и на каждом tcg-item: что бы ни оказалось внутри (длинный текст, широкий эмодзи, что угодно ещё
   не написанное) — оно обрежется ВНУТРИ своего же трека, никогда не наедет на соседний tcg-item и
   не вывалится из tcg-cell. box-sizing:border-box — padding/border считаются ВНУТРИ заданной
   grid-треком ширины, а не поверх неё (иначе даже верно посчитанный track мог стать теснее на
   величину padding). */
.tcg-cell > .tcg-item {
    min-width: 0;
    overflow: hidden;
    box-sizing: border-box;
}
/* .tcg-item сам остаётся flex-контейнером (2026-10-10, Widgets/Table.js — align-items для
   центрирования по высоте, см. тот файл) — это другой, внутренний уровень раскладки (как
   выравнивается СОДЕРЖИМОЕ одного tcg-item), не связан с тем, что сам tcg-item — grid-item в
   .tcg-cell. Без flex:1 на ребёнке <input> без явной ширины схлопывается к браузерному дефолту
   ~193px вместо заполнения доступного места — реальный баг, найденный на Doc_Orders.List/
   Doc_Invoices.List (Client "вылезал" в соседнюю колонку DocumentDate). */
.tcg-item > * {
    flex: 1 1 auto;
    min-width: 0;
}
.tcg-cell > .tcg-item-button {
    min-width: 0;
    overflow: hidden;
    box-sizing: border-box;
}
/* Padding кнопки здесь НЕ трогаем (убрано 2026-10-18, обсуждение с пользователем) — Table не решает
   за кнопку её внутренний отступ, это решает сам программист через Internal Padding самой кнопки
   (Button.js/node.padding) или дефолт Button.css. width:100% — кнопка занимает весь свой
   max-content-трек (grid уже посчитал его по реальному размеру кнопки, см. Table.js), все кнопки
   одной группы остаются одной ширины. overflow:hidden+box-sizing:border-box — защита "не вылезай
   за трек", не про padding.
   НЕ ДОБАВЛЯТЬ сюда padding снова, даже ради конкретного инцидента с обрезанной кнопкой — это
   прямое нарушение правила из Button.css (см. комментарий там же, у .form-button). */
.tcg-cell > .tcg-item-button > .form-button {
    width: 100%;
    overflow: hidden;
    box-sizing: border-box;
}

/* Кнопка как ПРЯМАЯ колонка таблицы (не через TableColumnGroup — обычная button-колонка вроде
   ViewBtn/AddToCartBtn в Ref_Products.List, 2026-10-11). Padding кнопки НЕ трогаем (убрано
   2026-10-18) — если колонка узкая (minWidth программиста) и дефолтный padding Button.css не
   влезает, это решает сам программист через Internal Padding кнопки, не Table.css исподтишка.
   НЕ ДОБАВЛЯТЬ сюда padding снова — см. правило в Button.css/.form-button.
   width:100% — кнопка занимает всю ширину своей (уже отступленной ячейкой) области. Высоту НЕ
   растягиваем (height:100% пробовали и убрали — в высокой строке кнопка превращалась в длинный
   столбик): .canvas-table-td сам растягивается на всю строку, но НЕ-grid ребёнок (сама кнопка) это
   наследование не получает, если явно не попросить. */
.canvas-table-td > .form-button {
    width: 100%;
    overflow: hidden;
    box-sizing: border-box;
}

/* Попап поиска по колонке (см. 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;
}

/* Своя копия, не связана с Internal Padding/node.padding (см. Button.css/.form-button) — это
   статичная разметка попапа поиска, не узел формы, переопределять её через специфичность откуда-то
   ещё так же не нужно, как и настоящие .form-control/.form-button ниже и в Field/Combobox/Select/
   Button.css. */
.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-control чуть выше — своя копия, не настоящая Internal Padding. */
.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;
}
