/* Компоненты сервиса в оформлении приложений аналитики и PROTOOLS.

   1. Bootstrap: поля, чекбоксы, переключатели, выпадающие меню, подсказки, модальные окна
   2. Таблицы .complex_table и обычные .table
   3. Управление таблицей: кнопки «на страницу» и «столбцы», пагинация, поиск, фильтры-кирпичики
   4. Календарь gijgo
   5. Блоки приложений
   6. Оповещения (window.notifications)
   7. Подсказки (атрибут data-tip)

   Только токены root.css - светлая и тёмная тема работают без отдельных правил.
   Подключается после navigation.css и до _app.css. Календарь gijgo грузится позже
   (через @import в _app.css), поэтому его селекторы здесь на класс тяжелее оригинальных */

/* Шеврон выпадающих кнопок - маской, чтобы цвет шёл из токена */
:root {
	--chevron-mask: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4.50495 5.78413L0.205241 1.25827C-0.0684138 0.970375 -0.0684138 0.503596 0.205241 0.215836C0.478652 -0.0719461 0.922098 -0.071946 1.19549 0.215837L5.00007 4.22052L8.80452 0.215953C9.07805 -0.0718292 9.52145 -0.0718292 9.79486 0.215953C10.0684 0.503736 10.0684 0.970492 9.79486 1.25839L5.49508 5.78425C5.35831 5.92814 5.17925 6 5.00009 6C4.82085 6 4.64165 5.928 4.50495 5.78413Z' fill='black'/%3E%3C/svg%3E");
}

/* ================= 1. BOOTSTRAP ================= */

/* ---------- Поля ввода ---------- */

.form-control,
.form-select {
	border-color: var(--input);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--foreground);
	transition: border-color .15s ease, box-shadow .15s ease;
}

.form-control::placeholder {
	color: var(--muted-foreground);
}

/* Автозаполнение браузера (логин, пароль) - на фоне поля, а не своим светлым: в тёмной теме поле светлело.
   Фон автозаполнения Chrome не перебить background-color - закрашиваем внутренней тенью, текст - text-fill-color */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:focus {
	-webkit-box-shadow: 0 0 0 1000px var(--card) inset;
	-webkit-text-fill-color: var(--foreground);
	caret-color: var(--foreground);
	transition: background-color 9999s ease-out 0s;
}

.form-control:-webkit-autofill:focus {
	-webkit-box-shadow: 0 0 0 1000px var(--card) inset, 0 0 0 3px var(--ring-veil);
}

/* Встроенные элементы браузера (автозаполнение, полосы прокрутки, календарь) - в тон теме */
[data-theme="dark"] {
	color-scheme: dark;
}

.form-control:focus,
.form-select:focus {
	background-color: var(--card);
	color: var(--foreground);
}

.form-control:disabled,
.form-control[readonly],
.form-select:disabled {
	background-color: var(--muted);
	color: var(--muted-foreground);
}

.form-control.datepicker[readonly]:not(:disabled),
.form-control.datetimepicker[readonly]:not(:disabled) {
	background-color: var(--card);
	color: var(--foreground);
	cursor: pointer;
}

.form-select {
	background-image: var(--icon-chevron);
	background-size: 12px 12px;
}

.form-control[type="file"]::file-selector-button {
	background-color: var(--secondary);
	color: var(--secondary-foreground);
}

.input-group-text {
	border-color: var(--input);
	background-color: var(--muted);
	color: var(--muted-foreground);
}

.form-control.is-invalid,
.form-select.is-invalid {
	border-color: var(--destructive);
}

.invalid-feedback {
	color: var(--destructive);
}

.text-muted,
.form-text {
	color: var(--muted-foreground) !important;
}

/* Классы Bootstrap с зашитым цветом: в светлой теме остаются как есть */
[data-theme="dark"] .text-danger {
	color: var(--destructive-text) !important;
}

[data-theme="dark"] .btn-secondary,
[data-theme="dark"] .btn-light {
	border-color: var(--border);
	background-color: var(--secondary);
	color: var(--secondary-foreground);
}

[data-theme="dark"] .btn-secondary:hover,
[data-theme="dark"] .btn-light:hover {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

/* Циферблат выбора времени в календаре (app.func.css) */
[data-theme="dark"] .gj-picker [role="body"] [role="dial"] {
	background-color: var(--accent);
	color: var(--foreground);
}

/* Ссылка в подписи - размера подписи. Иначе её раздувает до 14px общее a:not(.btn) из _app.css */
small a:not(.btn),
.form-text a:not(.btn) {
	font-size: inherit;
}

/* Ряд полей и сетка полей - все поля блока одной ширины и вместе занимают всю ширину ряда: колонка от 350 пикселей, сколько поместится.
   Последнее поле на отдельной строке остается шириной с остальными. Подпись с значком папки - в одну строку, поэтому поля стоят на одной линии.
   Первое значение grid-template-columns - для браузеров без min() */
.fields_row,
.fields_grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
	grid-template-columns: repeat(auto-fit, minmax(min(350px, 100%), 1fr));
	grid-gap: 12px 20px;
	gap: 12px 20px;
	align-items: start;
	margin-bottom: 16px;
}

/* Блок, где есть длинная подпись (склады возврата, нумерация отчета): колонка шире, чтобы подпись помещалась целиком.
   В одну колонку поле не растягивается на всю ширину */
.fields_row.fields_long_labels,
.fields_grid.fields_long_labels {
	grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
	grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
}

.fields_row > *,
.fields_grid > * {
	min-width: 0;
	max-width: 100%;
}

.fields_long_labels > .field:not(.wide) {
	max-width: 520px;
}

.fields_row > .field.half:only-of-type:not(.wide),
.fields_grid > .field.half:only-of-type:not(.wide) {
	max-width: 100%;
}

/* Длинное поле (текст письма) и подсказка на весь ряд - отдельной строкой. Поле ввода в нем все равно не шире 500 пикселей (ниже) */
.fields_row > .field.wide,
.fields_row > .form-text,
.fields_grid > .field.wide,
.fields_grid > .form-text {
	grid-column: 1 / -1;
}

/* Поле не шире своей колонки: длинный текст (составное имя в <nobr>, длинные значения) переносится, а не раздвигает ряд */
.fields_row > .field,
.fields_grid > .field {
	overflow-wrap: break-word;
	overflow-wrap: anywhere;
}

.fields_row > .field nobr,
.fields_grid > .field nobr {
	white-space: normal;
}

/* Поле-чекбокс (.field.form-check) - как обычный блок */
.fields_row > .field:not(.form-check),
.fields_grid > .field:not(.form-check) {
	display: flex;
	flex-direction: column;
}

/* Длинный выбранный пункт селекта не раздвигает поле, многоточие срабатывает (WB → Товары → Импорт, Остатки → Экспорт) */
.fields_row > .field > *,
.fields_grid > .field > * {
	min-width: 0;
	max-width: 100%;
}

/* Подпись в одну строку; шире контейнера (узкий экран) - с многоточием */
.fields_row > .field:not(.form-check) > label,
.fields_grid > .field:not(.form-check) > label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.fields_row > .field:not(.form-check) > label nobr,
.fields_grid > .field:not(.form-check) > label nobr {
	white-space: nowrap;
}

textarea.form-control,
.complex_table .search .form-control,
.fields_row > :not(.wide) .form-control,
.fields_row > :not(.wide) .form-select,
.fields_row > :not(.wide) .custom_select,
.fields_row > :not(.wide) .input-group,
.fields_grid > :not(.wide) .form-control,
.fields_grid > :not(.wide) .form-select,
.fields_grid > :not(.wide) .custom_select,
.fields_grid > :not(.wide) .input-group {
	max-width: none;
}

/* Значок «Создать поле / статус» в подписи поля - сразу за текстом, в строку с ним */
.field > label > a[data-action^="create_"],
.section_field > label > a[data-action^="create_"] {
	display: inline-flex;
	align-items: center;
	padding: 0;
	vertical-align: -2px;
}

/* ---------- Кнопки ----------

   Подписи кнопок - обычным регистром, без разрядки. !important - на случай правил
   в стилях шаблонов, которые идут после этого файла */

.btn,
button,
input[type="button"],
input[type="submit"],
input[type="reset"] {
	text-transform: none !important;
	letter-spacing: normal !important;
	word-spacing: normal !important;
}

/* ---------- Чекбоксы, радио, переключатели ----------

   Галочка, точка и кружок переключателя у Bootstrap - SVG с зашитым цветом.
   Берём их из токенов: в тёмной теме они перекрашиваются вместе со всем */

.form-check-input {
	border-color: var(--checkbox-border);
	background-color: var(--card);
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

/* Квадратные чекбоксы - 13×13 везде (переключатели .form-switch не трогаем).
   По вертикали - по центру первой строки подписи: подпись 13px × line-height 1.8 = 23,4px, отступ сверху 5px (_app.css) */
:not(.form-switch) > .form-check-input[type="checkbox"] {
	width: 13px;
	height: 13px;
	border-radius: 3px;
}

.form-check-input:hover {
	background-color: var(--accent);
}

.form-check-input[type="checkbox"]:checked {
	background-image: var(--icon-check);
}

.form-check-input[type="radio"]:checked {
	background-image: var(--icon-dot);
}

.form-check-input:checked:hover {
	background-color: var(--checked-radio-hover);
	border-color: var(--checked-radio-hover);
}

.form-switch .form-check-input,
.form-switch .form-check-input:focus {
	background-image: var(--icon-switch);
}

.form-switch .form-check-input:checked,
.form-switch .form-check-input:checked:focus {
	background-image: var(--icon-switch-on);
}

.form-check-input:disabled {
	background-color: var(--muted);
	cursor: default;
}

/* Отмеченный неактивный - не серым по серому (галочка не читалась): приглушенный черный в светлой теме, приглушенный основной в темной */
.form-check-input:disabled:checked {
	border-color: var(--checkbox-disabled);
	background-color: var(--checkbox-disabled);
	opacity: 1;
}

.form-check-label,
.form-check label {
	color: var(--foreground);
	cursor: pointer;
}

.form-check-input:disabled ~ .form-check-label {
	color: var(--muted-foreground);
	cursor: default;
}

/* ---------- Выпадающие меню ---------- */

/* У выпадающего списка нет внутренних отступов - только у его пунктов.
   overflow: hidden, чтобы заливка пунктов не вылезала за скругление */
.dropdown-menu {
	padding: 0;
	overflow: hidden;
	border-color: var(--border);
	border-radius: var(--radius-md);
	background-color: var(--popover);
	color: var(--popover-foreground);
	box-shadow: var(--shadow-md);
	font-size: 13px;
}

/* Подсказки полей учётной системы (data-action="autocomplete") - #autocomplete из _app.js.
   Как список кастомного селекта: без общего отступа, пункты на всю ширину, подсветка --accent */
#autocomplete {
	position: absolute;
	z-index: 1065;
	display: none;
	min-width: 240px;
	max-height: 300px;
	overflow-y: auto;
	padding: 0;
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--popover);
	color: var(--popover-foreground);
	box-shadow: var(--shadow-md);
}

#autocomplete ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

#autocomplete li {
	display: flex;
	align-items: center;
	min-height: 32px;
	padding: 4px 12px;
	font-size: 13px !important;
	line-height: 1.3;
	cursor: pointer;
}

#autocomplete li:hover {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

.dropdown-item {
	padding: 7px 12px;
	color: var(--popover-foreground);
}

.dropdown-item:hover,
.dropdown-item:focus {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

.dropdown-divider {
	border-color: var(--border);
}

/* ---------- Подсказки и поповеры ---------- */

.tooltip-inner {
	padding: 6px 10px;
	border-radius: var(--radius-md);
	background-color: var(--tooltip-bg);
	color: var(--tooltip-foreground);
	font-size: 12px;
}

.bs-tooltip-top .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { border-top-color: var(--tooltip-bg); }
.bs-tooltip-bottom .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { border-bottom-color: var(--tooltip-bg); }
.bs-tooltip-start .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { border-left-color: var(--tooltip-bg); }
.bs-tooltip-end .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { border-right-color: var(--tooltip-bg); }

.popover {
	border-color: var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--popover);
	box-shadow: var(--shadow-md);
}

.popover-header {
	border-bottom-color: var(--border);
	background-color: var(--muted);
	color: var(--foreground);
}

.popover-body {
	color: var(--popover-foreground);
}

/* ---------- Модальные окна ---------- */

.modal-content {
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--card);
	color: var(--card-foreground);
	box-shadow: var(--shadow-lg);
}

.modal-header,
.modal-footer {
	border-color: var(--border);
}

.btn-close {
	background-image: var(--icon-close);
}

/* Видео в модальном окне (_app.js, data-action="youtube" и "vk"): обычная карточка окна,
   сверху место под крестик, видео - по ширине окна в пропорции 16:9 */
#modal.youtube .modal-body {
	padding: 52px 16px 16px;
}

#modal.youtube iframe {
	display: block;
	width: 100%;
	height: auto !important;
	aspect-ratio: 16 / 9;
	margin: 0 !important;
	border-radius: var(--radius-md);
	background-color: var(--muted);
}

hr {
	color: var(--border);
	opacity: 1;
}

/* ================= 2. ТАБЛИЦЫ ================= */

/* Переменные Bootstrap: у него цвета таблицы зашиты в них */
.table {
	--bs-table-bg: transparent;
	--bs-table-accent-bg: transparent;
	--bs-table-striped-color: var(--foreground);
	--bs-table-striped-bg: var(--muted);
	--bs-table-active-color: var(--foreground);
	--bs-table-active-bg: var(--accent);
	--bs-table-hover-color: var(--foreground);
	--bs-table-hover-bg: var(--accent);
	color: var(--foreground);
	border-color: var(--border);
}

.table > :not(caption) > * > * {
	border-color: var(--border);
}

/* Во всех таблицах содержимое ячеек - по центру по вертикали. Bootstrap ставит top
   на таблицу и bottom на шапку, часть шаблонов - свои значения, отсюда !important */
table td,
table th {
	vertical-align: middle !important;
}

/* Названия столбцов - с заглавной буквы, как бы их ни написали в PHP («имя», «товар в …») */
table th::first-letter {
	text-transform: uppercase;
}

.table th {
	color: var(--foreground);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: normal;
	word-spacing: normal;
	text-transform: none;
}

.table td {
	font-size: 12px;
	vertical-align: middle;
}

/* ---------- .complex_table: таблица в карточке, как в аналитике ----------

   Рамку и скругление рисует .tbl_div - обёртка с прокруткой по горизонтали.
   Шапку прижимает к верху экрана _app.js (сдвигает thead при прокрутке страницы),
   поэтому у шапки свой фон: строки под ней не должны просвечивать */

.complex_table .tbl_div {
	overflow: hidden;
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--card);
}

.complex_table .tbl_scroll {
	overflow-x: auto;
}

/* Липкая копия шапки (.tbl_sticky_head, собирает _app.js) - с фоном карточки: если в первой строке шапки colspan
   в сумме меньше колонок, пустой хвост строки не просвечивает прокручиваемыми под ней строками */
.tbl_div > .tbl_sticky_head {
	background-color: var(--card);
}

.complex_table .table {
	margin-bottom: 0;
}

.complex_table thead {
	background-color: var(--card);
}

.complex_table thead th {
	padding: 8px 10px;
	border: none;
	background-color: var(--card);
	box-shadow: inset 0 -2px 0 var(--border);
	white-space: nowrap;
}

.complex_table th.border-left {
	border-left: 1px solid var(--border);
}

.complex_table tbody td {
	padding: 8px 10px;
	border-color: var(--border);
	font-size: 12px;
}

.complex_table tbody tr:hover {
	background-color: var(--accent);
}

.complex_table tbody tr.notbounded {
	opacity: .5;
}

/* Сортировка: стрелки в заголовке, отсортированный столбец - лёгкая подложка */
.complex_table [data-sort-field] {
	cursor: pointer;
}

.complex_table [data-sort-direction]::after {
	position: relative;
	top: -1px;
	margin-left: 4px;
	content: '↓↑';
	color: var(--muted-foreground);
	font-size: 10px;
	font-weight: 400;
}

.complex_table [data-sort-direction="asc"]::after {
	content: '↓';
	top: 2px;
	color: var(--foreground);
}

.complex_table [data-sort-direction="desc"]::after {
	content: '↑';
	top: -4px;
	color: var(--foreground);
}

.complex_table thead [data-sort-direction="asc"],
.complex_table thead [data-sort-direction="desc"],
.complex_table .sort_asc,
.complex_table .sort_desc {
	background-color: var(--muted);
}

/* Ссылки и иконки в ячейках */
.complex_table td a {
	color: var(--muted-foreground);
}

.complex_table td a.vkl {
	color: var(--foreground);
}

.complex_table td i {
	color: var(--foreground);
	font-size: 16px;
}

.complex_table td i.grey {
	color: var(--muted-foreground);
}

/* Метки состояния в ячейках: -tint - подложка, как у состояний в руте */
.complex_table tbody td span {
	position: relative;
	padding: 2px 8px;
	border-radius: var(--radius-sm);
}

.complex_table tbody td span.green { background-color: var(--success-tint); }
.complex_table tbody td span.red { background-color: var(--destructive-tint); }
.complex_table tbody td span.yellow { background-color: var(--warning-tint); }
.complex_table tbody td span.grey { background-color: var(--muted); }
.complex_table tbody td span.parts { display: block; padding: 0; margin-bottom: 0; }

/* Строки с состоянием подсвечиваются при наведении своим цветом */
.complex_table tbody tr.green:hover { background-color: var(--success-tint); }
.complex_table tbody tr.red:hover { background-color: var(--destructive-tint); }
.complex_table tbody tr.yellow:hover { background-color: var(--warning-tint); }

.complex_table tbody tr.green:hover td span.green,
.complex_table tbody tr.red:hover td span.red,
.complex_table tbody tr.yellow:hover td span.yellow,
.complex_table tbody tr.green:hover td span.grey,
.complex_table tbody tr.red:hover td span.grey,
.complex_table tbody tr.yellow:hover td span.grey {
	background-color: var(--surface-veil);
}

/* Служебные классы ячеек, которые проставляет сервер */
table td.bc_gray, table th.bc_gray {
	background-color: var(--muted);
	text-align: center;
	border-bottom: 1px solid var(--border);
}

table td.bc_light_gray, table th.bc_light_gray,
.complex_table tbody td.light_grey, .complex_table thead th.light_grey {
	background-color: var(--secondary);
}

table td.font_gray, table th.font_gray {
	cursor: pointer;
	color: var(--muted-foreground) !important;
	font-size: 79% !important;
	font-style: italic;
}

table td.font_gray_norm, table th.font_gray_norm {
	cursor: pointer;
	color: var(--muted-foreground) !important;
}

table th.center { text-align: center; }
table td .line_red { color: var(--destructive); font-weight: 600; }
table td .line_green { color: var(--success); font-weight: 600; }
table td .line_yellow { color: var(--warning); font-weight: 600; }

.complex_table td .alert {
	padding: .1rem .5rem;
	margin-bottom: 0;
	text-align: center;
}

/* .alert-* вне таблиц (статусы-фильтры Сборки и другие) в тёмной теме: у Bootstrap цвета зашиты и слишком светлые.
   В светлой теме остаются как есть. !important у success - его подложка в _app.css тоже с !important */
[data-theme="dark"] .alert-secondary {
	border-color: var(--checkbox-border);
    background-color: var(--accent);
	color: var(--foreground);
}

[data-theme="dark"] .alert-primary {
	border-color: var(--primary);
	background-color: var(--primary-tint);
	color: var(--primary);
}

[data-theme="dark"] .alert-success {
	border-color: var(--success);
	background-color: var(--success-tint) !important;
	color: var(--success-text);
}

[data-theme="dark"] .alert-info {
	border-color: var(--info);
	background-color: var(--info-tint);
	color: var(--info-text);
}

[data-theme="dark"] .alert-warning {
	border-color: var(--warning);
	background-color: var(--warning-tint);
	color: var(--warning-text);
}

[data-theme="dark"] .alert-danger {
	border-color: var(--destructive);
	background-color: var(--destructive-tint);
	color: var(--destructive-text);
}

/* Статусы заказов в таблицах (.alert-*.tbl-state): подложка оттенка, рамка и текст того же цвета; нейтральный - серым.
   Цвета - токены root.css, для светлой и темной темы */
.complex_table td .alert-secondary.tbl-state {
	border-color: var(--border);
	background-color: var(--muted) !important;
	color: var(--foreground);
}

.complex_table td .alert-primary.tbl-state {
	border-color: var(--primary);
	background-color: var(--primary-tint) !important;
	color: var(--primary);
}

.complex_table td .alert-success.tbl-state {
	border-color: var(--success);
	background-color: var(--success-tint) !important;
	color: var(--success-text);
}

.complex_table td .alert-info.tbl-state {
	border-color: var(--info);
	background-color: var(--info-tint) !important;
	color: var(--info-text);
}

.complex_table td .alert-warning.tbl-state {
	border-color: var(--warning);
	background-color: var(--warning-tint) !important;
	color: var(--warning-text);
}

.complex_table td .alert-danger.tbl-state {
	border-color: var(--destructive);
	background-color: var(--destructive-tint) !important;
	color: var(--destructive-text);
}

.complex_table div.tbl-notice {
	width: max-content;
	margin: 12px auto 0;
	color: var(--muted-foreground);
	font-size: 13px;
}

.table td[contentEditable]:hover,
.table td[contentEditable]:focus {
	background-color: var(--accent);
}

/* Совпадение с поиском */
.highlight {
	padding: 0 2px !important;
	border-radius: 2px;
	background-color: var(--warning-soft);
	color: var(--foreground);
}

/* ---------- Полосы прокрутки таблицы ---------- */

.complex_table .tbl_scroll::-webkit-scrollbar {
	height: 12px;
}

.complex_table .tbl_scroll::-webkit-scrollbar-track {
	border-top: 1px solid var(--border);
	background-color: var(--card);
}

.complex_table .tbl_scroll::-webkit-scrollbar-thumb {
	border: 3px solid transparent;
	border-radius: var(--radius-full);
	background-color: var(--primary);
	background-clip: content-box;
	cursor: pointer;
}

.complex_table .tbl_scroll::-webkit-scrollbar-thumb:hover {
	background-color: var(--primary-hover);
}

@supports not selector(::-webkit-scrollbar) {
	.complex_table .tbl_scroll {
		scrollbar-width: thin;
		scrollbar-color: var(--border) transparent;
	}
}

/* ================= 3. УПРАВЛЕНИЕ ТАБЛИЦЕЙ ================= */

/* ---------- Кнопки «на страницу», «столбцы» и др. ----------

   Разметка - Bootstrap dropdown: div.btn-small-action > a[data-bs-toggle] + .dropdown-menu.
   Оформление - как .connect_button в аналитике: кнопка в рамке с шевроном */

.complex_table .table_controls {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 0;
	background: none;
}

.complex_table .btn-small-action {
	display: inline-flex;
	align-items: stretch;
	height: var(--control-height);
	margin: 0;
	padding: 0;
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--foreground);
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease;
}

.complex_table .btn-small-action:hover {
	background-color: var(--accent);
	border-color: var(--checkbox-border);
}

.complex_table .btn-small-action:has(> .show) {
	background-color: var(--accent);
	border-color: var(--checkbox-border);
}

.complex_table .btn-small-action.red {
	border-color: var(--destructive-soft);
	background-color: var(--destructive-tint) !important;
}

.complex_table .btn-small-action > a,
.complex_table .btn-small-glyph {
	display: flex;
	align-items: center;
	gap: 6px;
	height: 100%;
	padding: 0 10px;
	color: var(--foreground);
	font-size: 13px;
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
}

.complex_table .btn-small-action i,
.complex_table .btn-small-action span {
	position: static;
	color: var(--foreground);
	font-size: 15px;
	line-height: 1;
}

.complex_table .btn-small-action .tbl_limit {
	min-width: 32px;
	font-size: 13px;
	text-align: center;
}

.complex_table .btn-small-action img {
	width: 15px;
	height: 15px;
}

[data-theme="dark"] .complex_table .btn-small-action img {
	filter: invert(1);
}

/* Тёмная тема: значки из ASSETS/icons - чёрные SVG Bootstrap Icons (папка, корзина, обновить...) - везде светлыми */
[data-theme="dark"] img[src*="/icons/"] {
	filter: invert(1);
}

/* Шеврон у кнопок с выпадающим списком */
.complex_table .btn-small-action > a[data-bs-toggle="dropdown"]::after {
	content: '';
	flex: 0 0 auto;
	width: 8px;
	height: 6px;
	background-color: var(--muted-foreground);
	-webkit-mask: var(--chevron-mask) no-repeat center / contain;
	mask: var(--chevron-mask) no-repeat center / contain;
	transition: transform .1s ease;
}

.complex_table .btn-small-action > a.show::after {
	transform: rotate(180deg);
}

/* Кнопка действия внутри ячейки - без рамки */
.complex_table .do_in_table .btn-small-action {
	width: max-content;
	height: auto;
	border: 0;
	background-color: transparent;
}

/* ---------- Списки кнопок ----------

   Списки без внутренних отступов (у «Столбцов» в разметке стоит p-2 - снимаем),
   отступы только у пунктов. Пункт - ссылка прямо в .dropdown-menu или в li */

.complex_table .dropdown-menu,
.complex_table .dropdown-menu.p-2 {
	min-width: 0;
	margin: 0;
	padding: 0 !important;
}

.complex_table .dropdown-menu li {
	margin: 0;
	padding: 0;
	list-style: none;
	line-height: 1.2;
}

.complex_table .dropdown-menu > a,
.complex_table .dropdown-menu > li > a {
	display: flex;
	align-items: center;
	gap: 8px;
	min-height: 32px;
	padding: 0 12px;
	color: var(--foreground);
	font-size: 13px;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color .15s ease, color .15s ease;
}

.complex_table .dropdown-menu > a:hover,
.complex_table .dropdown-menu > li > a:hover {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

/* «На страницу»: столбик чисел по центру, ширина - ровно как у кнопки.
   Отсчёт ширины идёт от .dropdown внутри рамки кнопки, поэтому +2px на рамку
   и сдвиг на 1px влево; отступ вниз - через translate, margin перебивает Popper */
.complex_table .dropdown-menu:has(> [data-action="tbl_limit"]) {
	width: calc(100% + 2px);
	translate: -1px 3px;
}

.complex_table .dropdown-menu [data-action="tbl_limit"] {
	justify-content: center;
	padding: 0 6px;
	color: var(--muted-foreground);
}

/* «Скачать»: форматы файла, у каждого значок документа */
.complex_table .dropdown-menu:has(> [data-action="tbl_get"]) {
	translate: 0 3px;
}

.complex_table .dropdown-menu [data-action="tbl_get"] {
	min-width: 120px;
	font-weight: 500;
}

.complex_table .dropdown-menu [data-action="tbl_get"]::before {
	content: '';
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	background-color: var(--muted-foreground);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5z'/%3E%3Cpath d='M8 6.5a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 1 1 .708-.708L7.5 10.793V7a.5.5 0 0 1 .5-.5'/%3E%3C/svg%3E") no-repeat center / contain;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5z'/%3E%3Cpath d='M8 6.5a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 1 1 .708-.708L7.5 10.793V7a.5.5 0 0 1 .5-.5'/%3E%3C/svg%3E") no-repeat center / contain;
}

.complex_table .dropdown-menu [data-action="tbl_get"]:hover::before {
	background-color: var(--foreground);
}

/* «Столбцы»: строка с чекбоксом, как в настройке столбцов аналитики.
   Чекбокс нарисован псевдоэлементом: включённый столбец помечен классом vkl */
.complex_table .dropdown-menu:has([data-action="tbl_columns"]) {
	translate: 0 3px;
}

/* Список длинный, и Popper при прокрутке перекидывал его то вверх, то вниз. У кнопки стоит
   data-bs-display="static": список всегда под кнопкой, правым краем по ней (кнопки - справа),
   и прокручивается вместе со страницей */
.complex_table .dropdown-menu[data-bs-popper="static"] {
	top: 35px;
	right: 0;
	left: auto;
}

.complex_table .dropdown-menu [data-action="tbl_columns"] {
	font-size: 12px;
}

/* Меню без пунктов (у КИЗов в «Столбцах» все пункты закомментированы) - кнопку не показываем: открывать нечего */
.complex_table .table_controls .dropdown:not(:has(> .dropdown-menu a)) {
	display: none;
}

.complex_table .dropdown-menu [data-action="tbl_columns"]::before {
	content: '';
	flex: 0 0 auto;
	width: 13px;
	height: 13px;
	border: 1px solid var(--checkbox-border);
	border-radius: var(--radius-sm);
	background: var(--card) no-repeat center / contain;
	transition: background-color .15s ease, border-color .15s ease;
}

.complex_table .dropdown-menu [data-action="tbl_columns"].vkl::before {
	border-color: var(--checked-radio-background);
	background-color: var(--checked-radio-background);
	background-image: var(--icon-check);
}

.complex_table .dropdown-menu [data-action="tbl_limit"].vkl {
	color: var(--foreground);
	font-weight: 600;
}

/* ---------- Пагинация ----------

   Разметку рисует pagination($box, page, pages) из _app.js в любой контейнер - у .complex_table это .pages_scroll.
   Как в приложении аналитики: очертания только у контейнера, кнопки прозрачные и проявляются при наведении,
   залита только текущая страница. Пропущенные номера - под «…» выпадающим списком */

.complex_table .pages {
	width: 100%;
	margin: 0 0 12px;
}

[data-pagination] {
	display: inline-flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 2px;
	max-width: 100%;
	padding: 4px;
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--card);
	user-select: none;
}

[data-pagination]:empty {
	display: none;
}

[data-pagination] .page_link {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 28px;
	height: 28px;
	margin: 0;
	padding: 0 6px;
	border: 0;
	border-radius: var(--radius-sm);
	background-color: transparent;
	color: var(--muted-foreground);
	font-size: 13px;
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	transition: background-color .15s ease, color .15s ease;
}

[data-pagination] .page_link:not(.active):not(.disabled):hover {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

[data-pagination] .page_link:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px var(--ring-veil);
}

[data-pagination] .page_link.active {
	background-color: var(--primary);
	color: var(--primary-foreground);
	font-weight: 600;
}

[data-pagination] .page_link.disabled {
	opacity: .4;
	cursor: default;
}

[data-pagination] .page_arrow svg {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

[data-pagination] .page_arrow.next svg {
	transform: rotate(180deg);
}

/* «…» и список скрытых номеров под ним */
[data-pagination] .page_more {
	position: relative;
	display: flex;
}

[data-pagination] .page_more_list {
	position: absolute;
	top: calc(100% + 6px);
	left: 50%;
	z-index: 1001;
	display: none;
	flex-direction: column;
	gap: 1px;
	min-width: 56px;
	max-height: 300px;
	overflow-y: auto;
	padding: 4px;
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--popover);
	box-shadow: var(--shadow-md);
	transform: translateX(-50%);
}

[data-pagination] .page_more.open .page_more_list {
	display: flex;
}

[data-pagination] .page_more.open .page_more_btn {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

/* В списке кнопка на всю ширину, иначе подсветка при наведении - узкое пятно посреди блока */
[data-pagination] .page_more_list .page_link {
	width: 100%;
	justify-content: flex-start;
	padding: 0 8px;
}

/* ---------- Фильтры-кирпичики ----------

   Как .filter_brick в PROTOOLS: плашка с подписью и счётчиком.
   Выбранный фильтр помечен классом vkl (его ставит _app.js) */

.complex_table .filter {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.complex_table .filter a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 5px 10px;
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--muted);
	color: var(--muted-foreground);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	user-select: none;
	transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.complex_table .filter a:not(.vkl):not(.active):hover {
	background-color: var(--accent);
	color: var(--accent-foreground);
}

.complex_table .filter a.vkl,
.complex_table .filter a.active {
	border-color: var(--primary);
	background-color: var(--secondary);
	color: var(--foreground);
	font-weight: 600;
}

.complex_table .filter a .count {
	color: var(--muted-foreground);
	font-variant-numeric: tabular-nums;
}

.complex_table .filter a .count:empty {
	display: none;
}

/* ---------- Поиск ----------

   Поле с крестиком очистки и счётчиком «N из M» поверх правого края */

.search .count,
.search > span {
	padding: 2px 8px;
	border-radius: var(--radius-sm);
	background-color: var(--muted);
	color: var(--muted-foreground);
	font-size: 12px;
}

.search > i {
	color: var(--muted-foreground);
}

/* Поиск таблицы стоит в одном ряду с кнопками управления - высота у них общая.
   Фильтр нод в левой панели - такой же */
.complex_table .search .form-control,
[data-widget="controls"] .search .form-control {
	height: var(--control-height);
	padding-top: 0;
	padding-bottom: 0;
	line-height: 1.2;
}

.complex_table .search > i,
.complex_table .search > span,
[data-widget="controls"] .search > i,
[data-widget="controls"] .search > span {
	top: 50%;
	transform: translateY(-50%);
	line-height: 1;
}

/* Счётчик «N из M» - с зазором от крестика очистки */
.complex_table .search > span,
[data-widget="controls"] .search > span {
	right: 42px;
}

[data-widget="controls"] .search {
	margin-bottom: 12px;
}

.search > i:hover {
	color: var(--foreground);
}

input.datepicker:hover ~ span {
    border: 1px solid var(--checkbox-border);
}

label:hover + div input.datepicker ~ span {
	border: 1px solid var(--checkbox-border);
}

/* ================= 4. КАЛЕНДАРЬ GIJGO =================

   Режим bootstrap4. Вид - как календарь аналитики: карточка, дни-плашки,
   выбранный день залит основным цветом. Шапку с крупной датой прячем: в аналитике её нет */

/* Поле с иконкой календаря */
.gj-datepicker-bootstrap [role="right-icon"].input-group-text,
.gj-datepicker-bootstrap .input-group-text,
.gj-timepicker-bootstrap .input-group-text {
	border-color: var(--input);
	background-color: var(--card);
	color: var(--muted-foreground);
}

.gj-datepicker-bootstrap .gj-icon,
.gj-timepicker-bootstrap .gj-icon {
	color: var(--muted-foreground);
	font-size: 18px;
}

.gj-datepicker.gj-datepicker-bootstrap [role="right-icon"] button {
	border-color: var(--input);
	background-color: var(--card);
	color: var(--muted-foreground);
}

/* Наведение на блок календаря - подсвечивается граница и поля, и блока с иконкой, как у кастомного селекта */
.gj-datepicker-bootstrap:hover .form-control,
.gj-datepicker-bootstrap:hover .input-group-text,
.gj-datepicker.gj-datepicker-bootstrap:hover [role="right-icon"] button,
.gj-timepicker-bootstrap:hover .form-control,
.gj-timepicker-bootstrap:hover .input-group-text {
	border-color: var(--muted-foreground);
}

/* Всплывающий календарь */
.gj-picker.gj-picker-bootstrap {
	padding: 14px;
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--popover);
	color: var(--popover-foreground);
	box-shadow: var(--shadow-md);
	user-select: none;
}

.gj-picker.gj-picker-bootstrap.datepicker [role="header"],
.gj-picker.gj-picker-bootstrap.datetimepicker [role="header"] {
	display: none !important;
}

.gj-picker.gj-picker-bootstrap div[role="navigator"] {
	display: flex;
	align-items: center;
	height: 28px;
	margin-bottom: 10px;
	line-height: 28px;
}

.gj-picker.gj-picker-bootstrap div[role="navigator"] div[role="period"] {
	color: var(--foreground);
	font-size: 14px;
	font-weight: 600;
}

.gj-picker.gj-picker-bootstrap div[role="navigator"] div:first-child,
.gj-picker.gj-picker-bootstrap div[role="navigator"] div:last-child {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 28px;
	max-width: 28px;
	height: 28px;
	border-radius: var(--radius-sm);
	transition: background-color .15s ease;
}

.gj-picker.gj-picker-bootstrap div[role="navigator"] div:first-child:hover,
.gj-picker.gj-picker-bootstrap div[role="navigator"] div:last-child:hover {
	background-color: var(--accent);
}

.gj-picker.gj-picker-bootstrap div[role="navigator"] .gj-icon {
	margin: 0;
	color: var(--muted-foreground);
	font-size: 18px;
}

/* Дни недели */
.gj-picker.gj-picker-bootstrap table tr th div {
	width: 36px;
	height: 32px;
	color: var(--muted-foreground);
	font-size: 12px;
	font-weight: 500;
	line-height: 32px;
}

/* Дни */
.gj-picker.gj-picker-bootstrap table tr td div {
	width: 36px;
	height: 36px;
	margin: 2px;
	border-radius: var(--radius-md);
	color: var(--foreground);
	font-size: 13px;
	font-weight: 500;
	line-height: 36px;
	transition: background-color .15s ease, color .15s ease;
}

.gj-picker.gj-picker-bootstrap table tr td.gj-cursor-pointer div:hover,
.gj-picker.gj-picker-bootstrap table tr td.focused div {
	border-radius: var(--radius-md);
	background-color: var(--accent);
	color: var(--accent-foreground);
}

.gj-picker.gj-picker-bootstrap table tr td.today div {
	color: var(--primary);
	font-weight: 700;
}

.gj-picker.gj-picker-bootstrap table tr td.selected.gj-cursor-pointer div {
	border-radius: var(--radius-md);
	border-color: var(--primary);
	background-color: var(--primary);
	color: var(--primary-foreground);
	font-weight: 600;
}

.gj-picker.gj-picker-bootstrap table tr td.disabled div,
.gj-picker.gj-picker-bootstrap table tr td.other-month div {
	color: var(--muted-foreground);
	opacity: .45;
}

/* Выбор месяца, года, десятилетия - те же плашки, только шире */
.gj-picker.gj-picker-bootstrap[type="year"] table tr td div,
.gj-picker.gj-picker-bootstrap[type="decade"] table tr td div,
.gj-picker.gj-picker-bootstrap[type="century"] table tr td div {
	width: 60px;
	height: 40px;
	line-height: 40px;
}

/* Время: циферблат и стрелка */
.gj-picker.gj-picker-bootstrap [role="body"] [role="dial"] {
	background-color: var(--muted);
	color: var(--foreground);
}

.gj-picker.gj-picker-bootstrap .arrow-begin,
.gj-picker.gj-picker-bootstrap [role="body"] [role="arrow"] {
	background-color: var(--primary);
}

.gj-picker.gj-picker-bootstrap .arrow-end {
	border-color: var(--primary);
}

.gj-picker.gj-picker-bootstrap [role="body"] [role="hour"].selected {
	color: var(--primary-foreground);
}

.gj-picker.gj-picker-bootstrap [role="footer"] button,
.gj-picker .gj-button {
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--foreground);
}

.gj-modal {
	background-color: var(--overlay);
}

/* ================= 5. БЛОКИ ПРИЛОЖЕНИЙ =================

   .content_element - основной блок приложения на фоне страницы: карточка с рамкой.
   Как в PROTOOLS: отделение от фона рамкой, а не заливкой. Таблицы в карточке рисуют
   рамку сами - им .table_content_element */

.content_element {
	padding: 10px;
	border-radius: var(--radius-md);
	background-color: var(--card);
}

.content_element:not(.table_content_element) {
	border: 1px solid var(--border);
}

/* Управление таблицей - поиск, кнопки, фильтры, страницы - одна карточка над таблицей.
   Первый ряд: поиск забирает всё свободное место, кнопки (.table_controls) - справа.
   Остальное (поля периода, фильтры, страницы) - рядами на всю ширину */
.complex_table .table_navigation:not(.sborka_navigation) {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
	margin-bottom: 12px;
}

.complex_table .table_navigation:not(.sborka_navigation) > * {
	flex: 0 0 100%;
	order: 3;
	min-width: 0;
}

.complex_table .table_navigation:not(.sborka_navigation) > .search {
	flex: 1 1 0;
	order: 1;
}

.complex_table .table_navigation:not(.sborka_navigation) > .table_controls {
	position: static;
	flex: 0 0 auto;
	order: 2;
	margin-left: auto;
	z-index: auto;
}

.complex_table .table_navigation .pages {
	margin-bottom: 0;
}

/* Заголовок таблицы в карточке управления (прогнозы поставок) - слева в первом ряду, кнопки справа */
.complex_table .table_navigation:not(.sborka_navigation) > .table_title {
	flex: 1 1 0;
	order: 1;
	margin: 0;
}

/* Таблица ещё не загружалась - пустой <table> не рисуем. Загрузилась без строк (.tbl_empty, ставит tbl_get в _app.js) -
   вместо шапки карточка с сообщением: текст - data-empty у .complex_table, иначе общий */
.complex_table.tbl_empty .tbl_div {
	display: none;
}

.complex_table .tbl_div:has(table:empty) {
	display: none;
}

.complex_table.tbl_empty::after {
	content: 'Данных нет';
	display: block;
	padding: 32px 20px;
	border: 1px dashed var(--border);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--muted-foreground);
	font-size: 13px;
	text-align: center;
}

.complex_table.tbl_empty[data-empty]::after {
	content: attr(data-empty);
}

/* Сервер ответил ошибкой или не ответил (.tbl_error, текст - data-error, ставит tbl_get) - такая же нейтральная карточка */
.complex_table.tbl_error .tbl_div {
	display: none;
}

.complex_table.tbl_error::after {
	content: attr(data-error);
	display: block;
	padding: 32px 20px;
	border: 1px dashed var(--border);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--muted-foreground);
	font-size: 13px;
	text-align: center;
}

/* Пустой ряд фильтров (у остатков и цен) не должен давать отступ внутри карточки */
.complex_table .table_navigation > .table_filters:has(> .filter:empty) {
	display: none;
}

/* Поля над таблицей (период, склад, группировка) - в ряд, на узком экране переносятся */
.table_params {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 12px 20px;
}

.table_param {
	flex: 0 1 240px;
	min-width: 0;
}

.table_param.wide {
	flex-basis: 100%;
}

/* Без поиска (поставки) поля над таблицей встают на его место - в первый ряд слева от кнопок.
   Пока помещаются - в строку, иначе - по одному в строке */
.complex_table .table_navigation:not(.sborka_navigation):not(:has(> .search)) > .table_params {
	flex: 1 1 0;
	order: 1;
	container: table_params / inline-size;
}

.complex_table .table_navigation:not(.sborka_navigation):not(:has(> .search)):has(> .table_params) > .table_controls {
	align-self: flex-end;
}

/* Период таблицы - кнопка-дропдаун как в аналитике: выглядит как поле выбора (кастомный селект),
   на ней выбранные даты; поля «Начало» и «Конец периода» - в меню под ней */
.table_period_toggle,
.table_dropdown_toggle {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	height: var(--control-height);
	padding: 0 10px;
	border: 1px solid var(--input);
	border-radius: var(--radius-md);
	background-color: var(--card);
	color: var(--foreground);
	font-size: 13px;
	line-height: 1.2;
	text-align: left;
	cursor: pointer;
	transition: border-color .15s ease;
}

.table_period_toggle:hover,
.table_dropdown_toggle:hover {
	border-color: var(--muted-foreground);
}

.table_period_toggle[aria-expanded="true"],
.table_dropdown_toggle[aria-expanded="true"] {
	outline: 0;
	border-color: var(--ring);
}

.table_period_toggle:focus-visible,
.table_dropdown_toggle:focus-visible {
	outline: 0;
	border-color: var(--ring);
}

.table_period_label,
.table_dropdown_label {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.table_period_chevron,
.table_dropdown_chevron {
	flex: 0 0 auto;
	width: 10px;
	height: 6px;
	background-color: var(--muted-foreground);
	-webkit-mask: var(--chevron-mask) no-repeat center / contain;
	mask: var(--chevron-mask) no-repeat center / contain;
	transition: transform .15s ease;
}

.table_period_toggle[aria-expanded="true"] .table_period_chevron,
.table_dropdown_toggle[aria-expanded="true"] .table_dropdown_chevron {
	transform: rotate(180deg);
}

/* у меню таблиц отступы только у пунктов (padding 0 !important выше) - у меню периода свой */
.complex_table .table_period_menu {
	padding: 12px !important;
}

.table_period_menu.show {
	display: flex;
	gap: 12px;
}

.table_period_field {
	width: 180px;
}

/* Дропдаун параметров таблицы (аналитика: «Параметры расчёта») - выглядит как «Период»; в меню поля сеткой в две колонки.
   data-bs-display="static": без Popper у меню нет transform, и списки кастомных селектов внутри (position: fixed) стоят на месте.
   Меню - от левого края кнопки (общее правило static-меню таблиц прижимает его вправо, под кнопки справа) */
.complex_table .table_dropdown_menu {
	padding: 12px !important;
}

.complex_table .table_dropdown_menu[data-bs-popper="static"] {
	top: calc(100% + 4px);
	right: auto;
	left: 0;
}

.table_dropdown_menu.show {
	display: grid;
	grid-template-columns: repeat(2, 260px);
	grid-gap: 12px 16px; gap: 12px 16px;
}

.table_dropdown_field.wide {
	grid-column: 1 / -1;
}

.table_dropdown_field .form-check {
	margin: 0;
}

@media (max-width: 767px) {
	.table_dropdown_menu.show {
		grid-template-columns: minmax(0, 1fr);
		width: 320px;
		width: min(320px, calc(100vw - 48px));
	}
}

.table_period_field .form-label,
.table_dropdown_field .form-label {
	margin-bottom: 4px;
	font-size: 12px !important;
	color: var(--muted-foreground);
}

@container table_params (max-width: 560px) {
	.table_params > .table_param {
		flex-basis: 100%;
	}
}

/* Таблица логов на вкладке «Консоль» - в карточке, рамку и скругление рисует обёртка */
.logs_table.content_element {
	margin-bottom: 12px;
	padding: 0;
	overflow: hidden;
}

.logs_table .table {
	margin-bottom: 0;
}

/* Логов нет (.logs_empty) или ошибка загрузки (.logs_error, текст - data-error) - вместо пустой шапки карточка,
   как у таблиц (.tbl_empty / .tbl_error); «Больше логов» тогда не нужна. Состояние ставит logs_state() в _app.js */
.logs_table.logs_empty,
.logs_table.logs_error {
	border-style: dashed;
}

.logs_table.logs_empty .table,
.logs_table.logs_error .table,
.logs_table.logs_empty + .morelogs,
.logs_table.logs_error + .morelogs {
	display: none;
}

/* Пока логи не пришли (.logs_loading - сразу в разметке, снимает logs_state()) - вместо шапки спиннер, как у обновления таблиц */
.logs_table.logs_loading {
	border-style: dashed;
}

.logs_table.logs_loading .table,
.logs_table.logs_loading + .morelogs {
	display: none;
}

.logs_table.logs_loading::before {
	content: '';
	display: block;
	width: 18px;
	height: 18px;
	margin: 28px auto 0;
	border: 2px solid var(--border);
	border-top-color: var(--primary);
	border-radius: var(--radius-full);
	animation: spin .8s linear infinite;
}

.logs_table.logs_loading::after {
	content: 'Загружаем логи…';
	display: block;
	padding: 10px 20px 28px;
	color: var(--muted-foreground);
	font-size: 13px;
	text-align: center;
}

.logs_table.logs_empty::after,
.logs_table.logs_error::after {
	display: block;
	padding: 32px 20px;
	color: var(--muted-foreground);
	font-size: 13px;
	text-align: center;
}

.logs_table.logs_empty::after {
	content: 'Логов пока нет';
}


.logs_table.logs_error::after {
	content: attr(data-error);
}

/* ================= 6. ОПОВЕЩЕНИЯ =================

   window.notifications(text, status) в _app.js - карточки стопкой в правом верхнем углу (top считает
   notifications: 10px от верхнего меню), новые снизу, сами скрываются через 6 с.
   Текст всегда --foreground, состояние передают иконка, подложка (-tint) и рамка (-soft).
   Без класса состояния карточка нейтральная - так выглядит info */

#notifications {
	position: fixed;
	right: 24px;
	top: 10px;
	z-index: 1090;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 8px;
	width: 380px;
	width: min(380px, calc(100vw - 48px));
	/* Пустые места контейнера не должны перехватывать клики по странице */
	pointer-events: none;
}

#notifications .notification {
	--notification-accent: var(--muted-foreground);

	display: flex;
	align-items: flex-start;
	gap: 10px;
	width: 100%;
	padding: 12px 10px 12px 14px;
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	background-color: var(--popover);
	box-shadow: var(--shadow-lg);
	color: var(--foreground);
	font-size: 13px;
	line-height: 1.45;
	pointer-events: auto;
	animation: notification_in .22s ease-out;
}

#notifications .notification.success {
	--notification-accent: var(--success);
	border-color: var(--success-soft);
	background-color: var(--success-tint);
}

#notifications .notification.failed {
	--notification-accent: var(--destructive);
	border-color: var(--destructive-soft);
	background-color: var(--destructive-tint);
}

#notifications .notification.warning {
	--notification-accent: var(--warning);
	border-color: var(--warning-soft);
	background-color: var(--warning-tint);
}

#notifications .notification.closing {
	animation: notification_out .2s ease-in forwards;
}

#notifications .notification_icon {
	flex: none;
	width: 18px;
	height: 18px;
	margin-top: 1px;
	fill: none;
	stroke: var(--notification-accent);
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

#notifications .notification_text {
	flex: 1;
	min-width: 0;
	overflow-wrap: break-word;
	overflow-wrap: anywhere;
}

#notifications .notification_text a {
	font-size: inherit;
}

/* Подложка кнопки - полупрозрачная: на цветной карточке сплошной --accent лёг бы серым пятном */
#notifications .notification_close {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	margin: -2px 0 0;
	padding: 0;
	border: 0;
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--muted-foreground);
	cursor: pointer;
	transition: background-color .15s ease, color .15s ease;
}

#notifications .notification_close:hover {
	background-color: var(--surface-veil);
	color: var(--foreground);
}

#notifications .notification_close:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px var(--ring-veil);
}

#notifications .notification_close svg {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
}

@keyframes notification_in {
	from {
		opacity: 0;
		transform: translateY(8px) scale(.98);
	}
}

@keyframes notification_out {
	to {
		opacity: 0;
		transform: translateX(16px);
	}
}

@media (prefers-reduced-motion: reduce) {
	#notifications .notification,
	#notifications .notification.closing {
		animation: none;
	}
}

/* ================= 7. ПОДСКАЗКИ =================

   Атрибут data-tip="Текст" на элементе - модуль в _app.js показывает один общий узел #app_tip.
   Тёмная плашка как в «Общей сводке» аналитики; .rich - строки «заголовок / подпись - значение / пояснение»
   (атрибут data-tip-html, собирается tip_rows()) */

#app_tip {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 2000;
	max-width: 280px;
	padding: 6px 9px;
	border-radius: var(--radius-sm);
	background: var(--tooltip-bg);
	box-shadow: var(--shadow-lg);
	color: var(--tooltip-foreground);
	font-size: 12px;
	font-weight: 500;
	line-height: 1.45;
	white-space: pre-line;
	overflow-wrap: break-word;
	overflow-wrap: anywhere;
	pointer-events: none;
	opacity: 0;
	visibility: hidden;
	transition: opacity .12s ease, visibility .12s;
}

#app_tip.show {
	opacity: 1;
	visibility: visible;
}

#app_tip.rich {
	min-width: 150px;
	padding: 8px 10px;
	font-size: 11px;
	white-space: normal;
}

#app_tip .app_tip_row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
}

#app_tip .app_tip_row b {
	margin-bottom: 2px;
	font-size: 12px;
	font-weight: 700;
}

#app_tip .app_tip_row i {
	font-style: normal;
	font-weight: 600;
	white-space: nowrap;
}

#app_tip .app_tip_row span {
	color: var(--tooltip-muted);
}

/* Пояснение - блок на всю ширину под разделителем; сразу после заголовка разделитель не нужен */
#app_tip .app_tip_row em {
	display: block;
	margin: 4px 0 3px;
	padding-top: 5px;
	border-top: 1px solid var(--tooltip-divider);
	color: var(--tooltip-muted);
	font-size: 10.5px;
	font-style: normal;
	line-height: 1.5;
}

#app_tip .app_tip_row:nth-child(2) em {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

/* ================= ИНФОРМЕРЫ =================

   Блок с пояснением по степени важности: .informer + цвет.
   .informer_warning (оранжевый) - без этого не заработает или будут серьезные проблемы и ограничения;
   .informer_info (сине-голубой) - важно учесть, но не критично.
   Заголовок рисует CSS («Важно» / «Обратите внимание»), свой - атрибутом data-title. Внутри - абзацы, списки, <br> */

.informer {
	padding: 12px 14px;
	border: 1px solid;
	border-radius: var(--radius-md);
	color: var(--foreground);
	font-size: 13px;
	line-height: 1.5;
}

.informer::before {
	display: block;
	margin-bottom: 4px;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
}

.informer > * {
	margin: 0;
}

.informer > * + * {
	margin-top: 6px;
}

.informer ul {
	padding-left: 18px;
}

.informer_warning {
	border-color: var(--warning-soft);
	background-color: var(--warning-tint);
}

.informer_warning::before {
	content: 'Важно';
	color: var(--warning-text);
}

.informer_info {
	border-color: var(--info-soft);
	background-color: var(--info-tint);
}

.informer_info::before {
	content: 'Обратите внимание';
	color: var(--info-text);
}

.informer[data-title]::before {
	content: attr(data-title);
}

/* Информер после подсказки, чекбокса или абзаца и блок после информера - через 12px в любом контейнере
   (в .section_option ритма карточек нет - информер прилипал к подсказке). Своё правило контейнера сильнее */
* + .informer,
.informer + * {
	margin-top: 12px;
}

/* Ритм карточек обнуляет отступы детей - внутри информера свой (выше) */
.section_cards .informer > * {
	margin-bottom: 0;
}

/* ================= ЗАГРУЗКА =================

   Запрос к серверу (#app.update - ставит _app.js): интерфейс не кликается, содержимое чуть приглушено,
   по центру экрана - плашка «Загрузка…» с индикатором. Плашка и приглушение - с задержкой 0,3 с,
   чтобы быстрые запросы (сохранение, подсказки полей) не мигали. Раньше было только opacity: .5 у всего приложения */

#app.update {
	opacity: 1;
	pointer-events: none;
}

body:has(> #app.update),
body:has(#app.update) {
	cursor: progress;
}

#app.update > .service-tab {
	animation: app_busy_dim .2s ease .3s both;
}

@keyframes app_busy_dim {
	from { opacity: 1; }
	to { opacity: .6; }
}

/* Плашка */
#app.update::after {
	content: 'Загрузка…';
	position: fixed;
	z-index: 3000;
	top: 50%;
	left: 50%;
	width: 160px;
	margin: -22px 0 0 -80px;
	padding: 12px 16px 12px 44px;
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	background-color: var(--popover);
	box-shadow: var(--shadow-lg);
	color: var(--popover-foreground);
	font-size: 13px;
	font-weight: 500;
	line-height: 18px;
	animation: app_busy_show .15s ease .3s both;
}

/* Индикатор - слева в плашке */
#app.update::before {
	content: '';
	position: fixed;
	z-index: 3001;
	top: 50%;
	left: 50%;
	width: 18px;
	height: 18px;
	margin: -9px 0 0 -64px;
	border: 2px solid var(--border);
	border-top-color: var(--primary);
	border-radius: var(--radius-full);
	animation: app_busy_show .15s ease .3s both, spin .8s linear infinite;
}

@keyframes app_busy_show {
	from { opacity: 0; }
	to { opacity: 1; }
}

/* Таблица перезагружается (.load - ставит tbl_get): поверх - вуаль и индикатор, таблица не кликается.
   Вуаль заменяет и заглушку «нет данных» (.tbl_empty) - пока данные грузятся, она неверна.
   isolation: своя стопка слоев, чтобы вуаль и индикатор были выше шапки (thead - 99), ее липкой копии (.tbl_sticky_head - 100)
   и зон прокрутки (.tbl_scroll_left/right - 999), но не поднимались над меню и окнами страницы */
.complex_table.load {
	isolation: isolate;
	pointer-events: none;
}

.complex_table.load::after {
	content: '';
	display: block;
	position: absolute;
	z-index: 1000;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	min-height: 120px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: var(--radius-md);
	background-color: var(--overlay);
}

/* Индикатор - по центру экрана и при прокрутке длинной таблицы. Отрицательный отступ снизу: блок не сдвигает таблицу */
.complex_table.load::before {
	content: '';
	display: block;
	position: sticky;
	z-index: 1001;
	top: calc(50vh - 13px);
	width: 26px;
	height: 26px;
	margin: 0 auto -26px;
	border: 3px solid var(--border);
	border-top-color: var(--primary);
	border-radius: var(--radius-full);
	animation: spin .8s linear infinite;
}
