/* #16176 — картка контрагента: сторінка перегляд/редагування у стилі Nova Era
   (лівий сайдбар реквізитів + праві закладки розділів). Адаптовано з project-card.css. */

.agent-card { max-width: 1600px; }

/*+Kamala. claude. 2026-09-06. #17296 — дев'ята закладка («Договори») не вміщалась у ряд:
   права колонка сиділа на min-width:auto, тож розпиралась до min-content рядка закладок
   і виносила останню за правий край. Заміряно при viewport 1440: ряд закладок 1036px проти
   986px доступних, «Файли» 1441–1490 — ЦІЛКОМ поза екраном (до тикета — 1352–1401, видно).
   Рецепт той самий, що вже відпрацював на картці проєкту (project-card.css, .prj-card/.prj-tabs):
   колонці дозволяємо стискатись нижче власного вмісту, а ряд закладок переносимо на другий
   рядок замість обрізання. Горизонтальна прокрутка широких грідів лишається де й була — на .page-content. */
.agent-card > * { min-width: 0; }
.agent-card .agent-tabs > .a2-tab-bar { flex-wrap: wrap; }

/* ---- Лівий сайдбар реквізитів ---- */
.agent-card .agent-side {
	padding-right: 1rem;
	border-right: 1px solid #dfe3e8;
}
.agent-card .agent-side .agent-type-badge {
	align-self: start;
	margin-bottom: 0.25rem;
}
/* Бейджі ролей (перегляд) — в один рядок із переносом */
.agent-card .agent-roles {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
}

/* Read-only вид disabled-полів (показ як значення) — спільний для карток у card.css. */

/* ---- Заголовки секцій/FieldSet помітніші ---- */
.agent-card .a2-header,
.agent-card legend {
	font-weight: 600;
	color: #2c3e50;
}

/* ---- Адаптивність: на вузьких екранах сайдбар і закладки в одну колонку ---- */
@media (max-width: 1100px) {
	.agent-card {
		grid-template-columns: 1fr !important;
	}
	.agent-card .agent-side {
		border-right: none;
		border-bottom: 1px solid #dfe3e8;
		padding-right: 0;
		padding-bottom: 0.75rem;
	}
}
/* ШІ-помічник (етап 1) — розкладка сторінки чату. Пузирі/аватари переіспользують chat.css. */

.ai-assistant-page {
	height: 100%;
	min-height: 0;
	overflow: hidden;
}

/* ── Sidebar ───────────────────────────────────────────── */
.ai-assistant-page .ai-sidebar {
	border-right: 1px solid #e0e0e0;
	background: #fafbfc;
	min-height: 0;
	overflow: hidden;
}

.ai-sidebar-head {
	padding: 0.6rem;
	border-bottom: 1px solid #e8e8e8;
	align-items: center;
}

.ai-sidebar-head .btn:first-child {
	flex: 1 1 auto;
}

.ai-chat-list {
	overflow-y: auto;
	overflow-x: hidden;
	min-height: 0;
	padding: 0.25rem;
}

.ai-chat-list .a2-list-item {
	border-radius: 6px;
	margin-bottom: 2px;
	cursor: pointer;
}

.ai-chat-list .a2-list-item.ai-chat-item:hover {
	background: #eef1f5;
}

.ai-chat-list .a2-list-item.active {
	background: #e3f2fd;
}

.ai-chat-item-row {
	align-items: center;
	width: 100%;
	padding: 0.1rem 0.25rem;
}

.ai-chat-title {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ai-chat-del {
	flex: 0 0 auto;
	opacity: 0;
	transition: opacity 0.15s;
}

.ai-chat-list .a2-list-item:hover .ai-chat-del {
	opacity: 0.6;
}

.ai-chat-del:hover {
	opacity: 1 !important;
}

/* A2v10 ListItem.Content рендериться у .generic-list-item (grid-template-columns: auto 1fr auto),
   рядок чату лягає в .list-item-body — середню колонку 1fr. Її дефолтний min-width:auto = min-content
   nowrap-заголовка, тож довгий заголовок розпирає трек ширше за сайдбар, рядок вилазить праворуч і
   кнопку видалення зрізає overflow-x:hidden (стає некликабельною). minmax(0,1fr) + min-width:0 знімають
   авто-мінімум → заголовок ужимається в ellipsis, кнопка завжди в межах сайдбара. */
.ai-chat-list .generic-list-item {
	grid-template-columns: auto minmax(0, 1fr) auto;
}

.ai-chat-list .list-item-body {
	min-width: 0;
}

/* ── Main area ─────────────────────────────────────────── */
.ai-assistant-page .ai-main {
	min-height: 0;
	height: 100%;
	overflow: hidden;
	/* Рядок повідомлень мусить уміти стиснутись НИЖЧЕ свого контенту, інакше список не скролиться:
	   звичайний 1fr має auto-мінімум → трек росте до висоти контенту (.ai-main роздувається,
	   а overflow:auto в <ul> не спрацьовує). minmax(0,1fr) знімає цей мінімум. */
	grid-template-rows: minmax(0, 1fr) auto auto !important;
	/* #17441: одна ліва лінія низу чату — ліва рамка поля вводу. «Друкує», лічильник токенів
	   і рядок вводу беруть горизонтальний відступ звідси, щоб не розʼїхатись знову. */
	--ai-bottom-gutter: 0.75rem;
}

.ai-messages {
	overflow-y: auto;
	overflow-x: hidden;
	min-height: 0;
	/* Визначена висота (= висота grid-рядка minmax(0,1fr) у .ai-main) потрібна, щоб список
	   обмежувався і скролився. Без height:100% <ul> сайзиться по контенту й overflow:auto не діє. */
	height: 100%;
	padding: 1rem 1.25rem;
}

/* Текст повідомлень: платформений .list-item-body фарбує його в блідий #999 (наслідується
   в .chat-msg-body). Перекриваємо насиченим читабельним кольором. */
.ai-messages .chat-msg-body {
	color: #1f2933;
}

/* a2-ai-msg (лінкіфікація): зберігаємо переноси рядків, як у колишнього Span Wrap=PreWrap */
.ai-messages .ai-msg-text {
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

/* Robot avatar tint for assistant */
.ai-avatar {
	background: #7986cb;
}

.chat-message-own .ai-avatar {
	background: #42a5f5;
}

/* ── Welcome / empty state ─────────────────────────────── */
.ai-welcome {
	height: 100%;
	min-height: 0;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 2rem;
	color: #5a6472;
}

.ai-welcome-robot .ico {
	font-size: 3rem;
	color: #7986cb;
}

.ai-welcome-title {
	font-size: 1.25rem;
}

.ai-welcome-sub {
	max-width: 34rem;
	color: #8a94a2;
}

.ai-suggest-row {
	flex-wrap: wrap;
	justify-content: center;
	margin-top: 0.5rem;
}

.ai-suggest.btn {
	border: 1px solid #d4dae2;
	background: #fff;
	border-radius: 999px;
	padding: 0.35rem 0.9rem;
	color: #41506a;
}

.ai-suggest.btn:hover {
	background: #eef3fb;
	border-color: #b9c6db;
}

/* ── Typing indicator ──────────────────────────────────── */
.ai-typing {
	align-items: center;
	padding: 0 var(--ai-bottom-gutter) 0.5rem;
	color: #8a94a2;
}

.ai-typing-text {
	font-style: italic;
}

/* ── Monthly token counter (#17375) ── */
/* Лежить між індикатором «друкує» і полем вводу; горизонтальний відступ — спільний --ai-bottom-gutter. */
.ai-token-counter {
	padding: 0 var(--ai-bottom-gutter) 0.35rem;
	font-size: 0.85em;
	color: #8a94a2;
}

.ai-token-counter-warn {
	color: #b45309;
	font-weight: 600;
}

/* ── Input row ─────────────────────────────────────────── */
.ai-input-row {
	border-top: 1px solid #e0e0e0;
	background: #fafbfc;
	padding: 0.6rem var(--ai-bottom-gutter);
	align-items: flex-end;
}

.ai-input-row .control-group {
	flex: 1 1 0%;
	min-width: 0;
}

.ai-input-row .control-group textarea {
	width: 100%;
	resize: none;
}

.ai-input-row > .btn {
	flex: 0 0 auto;
}
/* #15934 — «дорожня карта» статусу АВР: горизонтальний степер маршруту погодження.
   Показ-онлі: відображає перелік статусів довідника і поточну позицію документа.
   Класи scoped під .avr-stepper, щоб не конфліктувати з платформними стилями. */
.avr-stepper {
	display: flex;
	align-items: flex-start;
	overflow-x: auto;
	gap: 0;
	margin: 0.25rem 0 0.5rem;
	padding: 2px 2px 4px;
}
.avr-step {
	flex: 1 0 auto;
	min-width: 62px;
	display: flex;
	flex-direction: column;
	align-items: center;
	position: relative;
	text-align: center;
}
.avr-step::before,
.avr-step::after {
	content: "";
	position: absolute;
	top: 13px;
	height: 2px;
	background: #d3d8e0;
	z-index: 0;
}
.avr-step::before { left: 0; width: 50%; }
.avr-step::after { right: 0; width: 50%; }
.avr-step:first-child::before,
.avr-step:last-child::after { display: none; }
.avr-step.done::before,
.avr-step.done::after,
.avr-step.current::before { background: #3f9d57; }
.avr-bead {
	position: relative;
	z-index: 1;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 12px;
	font-weight: 600;
	background: #fff;
	border: 2px solid #d3d8e0;
	color: #98a1b2;
}
.avr-step.done .avr-bead { background: #3f9d57; border-color: #3f9d57; color: #fff; }
/* Поточний етап — найсильніший акцент: ЗАЛИВКА беда + кільце. Пройдені беди теж кольорові (зелена
   заливка), тож самого лише синього кільця було замало, щоб «де я» читалось сильніше за «де вже був». */
.avr-step.current .avr-bead {
	background: #3b6fd4;
	border-color: #3b6fd4;
	color: #fff;
	box-shadow: 0 0 0 3px rgba(59, 111, 212, .2);
}
.avr-check { font-size: 14px; line-height: 1; }
/* Підписи етапів. Три стани мають РІЗНИЙ контраст, але жоден не «сірий шум»: пройдені читаються
   спокійно, поточний — найсильніший акцент, майбутні — приглушені, але ще AA-контрастні (#5b6577 на
   білому = 6.1:1). Раніше сюди ж прилітала inline opacity:.4 з компонента (див. avr-stepper.js) —
   через неї підписи майбутніх етапів фактично зникали. */
.avr-lbl {
	margin-top: 6px;
	font-size: 12px;
	line-height: 1.25;
	max-width: 92px;
	color: #5b6577;
	overflow-wrap: anywhere;      /* довга назва етапу переноситься, а не налазить на сусідній бед */
}
.avr-step.done .avr-lbl { color: #3d4757; }
.avr-step.current .avr-lbl {
	color: #14306e;
	font-weight: 700;
}
/* Нецветовий текстовий признак поточного етапу (accessibility): не покладаємось лише на колір/заливку */
.avr-cur-tag {
	display: block;
	margin-top: 1px;
	font-size: 9px;
	font-weight: 700;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: #3b6fd4;
}
/* у вертикальному режимі (сайдбар рахунку) мітка йде поряд у тому ж рядку підпису */
.avr-vertical .avr-cur-tag { display: inline; margin-top: 0; margin-left: .4rem; }
/* Ціль, недоступна для переходу зараз: приглушений бед + курсор. Підпис лишається читабельним —
   це стан МАРШРУТУ, а не «вимкнений контрол» (див. коментар у avr-stepper.js). */
.avr-step.avr-blocked { cursor: not-allowed; }
.avr-step.avr-blocked .avr-bead { opacity: 0.75; }

/* клікабельний режим (форма не read-only): курсор + підсвітка при наведенні */
.avr-stepper.clickable .avr-step { cursor: pointer; }
.avr-stepper.clickable .avr-step:hover .avr-bead {
	border-color: #3b6fd4;
	box-shadow: 0 0 0 3px rgba(59, 111, 212, .14);
}
/* :not(.current) — у поточного беда заливка синя, і синій текст на ній був би невидимий */
.avr-stepper.clickable .avr-step:not(.done):not(.current):hover .avr-bead { color: #3b6fd4; }

/* #16418(follow-up) item 6/7 — клікабельні цілі переходу: рух УПЕРЕД (accent-синій) vs ПОВЕРНЕННЯ/
   ВІДХИЛЕННЯ (orange). Перебиває done-зелений на біді цілі-повернення (вона лівіше поточної → без цього
   виглядала б як «пройдено», а не як дія відкату). Лише у клікабельному (не read-only) режимі. */
.avr-stepper.clickable .avr-step.avr-allow-fwd .avr-bead {
	border-color: #3b6fd4;
	color: #3b6fd4;
	cursor: pointer;
}
.avr-stepper.clickable .avr-step.avr-allow-back .avr-bead {
	background: #fff;
	border-color: #d9822b;
	color: #d9822b;
	cursor: pointer;
}
.avr-stepper.clickable .avr-step.avr-allow-fwd:hover .avr-bead { box-shadow: 0 0 0 3px rgba(59, 111, 212, .18); }
.avr-stepper.clickable .avr-step.avr-allow-back:hover .avr-bead { box-shadow: 0 0 0 3px rgba(217, 130, 43, .20); }
.avr-stepper.clickable .avr-step.avr-allow-back .avr-lbl { color: #b96a1b; }

/* #16439 — вертикальний режим (сайдбар картки рахунку): беди в колонку, підпис праворуч від беда.
   Конектор — ОДИН вертикальний відрізок ::after від низу беда до наступного беда (горизонтальні
   half-сегменти базового режиму вимикаємо). Кольорові правила станів (done/current/allow-fwd/back)
   спільні з горизонтальним — тут лише геометрія. */
.avr-stepper.avr-vertical {
	flex-direction: column;
	align-items: stretch;
	overflow-x: visible;
	margin: 0;
	padding: 2px 0;
}
.avr-vertical .avr-step {
	flex: 0 0 auto;
	flex-direction: row;
	align-items: flex-start;
	gap: 0.5rem;
	min-width: 0;
	text-align: left;
	padding-bottom: 0.9rem;
}
.avr-vertical .avr-step:last-child { padding-bottom: 0; }
.avr-vertical .avr-step::before { display: none; }
.avr-vertical .avr-step::after {
	top: 30px;                                  /* низ беда (28px) + 2px зазор */
	bottom: 0;
	left: 13px;                                 /* центр беда: (28 - 2) / 2 */
	right: auto;
	width: 2px;
	height: auto;
}
.avr-vertical .avr-lbl {
	margin-top: 0;
	padding-top: 6px;                           /* оптичне вирівнювання підпису по центру беда */
	max-width: none;
	font-size: 12px;
}

@media (prefers-color-scheme: dark) {
	.avr-step::before, .avr-step::after { background: #3a4351; }
	.avr-bead { background: #1a1f29; border-color: #3a4351; color: #6b7484; }
	.avr-step.done .avr-bead { background: #3f9d57; border-color: #3f9d57; color: #fff; }
	.avr-step.current .avr-bead { background: #3b6fd4; border-color: #6f9bef; color: #fff; box-shadow: 0 0 0 3px rgba(111, 155, 239, .25); }
	.avr-lbl { color: #98a1b2; }
	.avr-step.done .avr-lbl { color: #c3cad6; }
	.avr-step.current .avr-lbl { color: #e7eaf1; }
	.avr-cur-tag { color: #6f9bef; }
	.avr-stepper.clickable .avr-step.avr-allow-fwd .avr-bead { border-color: #6f9bef; color: #6f9bef; }
	.avr-stepper.clickable .avr-step.avr-allow-back .avr-bead { background: #1a1f29; border-color: #e0965a; color: #e0965a; }
	.avr-stepper.clickable .avr-step.avr-allow-back .avr-lbl { color: #e0965a; }
}
/* #16310 UX — індикація лінивого режиму вкладки «Ресурси» у plan/basicplan/edit.
   Усі _assets/*.css бандляться плоско app-wide (грузяться і на edit-сторінці).
   Класи лише для індикатора завантаження; пусте состояние малюється платформним .empty-panel. */

.bp-res-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    padding: 2rem;
    color: var(--text-muted, #6b7280);
    font-style: italic;
}

.bp-res-loading::before {
    content: "";
    width: 1.1em;
    height: 1.1em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: bp-res-spin .8s linear infinite;
}

@keyframes bp-res-spin {
    to { transform: rotate(360deg); }
}

/* Пусте состояние lazy: підказка «оберіть роботу» + дія «Завантажити всі ресурси».
   Без кнопки фільтри вид/статус/пошук у lazy показували порожньо (бачать лише відкриті роботи). */
.bp-res-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .25rem;
    padding: 1rem;
}

.bp-res-empty .empty-panel {
    margin: 0;
}

/* Плашка «показано лише ресурси відкритих робіт» при відборі «всі роботи» у lazy. */
.bp-res-partial {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: .25rem .5rem;
    padding: .5rem .75rem;
    background: var(--bg-info, #eff6ff);
    border: 1px solid var(--border-info, #bfdbfe);
    border-radius: 4px;
    color: var(--text-muted, #475569);
    font-size: .9em;
}


/* #16468 — Popover «Зв'язані документи» в тулбарі: бейдж позиціонується absolute і виступає
   за правий край іконки (right: -7px), тож штатного зазора divider'а не вистачає і лічильник
   візуально злипається з кнопкою «Зберегти». Компенсуємо виступ бейджа. */
.toolbar .popover-wrapper.bp-linked-docs {
    margin-right: .5rem;
}

/* #15871 — ручна ознака «робота фінішована» (без акта). У рядку плану це НЕ окремий прапорець,
   а тег-перемикач: у спокої виглядає як звичайний тег, підпис дії живе в Tip (ховер) — підміняти
   текст засобами CSS не можна, бо ::after не локалізується. */
.work-finish-tag {
    display: inline-block;
    margin-top: 2px;
    padding: 1px 6px;
    border-radius: 10px;
    font-size: .85em;
    line-height: 1.35;
    text-decoration: none;
    cursor: pointer;
    background: var(--bg-success, #dcfce7);
    color: var(--text-success, #166534);
    border: 1px solid transparent;
}

.work-finish-tag:hover {
    border-color: var(--text-success, #166534);
    text-decoration: none;
}

.work-finish-tag.is-closed {
    background: var(--bg-warning, #fef3c7);
    color: var(--text-warning, #92400e);
}

.work-finish-tag.is-closed:hover {
    border-color: var(--text-warning, #92400e);
}

/* Чіп у тулбарі: скільки робіт готові до фінішування. З'являється лише коли такі роботи є. */
.works-closable-chip {
    margin-right: .5rem;
    padding: 2px 8px;
    border-radius: 12px;
    background: var(--bg-success, #dcfce7);
    color: var(--text-success, #166534);
    text-decoration: none;
    white-space: nowrap;
}

.works-closable-chip:hover {
    text-decoration: none;
    filter: brightness(.95);
}/* +Kamala. claude. 2026-06-21. #16251 — компактний індекс планів/бюджетів.
   Після додавання колонки «Період» текстові колонки злипалися й переносилися на багато рядків.
   Тут: мінімальна ширина текстових колонок (не «злипаються») + клемп комірки максимум у 2 рядки. */

/* Мінімальна ширина текстових (з переносом, не центрованих) колонок.
   :not(.marker) — інакше тонка колонка-маркер статусу (#16436) розтягується до 8rem порожнім місцем. */
.bp-index-grid table.data-grid > tbody > tr > td:not(.no-wrap):not(.text-center):not(.text-right):not(.marker) {
    min-width: 8rem;
}

/* +Kamala. claude. 2026-07-30. #16698 — кнопки рядка притиснуті до ПРАВОГО краю.
   Остання колонка (панель команд) забирає весь надлишок ширини контейнера (930px на шаблонах при
   вікні 1902px), а .commandbar розтягується на всю комірку з кнопками при ЛІВОМУ краї. Після
   перебалансування ширин змістовних колонок лівий край цієї комірки переїхав так, що «центр рядка»
   (точка, у яку влучає клік «обрати рядок» — і в браузері, і у WebDriver) припав рівно на кнопку:
   заміряно 978px = Basicplan_Row_Copy, тобто клік по рядку відкривав діалог «Створити копію?».
   flex-end відсуває кнопки до 1846px — далеко від центру — і це заразом канонічне місце дій рядка. */
.bp-index-grid table.data-grid > tbody > tr > td:last-child > .commandbar {
    justify-content: flex-end;
}

/* Рядок не вище 2 текстових рядків (для no-wrap колонок — і так 1 рядок) */
.bp-index-grid table.data-grid > tbody > tr > td:not(.no-wrap) > .dg-cell,
.bp-index-grid table.data-grid > tbody > tr > td:not(.no-wrap) > a {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: break-word;
}
/* #16906 — сторінка «Підписка». Лише типографіка шапки й показників: решту тримають
   штатні Card/Table/TabPanel. */

/* CssClass="muted" уже стоїть у розмітці проєкту (тут і в money/, act/), але самого класу немає
   ані в застосунку, ані в платформі — приглушений текст ніколи не був приглушеним. Оголошуємо
   один раз тут: клас спільний, тож і визначення має бути одне, а не по копії на кожну сторінку. */
/* #6b7280 на білому дає контраст ~4.8:1 — формально проходить AA, але на дрібному тексті
   читається як «вимкнено». Для підписів і пояснень беремо темніший slate (#4b5563, ~7:1):
   приглушено відносно основного тексту, але це все ще текст, який читають. */
.muted {
    color: var(--text-muted, #4b5563);
}

/* Text/Span у A2v10 інлайнові, тож заголовок і підзаголовок зліплювались в один рядок
   («ПідпискаКеруйте тарифом…»). Розкладаємо по рядках тут, а не порожніми Span'ами в розмітці. */
.billing-head > * {
    display: block;
}

.billing-head {
    margin-bottom: .25rem;
}

.billing-title {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
}

/* Бейдж статусу в колонці StackPanel розтягувався на всю ширину картки — плашка на пів-екрана
   замість позначки. */
.billing-hero .tag-label {
    align-self: flex-start;
}

/* Підпис показника й назва тарифу — кожен своїм рядком (обидва інлайнові за замовчуванням). */
.billing-line,
.billing-plan,
.billing-fact {
    display: block;
}

/* Назва тарифу — головне слово в картці стану, тому крупніша за все навколо. */
.billing-plan {
    font-size: 1.25rem;
    font-weight: 600;
}

/* Показники «наступний платіж» і «користувачі»: один розмір на обидва, інакше вони
   читаються як різні за важливістю, хоча стоять поруч. */
.billing-fact {
    font-size: 1.05rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Розшифровка «₴500 × 5 місць» — під підсумком, а не поруч: Span інлайновий, і без цього
   сума з розшифровкою зліплювались в одне число («₴2 500₴500 × 5 місць»). nowrap — щоб на вузькому
   вікні вона не ламалась на третій рядок і не робила одну картку вищою за сусідні. */
.billing-unit {
    display: block;
    white-space: nowrap;
}

/* #17115 — варіанти продовження як тарифні картки, а не таблиця. П'ять колонок, з яких дві майже
   завжди порожні, читались як службова відомість; картка показує те саме як ВИБІР. Ширину обмежуємо
   тут же: на широкому моніторі три картки інакше розтягуються на весь екран. */
.plan-cards {
    display: grid;
    /* auto-fit + minmax, а не фіксовані три колонки: на вузькому вікні (сайдбар реквізитів забирає
       320px) картки самі переходять у стовпчик, замість стискатись до нечитабельного. */
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem;
    max-width: 68rem;
}

/* Flex-колонка потрібна саме тут: донизу притискається .plan-action, інакше кнопки трьох карток
   стоять на різній висоті — у річної над кнопкою зайвий рядок з економією. */
.plan-card {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: 1.25rem;
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: .5rem;
    background: #fff;
}

/* Рекомендований варіант виділяє сама картка, а не лише бейдж усередині: рамка прочитується
   раніше за текст. Друга рамка — box-shadow, а не border: 2px, бо товща рамка зсунула б вміст
   картки на піксель відносно сусідніх. */
.plan-card-featured {
    border-color: var(--accent-color, #3470b4);
    box-shadow: 0 0 0 1px var(--accent-color, #3470b4);
}

/* Період і бейдж («Рекомендовано»/«Поточний») — в один рядок. min-height тримає однакову висоту
   шапки в картці без бейджа, інакше сума в ній піднімається вище за сусідні. */
.plan-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    min-height: 1.75rem;
}

.plan-name {
    font-size: 1.05rem;
    font-weight: 600;
}

/* Сума — головне в картці, тому помітно крупніша за все навколо (як на pricing-сторінках). */
.plan-price {
    display: block;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.2;
}

/* align-self — той самий рецепт, що й у .billing-hero .tag-label вище: у flex-колонці бейдж
   інакше розтягується на всю ширину картки і перестає читатись як позначка. */
.plan-saving {
    margin-top: .25rem;
    align-self: flex-start;
}

/* text-align центрує бейдж «Поточний», що стоїть на місці кнопки; на саму кнопку не впливає —
   вона розтягнута на всю ширину нижче. Розтягувати бейдж НЕ можна: суцільна смуга на всю картку
   читається як ще одна кнопка, хоча вона нічого не робить. */
.plan-action {
    margin-top: auto;
    padding-top: 1.25rem;
    text-align: center;
}

/* Кнопка на всю ширину картки: три різні за довжиною підписи («Обрати»/«Оплатити місяць») інакше
   дають кнопки різної ширини, і ряд карток виглядає неохайно. */
.plan-action button {
    width: 100%;
}

/* Базовий кегль сторінки. Платформенний дефолт (~12px) на цій сторінці читається важко: тут не
   грід із сотнею рядків, а три варіанти тарифу і кілька пояснень — щільність не потрібна, потрібна
   читабельність. Піднімаємо в одному місці, щоб картки, сайдбар і пояснення лишались узгодженими. */
.billing-plans,
.billing-sidebar {
    font-size: .9375rem;
    line-height: 1.5;
}

/* Розшифровки й підписи були на два кроки дрібніші за значення — на межі читабельності.
   Один крок різниці достатньо, щоб прочитувалась ієрархія. */
.billing-unit,
.billing-line {
    font-size: .875rem;
}

.billing-doc + .billing-doc {
    border-top: 1px solid var(--border-color, #e5e7eb);
    padding-top: .5rem;
}
.btn {
  padding: 0.5rem 0.75rem;
  vertical-align: middle;
}
.btn:focus {
  outline-offset: -3px;
  outline-color: #bbb;
  outline-style: dotted;
  outline-width: 1px;
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn > .ico {
  margin-right: 0.2em;
}
.btn.btn-icon > .ico {
  margin-right: 0;
}
.btn:not([disabled]):hover {
  box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.4);
  transition: box-shadow linear 0.2s;
}
.btn:not([disabled]):active {
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2) inset;
  outline-style: none;
  transition: box-shadow linear 0.2s;
}
.btn .btn-badge {
  position: absolute;
  top: 3px;
  right: 3px;
  font-size: 9px;
  background-color: coral;
  border-radius: 50%;
  padding: 1px;
  min-width: 14px;
  min-height: 14px;
}
.btn.lg {
  padding: 0.85rem 1rem;
  font-size: 1.25rem;
  line-height: 1;
}
.btn.lg .ico {
  font-size: 1.3rem;
}
.btn.sm {
  padding: 0.4rem;
  font-size: 0.95rem;
  line-height: 1;
  min-height: 27px;
}
.btn.sm > .ico {
  font-size: 12px;
}
.btn.xs {
  padding: 0.25rem 0.7rem;
  font-size: 0.85rem;
  line-height: 1;
}
.btn.xs .ico {
  font-size: 0.85rem;
}
.btn.block + .btn.block {
  margin-top: 6px;
}
.btnclose {
  padding: 0 4px;
  line-height: normal;
  background-color: transparent;
  border: 1px solid transparent;
}
.caret {
  display: inline-block;
  margin: 0 0.25em;
  border: 4px solid transparent;
  vertical-align: middle;
  border-top-color: currentColor;
}
.caret.up {
  border-top-color: transparent;
  border-bottom-color: currentColor;
  vertical-align: 2px;
}
.btn.icon-top {
  display: inline-grid !important;
}
.btn.btn-primary {
  background-color: #3470b4;
  color: white;
}
.btn.btn-primary:active {
  background-color: #2b5c94 !important;
}
.btn.btn-primary:not([disabled]):hover {
  background-color: #2e64a0;
}
.btn.btn-primary[disabled] {
  color: #f5f5f5;
}
.btn.btn-orange,
.btn.btn-warning {
  background-color: #ffb74d;
  color: white;
}
.btn.btn-orange:active,
.btn.btn-warning:active {
  background-color: #ffa624 !important;
}
.btn.btn-orange:not([disabled]):hover,
.btn.btn-warning:not([disabled]):hover {
  background-color: #ffad33;
}
.btn.btn-orange[disabled],
.btn.btn-warning[disabled] {
  color: #f5f5f5;
}
.btn.btn-green,
.btn.btn-success {
  background-color: #5db750;
  color: white;
}
.btn.btn-green:active,
.btn.btn-success:active {
  background-color: #4c9d41 !important;
}
.btn.btn-green:not([disabled]):hover,
.btn.btn-success:not([disabled]):hover {
  background-color: #52a845;
}
.btn.btn-green[disabled],
.btn.btn-success[disabled] {
  color: #f5f5f5;
}
.btn.btn-red,
.btn.btn-danger,
.btn.btn-error {
  background-color: #da533f;
  color: white;
}
.btn.btn-red:active,
.btn.btn-danger:active,
.btn.btn-error:active {
  background-color: #c93c27 !important;
}
.btn.btn-red:not([disabled]):hover,
.btn.btn-danger:not([disabled]):hover,
.btn.btn-error:not([disabled]):hover {
  background-color: #d6402a;
}
.btn.btn-red[disabled],
.btn.btn-danger[disabled],
.btn.btn-error[disabled] {
  color: #f5f5f5;
}
.btn.btn-cyan,
.btn.btn-info {
  background-color: #60bbe5;
  color: white;
}
.btn.btn-cyan:active,
.btn.btn-info:active {
  background-color: #3dacdf !important;
}
.btn.btn-cyan:not([disabled]):hover,
.btn.btn-info:not([disabled]):hover {
  background-color: #4ab2e1;
}
.btn.btn-cyan[disabled],
.btn.btn-info[disabled] {
  color: #f5f5f5;
}
.btn-rounded {
  border-radius: 10rem;
  padding: 0.5rem;
  min-width: 2.6rem;
  min-height: 2.6rem;
}
.btn-outline {
  background-color: transparent;
  border: 1px solid #ddd;
}
.btn-outline:hover {
  border-color: #e5c365;
  background-color: #fdf4bf;
}
.btn-outline:active {
  background-color: #fff29d;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2) inset;
  border-color: #e5c365;
  outline: none;
}
.btn-outline:focus {
  outline: none;
}
.btn-outline .ico:before {
  color: #777 !important;
}

.btn-tb {
  padding: 5px 6px 6px 6px;
  white-space: nowrap;
  background-color: transparent;
  color: #222;
  min-width: 0;
  min-height: 28px;
  margin: 2px 0;
}
.btn-tb:focus {
  outline: 1px dotted #9dacca;
  outline-offset: -2px;
}
.btn-tb:hover {
  background-color: #fdf4bf;
  border-color: #e5c365;
  outline: none;
}
.btn-tb:active {
  background-color: #fff29d;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2) inset;
  border-color: #e5c365;
  outline: none;
}
.btn-tb:disabled {
  color: #999;
}
.btn-tb:disabled:hover {
  background-color: transparent;
  border-color: transparent;
}
.btn-tb > i.ico {
  display: inline-block;
  margin-right: 2px;
  color: #333;
}
.control-group .input-group .a2-inline {
  margin-left: 0 !important;
}

.a2-hyperlink.highlight .ico.ico-send:before {
  content: "\e950";
}
.a2-hyperlink.highlight:not([disabled]) .ico:before {
  color: #208cf8 !important;
}
.a2-hyperlink.highlight:not([disabled]) .ico.ico-send:before {
  content: "\e951";
}
.a2-hyperlink.small i.ico {
  font-size: 12px;
}
.a2-hyperlink.large i.ico {
  font-size: 15px;
}

/* TabBar Style="ButtonGroup" */

/* #17507 — контраст активної кнопки перемикача. Платформа дає білий текст на #9ab3e0
   (advance.min.css: .a2-tab-bar.tab-bar-button-group .a2-tab-button.active) — це 2.1:1 при нормі
   4.5:1, тобто активна кнопка читається ГІРШЕ за неактивні. Беремо колір основної кнопки застосунку
   (.btn-primary вище в цьому файлі, #3470b4 — 5.1:1 на білому тексті): перемикач стає контрастним і
   не вводить у систему ще один синій. Літерал, а не var(--accent-color, ...): ця змінна в проєкті
   ніде не визначена, а її fallback'и розходяться (#2563eb у tree-grid.css проти #3470b4 у
   billing.css), тож посилання на неї зробило б колір заручником чужого рішення. Пару «фон + текст»
   тримаємо разом навмисне — щоб наступна правка бачила обидві половини контрасту.
   Селектор один-в-один платформенний: специфічність та сама, виграє порядок підключення
   (_Layout.tabbed.cshtml вантажить _assets після теми). Правило ГЛОБАЛЬНЕ — діє на всі 5 форм із
   ButtonGroup: catalog/project/edit, report/payrollcontrol/index, report/projectplantree/tab,
   report/projectcashflow/{index,tab}. */
.a2-tab-bar.tab-bar-button-group .a2-tab-button.active {
  background-color: #3470b4;
  border-color: #3470b4;
  color: #fff;
}/* Спільний read-only-вигляд карток-сторінок: disabled-поля показуються як значення
   (без рамки/фону, без іконок очистки/вибору/стрілки), порожні значення → «—»,
   дати вирівняні зліва. Спільне для картки проєкту (.prj-card, project-card.css) і
   контрагента (.agent-card, agent-card.css) — раніше дублювалося в обох файлах.
   Картка акта (.act-card, internalact-card.css) НАВМИСНО не входить: там
   read-only поля лишаються з рамками для однорідності з редагованими.

   Наприкінці файла — .doc-num: номер документа в шапці картки (Акт, План робіт). */

.prj-card .control-group.disabled .input-group,
.agent-card .control-group.disabled .input-group {
	background-color: transparent;
	border-color: transparent;
}
.prj-card .control-group.disabled .input-group input,
.prj-card .control-group.disabled .input-group textarea,
.prj-card .control-group.disabled .input-group .select-text,
.agent-card .control-group.disabled .input-group input,
.agent-card .control-group.disabled .input-group textarea,
.agent-card .control-group.disabled .input-group .select-text {
	color: #1f2d3d;
}
/* приховати дії (очистка ×, вибір …, олівець) у read-only полях */
.prj-card .control-group.disabled .input-group > a,
.agent-card .control-group.disabled .input-group > a {
	display: none;
}
/* приховати dropdown-стрілку: комбо показуються як текст значення */
.prj-card .control-group.disabled .caret,
.agent-card .control-group.disabled .caret {
	display: none;
}
/* порожнє значення селектора/комбо у перегляді → тире */
.prj-card .control-group.disabled .input-group .select-text:empty::after,
.agent-card .control-group.disabled .input-group .select-text:empty::after {
	content: '—';
	color: #9aa5b1;
}
/* порожні текстові поля у перегляді → тире (через placeholder), без сірої підказки */
.prj-card .control-group.disabled .input-group input::placeholder,
.prj-card .control-group.disabled .input-group textarea::placeholder,
.agent-card .control-group.disabled .input-group input::placeholder,
.agent-card .control-group.disabled .input-group textarea::placeholder {
	color: #9aa5b1;
	opacity: 1;
}
/* дати/значення у перегляді вирівняні зліва, ближче до label */
.prj-card .control-group.disabled .input-group input,
.agent-card .control-group.disabled .input-group input {
	text-align: left;
}

/* ---- Номер документа в шапці картки (#16693) ----
   Номер видає сервер, руками він не правиться. Повнорамковий TextBox поряд з
   редагованими «Найменування»/«Проєкт» читається як поле для вводу, тому номер
   малюємо як ЗНАЧЕННЯ поряд з «№» — без рамки й фону, кеглем свого заголовка.
   Опис один, споживачів два: .act-card (act/internalact/edit.view.xaml, стиль
   прийшов з UX-тюнінгу #16021) і картка Плану робіт (plan/basicplan/edit.view.xaml).
   Кегль — через --doc-num-size, бо заголовки карток різні (Акт 1.4rem, План 1.25rem),
   а номер має читатися частиною СВОГО заголовка; дефолт підходить Плану як є. */
.doc-num-label {
	color: #5a6b7b;
}
.control-group.doc-num {
	margin: 0;
}
/* Робочий тут ДРУГИЙ селектор (0,4,0): поле завжди Disabled="True", а платформне
   `.control-group.disabled .input-group` (0,3,0, з var(--bgPrimary)) інакше перебиває фон і
   лишає блакитну плашку. Перший (0,3,0) — та сама вага, що в платформи, тож тримається лише на
   порядку каскаду; лишений на випадок розмітки без .disabled. */
.control-group.doc-num .input-group,
.control-group.doc-num.disabled .input-group {
	background: transparent;
	border-color: transparent;
}
/* #16781 — номер не можна обрізати: це ідентифікатор документа. Фіксовані 6rem вміщали лише
   шаблон нумератора {nnnnn}; з префіксним шаблоном (АВР-{yyyy}-{nnnnn}, 14 символів) поле 90px
   різало значення до «АВР-202». Ширина йде за вмістом (field-sizing, Chrome 123+); фолбек у
   старих браузерах — дефолтна ширина input (~20 символів), а не 6rem. Той самий рецепт, що вже
   працює у складських документах (_assets/goodsreceipt.css, .gr-num).
   ponytail: стеля — номер довший за 26rem згорнеться в еліпсис; апгрейд — Static замість
   disabled-TextBox (але тоді втрачається платформений bind-контракт поля). */
.doc-num .input-group input {
	field-sizing: content;
	width: auto;
	min-width: 5rem;
	max-width: 26rem;
	text-overflow: ellipsis;
	padding-left: 0.25rem;
	text-align: left;
	font-size: var(--doc-num-size, 1.25rem);
	font-weight: 600;
	color: #2c3e50;
}
/* Changelog «Що нового» — feed (страница /home/changelog) и Taskpad главной */
.changelog-page .changelog-feed {
    padding: 1rem 1.25rem;
    overflow: auto;
    max-height: 100%;
}
.changelog-page .cl-row {
    padding: .55rem 0;
    border-bottom: 1px solid #ececec;
    align-items: start;
}
.changelog-page .cl-row:last-child { border-bottom: none; }
.changelog-page .cl-date { color: #8a8a8a; white-space: nowrap; }
.changelog-page .cl-tags:empty { display: none; }

/* Taskpad главной */
.cl-taskpad { padding: .25rem .25rem 1rem; }
.cl-taskpad .cl-tp-item {
    padding: .5rem 0;
    border-bottom: 1px solid #ececec;
}
.cl-taskpad .cl-tp-item:last-child { border-bottom: none; }
.cl-taskpad .cl-tp-date { color: #8a8a8a; font-size: .78rem; }
.cl-taskpad .cl-tp-all { margin-top: .75rem; display: inline-block; }
/* Task Chat Panel (inside Taskpad) */
.task-chat-panel .taskpad-body {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.task-chat-input {
	border-top: 1px solid #e0e0e0;
	background: #fafbfc;
	margin-top: auto;
	flex-shrink: 0;
}

.task-chat-input .stack-panel.horizontal {
	align-items: center;
}

/* Chat input row: [📎] [textarea] [send] */
.chat-input-row {
	align-items: flex-end !important;
}

.chat-input-row .control-group {
	flex: 1 1 0% !important;
	min-width: 0 !important;
	width: auto !important;
}

.chat-input-row .control-group textarea {
	width: 100%;
	resize: none;
}

.chat-input-row > .btn,
.chat-input-row > .a2-button {
	flex: 0 0 auto;
}

.chat-input-row > .btn {
	cursor: pointer;
	transition: opacity 0.15s, transform 0.1s;
}

.chat-input-row > .btn:hover {
	opacity: 0.85;
	transform: scale(1.05);
}

/* Message styles */
.chat-message,
.chat-message-own {
	padding: 0.4rem 0.6rem;
	border-radius: 6px;
	margin-bottom: 0.5rem;
	box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}

.chat-message {
	background: #f0f2f5 !important;
	margin-right: 2rem;
}

.chat-message-own {
	background: #e3f2fd !important;
	margin-left: 2rem;
}

/* Grouped messages: reduce gap and add visual connector */
.a2-list-item.chat-message + .a2-list-item.chat-message,
.a2-list-item.chat-message-own + .a2-list-item.chat-message-own {
	margin-top: -0.25rem;
	border-top-left-radius: 0;
	border-top-right-radius: 0;
}

/* First message in group: sharpen bottom corners when followed by continuation */
.a2-list-item.chat-message:has(+ .a2-list-item.chat-message),
.a2-list-item.chat-message-own:has(+ .a2-list-item.chat-message-own) {
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
	margin-bottom: 1px;
}

/* Message row layout: [avatar] [content] */
.chat-msg-row {
	align-items: flex-start;
}

.chat-msg-body {
	flex: 1 1 auto;
	min-width: 0;
}

/* Avatar circle with initials */
.chat-avatar {
	flex: 0 0 1.8rem;
	width: 1.8rem;
	height: 1.8rem;
	border-radius: 50%;
	background: #7986cb;
	color: white;
	font-size: 0.7rem;
	font-weight: 600;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-top: 0.1rem;
	line-height: 1;
}

.chat-message-own .chat-avatar {
	background: #42a5f5;
}

/* Quote block */
.chat-quote {
	border-left: 3px solid #1976d2;
	background: rgba(25, 118, 210, 0.08);
	border-radius: 0 4px 4px 0;
	margin-bottom: 0.2rem;
}

.chat-quote-text {
	font-style: italic;
	color: #666;
	font-size: 0.85em;
}

/* Quote preview in input area */
.chat-quote-preview {
	background: #fff3cd;
	border-left: 3px solid #ffc107;
	border-radius: 0 4px 4px 0;
	padding: 0.25rem 0.5rem;
	align-items: center;
}

/* Attachment preview */
.chat-attachment-preview {
	background: #e8f5e9;
	border-left: 3px solid #4caf50;
	border-radius: 0 4px 4px 0;
	padding: 0.25rem 0.5rem;
	align-items: center;
}

/* Date label */
.chat-date {
	font-size: 0.8em;
	color: #999;
}

/* Reply button */
.chat-reply-btn {
	opacity: 0;
	transition: opacity 0.15s;
}

.a2-list-item:hover .chat-reply-btn {
	opacity: 0.6;
}

.chat-reply-btn:hover {
	opacity: 1 !important;
}

/* Chat attachment link */
.chat-attach-link {
	align-items: center;
}

.chat-attach-icon {
	font-size: 0.85em;
	opacity: 0.7;
}

/* Chat file upload - compact icon-only style (override framework defaults) */
.chat-input-row .a2-file-upload {
	flex: 0 0 auto !important;
	align-self: flex-end;
	margin-bottom: 0.3rem;
}

.chat-input-row .a2-file-upload .file-upload {
	border: none !important;
	padding: 0 !important;
	min-height: auto !important;
	height: auto !important;
	background: transparent !important;
	cursor: pointer;
	display: inline-flex !important;
	align-items: center;
	position: relative;
	color: inherit;
}

.chat-input-row .a2-file-upload .file-upload input {
	position: absolute;
	width: 100%;
	height: 100%;
	opacity: 0;
	cursor: pointer;
}

.chat-input-row .a2-file-upload .upload-tip {
	display: none !important;
}

.chat-input-row .a2-file-upload .ico {
	font-size: 1.4rem !important;
	color: #888;
	position: static !important;
	top: auto !important;
	left: auto !important;
}

.chat-input-row .a2-file-upload .ico::before {
	content: "\e954" !important;
}

.chat-input-row .a2-file-upload .file-upload:hover .ico {
	color: #1976d2;
}

/* Chat messages list scrollable */
.task-chat-panel .a2-list.chat {
	overflow-y: auto;
	overflow-x: hidden;
	min-height: 0;
	flex: 1 1 auto;
}

/* Prevent message text from overflowing */
.chat-message,
.chat-message-own {
	word-break: break-word;
	overflow-wrap: break-word;
	min-width: 0;
}

/* Cancel task button - outlined danger style */
.modal .btn.btn-danger[test-id="Task_Cancel"] {
	background-color: transparent;
	color: #da533f;
	border: 1px solid #da533f;
}

.modal .btn.btn-danger[test-id="Task_Cancel"]:not([disabled]):hover {
	background-color: #da533f;
	color: white;
}

/* Dialog grid - adjust columns when chat Taskpad is collapsed */
.modal-content .dialog-grid {
	min-height: 0;
}

.modal-content .dialog-grid:has(.taskpad.collapsed) {
	grid-template-columns: 1fr auto !important;
}
.commandbar {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  padding: 0;
  overflow: visible;
  background-color: transparent;
  color: #208cf8;
}
.commandbar .btn-cb {
  white-space: nowrap;
  background-color: transparent;
  text-transform: lowercase;
  color: #222;
  min-width: 0;
  padding: 2px 4px 3px 4px;
}
.commandbar .btn-cb:focus {
  outline: 1px dotted #9dacca;
  outline-offset: -2px;
}
.commandbar .btn-cb:disabled {
  color: #777;
}
.commandbar .btn-cb:disabled:hover {
  background-color: transparent;
  border-color: transparent;
}
.commandbar.visible-active,
.commandbar.visible-hover {
  visibility: hidden;
}
.active .commandbar.visible-active,
.active .commandbar.visible-hover {
  visibility: visible;
}
tr:hover .commandbar.visible-hover {
  visibility: visible;
}
.data-grid td > .commandbar {
  margin: -3px;
}

table.tree-grid .commandbar {
  margin: -3px;
}

.commandbar .btn-cb:hover {
  outline: none;
  background-color: rgba(27, 166, 255, 0.2);
  border-color: #0f8e92;
}
.commandbar .btn-cb:active {
  outline: none;
  background-color: rgba(27, 166, 255, 0.2);
  border-color: #0f8e92;
  box-shadow: none;
}/* Dashboard Filter Bar */
.dashboard-filter-bar {
	display: flex;
	align-items: center;
	gap: 1rem;
	margin-bottom: 1rem;
	padding: 0.5rem 1rem;
	background: white;
	border-radius: 8px;
	box-shadow: 0 1px 3px rgba(0,0,0,0.1);
	flex-wrap: wrap;
}
.dashboard-filter-bar .filter-group {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}
.dashboard-filter-bar .filter-label {
	color: #666;
	font-size: 0.85rem;
	white-space: nowrap;
}
.dashboard-filter-bar select {
	padding: 4px 8px;
	border: 1px solid #ddd;
	border-radius: 4px;
	min-width: 150px;
	font-size: 0.85rem;
	background: white;
	cursor: pointer;
}
.dashboard-filter-bar select:focus {
	outline: none;
	border-color: var(--status-info);
	box-shadow: 0 0 0 2px rgba(33,150,243,0.15);
}

/* Searchable filter dropdown (#15536) */
.dashboard-filter-bar .searchable-select {
	position: relative;
	min-width: 180px;
}
.dashboard-filter-bar .ss-input {
	width: 100%;
	padding: 4px 8px;
	border: 1px solid #ddd;
	border-radius: 4px;
	font-size: 0.85rem;
	background: white;
	cursor: pointer;
	box-sizing: border-box;
}
.dashboard-filter-bar .ss-input:focus {
	outline: none;
	border-color: var(--status-info);
	box-shadow: 0 0 0 2px rgba(33,150,243,0.15);
}
.dashboard-filter-bar .ss-list {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	z-index: 50;
	max-height: 260px;
	overflow-y: auto;
	margin-top: 2px;
	background: white;
	border: 1px solid #ddd;
	border-radius: 4px;
	box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.dashboard-filter-bar .ss-item {
	padding: 6px 10px;
	font-size: 0.85rem;
	cursor: pointer;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.dashboard-filter-bar .ss-item:hover {
	background: #f0f7ff;
}
.dashboard-filter-bar .ss-empty {
	padding: 6px 10px;
	font-size: 0.85rem;
	color: #999;
}

/* Clickable task-list rows (#15536) */
.task-report-page .task-row {
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.task-report-page .task-row:hover {
	background-color: #f0f7ff !important;
}

/* Scrollable overdue block with sticky header (#16219) — менша висота, бо блок над списком задач */
.task-report-page .overdue-list-scroll {
	max-height: 35vh;
	overflow-y: auto;
}
.task-report-page .overdue-list-scroll thead th {
	position: sticky;
	top: 0;
	z-index: 1;
	background: #f5f5f5;
}

/* Dashboard Animations & Styles */
.dashboard-page {
	background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%);
	min-height: 100vh;
}

/* Card animations */
.kpi-card {
	transition: transform 0.3s ease, box-shadow 0.3s ease;
	cursor: pointer;
	animation: fadeInUp 0.5s ease-out;
	animation-fill-mode: both;
}
.kpi-card:hover {
	transform: translateY(-5px);
	box-shadow: 0 8px 25px rgba(0,0,0,0.15) !important;
}
.kpi-card:nth-child(1) { animation-delay: 0.05s; }
.kpi-card:nth-child(2) { animation-delay: 0.1s; }
.kpi-card:nth-child(3) { animation-delay: 0.15s; }
.kpi-card:nth-child(4) { animation-delay: 0.2s; }
.kpi-card:nth-child(5) { animation-delay: 0.25s; }
.kpi-card:nth-child(6) { animation-delay: 0.3s; }

@keyframes fadeInUp {
	from {
		opacity: 0;
		transform: translateY(20px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* Pulse animation for alerts */
.pulse-alert {
	animation: pulse 2s infinite;
}
@keyframes pulse {
	0% { box-shadow: 0 0 0 0 rgba(244, 67, 54, 0.4); }
	70% { box-shadow: 0 0 0 15px rgba(244, 67, 54, 0); }
	100% { box-shadow: 0 0 0 0 rgba(244, 67, 54, 0); }
}

/* Number counter animation */
.counter-value {
	display: inline-block;
	transition: all 0.3s ease;
}
.counter-value:hover {
	transform: scale(1.1);
}

/* Progress bar */
.progress-bar-container {
	width: 100%;
	height: 8px;
	background: #e0e0e0;
	border-radius: 4px;
	overflow: hidden;
	margin-top: 0.5rem;
}
.progress-bar {
	height: 100%;
	border-radius: 4px;
	transition: width 1s ease-out;
	background: linear-gradient(90deg, var(--status-success), #8BC34A);
}
.progress-bar.warning { background: linear-gradient(90deg, var(--status-warning), #FFC107); }
.progress-bar.danger { background: linear-gradient(90deg, var(--status-danger), #E91E63); }

/* Panel animations */
.panel-animated {
	animation: fadeIn 0.6s ease-out;
	animation-fill-mode: both;
}
.panel-animated:nth-of-type(1) { animation-delay: 0.35s; }
.panel-animated:nth-of-type(2) { animation-delay: 0.4s; }
.panel-animated:nth-of-type(3) { animation-delay: 0.45s; }

@keyframes fadeIn {
	from { opacity: 0; transform: translateY(10px); }
	to { opacity: 1; transform: translateY(0); }
}

/* Risk item animation */
.risk-item {
	transition: background-color 0.2s ease, padding-left 0.2s ease;
	border-left: 3px solid transparent;
}
.risk-item:hover {
	background-color: #fff5f5;
	padding-left: 1.25rem;
	border-left-color: var(--status-danger);
}

/* Finance stat hover */
.finance-stat {
	padding: 1rem;
	border-radius: 8px;
	transition: background-color 0.2s ease, transform 0.2s ease;
}
.finance-stat:hover {
	background-color: #f5f5f5;
	transform: scale(1.02);
}

/* Table row animation */
.data-grid tbody tr {
	transition: background-color 0.2s ease;
}

/* Status indicator */
.status-dot {
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	margin-right: 0.5rem;
	animation: blink 1.5s infinite;
}
.status-dot.green { background-color: var(--status-success); animation: none; }
.status-dot.yellow { background-color: var(--status-warning); }
.status-dot.red { background-color: var(--status-danger); }

@keyframes blink {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.5; }
}

/* Sparkline / Mini chart */
.mini-chart {
	display: flex;
	align-items: flex-end;
	height: 30px;
	gap: 2px;
	margin-top: 0.5rem;
}
.mini-chart-bar {
	flex: 1;
	background: linear-gradient(to top, var(--status-info), #64B5F6);
	border-radius: 2px 2px 0 0;
	transition: height 0.5s ease;
	min-height: 3px;
}
/* DataGrid: перетягування ширини колонок, дрібні утиліти комірок (вирівнювання, перенос/
   обрізання тексту, оверлей CommandBar) та наскрізні фікси обрізання спливашок у гриді/табі.
   Обʼєднано з column-resize.css і винесено з main_cpms.css під час рефакторингу _assets. */

/* ---- Перетягування ширини колонок DataGrid ---- */
/* Column resize handles for DataGrid */
table.data-grid.resizable > thead > tr > th:not(.fit):not(.marker):not(:last-child) {
    position: relative;
}

table.data-grid.resizable > thead > tr > th:not(.fit):not(.marker):not(:last-child)::after {
    content: '';
    position: absolute;
    /* Ширину/положення тримати синхронно з RESIZE_GRAB_PX у _components/column-resize.ts
       (зараз ±6px → right:-6px; width:12px). Симетрична смуга навколо межі + вищий z-index,
       ніж у сусідньої комірки, щоб хіт-тест влучав саме в цю th і ресайз брався стабільно
       при будь-якому масштабі екрана/зумі (DPR>1). */
    right: -6px;
    top: 4px;
    bottom: 4px;
    width: 12px;
    cursor: col-resize;
    z-index: 11;
    border-radius: 3px;
}

table.data-grid.resizable > thead > tr > th:not(.fit):not(.marker):not(:last-child):hover::after,
table.data-grid.resizable > thead > tr > th.col-resizing::after {
    background: rgba(0, 123, 255, 0.3);
}

body.col-resizing,
body.col-resizing * {
    cursor: col-resize !important;
    user-select: none !important;
}

/* ---- Щільність комірок fetch-гриду (type-ahead Selector) ---- */
.data-grid-fetch td {
    padding: 6px 8px !important;
}

.data-grid-fetch th .h-holder {
    padding: 2px 8px !important;
}

/* ---- Наскрізні фікси обрізання спливашок (Selector/DatePicker/меню) у гриді та табі ---- */
.a2-sticky-container {
    overflow: visible;
}

.tab-panel.full-page .tab-content {
    overflow: visible;
}
.DataGrid_overflow {
    overflow: visible;
    overflow-y: inherit;
}

/* #16099 — fixed-header грид (стиль DataGridPanel) дає скрол/обрізку на контейнері
   (.data-grid-container.fixed-header{overflow:auto}) і тілі (.data-grid-body.fixed-header).
   Це обрізає спливашки (Selector, DatePicker) у комірках. Знімаємо overflow селекторами тієї ж
   специфічності (.DataGrid_overflow.fixed-header, тай-брейк за порядком: appstyles після tabbed.css).
   Рівні .tab-panel/.tab-item уже visible у overflow-діалогах (Dialog Overflow=True → .modal-content.overflow). */
.DataGrid_overflow.fixed-header,
.DataGrid_overflow.fixed-header > .data-grid-body.fixed-header {
    overflow: visible;
    height: auto;
}

/*+claude. 2026-07-31. #16568 — ТЧ грошового документа: спливашка Selector у комірці різалась
   ТРЬОМА предками одразу. `.DataGrid_overflow` вище знімає лише перший (.data-grid-container),
   а `.tab-item`/`.tab-panel` картки платежу закінчуються РІВНО по нижньому краю гріда (вони
   розтягнуті по контенту), тож панель обрізалась на ~85px і на екрані її не було видно взагалі.
   Вимикаємо їхній overflow ТОЧКОВО, за класом на <TabPanel> — глобально чіпати `.tab-panel` не
   можна, у вкладок із довгим контентом на ньому тримається власний скрол.
   Специфічність: `.tab-panel.DocTabs_overflow` (0,2,0) б'є платформений `.tab-panel` (0,1,0);
   `... .tab-content .tab-item` (0,4,0) б'є `.tab-panel .tab-content .tab-item` (0,3,0).
   Наслідок відомий: ТЧ більше не має власного вертикального скролу — довгий документ розтягує
   вкладку, а скролиться `.page-content`. Для exchangediff це прийнятно (sticky-шапки в цьому гріді
   немає). Апгрейд, коли платформа навчиться рендерити `.selector-pane` через portal.
   #17509 — картка платежу з цього компромісу ВИЙШЛА (повновисотна вкладка + FixedHeader + .pay-rows-grid
   у site.css: тіло гріда вище за випадайку верхнього поля рядка; нижчі яруси складених комірок і
   нижні рядки доступні скролом самої ТЧ — панель у ньому не зникає). Клас лишився у
   money/exchangediff — правило не видаляти. */
.tab-panel.DocTabs_overflow,
.tab-panel.DocTabs_overflow .tab-content .tab-item {
    overflow: visible;
}

.OverflowX {
    overflow-x: auto;
}

/* ---- Вирівнювання вмісту комірок по центру вертикалі ---- */
.DataGrid_valign .data-grid-body .data-grid > tbody > tr > td {
    vertical-align: middle;
}

.a2-table td.ctrl {
    vertical-align: middle;
}

/* ---- Індекси каталогів/документів: НЕ сплющувати колонки ---- */
/*+claude. 2026-06-29. UI-review — стандарт для індекс-списків (каталоги + документи): колонки в
   натуральну ширину в один рядок (без переносу), зайві колонки за правим краєм → горизонтальний
   скрол (контейнер .data-grid-container вже overflow:auto). Допустимо для облікових систем.
   Застосовується через CssClass="cat-index-grid" (каталоги) / "doc-index-grid" (документи) на
   DataGrid. Блокові комірки (StackPanel — 2-рядкові «Бюджет»/«Замовник/Генпідрядник») не зачіпає:
   nowrap діє лише на текстові вузли. */
.cat-index-grid table.data-grid > tbody > tr > td,
.cat-index-grid table.data-grid > thead > tr > th,
.doc-index-grid table.data-grid > tbody > tr > td,
.doc-index-grid table.data-grid > thead > tr > th {
    white-space: nowrap;
}
.cat-index-grid,
.doc-index-grid {
    overflow-x: auto;
}
/* Розумне обмеження ширини комірки: дуже довгий текст (опис ресурсу 150-220+ симв.) не розтягує
   колонку на 1000+px, а обрізається в один рядок з «…». Повне значення доступне ресайзом колонки
   (грід resizable) або по кліку у картку. Cap на внутрішньому носії контенту (a/span), бо max-width
   на самому <td> в table-layout:auto не дотримується. Заразом знімає 2-рядковий .text-truncate-2
   (документи): inline-block робить -webkit-line-clamp інертним → один рядок + «…». */
/*+claude. 2026-07-02. tr:not(.group) — рядок групування (GroupBy: bank, moneystorage) кладе в td
   службові span.expmark/.grtitle/.grcount прямими дітьми; cap/inline-block їх ламав би. */
.cat-index-grid table.data-grid > tbody > tr:not(.group) > td > a,
.cat-index-grid table.data-grid > tbody > tr:not(.group) > td > span,
.doc-index-grid table.data-grid > tbody > tr:not(.group) > td > a,
.doc-index-grid table.data-grid > tbody > tr:not(.group) > td > span {
    display: inline-block;
    max-width: 40rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}
/* У fixed-режимі ресайзу (table-layout:fixed, клас resizable-fixed від _components/column-resize.ts)
   ширину диктує <col>, а не контент. Тоді 40rem-cap вище завеликий: при ручному звуженні колонки
   нижче 40rem текст вилазив би за вужчу комірку. Прив'язуємо носій до ширини комірки. */
.cat-index-grid table.data-grid.resizable-fixed > tbody > tr:not(.group) > td > a,
.cat-index-grid table.data-grid.resizable-fixed > tbody > tr:not(.group) > td > span,
.doc-index-grid table.data-grid.resizable-fixed > tbody > tr:not(.group) > td > a,
.doc-index-grid table.data-grid.resizable-fixed > tbody > tr:not(.group) > td > span {
    max-width: 100%;
}

/* ---- #16768: числова комірка не переноситься ---- */
/*+claude. 2026-08-03. #16768 — вузька колонка з неподільним значенням (сума, дата, номер) рвалась
   на 2-5 рядків, коли широкі сусіди забирали ширину. Видно лише на звуженому вікні (~1100px).
   Замість ~119 точкових Wrap="NoWrap" — одне правило.

   ЧОМУ через `text-right`, а НЕ через `Fit`: Wrap="NoWrap" — це лише спосіб навісити клас
   `no-wrap` на <td> (DataGridColumn.cs:107 → tabmain.js:7971 cellCssClass). А Fit="True" кладе
   клас `fit` на <col> (tabmain.js:8497), і <col> підтримує тільки width/background/border/
   visibility — white-space через нього не діє. Єдиний доступний хук на самому <td> — клас
   вирівнювання. У цій базі праве вирівнювання де-факто = числова колонка: з 640 оголошень
   DataGridColumn з Align="Right" текстову привязку мають три — $CoefText, $SeatsText і колонка
   дій settings/tenants/edit.dialog.xaml:93 ($ToggleLabel, прив'язка на Hyperlink ВСЕРЕДИНІ
   комірки, тому грепом по самому DataGridColumn не ловиться). У всіх трьох Wrap="NoWrap" уже
   стоїть власним атрибутом, тож правило їм нічого не змінює.

   Скоуп лише tbody — заголовки <th> переносяться далі (довгі підписи не мають розсувати грід).
   Прецедент наскрізного правила поруч: .cat-index-grid/.doc-index-grid вище (79 грідів).

   Заміри @1100px (значення підставлені скриптом — демо-база порожня), висота найвищого рядка
   та горизонтальний скрол контейнера ДО → ПІСЛЯ:
     zp/payroll/edit (14 колонок)        115px → 60px,  скролу нема → нема
     report/stockremainders (7)           136px → 36px,  нема → нема
     report/advancesettlements (7)        135px → 53px,  нема → нема
     report/employeesettlements (8)        96px → 53px,  нема → нема
     report/payslip «За вільний період»    76px → 76px,  нема → нема
     filemanager «Розмір» («57 KB»)   2 рядки у 7/16 → 1 рядок, нема → нема
   Нового горизонтального скролу не зʼявилось на жодному з 13 перевірених грідів: ширину віддає
   широка текстова колонка, яка переноситься сама (table-layout:auto + col.fit{width:0.1%}).
   Не зачіпає: ТЧ з <input> (ширину диктує контрол), table.a2-table і table.tg-table (basicplan,
   внутрішні акти, позиції рахунку — інший носій).
   Якщо колись зʼявиться ТЕКСТОВА right-aligned колонка — лікується локальним white-space:normal. */
table.data-grid > tbody > tr > td.text-right {
    white-space: nowrap;
}

/* ---- #16783: у fixed-режимі обрізання має бути ВИДИМИМ ---- */
/*+claude. 2026-08-03. #16783 — той самий кліп, що у двох правилах вище, але для двох випадків, які
   вони НЕ ловлять:
     1) .prj-index-grid — дрейф із #16653: клас дописали у whitelist column-resize.ts, а в списки
        селекторів вище (cat-/doc-) ні. Дописати його ТУДИ не можна — блок :124 несе ще й
        white-space:nowrap і перебив би 2-рядковий клемп «Найменування» (project-index.css).
     2) носій усередині <StackPanel> — правила вище беруть лише прямих дітей <td>, а 2-рядкові
        комірки «Собів./Продаж» кладуть контент у div.stack-panel > span.
   Без кліпу у fixed-режимі оголошена Width стає СТЕЛЕЮ, а нерозривна комірка має overflow:visible,
   тож хвіст значення малюється ПОВЕРХ сусідньої: заміряно на списку проєктів @1440px — «Собів.
   19 205 669,76» вилазило на 10.8px і накривало TagLabel статусу, «20.05.2026» у колонці 4.5rem —
   на 18.2px, без жодної ознаки обрізання.
   Скоуп лише text-right: після #16768 це і є ознака нерозривної комірки, а окрема гілка td.no-wrap
   нічого б не додала — платформа ставить no-wrap разом з align=right (DataGridColumn.cs, ColumnRole
   Id/Number), тож такі комірки вже покриті; решта no-wrap-ролей заодно дістає :fit, а fit-колонки
   column-resize.ts взагалі не чіпає (вони поза resizableIndices). Колонка «#» під правило теж
   потрапляє, але «…» там
   не з'явиться: column-resize.ts дає їй ceil+1 від натурального контенту, а не оголошену Width. */
table.data-grid.resizable-fixed > tbody > tr:not(.group) > td.text-right > span,
table.data-grid.resizable-fixed > tbody > tr:not(.group) > td.text-right > .stack-panel > span {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

/* ---- #16724: центрована ОСТАННЯ колонка відірвалась від свого заголовка ---- */
/*+claude. 2026-08-10. Причина НЕ в ширині як такій: у FixedHeader-гріді заголовок і комірка
   вирівнюються РІЗНО, а #16724 зробив цю давню розбіжність видимою.
   Align="Center" кладе клас `text-center` лише на <td> (main.js: dataGridColumn.classAlign →
   cellCssClass), тим часом платформа ЖОРСТКО вирівнює ліворуч будь-який <th> fixed-header гріда:
   `.data-grid-container.fixed-header > .data-grid-body.fixed-header > table > thead > tr > th
   { text-align: left !important }` (A2v10, themes/tabbed/DataGrid.less:459). Тобто заголовок завжди
   ліворуч, значення — по центру комірки. Поки колонка була завширшки з контент, розбіжність
   складала ~40px і читалась як дрібниця (заміряно там же, «Валюта» 120px: заголовок x=504,
   значення x=545). Після #16724 остання колонка бере width:auto й поглинає ВЕСЬ надлишок
   контейнера, тож у ЗМІСТОВНОЇ (не командної) останньої колонки розрив став на порядок більшим і
   читається як розсипана верстка. Заміряно money/settlementsregister, режим «Залишки», колонка
   «Останній рух» (оголошено 9em = 135px), позиція тексту заголовка → позиція дати:
     @1920 колонка 747px: 864 → 1194 (330px убік), після правила 864 → 864
     @1440 колонка 278px: 864 →  959  (95px убік), після правила 864 → 864
   Лікуємо саме комірку, а не заголовок: перебивати платформений !important означало б зрушити
   заголовки в УСІХ fixed-header грідах застосунку заради двох сторінок.
   Скоуп навмисно вузький — рівно та конфігурація, у якій #16724 роздуває колонку:
     .fixed-header    — лише там заголовок примусово ліворуч; у звичайному гріді <th> теж дістає
                        `text-center`, заголовок і значення центровані ОБИДВА, і правило зіпсувало б
                        збіг, який там уже є;
     .resizable-fixed — лише там працює width:auto на останній колонці (_components/column-resize.ts);
     .text-center     — рівно ті комірки, що розбігаються. Ліві й так стоять під заголовком, а ПРАВІ
                        лишаємо правими свідомо: число при правому краї гріда — облікова норма, і в
                        цій базі Align="Right" де-факто = числова колонка (див. #16768 вище). Ціна
                        відома: у режимі «Рухи» тієї ж сторінки «Сума, база» (8em → 627px @1920)
                        стоїть за 550px від свого заголовка. Якщо це колись визнають дефектом —
                        лікувати не вирівнюванням, а тим, щоб надлишок забирала лише БЕЗЗАГОЛОВКОВА
                        (командна) колонка, а не будь-яка остання.
   Кнопки й маркери не зачіпає: у 70 грідів whitelist'а fixed-режиму жодна остання CommandBar-/Fit-
   колонка не оголошує Align (перевірено грепом останнього <DataGridColumn> кожного файла), тож
   класу `text-center` на них немає. Рядок групування виключено, як і в правилах вище. */
.data-grid-body.fixed-header table.data-grid.resizable-fixed > tbody > tr:not(.group) > td:last-child.text-center {
    text-align: left;
}

/* ---- Перенос/обрізання довгого тексту в колонках ---- */
/* Word wrap for text with overlay buttons */
.text-wrap-container {
    position: relative;
}

.text-wrap {
    white-space: normal;
    word-wrap: break-word;
    display: block;
    padding: 2px 6px;
}

/* Truncate text with ellipsis - for long text in grid columns */
.text-truncate-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    max-height: 3em;
    line-height: 1.5em;
}

/* Перенос + обрізання до 4 рядків (довгі довідники в гридах з оверлей-кнопками) */
.text-wrap-truncate-4 {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    max-height: 6em;
    line-height: 1.5em;
    white-space: normal;
    word-wrap: break-word;
    padding: 2px 6px;
}

/* ---- #16587: видалення РЯДКА візуально ≠ очищення ПОЛЯ ---- */
/* У комірці ТЧ поруч опиняються дрібні іконки однакового кегля: «…» (підбір), «✕» очищення
   значення Selector'а (ShowClear → a.a2-hyperlink.add-on > i.ico-clear) і команда видалення
   всього рядка (a.a2-hyperlink > i.ico-delete у власній колонці). Дві останні майже не
   відрізняються, а ціна промаху різна: одне поле проти втрати введеного рядка.
   Розводимо кольором (небезпечна дія — червона, як платформений .ico-delete-red) і відступом
   зліва. Правило наскрізне для всіх ТЧ — XAML-розмітку не чіпаємо (інакше це 15+ файлів
   з Icon="Delete" → Icon="DeleteRed", і все одно без відступу й приглушення).
   Add-on'и всередині Selector'а не зачіпає: у них .ico-clear, а не .ico-delete.
   Два носії ТЧ: <DataGrid> → table.data-grid (документи), <Table> → table.a2-table
   (ресурси плану, edit_dialog_Resources — там та сама пара Clear/Delete у CommandBar). */
/* Відступ — САМЕ margin: платформа тримає `.a2-hyperlink .ico { padding: 0 !important }`
   (tabbed.min.css), тож padding-left тут мовчки не спрацював би (перевірено смоуком). */
table.data-grid td a.a2-hyperlink > i.ico-delete,
table.a2-table td a.a2-hyperlink > i.ico-delete {
    margin-left: 0.5rem;
    opacity: 0.7;
}

table.data-grid td a.a2-hyperlink > i.ico-delete::before,
table.a2-table td a.a2-hyperlink > i.ico-delete::before {
    color: #a94442;
}

table.data-grid td a.a2-hyperlink:hover > i.ico-delete,
table.a2-table td a.a2-hyperlink:hover > i.ico-delete {
    opacity: 1;
}

/* CommandBar overlay on right side */
.cmd-bar-right {
    position: absolute;
    right: 0;
    bottom: 0;
    justify-content: flex-end;
    gap: 16px;
    background: linear-gradient(to right, transparent, white 20%);
    padding-left: 20px;
}

/* ---- #16789: грід без FixedHeader обрізав праві колонки без смуги прокрутки ---- */
/*+claude. 2026-08-04. Платформений дефолт `.data-grid-container{overflow-x:hidden;overflow-y:auto}`
   (tabbed.min.css, вихідник A2v10 themes/tabbed/DataGrid.less:30-32) робить контейнер кліпером по
   обох осях, але скролером — лише по вертикалі. Наслідок: на вузькому вікні (~1100px) грід із 9+
   колонками просто ОБРІЗАЄ праві колонки, смуги немає ані на гріді, ані на сторінці, і значення
   недосяжне взагалі (money/exchangediff/edit: сховано 105-116px колонки «Курсова різниця»).
   Гіпотезу «оверлейний скролбар Windows» спростовано заміром: у робочих грідів трек рівно 15px і
   займає місце, а тут offsetHeight-clientHeight = 2px (рамка bordered), скролу немає.

   Міняємо hidden → auto тільки по осі X і тільки там, де контейнер УЖЕ кліпер:
     .fixed-header      — платформа сама ставить overflow:auto, скрол уже є (53 гріди з 9+ колонок);
     .DataGrid_overflow — клас існує РІВНО щоб зняти overflow (overflow:visible вище, рядок 55),
                          інакше ріжуться спливашки Selector/DatePicker у комірках ТЧ (#16099, #16568);
                          без цього карв-ауту нове правило (0,3,0) перебило б його (0,1,0) і повернуло б той баг.
   Нічого додатково не ріже: у грідів класу B платформений overflow-y:auto уже кліпить обидві осі
   (overflow-x:visible при overflow-y:auto недосяжний за спекою CSS), тож заміна hidden→auto лише
   додає можливість доскролити. Прецедент того самого app-level лікування: .inv-goods-grid у
   _assets/site.css (#16588) і .cat-index-grid/.doc-index-grid вище.

   Заміри @1100px (scrollWidth / clientWidth; смуга = offsetHeight - clientHeight) ДО → ПІСЛЯ:
     money/exchangediff/edit «Взаєморозрахунки» (9 кол.)   1095 / 974, смуга 1px → 17px  (+121px схованого)
     money/exchangediff/edit «Залишки каси та банку» (9)   1105 / 974, смуга 2px → 17px  (+131px схованого)
     document/movements діалог (9 і 8 кол.)                798 / 798,  смуга 2px → 2px   (влазить — без змін)
     settings/company/index (6 кол.)                       990 / 990,  смуга 0 → 0       (влазить — без змін)
   Різниця саме для КОРИСТУВАЧА: при overflow-x:hidden контейнер скролиться лише програмно
   (scrollLeft можна виставити з JS, але смуги/колеса/драгу немає), при auto — зʼявляється смуга.
   Гріди, що влазять у контейнер, не змінюються: overflow-x:auto дає смугу лише при переповненні.
   Ціна: у переповненому гріді контейнер стає на 15px вищим (смуга займає місце в лейауті). */
.data-grid-container:not(.fixed-header):not(.DataGrid_overflow) {
    overflow-x: auto;
}

/* ---- #16932: колонки деталізації (RowDetails) під колонками шапки ---- */
/*+Kamala. claude. 2026-08-13. #16932 — «з'їджають колонки по формі» у звіті «Розрахунки з підзвітними
   особами» (той самий дефект у звіті-близнюку «Взаєморозрахунки зі співробітниками»). Основну роботу
   робить розмітка (фіксовані Width у грошових DataGridColumn + Columns/правий Padding у деталізації —
   див. коментарі в обох index.view.xaml). Тут — два хвости, які з XAML не дістати.

   1) Різниця паддингу двох носіїв: платформа дає data-grid td .5rem, а .a2-table.compact td — 0 4px
      (A2v10 themes/tabbed: DataGrid.less «> tbody > tr > td{padding:.5rem}», Table.less:296). Колонки
      після правки збігаються межа-в-межу, а числа в них стояли б зі зсувом рівно 4px. Вирівнюємо
      горизонтальний паддинг деталізації по гріду; вертикальний (compact) не чіпаємо.
   2) Заголовок правої колонки прибитий ліворуч: у fixed-header гріді платформа жорстко ставить
      th{text-align:left!important} (DataGrid.less:460), а Align="Right" вішає text-right і на th, і на
      td. Поки колонки були Fit (завширшки з контент) розбіжність не читалась; з Width="8rem" заголовок
      відʼїхав би від своїх чисел. Пам'ять проєкту fixed-header-grid-th-align-left вимагає вузького
      скоупу — тут це клас settlements-grid на конкретних двох грідах, глобально th не чіпаємо.
      Специфічність (0,5,4) б'є платформені (0,4,4) при однаковому !important.
      Ціна відома: стрілка сортування (.h-holder:after, 15px) лишається праворуч від тексту, тож
      заголовок стоїть на ці 15px лівіше свого числа — так само, як у звичайних (не fixed-header)
      грідах застосунку. */
.settlements-grid tr.row-details table.a2-table.compact > thead > tr > td,
.settlements-grid tr.row-details table.a2-table.compact > tbody > tr > td {
    padding-left: .5rem;
    padding-right: .5rem;
}

.settlements-grid .data-grid-body.fixed-header > table.data-grid > thead > tr > th.text-right {
    text-align: right !important;
}

/* #17509 — той самий хвіст у ТЧ платежу (FixedHeader з #17509), але text-align тут НЕ діє: у fixed-header
   шапці підпис лежить у .h-holder — inline-flex на всю ширину th, і text-align:right на th дає computed
   right без жодного зсуву тексту (заміряно: span лишався біля лівого краю). Притискаємо flex-вміст. */
.pay-rows-grid .data-grid-body.fixed-header > table.data-grid > thead > tr > th.text-right > .h-holder {
    justify-content: flex-end;
}

/* ── Розкривний рядок майстер-гріду (DataGrid.RowDetails) ──────────────────────────────────────
   Кросдокументний патерн: деталь рядка читається як вкладена панель (світла підложка + акцент
   зліва inset, без зсуву розмітки), а не як ще рядки гріду. Значення — з payroll #16325, де цю
   розкладку вже прийняв аналітик; звідти ж :hover/:focus-within на полях деталі.
   БОРГ: .payroll-master-grid / .payroll-expand-hint / .payroll-hours-detail у timesheet.css —
   побайтовий близнюк цих правил; перевести payroll на ці класи окремим тікетом (у #16663 не
   чіпаємо здану чужу форму, її довелось би пересмоучувати). */
.doc-master-grid tr.row-details > td.details-cell {
	background-color: #f6f8fa;
	box-shadow: inset 3px 0 0 #94a3b8;
}
/* Шеврон-афорданс розкривності коло номера рядка */
.doc-expand-hint {
	color: #94a3b8;
	margin-right: 0.3rem;
	font-size: 0.85em;
}
/* Поля вводу в деталі: платформа малює .input-group з прозорим бордюром (видимий лише у фокусі),
   і на світлій підложці вони зливаються з таблицею. Робимо бордюр видимим у спокої.
   :not(.disabled) — щоб у ЗАТВЕРДЖЕНІЙ (read-only) заявці клітинки деталі не виглядали
   редагованими: платформа вішає .disabled на .control-group, сам input лишається без атрибута.
   Селектор повторює ФОРМУ платформенного (.grid-horizontal td > .control-group > .input-group,
   tabbed.min.css) — двокласовий .doc-row-detail .input-group програє йому за специфічністю
   (0,2,0 проти 0,3,1) і мовчки не застосовується; перевірено в браузері на цій формі. */
.doc-row-detail td > .control-group:not(.disabled) > .input-group {
	border-color: #cbd5e1;
	border-radius: 3px;
	background-color: #fff;
}
.doc-row-detail td > .control-group:not(.disabled) > .input-group:hover,
.doc-row-detail td > .control-group:not(.disabled) > .input-group:focus-within {
	border-color: #64748b;
}

/* ---- Помітка на видалення (#17638, ADR-0016 / GH #62 P1) ----
   Клас рядка приходить із Mark="{Bind $Mark}" MarkerStyle="Row" (платформа дописує його на <tr>).
   Помічений рядок має впадати в око (перша версія — лише приглушення + закреслення — читалась як
   «неактивний»): помаранчева смуга зліва + теплий фон у тон Alert/Warning, закреслення кольором
   попередження; текст НЕ блякне, чекбокс і кнопки рядка лишаються робочими. Фон — на <tr>, щоб
   hover/active гриду лишились помітними (їхні правила слабші за специфічністю — перекриваємо явно). */
table.data-grid > tbody > tr.dg-row.dm-marked {
    background-color: var(--status-warning-bg, #fff3e0);
}
/* смуга — на першій комірці: грид у border-collapse, box-shadow на <tr> там не малюється.
   Hover/active лишаємо платформні (tr.active — !important): смуга і закреслення видні й так. */
table.data-grid > tbody > tr.dg-row.dm-marked > td:first-child {
    box-shadow: inset 4px 0 0 var(--status-warning, #ff9800);
}
/* закреслення дублюється на <a>/<span>: платформа рендерить посилання inline-block, а туди
   text-decoration батька не успадковується */
table.data-grid > tbody > tr.dg-row.dm-marked > td,
table.data-grid > tbody > tr.dg-row.dm-marked > td a,
table.data-grid > tbody > tr.dg-row.dm-marked > td > span {
    text-decoration: line-through;
    text-decoration-color: var(--status-warning, #ff9800);
    text-decoration-thickness: 2px;
}
/* кнопки рядка й чекбокс — без закреслення: скасувати успадковане від td не можна, тому
   робимо їх атомарними inline-боксами (inline-flex/inline-block), куди воно не проникає */
table.data-grid > tbody > tr.dg-row.dm-marked > td .commandbar {
    display: inline-flex;
    text-decoration: none;
}
table.data-grid > tbody > tr.dg-row.dm-marked > td .checkbox {
    display: inline-block;
    text-decoration: none;
}

/* ---- #17639 (GH #62 P6) — помічене значення в Selector ШАПКИ документа ----
   Клас дає CssClass="{Bind Doc.X.$VoidClass}" (deletion-mark.createRefMarkProperties) на корені контролу.
   Та сама мова, що в рядку списку: помаранчева смуга зліва + закреслення кольором попередження. Лише
   текст значення, не плейсхолдер і не кнопки AddOns. */
.dm-ref-marked .input-group {
    box-shadow: inset 4px 0 0 var(--status-warning, #ff9800);
}
.dm-ref-marked .input-group input,
.dm-ref-marked .input-group .selector-text {
    text-decoration: line-through;
    text-decoration-color: var(--status-warning, #ff9800);
    text-decoration-thickness: 2px;
}
/* CPMS #16996: «Рухи документа» стали MDI-СТОРІНКОЮ (були модальним діалогом). Стеля висоти
   .modal-content (34rem, #16761) поїхала разом із модалкою — сторінка скролиться сама.
   Лишилася косметика згортуваних секцій-регістрів (#16953):
   1) платформна шапка панелі сіра (#999) і без ваги — секція читалася б слабше, ніж заголовок,
      тому повертаємо колір і вагу, а лічильник рядків (Description) лишаємо приглушеним, щоб він
      не сперечався з назвою регістру. Приглушення — --neutral700, а не --neutral500: останній
      (#b0b2ba) дає на білому ~2:1 контрасту, і кількість рядків — єдине, що видно у ЗГОРНУТОЇ
      секції, — читалася б ледь-ледь;
   2) .panel має margin-bottom:12px — на останній секції це «дірка» внизу, знімаємо. */
/* Сторінка без Page.Toolbar не отримує платформного .page-content, а padding живе саме на ньому —
   без цього перша секція лежить впритул до краю вкладки. */
.page.doc-movements {
    padding: 12px;
}

.page.doc-movements .panel > .panel-header {
    color: var(--text-header);
    font-weight: 500;
}

.page.doc-movements .panel > .panel-header .panel-header-slot .a2-panel-description {
    color: var(--neutral700);
    font-weight: normal;
}

.page.doc-movements .panel:last-child {
    margin-bottom: 0;
}
/*+Kamala. claude. 2026-07-14. #16103 — UX-полірування звіту «Взаєморозрахунки зі співробітниками».
   Тільки полірування ІСНУЮЧИХ платформних класів (StateCard, TabPanel, DataGrid, статична Table
   деталізації) — жодних нових компонентів. Скоуп — клас .employeesettlements-report на кореневому
   <Page> (appstyles вантажиться глобально, тож усе під цим селектором). Дизайн-система/токени —
   tokens.css (--status-info-bg, --nav800). Формули/розрахунки/знак сальдо не чіпаємо. */

/* ── Повна назва звіту на сторінці (вкладка оболонки буває скорочена) ─────────────────────────── */
/* !important перебиває платформений .bold {font-weight:500!important} (клас від Text Bold="True") */
.employeesettlements-report .es-report-title {
    display: block;
    font-size: 1.15rem;
    font-weight: 700 !important;
    margin: 0 0 0.75rem 0;
}

/* ── KPI-картки: ієрархія (назва→сума→пояснення), контраст, тиха піктограма, сума без переносу ──── */
/* контраст тексту кольорових карток: платформа ставить color:#000000a0 (низький) → повна насиченість */
.employeesettlements-report .a2-state-card.a2-state-card-styled {
    color: #1a1a1a;
}
/* назва (Header) — «мітка»: дрібніша, розріджена, напівжирна — над великою сумою */
.employeesettlements-report .a2-state-card .a2-state-card-header {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    opacity: 0.85;
}
/* сума — головний елемент; не переносити (нулі/мільйони в один рядок) */
.employeesettlements-report .a2-state-card .a2-state-card-text {
    white-space: nowrap;
    margin: 0.15rem 0;
}
/* пояснення (Footer) — приглушене, дрібне */
.employeesettlements-report .a2-state-card .a2-state-card-footer {
    font-size: 0.78rem;
    opacity: 0.8;
}
/* зменшити візуальний вплив фонової піктограми (менша й блідіша) */
.employeesettlements-report .a2-state-card .a2-card-icon {
    font-size: 3rem;
    opacity: 0.55;
}

/* ── Активна вкладка: не лише верхня лінія, а й фон + насиченість тексту ───────────────────────── */
.employeesettlements-report .tab-panel .tab-header > li.active {
    background: var(--status-info-bg, #E3F2FD);
    font-weight: 700;
}

/* ── Деталізація по співробітнику: дочірній блок обраного рядка (відступ + фон + ліва межа) ─────── */
.employeesettlements-report .es-operations {
    background: var(--neutral50, #f7f8fa);
    border-left: 3px solid var(--nav800, #2573a8);
    border-radius: 0 4px 4px 0;
    margin: 0.25rem 0 0.25rem 1.5rem;
}
.employeesettlements-report .es-op-title {
    display: block;
    font-weight: 700 !important;
    font-size: 0.95rem;
    margin-bottom: 0.1rem;
}

/* ── Довгі назви документів/проектів не ламають сітку: обрізка з ellipsis ──────────────────────── */
/* DataGridColumn CssClass → td.es-ellip; TableCell CssClass → td.es-ellip у статичній таблиці */
/*+Kamala. claude. 2026-08-28. #17113 — 22rem → 15rem, і клас додано на «Проєкт» журналу.
   Восьма колонка («У відомостях») вивела «Журнал операцій» за 1366px, а платформений
   .data-grid-container має overflow-x:hidden — тобто не скрол, а ОБРІЗКА: суми показувались
   як «45» замість «45 000,00». MinWidth стелею не є (колонка росте під контент), тож єдиний
   реальний обмежувач ширини текстових колонок — цей max-width. Він і тримає бюджет ширини. */
.employeesettlements-report td.es-ellip .dg-cell,
.employeesettlements-report td.es-ellip > a.a2-hyperlink,
.employeesettlements-report td.es-ellip > span {
    display: inline-block;
    max-width: 15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
    word-break: normal;
}
/* ── #17420 «По проєктах»: рядок групи (клас es-group приходить із Mark="{Bind $RowClass}") ─────── */
.employeesettlements-report .data-grid tr.dg-row.es-group > td {
    background: var(--status-info-bg, #E3F2FD);
    font-weight: 600;
}
/* бейджі «N співроб.» у групі та «%» частки біля бригади */
.employeesettlements-report .es-badge {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0 0.45rem;
    border-radius: 0.6rem;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.25rem;
    background: #dbe7fb;
    color: #1d4ed8;
    white-space: nowrap;
}
.employeesettlements-report .es-badge.es-share {
    background: #ede4fb;
    color: #6d28d9;
}

/* дата/вид у деталізації — в один рядок */
.employeesettlements-report td.es-nowrap,
.employeesettlements-report td.es-nowrap > span {
    white-space: nowrap;
}
/*!@localize*/
/* claude. 2026-07-17. UX: порожній список без жодного тексту виглядав як «зламаний» грід.
   Платформа завжди рендерить контейнер .data-grid-empty, коли рядків нема, але контент у ньому
   з'являється лише якщо view оголосив DataGrid.EmptyPanel — у більшості index-сторінок його нема.
   Фолбек: для ПОРОЖНЬОГО контейнера показуємо локалізований напис через ::before (ключ NothingFound,
   є в усіх 5 локалях). Якщо view має власний EmptyPanel — контейнер не порожній, :empty не спрацьовує,
   подвійного напису не буде. Файл під маркером локалізації (перший рядок), тому тут не можна писати
   літерал «собачка+квадратна дужка» в коментарях. */
.data-grid-empty:empty::before {
    content: "Нічого не знайдено";
    display: block;
    padding: 2.5rem 1rem;
    text-align: center;
    color: #999;
}
/* +Kamala. claude. 2026-08-03. #16741 — доводка картки «Визначення курсових різниць».
   Скоуп — рівно два гріди цієї форми (CssClass="exchangediff-grid" на <DataGrid>; у A2v10
   CssClass гріда сідає на .data-grid-container, як .DataGrid_overflow у datagrid.css).
   Прецедент точкового лікування комірок гріда — schedule.css. */

/* п.1 «Курс валюти» не виглядає редагованим.
   Спільний хук застосунку вже є і вже спрацював: DataGridColumn з ValuedControl усередині →
   _noPadding → td.cell-editable → site.css:71-78 фарбує комірку в #fffff8. Але тема навмисно
   гасить рамку інпута в гріді з лініями:
       .grid-horizontal td > .control-group > .input-group { border-color: transparent }
   а GridLines="Horizontal" — норма для ТЧ документів. На білому #fffff8 нерозрізненний, тож
   комірка читається як звичайний текст. Повертаємо рамку РІВНО тут, платформеним токеном
   (--neutral400 — те саме, чим .control-group .input-group малюється поза грідом).
   Специфічність 0,5,1 проти 0,3,1 у теми, плюс appstyles вантажаться після tabbed.css.
   :not(.disabled) — на проведеному документі ($Locked → .control-group.disabled) поле не
   редагується, і рамка там була б брехнею. */
.exchangediff-grid td.cell-editable > .control-group:not(.disabled) > .input-group {
    border-color: var(--neutral400);
}

.exchangediff-grid tr:hover td.cell-editable > .control-group:not(.disabled) > .input-group {
    border-color: var(--neutral500, #888);
}

/* п.3 порожня ТЧ: смуга прокрутки і НЕВИДИМИЙ напис «Нічого не знайдено».
   .data-grid-empty позиціонується absolute усередині .data-grid-container (position:relative),
   тому дає scrollHeight 132 при clientHeight 36 → трек скролбара, а сам напис (::before із
   empty-state.css, 95px) обрізається і на екрані його немає взагалі. Контейнер тут не
   розтягується: вкладки картки ростуть по контенту (#16568, datagrid.css:71-85).
   Резервуємо висоту саме для порожнього стану — :has() (v-if, елемент існує лише коли рядків
   нема), щоб грід з одним рядком не отримав зайвої порожнечі під ним.
   Чому 10rem, а не заміряні «рівно достатні» 9rem: потрібна висота = 6,5rem (empty-state) + 39px
   (шапка --header-height:36px + межі, ФІКСОВАНІ пікселі), тобто 9rem вистачає лише поки корінний
   кегль ≤ 15,6px — при 15px запас був 2px. 10rem дає ~15px і тримається до ~17px. */
.exchangediff-grid:has(.data-grid-empty) {
    min-height: 10rem;
}
/* ============================================================================
   Файловий менеджер (#16147) — «архітектурний лист» у синій темі додатка.
   Уся верстка scoped через .fm-* (нічого глобального поза namespace). Кольори —
   з tokens.css (--nav900/800/700, --status-info-bg). Підхоплюється A2v10
   /_shell/appstyles (порядко-незалежно). Без зовнішніх шрифтів: Georgia для
   крупного заголовка, системний monospace для технічних міток.
   ============================================================================ */

/* ── Розкладка сторінки з лівим Taskpad (колонки, тулбар, скрол панелі, пейджер) — спільний фікс
   платформеного бага у site.css, блок «Спільний фікс розкладки сторінок з ЛІВИМ Taskpad».
   Тут лишається лише специфічне для файлменеджера: закріплення панелі. Платформа ігнорує
   Collapsible="False" (клас .collapsible лишається й рендерить «‹‹»-хендл) — ховаємо хендл,
   тоді панель не згортається й не лишає порожню колонку. ── */
.page.page-grid.taskpad-left:has(.fm-page) .taskpad-collapse-handle { display: none; }

/* ── Контентна колонка: flex, щоб ledger займав залишок висоти й скролився всередині.
   Делікатна «міліметрівка» синім, без беж/оранж домінанти. ── */
.fm-page {
	display:flex;
	flex-direction:column;
	height:100%;
	min-height:0;
	padding:10px 20px 0;
	background-color:#f6f8fb;
	background-image:
		linear-gradient(rgba(34,69,108,.045) 1px, transparent 1px),
		linear-gradient(90deg, rgba(34,69,108,.045) 1px, transparent 1px);
	background-size:26px 26px;
}

/* ── masthead ── */
.fm-masthead {
	display:flex;
	align-items:flex-end;
	justify-content:space-between;
	gap:24px;
	padding-bottom:8px;
	border-bottom:2px solid var(--nav900,#1a4a7a);
}
.fm-kicker {
	display:flex;
	align-items:center;
	gap:8px;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
	font-size:10.5px;
	letter-spacing:.04em;
	text-transform:uppercase;
	color:#8a94a6;
}
.fm-kicker-sq { width:8px; height:8px; background:var(--nav800,#2573a8); display:inline-block; }
.fm-title {
	margin:4px 0 0;
	font-family:Georgia,'Times New Roman',serif;
	font-weight:600;
	font-size:26px;
	line-height:1;
	letter-spacing:-.01em;
	color:var(--nav900,#1a4a7a);
}
.fm-sub { font-size:12.5px; color:#5b6675; margin-top:4px; }

/* ── Toolbar (пошук + дії + перемикач вигляду) — над таблицею, одним рядком. ── */
.fm-toolbar { margin-bottom:8px; }
.fm-toolbar .btn:disabled { opacity:.55; }


/* ── KPI ── */
.fm-kpi {
	display:grid;
	grid-template-columns:repeat(4,1fr);
	border:1px solid rgba(34,69,108,.2);
	background:#fff;
	margin-bottom:10px;
}
.fm-stat { padding:8px 14px; border-right:1px solid rgba(34,69,108,.1); }
.fm-stat:last-child { border-right:none; }
.fm-stat-v {
	font-family:Georgia,'Times New Roman',serif;
	font-weight:600;
	font-size:22px;
	line-height:1;
	color:var(--nav900,#1a4a7a);
}
.fm-stat-u { font-size:13px; color:#9aa3b0; margin-left:3px; }
.fm-stat-k {
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
	font-size:9.5px;
	letter-spacing:.04em;
	text-transform:uppercase;
	color:#9aa3b0;
	margin-top:4px;
}

/* ── ledger (DataGrid). fm-grid сидить на обгортці .data-grid-container, не на <table>. ── */
.fm-page > .fm-grid { flex:1 1 auto; min-height:0; border:1px solid rgba(34,69,108,.2); background:#fff; }

/* Зебра/hover/виділення — 3 візуально різні стани (UX-ревью: раніше зебра й hover обидва були синіми
   й читались як «вибрано»). Зебра — нейтрально-сірий (класи .even є завжди, навіть при no-striped, тому
   фарбуємо через контейнер), hover — трохи темніший нейтральний. Реальне виділення (checkbox) —
   ЄДИНИЙ синій акцент грида, той самий --status-info-bg, що й активна категорія сайдбара (fm-cat.is-active);
   застосовується через платформний DataGrid.Mark="{Bind $Mark}" MarkerStyle="Row" (клас .info на <tr>). */
.fm-grid table.data-grid > tbody > tr.even > td { background-color:#f3f5f8; }
.fm-grid table.data-grid > tbody > tr:hover > td { background-color:#e8ecf1; }
.fm-grid table.data-grid > tbody > tr.info > td { background-color:var(--status-info-bg,#e3f2fd); }
.fm-grid table.data-grid > tbody > tr > td {
	padding:8px 12px; vertical-align:middle; border-bottom:1px solid rgba(34,69,108,.08);
}
.fm-grid table.data-grid > thead > tr > th {
	background-color:#eef3f9;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
	font-size:9.5px;
	letter-spacing:.1em;
	text-transform:uppercase;
	color:#6b7785;
	border-bottom:1.5px solid rgba(34,69,108,.28);
}

/* Довгі імена файлів — обрізати ellipsis. Клас колонки fm-name-col (DataGridColumn CssClass),
   не :nth-child — не залежить від порядку колонок. */
.fm-grid td.fm-name-col { max-width:380px; }
.fm-grid td.fm-name-col .a2-hyperlink {
	display:inline-block; max-width:100%; overflow:hidden; text-overflow:ellipsis;
	white-space:nowrap; vertical-align:bottom;
}

/* glyph типу файлу: рамка + «загнутий уголок» (dog-ear), колір з $GlyphStyle. */
.fm-glyph {
	display:inline-flex;
	align-items:flex-end;
	justify-content:center;
	width:30px; height:36px;
	border:1.5px solid currentColor;
	border-radius:2px;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
	font-weight:700; font-size:8px; letter-spacing:.02em;
	padding-bottom:3px;
	position:relative;
	background:#fff;
}
.fm-glyph::before {
	content:""; position:absolute; top:0; right:0;
	border-width:6px; border-style:solid;
	border-color:currentColor currentColor transparent transparent;
	opacity:.32;
}

/* назва файлу + вторинний контекст */
.fm-rowmeta {
	font-size:11px;
	color:#9aa3b0;
	margin-top:1px;
	max-width:340px;
	overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* #17265 — до чого привʼязано. Темніше й зі стрілкою, щоб не зливалося з технічною
   метастрічкою (тип · розмір): це відповідь на питання «розібрано куди», а не службовий дріб'язок. */
.fm-rowbound {
	color:#4a5568;
}
.fm-rowbound::before {
	content:"\2192\00a0";  /* → */
	color:#9aa3b0;
}

/* об'єкт системи: крапка + (вид / назва-посилання) */
.fm-objcell { display:flex; align-items:flex-start; gap:8px; }
.fm-dot { width:8px; height:8px; border-radius:50%; flex:none; margin-top:5px; background:#5f6b7a; }
.fm-objkind {
	font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:.06em;
	color:#8a94a6; line-height:1.4;
}

/* відповідальний: круглий бейдж ініціалів + ім'я */
.fm-resp { display:flex; align-items:center; gap:9px; font-size:13px; color:#3a4350; }
.fm-av {
	width:24px; height:24px; flex:none; border-radius:50%;
	border:1.5px solid var(--nav700,#4a90c2);
	color:var(--nav800,#2573a8);
	display:inline-flex; align-items:center; justify-content:center;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace; font-size:8.5px; font-weight:700;
}
.fm-size { font-family:ui-monospace,'Cascadia Mono',Consolas,monospace; font-size:11.5px; color:#5b6675; }

/* ── Сайдбар фільтрів (Page.Taskpad) ── */
.fm-sidebar { display:flex; flex-direction:column; gap:3px; padding:4px 2px; }
.fm-sidebar .selector, .fm-sidebar .date-picker, .fm-sidebar .text-box { margin-bottom:4px; }

.fm-section-title {
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace;
	font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
	color:#9aa3b0; margin:13px 0 4px; padding:0 8px;
	display:flex; align-items:center; gap:8px;
}
.fm-section-title::after { content:""; flex:1; height:1px; background:rgba(34,69,108,.14); }

/* «Всі файли» — крупний пункт-перемикач (активний = темно-синій). Клас fm-cat--all (не :first-child,
   щоб стиль не залежав від порядку елементів у сайдбарі). */
.fm-sidebar .fm-cat--all { padding:9px 10px; }
.fm-sidebar .fm-cat--all .a2-hyperlink { font-weight:600; font-size:15px; }
.fm-sidebar .fm-cat--all.is-active { background:var(--nav900,#1a4a7a); }
.fm-sidebar .fm-cat--all.is-active .a2-hyperlink,
.fm-sidebar .fm-cat--all.is-active .fm-count { color:#fff; }
.fm-sidebar .fm-cat--all.is-active::before { display:none; }

.fm-cat {
	display:flex; align-items:center; gap:8px;
	padding:4px 8px; margin:0; border-radius:3px; cursor:pointer; position:relative;
}
.fm-cat:hover { background:#eef3f9; }
.fm-cat.is-active { background:var(--status-info-bg,#e3f2fd); }
.fm-cat.is-active::before { content:""; position:absolute; left:-2px; top:4px; bottom:4px; width:3px; background:var(--nav800,#2573a8); }
.fm-cat > a { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fm-cat.is-active > a { color:var(--nav900,#1a4a7a); font-weight:600; }

.fm-cat-dot { width:8px; height:8px; flex:none; border-radius:2px; background:#5f6b7a; }
.fm-cat-dot-resp { border-radius:50%; background:#8a94a6; }

.fm-count {
	flex:0 0 auto; min-width:20px; text-align:center;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace; font-size:11px;
	color:#7a8696; background:rgba(34,69,108,.07); border-radius:9px; padding:0 7px;
}
.fm-cat.is-active .fm-count { color:#fff; background:var(--nav700,#4a90c2); }

/* ── Картковий вид (toggle Список/Картки). Та сама CollectionView (Files) — інший рендер.
   Переиспользует .fm-glyph / .fm-dot / .fm-objkind / .fm-resp / .fm-av зі списку. ── */
.fm-cards {
	flex:1 1 auto; min-height:0; overflow:auto; align-content:start;
	display:grid; grid-template-columns:repeat(auto-fill, minmax(248px, 1fr)); gap:14px;
	padding:2px 2px 6px;
}
.fm-card {
	background:#fff; border:1px solid rgba(34,69,108,.16); border-radius:10px;
	padding:14px; display:flex; flex-direction:column; gap:11px; height:max-content;
	transition:border-color .15s, box-shadow .15s;
}
.fm-card:hover { border-color:var(--nav700,#4a90c2); box-shadow:0 2px 10px rgba(34,69,108,.1); }
.fm-card-top { display:flex; gap:11px; align-items:flex-start; }
.fm-card-top .a2-hyperlink {
	font-weight:500; font-size:14px; color:var(--nav800,#2573a8); line-height:1.3;
	display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.fm-card-obj { display:flex; align-items:center; gap:7px; font-size:12.5px; min-width:0; }
.fm-card-obj .fm-dot { margin-top:0; }
.fm-card-obj .fm-objkind { flex:none; }
.fm-card-obj .a2-hyperlink { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--nav800,#2573a8); }
.fm-card-foot { display:flex; align-items:center; justify-content:space-between; gap:8px; border-top:1px solid rgba(34,69,108,.1); padding-top:9px; }
.fm-card-foot .fm-resp { min-width:0; }
.fm-card-foot .fm-resp > span:last-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fm-card-meta {
	display:flex; flex-direction:column; align-items:flex-end; flex:none; text-align:right;
	font-family:ui-monospace,'Cascadia Mono',Consolas,monospace; font-size:10.5px; color:#8a94a6; line-height:1.5;
}

/* ── #17014 Вхідні документи ─────────────────────────────────────────────────
   Три колонки: список · перегляд · властивості. Ширини задає XAML-грід
   (24rem / 1fr / 22rem), тут лише рамки, скрол і контрол завантаження. */
.fm-inbox { border-top:1px solid #e3e7ee; overflow:hidden; }
.fm-inbox-list { border-right:1px solid #e3e7ee; overflow:hidden; }
.fm-inbox-preview { border-right:1px solid #e3e7ee; overflow:hidden; background:#f7f8fa; }
/* align-items:start — платформений .grid ставить flex-end, і панель/підказка притискались
   до НИЗУ колонки (див. пам'ять a2v10-fullheight-frame-gotchas). */
.fm-inbox-props { overflow-y:auto; padding:10px 12px; align-items:start; align-content:start; }

/* Перегляд. Усі елементи — ПРЯМІ нащадки комірки гріда (FileImage рендериться голим <img>,
   PdfViewer — <object>, IFrame для Word/Excel — <iframe>), тому селектори по прямому нащадку. */
.fm-inbox-preview > object,
.fm-inbox-preview > iframe { width:100%; height:100%; min-height:0; border:0; }
/* max-*, а не width/height: скан на 4000px має вміститися, а мініатюра — не розтягнутися
   на всю панель у мило. Центруємо в комірці. */
.fm-inbox-preview > img {
	max-width:100%; max-height:100%; min-height:0;
	object-fit:contain; align-self:center; justify-self:center;
}
.fm-inbox-preview > .a2-alert { align-self:start; margin:12px; }

/* Зона завантаження пачки (a2-inbox-upload). */
.fm-inbox-upload { padding:8px; }
.fm-inbox-upload__drop {
	display:flex; align-items:center; justify-content:center; gap:8px;
	min-height:64px; padding:10px 12px; cursor:pointer;
	border:1px dashed #b9c2d0; border-radius:6px; background:#fbfcfe;
	color:#5b6675; font-size:12px; text-align:center; transition:border-color .12s, background .12s;
}
.fm-inbox-upload__drop:hover,
.fm-inbox-upload__drop.hover { border-color:#22456c; background:#f0f4fa; }
.fm-inbox-upload__drop.busy { cursor:progress; opacity:.7; }
.fm-inbox-upload__drop input[type=file] { display:none; }
.fm-inbox-upload__tip { line-height:1.35; }
.fm-inbox-upload__errors {
	margin:6px 2px 0; font-size:11.5px; color:#b03030; line-height:1.45;
	max-height:8rem; overflow-y:auto;
}

/* ── #17330 Оболонка з вкладками (filemanager/shell.view.xaml) ───────────────────────────────
   Платформений .tab-panel — це CSS-грід `grid-template-rows: auto 1fr` (advance.css). Рядок 1fr
   має ТИПОВЕ min-height:auto, тому висока сторінка всередині вкладки не вміщується в нього, а
   розпирає: виміряно на живій сторінці — панель 794px проти вмісту 1349px. Наслідків два, і
   обидва видно очима. Перший: скролиться вся вкладка цілком, тобто masthead, KPI і тулбар їдуть
   угору разом зі списком — при тому, що .fm-page збудована саме на ВНУТРІШНЬОМУ скролі гріда
   (.fm-page > .fm-grid: flex 1 1 auto + min-height 0). Другий: власна смуга прокрутки панелі
   з'їдає ~15px ширини, і на 1366px колонка «Дата завантаження» обрізається сильніше, ніж на
   окремій сторінці (контейнер 967px проти 982px).
   min-height:0 повертає рядку право стискатися. Більше нічого не потрібно: ланцюг висоти вже
   є — .tab-item.full-height і .a2-include.full-height тягнуть height:100% (advance.css).
   Правило scoped класом fm-shell, щоб не чіпати 27 інших форм із TabPanel. ── */
.tab-panel.fm-shell > .tab-content { min-height: 0; }
/* Діаграма Ганта (дерево робіт плану): контейнер, липка шапка/тулбар, popover,
   стрілки залежностей, контекст-меню, режим звʼязування, діалог і список залежностей.
   Винесено з main_cpms.css під час рефакторингу _assets. */

.gantt-container {
    overflow: auto;
    height: 100%;
}

.gantt-header {
    position: sticky;
    top: 37px;
    z-index: 5;
    background: #fff;
}

.a2-graphics + .toolbar,
.grid:has(.gantt-header) > .toolbar {
    position: sticky;
    top: 0;
    z-index: 6;
    background: var(--background, #fff);
}

.gantt-popover {
    position: absolute;
    z-index: 10;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    padding: 10px 14px;
    min-width: 200px;
    max-width: 320px;
    font-family: 'Segoe UI', sans-serif;
    font-size: 12px;
    line-height: 1.5;
    pointer-events: auto;
}

.gantt-popover-title {
    font-weight: 600;
    font-size: 13px;
    color: #1565c0;
    margin-bottom: 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid #e0e0e0;
}

.gantt-popover-row {
    padding: 2px 0;
    color: #333;
}

.gantt-popover-label {
    color: #777;
    font-weight: 500;
}

.gantt-popover-progress {
    font-weight: 600;
    color: #2196f3;
}

/* Dependency arrows */
.gantt-dep-arrow {
    stroke: #e57373;
    stroke-width: 1.5;
    fill: none;
    pointer-events: stroke;
    cursor: pointer;
}
.gantt-dep-arrow:hover {
    stroke: #d32f2f;
    stroke-width: 2.5;
}

/* Context menu */
.gantt-context-menu {
    position: absolute;
    z-index: 20;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    min-width: 180px;
    font-family: 'Segoe UI', sans-serif;
    font-size: 12px;
    padding: 4px 0;
}
.gantt-context-menu-item {
    padding: 6px 16px;
    cursor: pointer;
    white-space: nowrap;
}
.gantt-context-menu-item:hover {
    background: #e3f2fd;
}
.gantt-context-menu-item.disabled {
    color: #aaa;
    pointer-events: none;
}
.gantt-context-menu-item.danger {
    color: #e53935;
}
.gantt-context-menu-item.danger:hover {
    background: #ffebee;
}

/* Linking mode */
.gantt-linking rect,
.gantt-linking path {
    cursor: crosshair;
}
.gantt-link-source rect,
.gantt-link-source path {
    stroke: #e53935 !important;
    stroke-width: 2 !important;
    stroke-dasharray: 4 2;
}
.gantt-linking-hint {
    position: fixed;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 100;
    background: #1565c0;
    color: #fff;
    padding: 8px 20px;
    border-radius: 4px;
    font-size: 13px;
    font-family: 'Segoe UI', sans-serif;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    pointer-events: none;
}

/* Dependency dialog */
.gantt-dep-dialog {
    position: absolute;
    z-index: 20;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    padding: 12px 16px;
    min-width: 240px;
    font-family: 'Segoe UI', sans-serif;
    font-size: 12px;
}
.gantt-dep-dialog label {
    display: block;
    margin-bottom: 4px;
    font-weight: 500;
    color: #555;
}
.gantt-dep-dialog select,
.gantt-dep-dialog input {
    width: 100%;
    padding: 4px 8px;
    border: 1px solid #ccc;
    border-radius: 3px;
    font-size: 12px;
    margin-bottom: 8px;
}
.gantt-dep-dialog .dep-dialog-buttons {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 4px;
}
.gantt-dep-dialog button {
    padding: 4px 14px;
    border: 1px solid #ccc;
    border-radius: 3px;
    font-size: 12px;
    cursor: pointer;
    background: #fff;
}
.gantt-dep-dialog button.primary {
    background: #1565c0;
    color: #fff;
    border-color: #1565c0;
}
.gantt-dep-dialog button.primary:hover {
    background: #1256a8;
}
.gantt-dep-dialog button.danger {
    color: #e53935;
    border-color: #e53935;
}
.gantt-dep-dialog button.danger:hover {
    background: #ffebee;
}

/* Dependencies list popup */
.gantt-deps-list {
    position: absolute;
    z-index: 20;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    padding: 10px 14px;
    min-width: 280px;
    max-width: 400px;
    max-height: 300px;
    overflow-y: auto;
    font-family: 'Segoe UI', sans-serif;
    font-size: 12px;
}
.gantt-deps-list-title {
    font-weight: 600;
    color: #1565c0;
    margin-bottom: 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid #e0e0e0;
}
.gantt-deps-list-section {
    font-weight: 500;
    color: #777;
    margin-top: 6px;
    margin-bottom: 2px;
}
.gantt-deps-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 3px 0;
    border-bottom: 1px solid #f0f0f0;
    cursor: pointer;
}
.gantt-deps-list-item:hover {
    background-color: #e3f2fd;
}
.gantt-deps-list-item:last-child {
    border-bottom: none;
}
.gantt-deps-list-item .dep-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.gantt-deps-list-item .dep-type {
    color: #1565c0;
    font-weight: 500;
    margin-left: 8px;
    white-space: nowrap;
}
.gantt-deps-list-item .dep-delete {
    color: #e53935;
    cursor: pointer;
    margin-left: 8px;
    font-size: 14px;
}
.gantt-deps-list-item .dep-delete:hover {
    color: #b71c1c;
}
/* #16476 — картка «Прибуткова накладна»: первинний документ, а не сітка реквізитів.
   #16868 — реквізити живуть у лівому Taskpad (.gr-side), у робочій області лишилась сама товарна
   частина (.gr-doc). Усе scoped під .gr-doc / .gr-side. Клас .act-card НЕ переиспользуємо — він
   прив'язаний до форми акта (internalact-card.css) і тягне за собою її max-width, фінблок і адаптивність. */

/* Розкладка сторінки з лівим Taskpad (колонки, тулбар на всю ширину, скрол панелі) — спільний фікс
   платформеного бага у site.css, блок «Спільний фікс розкладки сторінок з ЛІВИМ Taskpad». */

/* ---- Ліва панель реквізитів ---- */
.gr-side {
	padding: 0 0.25rem 1rem;
}
.gr-side .a2-header.gr-title {
	margin: 0;
	font-size: 1.05rem;
	font-weight: 600;
	color: #2c3e50;
}
/* «№» — спокійний службовий підпис, номер поруч — частина заголовка документа */
.gr-side .gr-num-label {
	color: #5a6b7b;
}
.gr-side .control-group.gr-num {
	margin: 0;
}
.gr-side .gr-num .input-group {
	background: transparent;
	border-color: transparent;
}
/* Номер не можна обрізати — це ідентифікатор документа. Ширина йде за вмістом (field-sizing,
   Chrome 123+); фолбек у старих браузерах — дефолтна ширина input, а не фіксовані 8rem, на яких
   різався «__TEST_RLS_GR__».
   ponytail: стеля — номер, довший за ширину панелі, згорнеться в еліпсис; апгрейд — Static замість
   disabled-TextBox (але тоді втрачається платформений bind-контракт поля). */
.gr-side .gr-num .input-group input {
	field-sizing: content;
	width: auto;
	min-width: 4rem;
	max-width: 100%;
	padding-left: 0;
	text-align: left;
	text-overflow: ellipsis;
	font-size: 1.35rem;
	font-weight: 600;
	color: #2c3e50;
}
/* #17154 (UI-рев'ю зауважень від 06.09) — значення реквізиту в 23-рем панелі часто не влазить:
   «51 ПАРАЛЕЛЬ Рекламно-поліграфічна агенція ТОВ» лишає в полі «51 ПАРАЛЕЛЬ Рекламно-полі», і
   платформений input різав його ПОСЕРЕДИНІ слова — без жодної ознаки, що текст продовжується, тобто
   обрізане ім'я читалось як повне. Еліпсис робить обрив чесним. Правило спільне для всіх карток на
   .gr-side, а не локальне для повернення: поле-Selector у панелі однакове в усіх вертикальних формах
   (накладна, рахунок, переміщення, списання), і чинити його в одній означало б розвести їх вигляд.
   Той самий приём уже стоїть на номері документа вище.
   Стеля: у ФОКУСІ браузер еліпсис не малює, а прокручує вміст — для читання цього достатньо, повне
   значення лишається доступним через підбір «…» або перехід у картку. */
.gr-side .input-group input {
	text-overflow: ellipsis;
}
.gr-side .gr-side-state {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin-bottom: 0.25rem;
}
/* Роздільники секцій панелі: «Постачальник» / «Отримувач» / «Кошти» */
.gr-side .a2-header.gr-side-sect {
	margin: 0.5rem 0 0;
	padding-top: 0.5rem;
	border-top: 1px solid #e9edf1;
	font-size: 0.8rem;
	font-weight: 600;
	color: #5a6b7b;
	text-transform: uppercase;
	letter-spacing: 0.02em;
}

/* ---- Товарна частина: займає всю робочу область ---- */
/* Трек таблиці має ПІДЛОГУ, а не лише 1fr: інакше на низькому вікні він стискається до нуля, а
   min-height усередині лише ховає вміст під обрізом (1fr — це максимум доступного, min-height
   нащадка трек не розтягує). З minmax сторінка виростає за висоту вікна і скролиться сама.
   !important — бо grid-template-rows приходить inline-стилем від платформи (XAML Rows). */
.gr-doc {
	grid-template-rows: auto minmax(12rem, 1fr) auto !important;
	/* Grid без Columns друкується з неявною колонкою max-content → таблиця розсовувала б сторінку.
	   Тримаємо трек у minmax(0,1fr), а горизонтальний скрол віддаємо ЛИШЕ контейнеру таблиці. */
	grid-template-columns: minmax(0, 1fr);
	min-width: 0;
	overflow-y: auto;
}
/* #16990 (п.1) — форми, де ТЧ у ТРЕТЬОМУ ряду (переміщення/списання/реалізація/введення залишків/
   повернення постачальнику: шапка, реквізити, товари[, підвал — implicit auto]). Базовий трек-шаблон
   вище писався під прихід (товари в ряду 2) і розтягував у них ряд РЕКВІЗИТІВ — звідси порожня
   область між реквізитами й таблицею. */
.gr-doc.gr-doc-goods3 {
	grid-template-rows: auto auto minmax(12rem, 1fr) !important;
}
.gr-doc .data-grid-container {
	overflow-x: auto;
	min-height: 12rem;
	min-width: 0;
	max-width: 100%;
}
/* #17203 — підлогу колонки тримає MinWidth у розмітці, але назву, довшу за саму підлогу, він не
   рятує: у <input> хвіст просто зникає за краєм, і без еліпсиса ЗДАЄТЬСЯ, що назва така й є
   (виміряно: «Герметик акрил. 310мл (білий) 06177» просить 264px, у полі 211px). Повне значення
   дає Tip (title), еліпсис лишає видимим сам факт обрізання. Правило спільне для ВСІХ форм на
   .gr-doc (прихід, реалізація, переміщення, списання, повернення, заявка, введення залишків) —
   поведінка бажана в кожній, тож окремих класів на чотири документи задачі не заводимо.
   БЕЗ `[type="text"]`: платформа рендерить поле селектора як голий <input> без атрибута type
   (text — лише дефолт IDL), тож `input[type="text"]` не збігається НІ З ЧИМ і правило мовчки
   не працює. */
/* #17492 — той самий еліпсис для форм, чия ТЧ побудована на <Table>, а не на DataGrid: селектор
   .data-grid-container до них НЕ доїжджав, хоча коментар вище називає «введення залишків» серед
   цілей правила. Побачили це, коли «олівець» додав рядку третю іконку: у nom_remainders поле
   «Складу» лишилось 64px, і «Основний склад 22» обривалось без жодної ознаки обрізання
   (виміряно на 1366 і 1440). Платформа рендерить рядок Table як table.a2-table. */
.gr-doc .data-grid-container .input-group input,
.gr-doc table.a2-table .input-group input {
	text-overflow: ellipsis;
}
.gr-doc .a2-header.gr-sect {
	margin: 0;
	font-size: 1rem;
	font-weight: 600;
	color: #2c3e50;
}
/* Тулбар секції — дії над рядками, без власного фону/рамки */
.gr-doc .gr-goods-head .toolbar {
	padding: 0;
	background: transparent;
	border: 0;
}
/* Налаштування ПДВ — компактний блок біля таблиці, на яку впливає */
.gr-doc .gr-vat .control-group {
	margin: 0;
}
.gr-doc .gr-vat .control-group > label {
	font-size: 0.75rem;
	color: #5a6b7b;
}
/* ---- Підсумки: типографіка замість кольорових бейджів ---- */
.gr-doc .gr-foot {
	padding-top: 0.5rem;
	border-top: 1px solid #dfe3e8;
	/* Платформений .grid має align-items:flex-end (tabbed.min.css) — без цього рядка колонки
	   підвалу вирівнюються по НИЗУ, і нижчий блок «Коментар» починався на висоті другого рядка
	   підсумків. Grid.VAlign="Top" у розмітці тут не допомагає: він задає align-self самого
	   підвалу в сітці сторінки, а не вирівнювання його власних колонок. */
	align-items: start;
}
.gr-doc .gr-totals {
	min-width: 18rem;
	column-gap: 1.25rem;
	row-gap: 0.2rem;
}
.gr-doc .gr-totals .gr-tot-l {
	color: #5a6b7b;
	font-size: 0.875rem;
}
.gr-doc .gr-totals .gr-tot-v {
	justify-self: end;
	font-variant-numeric: tabular-nums;
	color: #1b2230;
}
/* Головне число документа */
.gr-doc .gr-totals .gr-tot-l.gr-tot-main {
	padding-top: 0.3rem;
	border-top: 1px solid #dfe3e8;
	color: #2c3e50;
	font-size: 1rem;
	font-weight: 600;
}
.gr-doc .gr-totals .gr-tot-v.gr-tot-main {
	padding-top: 0.3rem;
	border-top: 1px solid #dfe3e8;
	font-size: 1.5rem;
	font-weight: 700;
}

/* #17473 (зауваження 3 тестера, 25.09) — перелік проєктів рядків у шапці (режим «Проєкт у ТЧ»).
   Платформене .input-group.static має ФІКСОВАНУ висоту 30px, тож другий рядок переліку зрізався б
   навіть без обмеження: висоту відпускаємо, а клемп 2 рядки ставимо на саме значення (.static-input),
   не на control-group — там він захоплював і підпис «Проєкт». Повне значення лишається в Tip. */
.gr-side .gr-project-list .input-group.static {
	height: auto;
	min-height: 30px;
	padding-bottom: 5px;
}
/* Специфічність ВИЩА за платформене `.control-group .input-group.static > span` (inline-grid),
   інакше display і line-height цього правила мовчки програють. */
.gr-side .gr-project-list .input-group.static > .static-input {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	height: auto;
	line-height: 1.4;
	/* Нижній відступ — на обгортці: overflow клемпу ріже по padding-box, і 5px знизу тут
	   показували б верх третього рядка. */
	padding: 5px 5px 0;
	white-space: normal;
}
/* claude. 2026-06-30. Футер index-сторінок (компонент a2-grid-footer): пейджер ліворуч + вибір
   розміру сторінки праворуч одним рядком. Компонент сам переносить себе у грід-контейнер сторінки
   (mounted → placeInGrid), тож стилі адресують його як ПРЯМОГО нащадка .page.page-grid у грід-рядку 3
   (де раніше жив .page-pager). Декларативно, без залежності від JS-таймінгу розкладки. */
.page.page-grid > .a2-grid-footer {
	grid-row: 3;
	grid-column: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 4px 8px 4px 0;
	min-width: 0;
}

/* taskpad-left (файловий менеджер): контент у колонці 2, тож і футер туди. */
.page.page-grid.taskpad-left > .a2-grid-footer {
	grid-column: 2;
}

.a2-grid-footer .a2-pager {
	margin: 0;
}

.a2-grid-footer .agf-size {
	display: flex;
	align-items: center;
	gap: .5rem;
	white-space: nowrap;
}

.a2-grid-footer .agf-select {
	min-width: 4rem;
	height: 1.75rem;
}

.a2-grid-footer .agf-pin {
	display: inline-flex;
	align-items: center;
	color: var(--text-link, #2b6ca3);
	text-decoration: none;
}

.a2-grid-footer .agf-pin:hover {
	color: var(--text-link-hover, #1b4d77);
}
/* #17225 — домашня сторінка: віджети платформеного Dashboard (MainApp/_home/home.view.xaml).
   Фон сторінки — .homepage у site.css. */
.home-dash {
	height: 100%;
}
.home-dash .dashboard {
	gap: .75rem;
	padding: .75rem;
}

.home-widget {
	background: #fff;
	border-radius: 10px;
	padding: .6rem .8rem;
	height: 100%;
	overflow: auto;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
	display: flex;
	flex-direction: column;
	gap: .4rem;
}
.home-widget-title {
	font-weight: 600;
	font-size: .95rem;
	color: #1f2937;
}
.home-widget-body {
	display: flex;
	flex-direction: column;
	gap: .4rem;
	/* #17227 — тіло займає решту картки, щоб діти з flex:1 (hero, матриця) могли її заповнити */
	flex: 1;
	min-height: 0;
}

/* #17226 — матриця: a2-graphics міряє контейнер при mount, тож хосту потрібна власна висота
   (flex:1 у колонці картки), інакше SVG нульової висоти. */
.home-matrix {
	flex: 1;
	min-height: 12rem;
	min-width: 0;
}
/* компонент міряє ширину на mount, коли сітка ще не осіла, і SVG виходить на десяток px ширшим за картку;
   праворуч у нього лише внутрішній відступ (R=24px), тож ховаємо, а не скролимо */
.home-matrix .a2pm-host {
	overflow-x: hidden;
}
.home-actions {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
}
.home-changelog {
	padding: 0;
}
/* #17227 — settings/theme: зона аплоаду в горизонтальному StackPanel стискається до нуля — розтягуємо;
   вужча за 320px вона ламає підказку на 3 рядки, і платформенна іконка (top:1rem) наїжджає на текст,
   тож кнопка «Прибрати» за браком місця переноситься під зону */
.theme-home-actions {
	flex-wrap: wrap;
}
.theme-home-actions .a2-file-upload {
	flex: 1;
	min-width: 320px;
}
.theme-home-image img {
	display: block;
	border-radius: 8px;
}
/* #17227 — картинка компанії: заповнює картку, зайве обрізається */
.home-hero {
	flex: 1;
	min-height: 0;
	overflow: hidden;
	border-radius: 8px;
}
.home-hero img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.home-widget-list {
	background: #eef2f7;
	border-radius: 8px;
	padding: .5rem .7rem;
	font-weight: 600;
	cursor: grab;
}

/* #17227 — «Класична головна»: порожня розкладка = лендінг. Слот empty платформа кладе у першу клітинку
   сітки, тож картинку абсолютно розтягуємо на весь контейнер дашборда, а кнопку «Налаштувати» піднімаємо над нею. */
/* .dashboard-container уже position:relative; overflow:hidden (платформа); порожній борд кладе
   .start-toolbar.no-items абсолютно у правий кут — лишається підняти його над картинкою */
.home-dash .start-toolbar {
	z-index: 1;
}
.home-landing {
	position: absolute;
	inset: 0;
	overflow: hidden;
}
.home-landing img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* #17718 — «Перший горизонт»: кільце x/N, пункти за 4 кроками, смуга згорнутого стану */
.hz-full {
	display: flex;
	flex-direction: column;
	gap: .5rem;
}
.hz-head {
	display: flex;
	align-items: center;
	gap: .8rem;
}
.hz-ring {
	width: 3.4rem;
	height: 3.4rem;
	border-radius: 50%;
	flex: none;
	display: grid;
	place-items: center;
	position: relative;
}
/* «дірка» кільця — білий диск поверх conic-gradient */
.hz-ring::before {
	content: "";
	position: absolute;
	inset: .45rem;
	border-radius: 50%;
	background: #fff;
}
.hz-ring-text {
	position: relative;
	font-weight: 700;
	font-size: .95rem;
}
.hz-head-text {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-width: 0;
}
.hz-title {
	font-weight: 600;
}
.hz-subtitle,
.hz-hint {
	font-size: .8rem;
	color: #7a8796;
}
.hz-steps {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: .5rem;
}
.hz-step {
	border: 1px solid #dde3ea;
	border-radius: 7px;
	padding: .4rem .6rem;
}
.hz-step-title {
	display: flex;
	justify-content: space-between;
	font-size: .75rem;
	text-transform: uppercase;
	letter-spacing: .03em;
	color: #7a8796;
	margin-bottom: .2rem;
}
.hz-item {
	display: flex;
	gap: .45rem;
	padding: .3rem 0;
	border-top: 1px dashed #edf0f3;
}
.hz-step-title + .hz-item {
	border-top: 0;
}
.hz-ic {
	width: .8rem;
	height: .8rem;
	border-radius: 50%;
	flex: none;
	margin-top: .25rem;
}
.hz-ok .hz-ic { background: #1f8c3a; }
.hz-warning .hz-ic { background: #c27400; }
.hz-error .hz-ic { background: #c0392b; }
.hz-txt {
	display: flex;
	flex-direction: column;
	min-width: 0;
}
.hz-warning .hz-text { color: #c27400; font-weight: 600; }
.hz-error .hz-text { color: #c0392b; font-weight: 600; }
.hz-act {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .2rem .7rem;
	margin-top: .15rem;
	font-size: .85rem;
}
.hz-control {
	display: flex;
	flex-direction: column;
	gap: .1rem;
	border-top: 1px solid #edf0f3;
	padding-top: .4rem;
}
.hz-control-title {
	font-weight: 600;
	font-size: .85rem;
}
.hz-control-row {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	align-items: baseline;
}
.hz-band {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: .5rem .8rem;
	border-radius: 7px;
	border: 1px solid;
}
.hz-band-text {
	font-weight: 600;
	flex: 1;
}
.hz-band.hz-ok { background: #f3fbf5; border-color: #bfe3c8; color: #1f8c3a; }
.hz-band.hz-warning { background: #fff8ec; border-color: #f1d49c; color: #c27400; }
.hz-band.hz-error { background: #fdecea; border-color: #f0b8b1; color: #c0392b; }
/* claude. 2026-09-26. #17722 — шпаргалка гарячих клавіш (Ctrl+/) і кнопка ⌨ у шапці; розмітку будує
   _assets/hotkeys.js. z-index 1110: поверх діалогу (модальний стек) і поверх палітри пошуку по меню
   (.ms-backdrop 1100 — Ctrl+/ з відкритої палітри). Карта шарів — tokens.css. Підкладка й тінь — як у
   палітри (menu-search.css), щоб два оверлеї застосунку виглядали однаково. */
.hk-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1110;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #00000059;
}
.hk-sheet {
  min-width: 26rem;
  max-width: 90vw;
  padding: 1rem 1.25rem;
  background-color: #fff;
  border-radius: 6px;
  box-shadow: 0 8px 32px #00000047;
}
.hk-sheet-title {
  font-weight: 600;
  font-size: 1.1rem;
  margin-bottom: 0.75rem;
}
.hk-sheet-table {
  border-collapse: collapse;
  width: 100%;
}
.hk-sheet-table td {
  padding: 0.3rem 0.5rem;
  vertical-align: middle;
}
.hk-sheet-table .hk-keys {
  white-space: nowrap;
  width: 1%;
}
.hk-sheet-table kbd {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  font-family: inherit;
  font-size: 0.85rem;
  border: 1px solid #ccc;
  border-bottom-width: 2px;
  border-radius: 4px;
  background-color: #f7f7f7;
}
.hk-sheet-table .hk-state {
  color: #888;
  font-size: 0.85rem;
  white-space: nowrap;
}
.hk-sheet-table tr.hk-off td:not(.hk-state) {
  opacity: 0.45;
}
.hk-sheet-help {
  display: inline-block;
  margin-top: 0.75rem;
}
.hk-header-btn {
  display: inline-flex;
  align-items: center;
  padding: 0 6px;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
}
.hk-header-glyph {
  font-size: 1.25rem;
  line-height: 1;
}
/* #16021 — структурована картка Акта приймання робіт (вкладка «Основне»):
   max-width, шапка-рядок, секції, фінансові KPI-картки, адаптивність.
   Стиль узгоджений з карткою Проєкту (project-card.css). */

/* Робоча ширина контенту — трохи ширша, але не на весь екран */
.act-card {
	max-width: 1200px;
}

/* ---- Шапка документа: [назва №] [статус] ....... [дата час] ----
   Три групи замість семи рівноправних елементів: ідентифікація документа читається як один заголовок,
   статус — поруч, дата/час — окремою групою реквізитів праворуч. */
.act-card .act-head {
	padding: 0 0 0.75rem;
	border-bottom: 1px solid #dfe3e8;
	margin-bottom: 0.75rem;
	/* #16693 — кегль номера документа: сам вигляд поля описано ОДИН раз у card.css (.doc-num),
	   тут лише розмір під заголовок акта (.act-title, 1.4rem). */
	--doc-num-size: 1.4rem;
}
.act-card .a2-header.act-title {
	margin: 0;
	font-size: 1.4rem;
	font-weight: 600;
}
/* «від» — спокійний службовий підпис у рядку шапки («№» — спільний .doc-num-label у card.css) */
.act-card .act-head .act-from {
	color: #5a6b7b;
}
/* Статус проведення — помітний, але не конкурує з назвою */
.act-card .act-head .tag-label {
	align-self: center;
}
/* Група дати/часу — праворуч (у Grid немає attached Align, лише VAlign) */
.act-card .act-when {
	justify-self: end;
}
/* Дата важливіша за час: час — компактний, без розтягнутого поля на 214px */
.act-card .act-when .act-time .input-group {
	width: 7.5rem;
}
.act-card .act-when .act-time .input-group input {
	width: 4.5rem;
	color: #5a6b7b;
}

/* ---- Заголовки секцій: помітніші за звичайні labels ---- */
.act-card .a2-header {
	font-weight: 600;
	color: #2c3e50;
}
.act-card .a2-header.sect {
	margin-top: 1.1rem;
	padding-top: 0.4rem;
	border-top: 1px solid #dfe3e8;
}

/* ---- Read-only відомості з Проєкту (Замовник/Генпідрядник) ----
   Раніше вони виглядали як згаслі поля вводу — тобто «зламані» або «випадково disabled». Насправді це
   довідкове значення, яке не редагується ніколи. Тому: без рамки/фону інпута, значення — звичайним
   текстом, під групою — підпис-джерело (act-ro-src). Замок лишається платформним (Disabled=True). */
.act-card .control-group.disabled .input-group input::placeholder {
	color: #9aa5b1;
	opacity: 1;
}
.act-card .control-group.act-ro .input-group {
	background: transparent;
	border-color: transparent;
	padding-left: 0;
}
.act-card .control-group.act-ro .input-group input {
	padding-left: 0;
	color: #1b2230;          /* значення читається як текст, а не як згаслий інпут */
	font-weight: 500;
}
.act-card .act-ro-src {
	display: block;
	margin-top: -0.25rem;
	font-size: 0.75rem;
	color: #5a6b7b;
}

/* ---- Фінансові показники: дві порівнянні групи (собівартість / продаж) ----
   Було: рамка навколо всього блоку + рамка на кожній із чотирьох карток — три рівні вкладених рамок, у
   яких підсумок з ПДВ не відрізнявся від складових. Стало: рамок нема взагалі, групу тримає ліва
   акцентна лінія, підсумок — велике число, складові — дрібні й сірі. */
.act-card .act-fin {
	margin-top: 0.5rem;
	padding: 0;
	background: transparent;
	border: 0;
}
.act-card .act-fin .a2-state-card {
	min-width: 0;
	background: transparent;
	border: 0;
}
/* Група: ліва лінія замість рамки. Продаж — спокійний синій акцент, собівартість — нейтральний сірий. */
.act-card .act-fin > .grid {
	padding-left: 0.75rem;
	border-left: 3px solid #d4dbe3;
}
.act-card .act-fin > .grid.act-fin-sales {
	border-left-color: #6f9bef;
}
/* Головне число групи — підсумок з ПДВ */
.act-card .act-fin .a2-state-card:not(.compact) .a2-state-card-text {
	font-size: 1.75rem;
	font-weight: 700;
	color: #1b2230;
}
.act-card .act-fin > .grid.act-fin-sales > .a2-state-card:not(.compact) .a2-state-card-text {
	color: #14306e;
}
/* Складові (без ПДВ / ПДВ) — явно вторинні */
.act-card .act-fin .a2-state-card.compact .a2-state-card-text {
	font-size: 1rem;
	font-weight: 500;
	color: #5a6b7b;
}
.act-card .act-fin .a2-state-card.compact .a2-state-card-header {
	color: #7b8794;
}

/* ================= Вкладка «Роботи» ================= */

/* P1: горизонтальне переповнення сторінки.
   ПРИЧИНА: обидва Grid'и вкладки оголошені лише рядками (Rows="4*,6*" / "Auto,1*,Auto") — без Columns
   платформа НЕ друкує inline grid-template-columns, і неявна колонка бере max-content найширшої дитини,
   тобто ~1126px таблиці робіт. Панель Splitter'а — ~967px, тож тулбар, пейджер і вкладки Ресурсів
   розтягувались до ширини таблиці й виїжджали за екран: пошук і «Колонки» ставали недосяжними, поки не
   проскролиш горизонтально ВСЮ панель.
   ЛІКИ: тримаємо колонку в minmax(0,1fr) (0 — щоб min-content дитини не роздував трек), а горизонтальний
   скрол віддаємо ЛИШЕ таблиці (.act-works-scroll). Без !important: inline-стилю на цих Grid'ах немає. */
.act-works-pane,
.act-works {
	grid-template-columns: minmax(0, 1fr);
	min-width: 0;
}
.act-works-scroll {
	overflow-x: auto;
	min-width: 0;
	max-width: 100%;
}
/* Найменування лишається читабельним при горизонтальному скролі таблиці.
   ponytail: sticky на першій текстовій колонці, а не платформний FixedColumns — у Table його немає
   (він є лише в DataGrid). Стеля: працює, поки колонка одна; знадобиться заморозити кілька — переводити
   таблицю на DataGrid, а це переписування всіх рядкових редакторів. */
.act-works-scroll table.a2-table td:nth-child(4),
.act-works-scroll table.a2-table th:nth-child(4) {
	position: sticky;
	left: 0;
	z-index: 1;
	background: #fff;
}
/* Тулбар: групи переносяться, а не розсовують сторінку */
.act-works-tb {
	flex-wrap: wrap;
	row-gap: 0.25rem;
	min-width: 0;
}
/* Права група (пошук + «Колонки») — один flex-item, nowrap: при браку ширини переноситься ЦІЛКОМ,
   а не лишає «Колонки» саму на другому рядку (зауваження 1) */
.act-works-tb .act-works-right {
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	gap: 0.35rem;
}
/* Заголовки таблиці: короткий текст + Tip (див. XAML) — тут лише заборона на 3-4 рядкові переноси */
.act-works-scroll table.a2-table thead td {
	white-space: nowrap;
	vertical-align: bottom;
}

/* Порожній стан таблиці робіт — по центру робочої області, а не притиснутий текст пейджера */
.act-works-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 2rem 1rem;
	text-align: center;
	color: #5a6b7b;
}
.act-works-empty-title {
	font-size: 1.05rem;
	font-weight: 600;
	color: #2c3e50;
}
.act-works-empty-hint {
	font-size: 0.875rem;
	color: #5a6b7b;
}
/* Причина недоступності CTA на замороженому етапі маршруту (зауваження 2): спокійна засторога, не помилка */
.act-works-empty-frozen {
	max-width: 32rem;
	color: #8a6d3b;
}
/* Пояснення залежності блоку Ресурси/Накладні від робіт */
.act-detail-empty {
	padding: 1.5rem 1rem;
	text-align: center;
	color: #5a6b7b;
}

/* ---- Адаптивність: на вузьких екранах секції та фінблок — в одну колонку ---- */
@media (max-width: 1000px) {
	.act-card > .grid:not(.act-head) {
		grid-template-columns: 1fr !important;
	}
}
/* На дуже вузьких екранах шапка документа теж в одну колонку */
@media (max-width: 700px) {
	.act-card .act-head {
		grid-template-columns: 1fr !important;
	}
}
/* Kanban board custom styles */

/* ===== Layout: independent lane scrolling ===== */

.kanban {
    overflow-x: auto;
    overflow-y: hidden;
    height: 100%;
}

.kanban .kanban-body {
    flex-grow: 1;
    overflow: hidden;
}

.kanban .lane {
    overflow-y: auto;
    flex-direction: column;
    align-self: stretch;
}

.kanban .kanban-header {
    z-index: 2;
    background: var(--background, #fff);
    flex-shrink: 0;
}

.kanban .kanban-footer {
    z-index: 2;
    background: var(--background, #fff);
    flex-shrink: 0;
}

/* ===== Lane header ===== */

.kanban-lane-header {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Color-coded lane headers */
.kanban .lane-header:has(.lane-color-info) {
    background: var(--status-info-bg);
    border-bottom: 2px solid var(--status-info);
}

.kanban .lane-header:has(.lane-color-warning) {
    background: var(--status-warning-bg);
    border-bottom: 2px solid var(--status-warning);
}

.kanban .lane-header:has(.lane-color-success) {
    background: var(--status-success-bg);
    border-bottom: 2px solid var(--status-success);
}

.kanban .lane-header:has(.lane-color-danger) {
    background: var(--status-danger-bg);
    border-bottom: 2px solid var(--status-danger);
}

.kanban-lane-count {
    font-size: 0.85em;
    color: #999;
    font-weight: normal;
}


/* ===== Card: project line ===== */

.kanban .kanban-card .kanban-card-header {
    padding: 4px 8px 2px;
    border-bottom: none;
}

.kanban-card-project {
    font-size: 0.75em;
    color: #999;
    line-height: 1.3;
}

/* ===== Card content ===== */

.kanban .kanban-card .kanban-card-content {
    padding-top: 2px;
    padding-bottom: 6px;
}

.kanban-card-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.4;
}

.kanban-card-meta {
    font-size: 0.85em;
    color: #666;
}

/* ===== Card footer indicators ===== */

.kanban .kanban-card .kanban-card-footer {
    padding: 2px 8px 4px;
    border-top: 1px solid var(--neutralBkDarker);
}

/* Hide footer when no visible indicators */
.kanban .kanban-card .kanban-card-footer:not(:has(.kanban-card-footer-bar)) {
    padding: 0;
    border-top: none;
}

.kanban-card-footer-bar {
    display: flex;
    align-items: center;
}

.kanban-card-indicator {
    font-size: 0.8em;
    color: #888;
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.kanban-card-indicator .ico {
    font-size: 0.95em;
}

/* Progress >= 90% highlighted green */
.kanban-progress-high {
    color: #2e7d32;
    font-weight: 600;
}

.kanban-progress-high .ico {
    color: #2e7d32;
}

/*+Kamala. claude. 2026-09-11. #17325 — opt-in полірування платформних StateCard (KPI-карток).
   Вмикається класом .kpi-polish на корені форми/діалогу (Page/Dialog CssClass) — глобально
   StateCard не чіпаємо: ними користуються ~20 форм, і вигляд кожної змінився б мовчки.
   Перший користувач — money/cashflow/drilldown.dialog.xaml. employeesettlements-report.css несе
   старішу власну копію тих самих правил; перевести її на цей клас — окремим тікетом, бо зміниться
   вигляд того звіту (там ще uppercase у мітці). Наступна форма — підключає клас, а не копіює. */

/* платформа ставить кольоровим карткам color:#000000a0 — сума на зеленій/блакитній сіріє */
.kpi-polish .a2-state-card.a2-state-card-styled {
    color: #1a1a1a;
}
/* назва — мітка над сумою: дрібніша, напівжирна */
.kpi-polish .a2-state-card .a2-state-card-header {
    font-size: 0.8rem;
    font-weight: 600;
    opacity: 0.85;
}
/* сума — головне; мільйони в один рядок */
.kpi-polish .a2-state-card .a2-state-card-text {
    white-space: nowrap;
}
/* пояснення — приглушене */
.kpi-polish .a2-state-card .a2-state-card-footer {
    font-size: 0.78rem;
    opacity: 0.75;
}
.kpi-polish .a2-state-card .a2-card-icon {
    opacity: 0.5;
}
/* ============================================================================
   #16494 — командна палітра пошуку по меню (menu-search.js).
   z-index 1100: вище модального стека (100) і type-ahead Selector'а платформи
   (1070) — палітра має відкриватись і поверх діалогу; нижче банера ліцензії
   (10000), який має лишатись видимим. Карта шарів — tokens.css.
   ============================================================================ */

.ms-backdrop {
	position: fixed;
	inset: 0;
	z-index: 1100;
	background: #00000059;
	display: flex;
	justify-content: center;
	align-items: flex-start;
}

.ms-box {
	width: 100%;
	max-width: 560px;
	margin-top: 12vh;
	display: flex;
	flex-direction: column;
	max-height: 70vh;
	background: #fff;
	border-radius: 6px;
	box-shadow: 0 8px 32px #00000047;
	overflow: hidden;
}

.ms-input {
	flex: 0 0 auto;
	border: none;
	border-bottom: 1px solid #dcdcdc;
	outline: none;
	padding: 14px 16px;
	font-size: calc(var(--fontSize) + 2px);
	font-family: inherit;
	color: inherit;
}

.ms-list {
	flex: 1 1 auto;
	overflow-y: auto;
	margin: 0;
	padding: 4px 0;
	list-style: none;
}

.ms-item {
	padding: 6px 16px;
	cursor: pointer;
}

.ms-item.selected,
.ms-item:hover {
	background: var(--status-info-bg);
}

.ms-name {
	font-size: var(--fontSize);
	line-height: 1.3;
}

.ms-name b {
	color: var(--nav800);
}

.ms-path {
	font-size: calc(var(--fontSize) - 3px);
	color: #7a7a7a;
	line-height: 1.3;
}

.ms-empty {
	padding: 12px 16px;
	color: #7a7a7a;
	font-size: var(--fontSize);
}

/* ---- пошук усередині панелі розділу (.mdi-menu) --------------------------------------------
   Панель темна (--mdi-menu-bg), тож поле й результати мають власне оформлення, а не світле
   з палітри вище. Ширину не задаємо — тягнеться по панелі. */

.mdi-menu .ms-panel-box {
	padding: 4px 12px 8px;
}

.mdi-menu .ms-panel-input {
	width: 100%;
	box-sizing: border-box;
	padding: 5px 8px;
	border: 1px solid var(--mdi-menu-line);
	border-radius: 3px;
	background: #ffffff1f;
	color: var(--mdi-menu-text);
	font-family: inherit;
	font-size: calc(var(--fontSize) - 1px);
	outline: none;
}

.mdi-menu .ms-panel-input::placeholder {
	color: var(--mdi-menu-light);
}

.mdi-menu .ms-panel-input:focus {
	background: #ffffff2e;
	border-color: var(--nav-accent);
}

.mdi-menu .ms-panel-list {
	display: none;
	margin: 0;
	padding: 0;
	list-style: none;
}

.mdi-menu .ms-panel-list .ms-item {
	padding: 5px 12px;
	cursor: pointer;
	color: var(--mdi-menu-text);
}

.mdi-menu .ms-panel-list .ms-item.selected,
.mdi-menu .ms-panel-list .ms-item:hover {
	background: var(--mdi-menu-hover);
}

.mdi-menu .ms-panel-list .ms-name b {
	color: var(--nav-accent);
}

.mdi-menu .ms-panel-list .ms-path {
	color: var(--mdi-menu-light);
}

.mdi-menu .ms-panel-list .ms-empty {
	color: var(--mdi-menu-light);
	padding: 8px 12px;
}
.modal {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.modal-header {
  background-color: #759bbb;
  padding: 0.5rem 0.75rem;
  cursor: move;
  font-weight: 500;
  border-bottom: 1px solid #ddd;
  min-height: 3rem;
  line-height: 1.9rem;
}
.modal-header .modal-title-info {
  margin-left: 1rem;
}
.modal-header .btnclose {
  float: right;
  color: #aaa;
  width: 1.9rem;
  height: 1.9rem;
}
.modal-header .btnclose:not([disabled]):hover,
.modal-header .btnclose:not([disabled]):active,
.modal-header .btnclose:not([disabled]):focus {
  color: #555;
  background-color: #fff9d0;
  border-color: #e5c365;
}
.modal-header .btnclose[disabled] {
  cursor: not-allowed;
  opacity: 0.5;
}
.modal-header .btn-help {
  float: right;
  color: #999;
  line-height: 1.8rem;
  padding: 0 4px;
  margin-right: 0.2rem;
  border: 1px solid transparent;
}
.modal-header .btn-help:hover {
  background-color: #fff9d0;
  border-color: #e5c365;
}
.modal-footer {
  padding: 0.75rem;
  background-color: #f9f9f9;
  border-top: 1px solid #ddd;
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
}
.modal-footer .btn {
  min-width: 6rem;
}
.modal-footer .btn + .btn,
.modal-footer .btn + .dropdown,
.modal-footer .dropdown + .btn {
  margin-left: 0.75rem;
}
.modal-footer .btn-help {
  cursor: pointer;
  margin-top: 5px;
}
.modal-footer .btn-help .ico {
  margin-right: 4px;
}
.modal-footer .btn-help:hover {
  text-decoration: none;
}
.modal-footer .btn + .btn-caret {
  min-width: 0;
  margin-left: 0;
}
.modal-body.confirm,
.modal-body.alert,
.modal-body.info {
  margin: 1.5rem 0.75rem;
  display: flex;
}
.modal-body.confirm > .ico,
.modal-body.alert > .ico,
.modal-body.info > .ico {
  font-size: 24px;
  display: inline-block;
  margin: 0 12px;
}
.modal-body.confirm > div,
.modal-body.alert > div,
.modal-body.info > div {
  white-space: pre-wrap;
}
.modal-content.content-iframe {
  display: flex;
}
.modal-content {
  flex-grow: 2;
  overflow: auto;
  position: relative;
}
.modal-content.overflow {
  overflow: visible;
}
.modal-content.overflow .tab-panel {
  overflow: visible;
}
.modal-content.overflow .tab-panel .tab-item {
  overflow: visible;
}
.modal-content .dialog-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  padding: 0;
  grid-gap: 0;
  height: 100%;
}
.button-on-top .modal-content {
  order: 2;
}
.button-on-top .modal-footer {
  order: 1;
  border-bottom: 1px solid #ddd;
  border-top: none;
}
 
.modal-animation-frame.show {
  transition: background-color linear 0.1s, backdrop-filter step-end 0.1s;
  background-color: rgba(0, 0, 0, 0.2);
 }
.modal-animation-window:not([maximize]) {
  box-shadow: none;
  backface-visibility: hidden;
  transform: translate(0, -33%);
  opacity: 0;
}
.modal-animation-window:not([maximize]).loaded {
  transition: transform ease 0.1s, box-shadow ease 0.1s, opacity ease 0.1s;
  transform: translate(0, 0);
  opacity: 1;
  box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
}
.modal-animation-window[maximize] {
  box-shadow: none;
  backface-visibility: hidden;
  transform: scale(0.8, 0.8);
  transform-origin: center top;
  opacity: 0;
}
.modal-animation-window[maximize].loaded {
  transition: transform ease 0.1s, box-shadow ease 0.1s, opacity 0.1s ease;
  transform: scale(1, 1);
  box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
  opacity: 1;
}
.modal-header-menu {
  float: right;
  cursor: pointer;
}
.modal-header-menu .modal-menu-link {
  color: black;
  display: inline-block;
  width: 1.9rem;
  height: 1.9rem;
  margin: 0 2px;
  text-align: center;
}
.modal-header-menu .modal-menu-link:hover {
  background-color: #fff9d0;
  border-color: #e5c365;
}

/* ---- CPMS: дрібні overflow/stacking-фікси діалогів (винесено з main_cpms.css) ---- */
.modal-content.InlineDialog_cpms {
    overflow: visible;
}

/* Ensure browse dialogs opened from within InlineDialog appear on top.
   modal-stack z-index is 100; keeping InlineDialog below it fixes stacking. */
.inline-modal-wrapper {
    z-index: 99 !important;
}

/* CPMS: навмисне перекриття — платформне .modal-animation-frame.show (вище в цьому
   файлі) вмикає backdrop-filter у transition; ми його глушимо (різні властивості,
   тож порядок не конфліктує). */
.modal-animation-frame.show {
    backdrop-filter: none;
}

.modal-footer .btn-more {
    min-width: auto;
}
/* claude. 2026-07-19. #16486 — згортання груп у бічній панелі розділу.
   Поведінка — в navpane-collapse.js; тут лише вигляд: маркер-стрілка на заголовку групи
   і приховування списку згорнутої групи. Клас has-collapse ставить скрипт лише тим групам,
   де є що згортати, тож у групи без вкладених пунктів стрілка не з'явиться. */

.mdi-menu li.level-0.has-collapse > span.folder {
    cursor: pointer;
    user-select: none;
}

.mdi-menu li.level-0.has-collapse > span.folder::before {
    content: '';
    display: inline-block;
    width: 0;
    height: 0;
    margin-right: .45em;
    vertical-align: middle;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transform: rotate(90deg);
    transition: transform .12s ease;
    opacity: .75;
}

.mdi-menu li.level-0.has-collapse.collapsed > span.folder::before {
    transform: rotate(0deg);
}

.mdi-menu li.level-0.collapsed > ul {
    display: none;
}
/* +Kamala. claude. 2026-08-07. #16672 (B3) — матриця звіту «Аналіз забезпечення потреб»
   (a2-needs-analysis, _assets/needs-analysis.js): дерево × місяці × групи показників. */

.na { display: flex; flex-direction: column; gap: .5rem; min-width: 0; height: 100%; font-size: .85rem; }

/* панель перемикачів: групи, деталізація по місяцях, слайдер глибини */
.na .na-bar { display: flex; align-items: center; gap: .5rem 1rem; flex-wrap: wrap; flex: 0 0 auto; }
.na .na-gr { display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; cursor: pointer; }
.na .na-sep { width: 1px; height: 1.2rem; background: var(--border-color, #d0d3d9); }
.na .na-lvl { display: inline-flex; align-items: center; gap: .4rem; color: var(--text-muted, #6b7280); white-space: nowrap; }
.na .na-slider { width: 8rem; vertical-align: middle; }
.na .na-lvl b { color: var(--text-color, #1f2937); }
.na .na-chkinfo { margin-left: auto; color: var(--text-muted, #6b7280); white-space: nowrap; }

/* Голий чекбокс платформа ховає: правило `input[type="checkbox"]:not(.switch)` у tabbed.min.css робить
   opacity:0 + position:absolute + нульовий розмір, бо очікує кастомний вигляд через label-обгортку.
   У нас обгортки немає, тож повертаємо нативний вигляд — інакше і перемикачі груп, і виділення рядків
   стають невидимими (той самий прецедент, що #16417 у rgk-sheet.css). Селектор із [type] дає
   специфічність (0,3,1) і перебиває платформний (0,2,1) без !important. */
.na input[type="checkbox"].na-cb {
	position: static; left: auto; top: auto;
	width: 1em; height: 1em; margin: 0; opacity: 1; z-index: auto;
	-webkit-appearance: checkbox; appearance: checkbox; cursor: pointer;
}

.na .na-scroll { flex: 1 1 auto; overflow: auto; border: 1px solid var(--border-color, #d7dee6); border-radius: 4px; }
.na .na-table { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; }
.na .na-table th, .na .na-table td {
	border-bottom: 1px solid #eef1f5; border-right: 1px solid #f2f5f8; padding: 2px 8px; background: #fff;
}

/* шапка у два поверхи: період (або «Разом») → група. Другий поверх липне під першим, тож у
   .na-bh задана фіксована висота — без неї top другого поверху нема від чого відрахувати. */
.na .na-table thead th {
	position: sticky; z-index: 4; background: #f4f6f9; font-weight: 600; text-align: right;
	white-space: nowrap; border-bottom: 1px solid #d7dee6;
}
.na .na-table thead th.na-bh { top: 0; height: 1.7rem; text-align: center; }
.na .na-table thead th.na-gh { top: 1.7rem; font-weight: 500; font-size: .8em; color: #5d6875; }
.na .na-table thead th.na-frz0,
.na .na-table thead th.na-frz1,
.na .na-table thead th.na-frz2,
.na .na-table thead th.na-frz3 { top: 0; z-index: 6; text-align: left; }

/* Заморожена ліва аналітична частина. Зсув left кожного наступного стовпця — сума ширин попередніх,
   тому ширини тут ЖОРСТКІ (width, а не min/max): sticky-стовпець не знає, скільки зайняв сусід зліва,
   і плаваюча ширина назви поїхала б по всій замороженій частині. Довга назва ріжеться багатокрапкою,
   повний текст лишається в title. */
.na .na-chk, .na .na-name, .na .na-code, .na .na-unit { position: sticky; z-index: 3; background: #fff; }
.na .na-chk { left: 0; width: 2rem; min-width: 2rem; text-align: center; padding: 2px 4px; }
.na .na-name { left: 2rem; width: 22rem; min-width: 22rem; max-width: 22rem; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.na .na-code { left: 24rem; width: 7rem; min-width: 7rem; text-align: left; color: var(--text-muted, #6b7280); font-size: .9em; }
.na .na-unit { left: 31rem; width: 4rem; min-width: 4rem; text-align: left; color: var(--text-muted, #6b7280); font-size: .9em; }
/* межа замороженої частини — на останньому з НАЯВНИХ стовпців: «Од.» показується не завжди, тож
   клас вішає шаблон, а не селектор на кшталт :last-of-type (він дивиться на останній td рядка) */
.na .na-frzlast { border-right: 1px solid var(--border-color, #d7dee6); }

.na .na-name-text { display: inline-block; }
.na .na-caret { display: inline-block; width: 1rem; cursor: pointer; color: var(--text-muted, #6b7280); user-select: none; }
.na .na-caret-off { cursor: default; }

/* рівні дерева: вид ресурсу і ресурс несуть основне навантаження, нижче — довідково.
   Kind 6 (накладна витрата, B7 #16676) стоїть на тому самому рівні, що ресурс, — і виглядає так само. */
.na .na-kind1 > td { font-weight: 700; background: #eef2f6; }
.na .na-kind2 > td, .na .na-kind6 > td { font-weight: 600; background: #f8fafc; }
.na .na-kind5 > td { color: #4a5561; }

.na .na-cell { text-align: right; white-space: nowrap; min-width: 6rem; font-variant-numeric: tabular-nums; }
.na .na-cell .na-s { display: block; }
.na .na-cell .na-q { display: block; font-size: .8em; color: #8a94a1; }
.na .na-tot { background: #fbfcfd; }
.na .na-cur { background: #eaf3fb; }
.na .na-past { background: #fafbfc; }
.na .na-nodate { background: #fdf9f2; }

/* рядок балансу: незакрита потреба + відсотки від плану (§7 контракту) */
.na .na-bal > td { background: #fcfdfe; font-size: .85em; color: var(--text-muted, #5d6875); font-style: italic; }
.na .na-bal .na-unclosed { color: var(--danger-color, #c0392b); font-weight: 700; font-style: normal; }
.na .na-bal .na-over { color: var(--accent-color, #7b5ea7); font-weight: 700; font-style: normal; }
/* пороги §1.8: жовтий >= 90 %, червоний > 100 %. Ліва смуга — другий, не-кольоровий канал; той самий
   сенс дублюється в title комірки. */
.na .na-bal .na-warn { background: #fdf3d7; border-left: 3px solid var(--warning-color, #d79b1e); color: #7a5a10; font-style: normal; }
.na .na-bal .na-crit { background: #fbe4e0; border-left: 3px solid var(--danger-color, #c0392b); color: #8e2b20; font-weight: 700; font-style: normal; }

.na .na-empty { padding: 1.5rem; color: #8a94a1; text-align: center; border: 1px solid var(--border-color, #d7dee6); border-radius: 4px; }
/*+Kamala. claude. 2026-07-13. #16106 — межі браузерного друку звіту «Зведена інформація по об'єктах».
   Кнопка «Друк» (Command=Print) / Ctrl+P друкують увесь DOM: тулбар фільтрів, кнопки, шеврон-афорданс,
   екранні обмеження висоти/скролу. Ховаємо чром, знімаємо ліміти, друкуємо KPI + таблицю. Секція
   «Виплати по об'єктах» (.os-payment-section) у друк не йде — дублює фінансові колонки таблиці й давала
   зайву другу сторінку. Клас .objectsummary-report — на кореневому <Page>. Іменована @page (НЕ глобальна:
   глобальний @page протік би орієнтацією/полями на ВСІ друки застосунку — appstyles вантажиться скрізь). */

/* екранна шапка друку прихована — показуємо лише в @media print */
.objectsummary-report .os-print-header { display: none; }

/* TreeGridColumn не має Wrap — числові (right-aligned) клітинки дерева не переносимо (екран і друк) */
.objectsummary-report .tree-grid td.text-right,
.objectsummary-report .tree-grid th.text-right { white-space: nowrap; }

@media print {
    @page objectsummary-print {
        size: A4 landscape;
        margin: 9mm;
    }
    .objectsummary-report {
        page: objectsummary-print;
    }

    /* секція «Виплати по об'єктах» (заголовок + легенда + .os-bars + картки) — цілком поза друком */
    .objectsummary-report .os-payment-section {
        display: none !important;
    }

    /* print-only шапка: назва звіту окремим рядком, фільтри — рядком нижче */
    .objectsummary-report .os-print-header {
        display: block;
        margin-bottom: 5mm;
    }
    .objectsummary-report .os-print-title {
        display: block;
        font-size: 15px;
        /* !important: перебиває платформений .bold {font-weight:500!important} (клас від Text Bold="True") */
        font-weight: 700 !important;
        margin: 0 0 2mm 0;
    }
    .objectsummary-report .os-print-filters {
        display: block;
        font-size: 10px;
        line-height: 1.4;
    }

    /* прибрати чром: тулбар фільтрів, будь-які кнопки, нативний toggle розгортання TreeGrid (<a class="toggle">) */
    .objectsummary-report .toolbar,
    .objectsummary-report button,
    .objectsummary-report .tree-grid a.toggle {
        display: none !important;
    }

    /* зняти екранні обмеження висоти/скролу контейнерів — інакше в друк лізе лише видима область */
    .objectsummary-report .page-content,
    .objectsummary-report .a2-sticky-container,
    .objectsummary-report .tree-grid {
        overflow: visible !important;
        height: auto !important;
        max-height: none !important;
    }

    /* екранні тіні у друк не потрібні */
    .objectsummary-report .a2-state-card,
    .objectsummary-report .card {
        box-shadow: none !important;
    }

    /* статуси читабельні без друку фонів (браузер за замовч. не друкує background): темний текст, без плашки */
    .objectsummary-report .tag-label {
        color: #1a1a1a !important;
        background: transparent !important;
        border: none !important;
        padding: 0 !important;
        font-weight: 600;
    }

    /* числові значення не переносити; текст не рвати по літерах */
    .objectsummary-report td,
    .objectsummary-report th {
        white-space: nowrap;
        word-break: keep-all;
        overflow-wrap: normal;
    }
    /* колонка об'єкта (перша в дереві) — достатня ширина, перенос лише по словах (довгі назви) */
    .objectsummary-report .tree-grid td:first-child,
    .objectsummary-report .tree-grid th:first-child {
        white-space: normal;
        word-break: keep-all;
        overflow-wrap: break-word;
        min-width: 45mm;
    }

    /* рядки таблиці не розривати між сторінками; поточні розкриті рядки друкуються як є */
    .objectsummary-report tr {
        break-inside: avoid;
    }

    /* KPI-картки у ряд, не обрізати */
    .objectsummary-report .os-kpi {
        grid-template-columns: repeat(5, minmax(0, 1fr)) !important;
    }
}
/* +Kamala. claude. 2026-07-16. #16041 — «Оперативний план-факт»: денна сітка АРМ прораба (a2-operplan-grid) */

.opg {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	font-size: 0.85rem;

	/* ширини закріпленого блоку (Найменування+Код+Од.) — з них рахуються left-зсуви sticky-колонок */
	--opg-w-name: 17rem;
	--opg-w-code: 5.5rem;
	--opg-w-unit: 2.75rem;

	/* +Kamala. claude. 2026-07-19. #16041 (зауваження «ширина колонок») — ширина колонки ДНЯ, спільна на
	   всі дні. Індивідуальні ширини = :style на кожну денну комірку (~48к виразів) — рівно та зайва
	   робота на комірку, яку прибирали в перф-фіксі а1 (183 с → 3,3 с). Drag міняє ОДНУ змінну на корені
	   .opg, Vue не перемальовує жодного рядка, далі працює сам layout браузера.
	   ponytail: ширина не персиститься (скидається при перезавантаженні вкладки); якщо попросять
	   запам'ятовувати — localStorage за зразком _components/column-resize.ts:110-140. */
	--opg-w-day: 4.35em;

	/* семантика кольору (#16041 UX): приглушені заливки, червоний — лише підтверджене відхилення */
	--opg-dev-bg: #fbe3e5;
	--opg-dev-fg: #8a1c24;
	--opg-ok-bg: #e8f5e9;

	/* +Kamala. claude. 2026-07-17. #16041 (UX) — БЕЗ min-width:0 grid-айтем .full-height-panel не
	   стискається нижче ширини контенту (min-width:auto у grid/flex-айтема), сітка роздувалась до
	   ширини всіх 31 дня (~2290px), горизонтальний скрол діставався .page-content, а панель із
	   легендою їхала за межі екрана. Скрол має належати ЛИШЕ .opg-scroll. */
	min-width: 0;
	max-width: 100%;

	/* +Kamala. claude. 2026-07-18. #16041 (зауваження 1/а2) — те саме по ВЕРТИКАЛІ: без min-height:0
	   flex-айтем .opg-scroll не стискається нижче висоти контенту, скрол лишався у .page-content. */
	min-height: 0;
}

/* +Kamala. claude. 2026-07-18. #16041 (зауваження 1/а2) — «зафіксувати шапку з датами при вертикальній
   прокрутці». Шапка вже була position:sticky, але липла не до того контейнера: платформний
   .full-height-panel — це grid БЕЗ grid-template-rows, тобто неявний трек auto, який росте під контент
   (виміряно: панель 570px, трек і .opg — 2263px). height:100% у .opg резолвиться проти ТРЕКА, а не проти
   панелі → .opg-scroll отримував висоту контенту, його scrollTop завжди 0, а реально прокручувався
   .page-content — і весь .opg-scroll разом із «приклеєною» шапкою їхав за екран.
   minmax(0,1fr) робить трек обмеженим висотою панелі → скрол повертається у .opg-scroll, sticky працює.
   !important обов'язковий: платформа пише інлайновий style="grid-template-rows: auto" на самій панелі,
   і його не перебити специфічністю. Друге правило — для стану «проєкт не обрано», коли поруч з .opg
   у панелі живе ще й <Alert> (тоді треків два: авто під алерт + обмежений під сітку). */
.full-height-panel:has(> .opg) { grid-template-rows: minmax(0, 1fr) !important; }
.full-height-panel:has(> .opg):has(> .a2-alert) { grid-template-rows: auto minmax(0, 1fr) !important; }

/* панель над таблицею: НЕ всередині .opg-scroll → завжди у видимій зоні, не їде по горизонталі */
.opg .opg-bar {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.3rem 0.5rem;
	flex: 0 0 auto;
	flex-wrap: wrap;
	min-width: 0;
}
.opg .opg-barbtn {
	border: 1px solid var(--border-color, #d0d3d9);
	background: var(--table-header-bg, #f3f4f6);
	border-radius: 4px;
	padding: 2px 8px;
	cursor: pointer;
	font: inherit;
	font-size: 0.8rem;
	white-space: nowrap;
}
.opg .opg-barbtn:hover:not(:disabled) { background: #e8eaef; }
.opg .opg-barbtn:disabled { opacity: .45; cursor: not-allowed; }
.opg .opg-depth { color: var(--text-muted, #6b7280); white-space: nowrap; }
.opg .opg-sep { width: 1px; height: 1.2rem; background: var(--border-color, #d0d3d9); }

/* легенда: показує зразок клітинки (план над фактом) + семантику кольорів */
.opg .opg-legend {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	gap: 0.9rem;
	color: var(--text-muted, #6b7280);
	white-space: nowrap;
}
.opg .opg-lg { display: inline-flex; align-items: center; gap: 0.3rem; }
.opg .opg-lg-swatch {
	display: inline-block;
	width: 0.85rem; height: 0.85rem;
	border: 1px solid var(--border-color, #d0d3d9);
}
.opg .opg-lg-dev .opg-lg-swatch { background: var(--opg-dev-bg, #fbe3e5); }
.opg .opg-lg-ok .opg-lg-swatch { background: var(--opg-ok-bg, #e8f5e9); }
.opg .opg-lg-dirty .opg-lg-swatch { background: #fff; outline: 2px solid #1976d2; outline-offset: -2px; }
/* міні-зразок клітинки: план зверху / факт знизу */
.opg .opg-lg-cell {
	display: inline-block;
	border: 1px solid var(--border-color, #d0d3d9);
	line-height: 1;
	text-align: right;
	min-width: 3.2rem;
}
.opg .opg-lg-cell i { display: block; font-style: normal; font-size: 0.7rem; padding: 1px 3px; }
.opg .opg-lg-cell .lg-p { background: #eef2f7; color: var(--text-muted, #6b7280); }
.opg .opg-lg-cell .lg-f { color: var(--text-color, #1f2937); }

/* верхня дубль-полоса горизонтального скролу: тонка смужка (лише скролбар), синхронна з таблицею.
   Дає доступ до прокрутки днів згори, не мотаючи довгу таблицю до низу до нижньої полоси. */
.opg .opg-hscroll {
	flex: 0 0 auto;
	overflow-x: auto;
	overflow-y: hidden;
	border: 1px solid var(--border-color, #d0d3d9);
	border-bottom: 0;
}
.opg .opg-hscroll-in { height: 1px; }

.opg .opg-scroll {
	flex: 1 1 auto;
	overflow: auto;             /* основний власник вертикального+горизонтального скролу */
	min-width: 0;
	min-height: 0;              /* #16041: інакше flex-айтем не стискається нижче висоти таблиці */
	border: 1px solid var(--border-color, #d0d3d9);
}

.opg-table {
	border-collapse: separate;
	border-spacing: 0;
	width: max-content;
	min-width: 100%;
}

.opg-table th,
.opg-table td {
	border-right: 1px solid var(--border-color, #d0d3d9);
	border-bottom: 1px solid var(--border-color, #d0d3d9);
	padding: 2px 6px;
	text-align: right;
	white-space: nowrap;
	background: #fff;
	box-sizing: border-box;
}

/* липка шапка — ОДИН ряд (без rowspan/зсувів: другий ряд з хардкодним top накривав перший рядок даних) */
.opg-table thead th {
	position: sticky;
	top: 0;
	z-index: 4;
	background: var(--table-header-bg, #f3f4f6);
	font-weight: 600;
	text-align: center;
	vertical-align: bottom;
}
/* довгі заголовки підсумкових колонок переносяться на два рядки (день-колонки лишаються nowrap) */
.opg-table thead th.opg-num { white-space: normal; line-height: 1.15; }

/* ЗАКРІПЛЕНИЙ БЛОК: Найменування + Код + Од. (єдиний блок, зсуви з --opg-w-*) */
.opg-table .opg-name {
	position: sticky; left: 0; z-index: 3;
	width: var(--opg-w-name); min-width: var(--opg-w-name); max-width: var(--opg-w-name);
	text-align: left; overflow: hidden; text-overflow: ellipsis;
}
.opg-table .opg-code {
	position: sticky; left: var(--opg-w-name); z-index: 3;
	width: var(--opg-w-code); min-width: var(--opg-w-code); max-width: var(--opg-w-code);
	text-align: left; overflow: hidden; text-overflow: ellipsis;
}
.opg-table .opg-unit {
	position: sticky; left: calc(var(--opg-w-name) + var(--opg-w-code)); z-index: 3;
	width: var(--opg-w-unit); min-width: var(--opg-w-unit); max-width: var(--opg-w-unit);
	text-align: center; color: var(--text-muted, #6b7280);
	/* +#16565 (ui-review) — як у сусідів .opg-name/.opg-code: без цього довга одиниця
	   («маш-год») вилазила зі sticky-бокса і НАКЛАДАЛАСЬ на текст нової колонки «Виконавець»
	   (раніше праворуч було право-вирівняне число і переповнення падало в порожнє місце) */
	overflow: hidden; text-overflow: ellipsis;
	/* межа+тінь між закріпленою частиною і даними, що прокручуються */
	box-shadow: 3px 0 4px -2px rgba(0, 0, 0, .25);
	border-right: 2px solid var(--border-color, #b9bec7);
}
.opg-table thead .opg-name,
.opg-table thead .opg-code,
.opg-table thead .opg-unit { z-index: 5; }
.opg-table .opg-name-text { display: inline-flex; align-items: center; gap: 0.15rem; max-width: 100%; }
.opg-table .opg-name-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* маркер розгортання/згортання групи WBS */
.opg-table .opg-tog {
	flex: 0 0 auto;
	width: 1.1rem; height: 1.1rem;
	line-height: 1;
	border: 0; background: transparent; padding: 0;
	cursor: pointer; color: var(--text-muted, #6b7280);
	font-size: 0.75rem;
}
.opg-table .opg-tog:hover { color: var(--text-color, #1f2937); }
.opg-table .opg-tog:focus-visible { outline: 2px solid #1976d2; outline-offset: 1px; }
.opg-table .opg-tog-empty { display: inline-block; width: 1.1rem; flex: 0 0 auto; }

.opg-table .opg-num { min-width: 5rem; }

/* +#16565 — «Виконавець»: НЕзакріплена (одразу за sticky-блоком, перед «Обсяг ЖЦП»);
   довга назва контрагента ріжеться ellipsis'ом, повна — у title комірки */
.opg-table .opg-exec {
	width: var(--opg-w-exec, 10rem); min-width: var(--opg-w-exec, 10rem); max-width: var(--opg-w-exec, 10rem);
	text-align: left; overflow: hidden; text-overflow: ellipsis;
}

/* +#16565 — ресайз підсумкових колонок: та сама механіка, що в днів, але змінна НА КОЛОНКУ.
   Без оверрайда (var не задана) fallback'и відтворюють старе поводження (auto + min 5rem);
   після ресайзу трійка стає жорсткою, довге число чесно ріжеться ellipsis'ом. */
.opg-table .opg-n0 { width: var(--opg-w-n0, auto); min-width: var(--opg-w-n0, 5rem); max-width: var(--opg-w-n0, none); }
.opg-table .opg-n1 { width: var(--opg-w-n1, auto); min-width: var(--opg-w-n1, 5rem); max-width: var(--opg-w-n1, none); }
.opg-table .opg-n2 { width: var(--opg-w-n2, auto); min-width: var(--opg-w-n2, 5rem); max-width: var(--opg-w-n2, none); }
.opg-table .opg-n3 { width: var(--opg-w-n3, auto); min-width: var(--opg-w-n3, 5rem); max-width: var(--opg-w-n3, none); }
.opg-table .opg-n4 { width: var(--opg-w-n4, auto); min-width: var(--opg-w-n4, 5rem); max-width: var(--opg-w-n4, none); }
.opg-table td.opg-num { overflow: hidden; text-overflow: ellipsis; }

/* ширина мусить збігатися з .opg-cell нижче, інакше шапка і тіло розійдуться — тепер синхронізація
   механічна: обидва беруть ту саму --opg-w-day. Трійка (а не лише min-width) обов'язкова З ОБОХ боків:
   при table-layout:auto ширина колонки = максимум по th і td, тож звужувати треба їх разом. */
.opg-table .opg-dh {
	width: var(--opg-w-day); min-width: var(--opg-w-day); max-width: var(--opg-w-day);
	font-weight: 600; line-height: 1.1;
}
.opg-table .opg-dh .opg-dow { display: block; font-weight: 400; font-size: 0.75em; color: var(--text-muted, #6b7280); }

/* групи (WBS-вузли) */
.opg-table tr.opg-group td { background: var(--table-header-bg, #f3f4f6); font-weight: 600; }

/* денна клітинка: план (верх, м'який фон) над фактом (низ, редагується).
   ЖОРСТКА ширина: table{width:max-content} інакше переміряє колонку під контент, і поява редактора
   розсовувала б сітку. position:relative — якір для накладеного .opg-input. */
.opg-table .opg-cell {
	padding: 0;
	position: relative;
	/* +Kamala. claude. 2026-07-18. #16041 (зауваження 2) — 3.9em → 4.35em: правий жолоб під маркер
	   відхилення (10px, див. .opg-fact нижче) інакше з'їв би бюджет тексту. Ширину додано РІВНО на
	   жолоб, тож жодне значення, що вміщалось до правки, не почало обрізатись. Це важливо: за даними
	   прода дольова денна величина (Value / днів строку) буває до 7 знаків («1 234,5»), і клітинка
	   без overflow:hidden не обрізає, а РОЗСОВУЄ колонку, ламаючи жорстку сітку.
	   Тримати синхронно з .opg-dh вище — з 19.07 обидва беруть --opg-w-day (ресайз колонок днів). */
	width: var(--opg-w-day); min-width: var(--opg-w-day); max-width: var(--opg-w-day);
}

/* +Kamala. claude. 2026-07-19. #16041 — ручка ресайзу в заголовку дня: тягнеш будь-який день, міняється
   ширина ВСІХ (одна --opg-w-day). th у thead уже position:sticky, тобто positioned — absolute чіпляється
   до нього. Ширина 6px має збігатися з відчуттям цілі: менше — не влучиш, більше — заважає кліку по шапці. */
.opg-table .opg-resizer {
	position: absolute;
	top: 0;
	right: 0;
	width: 6px;
	height: 100%;
	cursor: col-resize;
	user-select: none;
	z-index: 1;
}
.opg-table .opg-resizer:hover { background: #1976d2; opacity: 0.35; }
body.opg-resizing, body.opg-resizing * { cursor: col-resize !important; user-select: none !important; }
.opg-table .opg-plan,
.opg-table .opg-fact {
	position: relative;
	/* +Kamala. claude. 2026-07-18. #16041 (зауваження 2) — правий жолоб під маркер відхилення (▼).
	   Число вирівняне праворуч, а маркер абсолютний у тому ж боксі: при ширині колонки 3.9em коротке
	   значення («1») ставало рівно на трикутник і зливалося з ним. Жолоб даємо ОБОМ половинам, інакше
	   числа плану і факту розійшлися б по правому краю. Ширину колонки збільшено рівно на жолоб
	   (3.9em → 4.35em, див. .opg-cell), тож бюджет тексту НЕ зменшився — інакше значення з 6-7 знаків
	   (за даними прода — 356 робіт) почали б розсовувати колонку. */
	padding: 1px 10px 1px 4px;
	min-height: 1.15rem;
	/* +Kamala. claude. 2026-07-19. #16041 (ширина колонок) — до ресайзу ширина дня була константою,
	   підібраною під найдовше значення, і обрізати було нічого. Тепер колонку можна звузити вручну:
	   без цього довге число («3,258» — заміряно на формі) вилазить у сусідню комірку на кілька px.
	   Ставимо на div, а не на td: overflow на display:table-cell — сіра зона специфікації.
	   Повне значення лишається в tooltip'і комірки (cellTitle). */
	overflow: hidden;
}
.opg-table .opg-plan {
	background: #eef2f7;
	color: var(--text-muted, #6b7280);
	border-bottom: 1px dotted var(--border-color, #d0d3d9);
}
.opg-table .opg-fact { cursor: pointer; }
.opg-locked .opg-table .opg-fact,
.opg-table tr.opg-group .opg-fact { cursor: default; }

/* компактні позначки П/Ф — лише на заповнених значеннях, без приросту висоти рядка */
.opg-table .opg-plan.opg-has::before,
.opg-table .opg-fact.opg-has::before {
	position: absolute;
	left: 3px;
	top: 1px;
	font-size: 0.62rem;
	line-height: 1.15rem;
	opacity: .42;
	font-weight: 600;
	pointer-events: none;
}
.opg-table .opg-plan.opg-has::before { content: 'П'; }
.opg-table .opg-fact.opg-has::before { content: 'Ф'; }

/* hover/focus редагованої клітинки */
.opg-table tr.opg-leaf .opg-fact:hover { background: #e3f2fd; }
.opg-table tr.opg-leaf .opg-fact:focus-visible { outline: 2px solid #1976d2; outline-offset: -2px; }

/* СЕМАНТИКА КОЛЬОРУ (#16041 UX): червоний — ЛИШЕ підтверджене відхилення на минулу/поточну дату;
   стан дублюється маркером (▼) і tooltip'ом, не лише кольором (палітра — у змінних на .opg вгорі). */
.opg-table .opg-fact.opg-dev { background: var(--opg-dev-bg) !important; color: var(--opg-dev-fg); }
.opg-table .opg-fact.opg-ok { background: var(--opg-ok-bg) !important; }
.opg-table .opg-fact.opg-dev::after {
	content: '▼';
	position: absolute;
	/* сидить у правому жолобі (padding-right вище), не наїжджаючи на цифру — #16041, зауваження 2 */
	right: 1px; bottom: 0;
	font-size: 0.5rem;
	line-height: 1;
	opacity: .75;
	pointer-events: none;
}
/* підсумкова колонка «Залишок плану»: нейтральна; червона лише для ЗАВЕРШЕНОГО місяця з недовиконанням */
.opg-table td.opg-num.opg-dev { background: var(--opg-dev-bg) !important; color: var(--opg-dev-fg); }

/* НЕЗБЕРЕЖЕНА правка: синій контур (не конфліктує із заливкою відхилення) */
.opg-table .opg-fact.opg-dirty {
	outline: 2px solid #1976d2;
	outline-offset: -2px;
	font-weight: 600;
}
/* помилка вводу */
.opg-table .opg-cell.opg-err .opg-input { border-color: #c62828; background: #fff5f5; }
.opg .opg-errmsg { color: #c62828; white-space: nowrap; }

/* вихідні — відчутно слабші за відхилення */
.opg-table td.opg-we, .opg-table th.opg-we { background: #fbfaf5; }
.opg-table th.opg-we { color: var(--text-muted, #6b7280); }
/* сьогодні — підсвічена ВСЯ колонка, не лише рамка заголовка */
.opg-table td.opg-today, .opg-table th.opg-today { background: #eaf3fd; }
.opg-table th.opg-today { box-shadow: inset 0 -2px 0 0 #1976d2; }

/* редактор НАКЛАДАЄТЬСЯ на нижню (фактову) половину клітинки: out-of-flow → не впливає на ширину
   колонки, сітка не «стрибає»; план лишається видимим під час вводу */
.opg-table .opg-input {
	position: absolute;
	top: 50%; bottom: 0; left: 0; right: 0;
	width: auto;
	min-width: 0;
	border: 1px solid #1976d2;
	padding: 0 3px;
	font: inherit;
	text-align: right;
	box-sizing: border-box;
	z-index: 2;
}
.opg-table .opg-input:focus { outline: 2px solid #1976d2; outline-offset: -3px; }

.opg-table tr.opg-empty td { text-align: center; color: var(--text-muted, #6b7280); padding: 1rem; }
/* +Kamala. claude. 2026-06-10. #16164 — Payroll readiness checklist (Variant C).
   Кольорове кодування рядків + пом'якшені фони для error/warning.
   Автопідхоплюється A2v10 через /_shell/appstyles (всі CSS у _assets). */

[test-id="Payroll_Readiness"] .rd-ok {
	color: #1f8c3a;
}
[test-id="Payroll_Readiness"] .rd-err {
	color: #c0392b;
	background-color: rgba(231, 76, 60, 0.06);
	border-left: 3px solid #c0392b;
}
[test-id="Payroll_Readiness"] .rd-warn {
	color: #b56500;
	background-color: rgba(241, 196, 15, 0.08);
	border-left: 3px solid #f1c40f;
}

[test-id="Payroll_Readiness"] .rd-err .text-muted,
[test-id="Payroll_Readiness"] .rd-warn .text-muted {
	color: inherit;
	opacity: 0.78;
}

/* Збираємо рядки в більш щільний список (Repeater без проміжків). */
[test-id="Payroll_Readiness"] .grid {
	margin: 0.15rem 0;
	border-radius: 3px;
}
/* +Kamala. claude. 2026-09-13. #17390 — звіт «Контроль нарахувань» [24-КН] (report/payrollcontrol).
   Scoped коренем сторінки .payrollcontrol-report: класи рядків і колонок a2-tree-grid (rowclassprop /
   cssclass колонки) і плитки лічильників. ВИСОТА РЯДКА НЕ ЗМІНЮЄТЬСЯ: грід віртуалізований і міряє
   висоту по першому рядку (tree-grid.js, virtualrows) — жодних padding / border-width на td тут. */

.payrollcontrol-report .pc-filters { margin-bottom: 0.25rem; align-items: flex-start; }
/* #17419 поле <TagsFilter> росте під теги (toolbar.css) — рядок фільтрів стає вищим; підписи й галочки
   тримаємо по верху, щоб не зʼїжджали вниз разом із вищим полем */
.payrollcontrol-report .pc-filters > .control-group > label { align-self: flex-start; line-height: 2.2em; }
.payrollcontrol-report .pc-filters > .checkbox,
.payrollcontrol-report .pc-filters > .btn { margin-top: 0.3rem; }

/* плитки-лічильники: кнопка-фільтр, повторний клік знімає відбір */
.payrollcontrol-report .pc-tiles { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.5rem 0; }
/* у .btn рамки немає зовсім — стиль і ширину лівої межі задаємо тут, колір — класом стану */
.payrollcontrol-report .pc-tiles .btn.pc-tile { border-left: 4px solid transparent; min-width: 6.5rem; }
.payrollcontrol-report .pc-tiles .btn.pc-tile-danger { border-left-color: #d13438; }
.payrollcontrol-report .pc-tiles .btn.pc-tile-warning { border-left-color: #e0a100; }
.payrollcontrol-report .pc-tiles .btn.pc-tile-success { border-left-color: #2e8b57; }
.payrollcontrol-report .pc-tiles .btn.pc-tile-on { background: #e8f0fe; border-color: var(--accent-color, #2563eb); font-weight: 600; }

.payrollcontrol-report .pc-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.25rem; margin-bottom: 0.5rem; }
/* TabBar ButtonGroup платформи тягнеться на всю ширину — у рядку контролів він за вмістом */
.payrollcontrol-report .pc-controls .a2-tab-bar { flex: 0 0 auto; width: auto; }
.payrollcontrol-report .pc-controls .a2-tab-button { padding: 0.3rem 0.9rem; }

/* стан рядка — власне порушення вузла (батьки несуть лише чип стану) */
.payrollcontrol-report .tg-table tr.pc-row-danger td { background: #fdecee; }
.payrollcontrol-report .tg-table tr.pc-row-warn td { background: #fff7e0; }
.payrollcontrol-report .tg-table tr.pc-row-ref td { color: var(--text-muted, #6b7280); }

/* РАЗОМ / УТРИМАНО — фоном (ТЗ §6.4); «Призначені роботи» у вигляді «Від працівника» — сірі, довідкові */
.payrollcontrol-report .tg-table td.pc-col-total,
.payrollcontrol-report .tg-table th.pc-col-total { background: #eef3fb; font-weight: 600; }
.payrollcontrol-report .tg-table td.pc-col-ref,
.payrollcontrol-report .tg-table th.pc-col-ref { color: var(--text-muted, #6b7280); }

/* tag-label поза тулбаром платформа рендерить блоком на всю ширину — у легенді це чипи в один ряд */
.payrollcontrol-report .pc-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.5rem; }
.payrollcontrol-report .pc-legend .tag-label { display: inline-block; }

/* #17396 друк — браузерний (кнопка «Друк» / Ctrl+P), за еталоном objectsummary-report.css. Приховані блоки
   колонок у друк не йдуть за побудовою: їх немає в $Cols, отже й у DOM. Друкуються рядки, розкриті на
   екрані; друк самого дерева — tree-grid.css / tree-grid.js. */
.payrollcontrol-report .pc-print-header { display: none; }

@media print {
    /* Іменована @page, НЕ глобальна: appstyles вантажиться на кожній сторінці, і глобальний @page зробив би
       альбомними всі друки застосунку. Firefox іменованих @page не підтримує — там книжкова. */
    @page payrollcontrol-print {
        size: A4 landscape;
        margin: 8mm;
    }
    .payrollcontrol-report {
        page: payrollcontrol-print;
    }

    .payrollcontrol-report .pc-print-header { display: block; margin-bottom: 4mm; }
    .payrollcontrol-report .pc-print-title { display: block; font-size: 15px; font-weight: 700; margin: 0 0 2mm 0; }
    .payrollcontrol-report .pc-print-filters { display: block; font-size: 10px; line-height: 1.4; }

    /* чром екрана: тулбари, фільтри, плитки, перемикачі, кнопки */
    .payrollcontrol-report .toolbar,
    .payrollcontrol-report .pc-tiles,
    .payrollcontrol-report .pc-controls,
    .payrollcontrol-report button {
        display: none !important;
    }

    /* зняти екранні обмеження висоти/скролу рамки сторінки — інакше в друк лізе лише видима область */
    .payrollcontrol-report .page-content,
    .payrollcontrol-report .a2-sticky-container,
    .payrollcontrol-report .tree-grid {
        overflow: visible !important;
        height: auto !important;
        max-height: none !important;
    }

    /* стан рядка несе колір фону — без нього «Блокує» на папері не відрізнити */
    .payrollcontrol-report .tg-table tr.pc-row-danger td,
    .payrollcontrol-report .tg-table tr.pc-row-warn td {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    .payrollcontrol-report .tag-label {
        color: #1a1a1a !important;
        background: transparent !important;
        border: none !important;
        padding: 0 !important;
        font-weight: 600;
    }
}
/*+Kamala. claude. 2026-07-13. #11363 — межі браузерного друку розрахункових листів.
   Кнопка «Друк» (Command=Print) / Ctrl+P друкують увесь DOM сторінки: тулбар фільтрів,
   шапки вкладок, кнопки «У Telegram» і горизонтальний скрол лізли в друк. Ховаємо весь
   інтерфейс, лишаємо тільки картки. Клас .payslip-report — на кореневому <Page>.
   Іменована @page (не глобальна: глобальний @page протік би полями/орієнтацією на ВСІ друки
   застосунку, appstyles вантажиться на кожній сторінці — пор. report-fit #16312). */
@media print {
    @page payslip-print {
        size: A4 portrait;
        margin: 12mm;
    }
    .payslip-report {
        page: payslip-print;
    }

    /* прибрати весь чром: тулбари (фільтри + місяць/рік), шапки вкладок, кнопки в картці (Telegram) */
    .payslip-report .toolbar,
    .payslip-report .tab-header {
        display: none !important;
    }
    .payslip-report .card .btn {
        display: none !important;
    }

    /* друкувати ВСІ картки, а не лише видиму область: зняти обмеження висоти/скрол контейнерів,
       інакше в друк потрапляє тільки те, що вміщується на екрані, з горизонтальним скролом */
    .payslip-report .page-content,
    .payslip-report .tab-panel,
    .payslip-report .tab-content,
    .payslip-report .tab-item {
        overflow: visible !important;
        height: auto !important;
        max-height: none !important;
    }

    /* картка не розривається між сторінками; екранна тінь у друк не потрібна */
    .payslip-report .card {
        break-inside: avoid;
        box-shadow: none !important;
        border: 1px solid #d0d0d0;
    }

    /* картка вписується у ширину аркуша: на екрані два ряди-гріди мають фіксовані мінімуми
       (28rem+16rem+відступи ≈ 47rem) + порожня 3-тя колонка — це ширше за A4 portrait і права
       колонка «Відпрацьований час» обрізалася. У друк — дробові колонки (minmax(0,fr) ніколи не
       переповнюють), 3-тя порожня колонка прибрана. Ціль — лише два прямі гріди картки (шапка +
       summary), а не вкладений грід статусу/Telegram (він не є прямою дитиною .card). */
    .payslip-report .card > .grid {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) !important;
        column-gap: 1rem !important;
    }
}
/* claude. 2026-09-07. #17289 — спільні обмеження для попапів (.a2-popup — корінь роуту /_popup,
   рендериться всередині .popup-body поповера; в застосунку три: recent/list, plan/basicplan/linkeddocs,
   task/list/comments).

   Висота. Платформа не обмежує .a2-popup узагалі (у її CSS такого класу немає), і довгий список їде
   за нижній край вікна: історія — 20 рядків ≈ 1118px у вікні 991px (замір #17285), коментарі задачі
   app.[Taskn.Load] віддає взагалі без top. Ні власного скролу, ні прокрутки сторінки під попапом нема —
   нижні записи недосяжні. 70vh ≈ 12 рядків, решта докручується всередині попапа.

   Ширина. .popup-body отримує ширину ІНЛАЙНОВИМ стилем (:style="{width}" у компонента popover), тож
   перебити її можна тільки іншою властивістю: max-width працює без !important. 2rem, а не 1rem, —
   запас під смугу прокрутки сторінки (100vw її враховує, а кламп у dropdown-clamp.js міряє clientWidth,
   який ні; без запасу на 375px панель вилазила б за правий край на кілька пікселів). */
.popover-wrapper > .popup-body {
	max-width: calc(100vw - 2rem);
}

.a2-popup {
	max-height: 70vh;
	overflow-y: auto;
	/* Popup Width теж інлайновий (Popup.cs MergeStyle("width")): без цього на вузькому екрані
	   обрізана .popup-body лишалася б із 24rem-вмістом і горизонтальною смугою всередині. */
	max-width: 100%;

	/* Довгий нерозривний токен (склеєні «administrator30.08.2026», e-mail, шлях, номер документа)
	   ширший за обрізаний попап: за специфікацією overflow-y: auto вище доводить і overflow-x до
	   auto, тож замість переносу зʼявлялася друга, горизонтальна смуга, а перший рядок кожного
	   запису візуально обрізався (#17289, попап коментарів задачі на 375px).
	   Саме `anywhere`, а не `break-word`: вміст попапів — DataGrid, тобто <table>, і ширину їй
	   рахує min-content вмісту; `break-word` цей внесок НЕ зменшує, таблиця лишається ширшою за
	   контейнер. `anywhere` зменшує — комірка стискається до попапа й переносить. Обрізати
	   (overflow-x: hidden) не можна: це сховає текст замість того, щоб його показати.
	   Правило працює лише там, де перенос узагалі дозволено: комірці грида перенос вимикають
	   (див. td.wrap нижче), і вмикає його назад Wrap="Wrap" у DataGridColumn. */
	overflow-wrap: anywhere;
}

/* Попап коментарів висить у комірці індекс-списку задач, тож наскрізне правило
   `.doc-index-grid table.data-grid > tbody > tr > td { white-space: nowrap }` (_assets/datagrid.css,
   «колонки індексу в натуральну ширину») дістає і до ВКЛАДЕНОГО в попап грида — його специфічність
   (0,2,4) перебиває платформенний `.wrap` (0,1,0) від Wrap="Wrap". Перенос вимикався, і замість
   нього зʼявлялася горизонтальна смуга .data-grid-container (overflow-x: auto), яка обрізала
   перший рядок кожного коментаря. Повертаємо намір розмітки — селектор на клас-один довший за
   те правило, тож без !important. pre-line, а не normal, — рівно те, що платформа кладе в `.wrap`
   (переноси рядків самого коментаря лишаються). */
.a2-popup table.data-grid > tbody > tr > td.wrap {
	white-space: pre-line;
}
/* Production calendar compact editor */

.pc-editor {
	min-height: 0;
}

.pc-fields {
	padding: 0.45rem 0.65rem;
	background: #f8fafc;
	border-bottom: 1px solid #d8dee8;
}

.pc-toolbar {
	border-bottom: 1px solid #d8dee8;
}

.pc-main {
	min-height: 0;
	padding: 0.45rem 0.65rem 0.65rem;
	align-items: start;
}

.pc-side {
	min-height: 0;
	align-content: start;
	gap: 0.5rem;
}

.pc-memo textarea,
.pc-memo input {
	font-size: 0.85rem;
}

.pc-memo textarea {
	min-height: 4.1rem;
}

/* Month cards: 4 x 3 on wide screens */
.pc-months {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0.42rem;
	align-content: start;
	min-width: 0;
	padding: 0;
}

.pc-months > .list-item {
	min-width: 0;
	padding: 0 !important;
	background: transparent !important;
	border: none !important;
}

@media (max-width: 1600px) {
	.pc-months {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 1280px) {
	.pc-main {
		grid-template-columns: 1fr !important;
	}

	.pc-side {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 900px) {
	.pc-months,
	.pc-side {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 700px) {
	.pc-months,
	.pc-side {
		grid-template-columns: 1fr;
	}
}

.pc-month {
	display: flex;
	flex-direction: column;
	min-width: 0;
	border: 1px solid #d0d7de;
	border-radius: 6px;
	background: #fff;
	overflow: hidden;
}

.pc-month-header {
	padding: 0.22rem 0.5rem;
	font-size: 0.88rem;
	line-height: 1.2;
	font-weight: 600;
	background: #f5f7fa;
	border-bottom: 1px solid #d0d7de;
	color: #1f3a68;
	text-transform: capitalize;
}

.pc-weekdays {
	display: grid;
	grid-template-columns: repeat(7, minmax(0, 1fr));
	gap: 1px;
	padding: 2px 4px 0;
	font-size: 0.66rem;
	line-height: 1.15;
	font-weight: 600;
	color: #6a7480;
	text-transform: uppercase;
	background: #fafbfc;
	border-bottom: 1px solid #eceff3;
}

.pc-weekdays > span {
	min-width: 0;
	text-align: center;
	padding: 1px 0 2px;
}

.pc-wd-sat {
	color: #5b6772;
}

.pc-wd-sun {
	color: #8b1a1a;
}

.pc-days {
	display: grid !important;
	grid-template-columns: repeat(7, minmax(0, 1fr));
	gap: 1px;
	padding: 3px 4px 4px;
	background: transparent;
}

.pc-days > .list-item {
	min-width: 0;
	padding: 0 !important;
	background: transparent !important;
	border: none !important;
}

.pc-cell {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	justify-self: center;
	width: 100%;
	max-width: 2rem;
	height: 1.45rem;
	min-width: 0;
	font-size: 0.75rem;
	line-height: 1;
	border-radius: 4px;
	text-decoration: none !important;
	cursor: pointer;
	user-select: none;
	transition: box-shadow 0.1s ease;
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

.pc-cell,
a.pc-cell,
.pc-cell:hover,
.pc-cell:visited,
.pc-cell:focus {
	text-decoration: none !important;
}

.pc-cell:hover {
	box-shadow: inset 0 0 0 2px #2f6feb;
	outline: none;
}

.pc-cell:focus-visible {
	outline: 2px solid #2f6feb;
	outline-offset: 1px;
}

.pc-blank,
.pc-cell.pc-blank,
a.pc-cell.pc-blank {
	visibility: hidden;
	pointer-events: none;
	color: transparent !important;
	background: transparent !important;
	box-shadow: none !important;
}

/* Day type colors use fill plus underline for scanability */
.pc-work {
	background: #eff5ff;
	color: #14315b;
}

.pc-sat {
	background: #f1f3f5;
	color: #495057;
	border-bottom: 1px solid #adb5bd;
}

.pc-sun {
	background: #ffe3e3;
	color: #842029;
	border-bottom: 2px solid #d6336c;
	font-weight: 600;
}

.pc-holiday {
	background: #d3f9d8;
	color: #2b8a3e;
	border-bottom: 2px solid #2f9e44;
	font-weight: 600;
}

.pc-preholiday {
	background: #fff3bf;
	color: #5c3c00;
	border-bottom: 2px dashed #f59f00;
}

.pc-legend {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.35rem;
	padding: 0.5rem;
	font-size: 0.78rem;
	line-height: 1.2;
	color: #495057;
	background: #fafbfc;
	border: 1px solid #d8dee8;
	border-radius: 6px;
}

.pc-legend-item {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	min-width: 0;
}

.pc-legend-chip {
	display: inline-block;
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	border-radius: 3px;
}

.pc-summary {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	align-items: center;
	font-size: 0.8rem;
}

.pc-summary > .list-item {
	padding: 0 !important;
	background: transparent !important;
	border: none !important;
}

.pc-chip {
	padding: 1px 9px;
	border-radius: 12px;
	background: #f1f3f5;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.pc-chip-work {
	background: #eff5ff;
	color: #14315b;
}

.pc-chip-sat {
	background: #f1f3f5;
	color: #495057;
}

.pc-chip-sun {
	background: #ffe3e3;
	color: #842029;
}

.pc-chip-holiday {
	background: #d3f9d8;
	color: #2b8a3e;
}

.pc-chip-preholiday {
	background: #fff3bf;
	color: #5c3c00;
}

.pc-transfers-header {
	padding: 0.35rem 0.5rem;
	font-size: 0.86rem;
	font-weight: 600;
	color: #1f3a68;
	border: 1px solid #d0d7de;
	border-bottom: none;
	border-radius: 6px 6px 0 0;
	background: #f5f7fa;
}

.pc-transfers {
	min-height: 0;
}

.pc-transfers .data-grid-cell {
	padding: 2px 4px;
	font-size: 0.82rem;
	white-space: nowrap;
}

.pc-transfers-empty {
	padding: 0.8rem;
	text-align: center;
	color: #868e96;
	font-size: 0.82rem;
}

/* DatePicker popup escape: editday/transfer dialogs are narrow modals whose
   default .modal-content/.modal-body have overflow:hidden, which clips the
   datepicker calendar dropdown. Let it overflow but keep buttons visible. */
.modal-content.pc-popup-host {
	overflow: visible;
}
.modal-content.pc-popup-host .modal-body {
	overflow: visible;
}
/* #16064 — структурована картка проєкту: система ширин, секції, header, KPI-плитки.
   #16207 — орієнтація як у картці контрагента: лівий сайдбар реквізитів + праві закладки. */

/* #16943 — рамка картки однакова на всіх закладках: сайдбар і ряд закладок стоять на місці,
   скролиться лише вміст активної закладки.

   Висота. Картка тягнеться на всю висоту сторінки. Це працює, бо платформа дає .page-content
   ряд 1fr у сітці висотою 100% (advance.css, .page.page-grid) — тобто визначену висоту, від якої
   height:100% і рахується. Прокрутка сторінки при цьому просто не виникає: картка не переростає
   свій контейнер, а сайдбар і вміст закладки скроляться кожен окремо.

   Ширина. Кап 1600px знято зовсім (був із #16064). Раніше він діяв на десяти закладках, а на
   «Плані (дерево)» скасовувався через :has(.tg-root) — і права кромка стрибала при перемиканні,
   що й показано стрілками в тікеті. Повертати натомість 1600px усюди не стали: дерево WBS широке
   і отримало б горизонтальний скрол при вільному місці справа. Поля, яким повна ширина шкідлива,
   обмежені самі: .fin-block (56rem) на «Фінансах» і .prm-block (46rem) на «Параметрах». */
.prj-card {
	height: 100%;
}

/* min-height/min-width:0 — щоб діти сітки могли стиснутись нижче розміру свого вмісту: за
   замовчуванням у grid-item обидва мінімуми auto, і він розпирає картку. По вертикалі це
   повертало прокрутку всієї сторінки, по горизонталі — ряд із 12 закладок вимагав 1280px,
   колонка не стискалась, і .page-content їхав убік разом із сайдбаром. */
.prj-card > * {
	min-height: 0;
	min-width: 0;
}

/* Ряд закладок переносимо, а не ховаємо під горизонтальний скрол: у вузькому вікні всі 12
   лишаються видимими, рамка стоїть на місці, а рядок закладок просто стає у два рядки. */
.prj-tabs > .a2-tab-bar {
	flex-wrap: wrap;
}

/* Сайдбар реквізитів довший за екран на невисоких вікнах — власна прокрутка, не загальна. */
.prj-card .prj-side {
	overflow-y: auto;
}

/* Контейнер закладок: ряд 1 — TabBar, ряд 2 — корінь активного Case. Switch у A2v10 власної
   обгортки не рендерить (у Switch.cs вона зʼявляється лише при заданому Height і не отримує
   grid-позиції, тобто налізла б на ряд закладок), а діти Case лягають прямо сюди з grid-row:2.
   Тому «все, що не TabBar» — це рівно вміст активної закладки, і одне правило роздає прокрутку
   всім одинадцятьом. */
.prj-tabs > *:not(.a2-tab-bar) {
	min-height: 0;
	overflow: auto;
	/* align-content:start — інакше рядки закладки, розтягнутої тепер на всю висоту, розповзаються
	   по вільному місцю: на «Фінансах» під заголовком «Терміни» зяяла порожнеча, а плитки KPI
	   висіли внизу екрана. Закладкам із рядком 1* (Рух ГК, Акти, Графік оплат, Файли) це не
	   шкодить: вільне місце там і далі забирає саме той рядок. */
	align-content: start;
	/* grid-auto-rows:max-content — проти накладання таблиці на заголовок над нею. Таблиця всередині
	   grid-item віддає для розрахунку доріжки свою висоту при max-content ШИРИНІ (назви в один
	   рядок), а верстається у звуженій колонці (назви переносяться) і стає вищою. Поки корінь Case
	   ріс за вмістом, різниця не була видна; з визначеною висотою браузер лишає доріжку за першим
	   виміром, а платформенний align-items:flex-end виштовхує надлишок УГОРУ — на «Плані робіт та
	   бюджети» при ширині близько 1440px таблиця з'їжджала поверх заголовка «План робіт» і кнопки
	   «Створити план робіт». Заміряно: доріжка 332px проти реальних 419px. max-content прибиває
	   доріжку до фактичної висоти, і зайве йде у прокрутку закладки, як і має бути.
	   На закладки з явними Rows («Акти», «Графік оплат», «Файли», «Рух ГК» — у кожної свій набір)
	   не впливає: grid-auto-rows керує лише неявними доріжками, а там усі діти вкладаються в
	   оголошений шаблон. Діє тільки на чотири закладки з AutoFlow="Row" без Rows. */
	grid-auto-rows: max-content;
}

/* #16760 — рядок перемикача режимів колонок дерева: сегментовані кнопки + підказка, що саме показує
   поточний режим (сам перемикач — платформенний TabBar Style=ButtonGroup, тут лише розкладка рядка). */
.ppt-modes {
	align-items: center;
	padding: 0.25rem 0.5rem 0;
}
/* перемикач тримаємо по вмісту: у flex-рядку StackPanel він інакше розтягується на всю ширину
   й три кнопки режимів роздуваються на треть екрана кожна */
.ppt-modes .a2-tab-bar {
	flex: 0 0 auto;
	width: auto;
}
.ppt-modes .ppt-hint {
	color: var(--text-muted, #6b7280);
	font-size: 0.8rem;
}

/* ---- Лівий сайдбар основних реквізитів (#16207, за зразком .agent-side) ---- */
.prj-card .prj-side {
	padding-right: 1rem;
	border-right: 1px solid #dfe3e8;
}
/* Бейджі статусу/активності (перегляд) — в один рядок із переносом */
.prj-card .prj-side .prj-side-state {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	margin: 0.1rem 0 0.35rem;
}

/* ---- Класи ширин полів ---- */
/* Короткі значення: дати, суми, код */
.prj-card .control-group.fld-compact { max-width: 13rem; }

/* Read-only вид disabled-полів (показ як значення) — спільний для карток у card.css. */

/* ---- Заголовки секцій: помітніші за звичайні labels ---- */
.prj-card .a2-header {
	font-weight: 600;
	color: #2c3e50;
}
.prj-card .a2-header.sect {
	margin-top: 1.1rem;
	padding-top: 0.4rem;
	border-top: 1px solid #dfe3e8;
}

/* ---- Фінансовий блок: editable + KPI як єдиний модуль.
   #16207 — у власній закладці «Фінанси» обмежуємо ширину, щоб поля/плитки не розтягувались на весь контент ---- */
.prj-card .fin-block {
	margin-top: 0.5rem;
	max-width: 56rem;
	padding: 0.75rem;
	background: #f7f9fb;
	border: 1px solid #e7ebef;
	border-radius: 4px;
}
.prj-card .kpi-grid {
	margin-top: 0.4rem;
}
.prj-card .kpi-grid .a2-state-card {
	min-width: 0;
}
/* Знаки-оператори між плитками собівартості (Факт + Планова = Прогноз) — #15981, фідбек Гульнари */
.prj-card .kpi-grid .kpi-op {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 100%;
	font-size: 1.35rem;
	font-weight: 700;
	color: #6b7884;
	user-select: none;
}
/* Підзаголовок групи KPI (Реалізація/продаж · Собівартість) */
.prj-card .kpi-subhead {
	margin-top: 0.75rem;
	font-size: 0.78rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: #6b7884;
}

/* ---- Вкладка «Параметри» (#16820): кап ширини, щоб короткі налаштування не тяглись
   на всю контентну колонку (~1250px). Кап вужчий за .fin-block: тут немає KPI-плиток ---- */
.prj-card .prm-block {
	max-width: 46rem;
}
/* Поле, видимістю якого керує чекбокс над ним, — з відступом: видно, що воно залежне */
.prj-card .prm-block .prm-dep {
	margin-left: 1.6rem;
}

/* ---- Адаптивність: на вузьких екранах сайдбар і закладки в одну колонку (#16207) ---- */
@media (max-width: 1100px) {
	.prj-card {
		grid-template-columns: 1fr !important;
		/* #16943 — у стеку фіксована рамка шкідлива: сайдбар і вміст стоять один під одним,
		   і на двох окремих прокрутках лишалось би по кілька сантиметрів висоти на кожну.
		   Повертаємо звичайний ріст за вмістом і одну прокрутку сторінки.
		   !important обовʼязковий з тієї ж причини, що й у рядку вище: Height="100%" платформа
		   кладе інлайновим style, а інлайн зі звичайного стилю не перебити. */
		height: auto !important;
	}
	.prj-card .prj-side,
	.prj-tabs > *:not(.a2-tab-bar) {
		overflow: visible;
	}
	/* A2v10 рендерить Grid.Col інлайн-стилем grid-column:1/2 на дітях — самого
	   grid-template-columns:1fr мало, треба зняти закріплення колонки, інакше не стекаються */
	.prj-card > * {
		grid-column: auto !important;
	}
	.prj-card .prj-side {
		border-right: none;
		border-bottom: 1px solid #dfe3e8;
		padding-right: 0;
		padding-bottom: 0.75rem;
	}
}

/* ---- Вкладка «План робіт та бюджети» (#16865): два гриди, що ростуть за вмістом ----
   Плейсхолдер порожнього гриду — це ::before на .data-grid-empty з position:absolute.
   Коли грид росте за вмістом, у порожньому стані .data-grid-body має висоту самої шапки
   (36px), і текст «Нічого не знайдено» опиняється за межами контейнера з overflow:auto,
   тобто порожній грид виглядає зламаним. Мінімальна висота тіла повертає його у видиму зону.
   Тільки для ПОРОЖНЬОГО гриду (:has(> .data-grid-empty)) — інакше вона домалювала б порожню
   смугу під єдиним рядком непорожнього гриду. */
.prj-card .grid-autoheight .data-grid-body:has(> .data-grid-empty) {
	min-height: 8rem;
}
/* +Kamala. claude. 2026-07-12. #16402 — огляд портфеля проєктів: 3 нові режими картки/kanban/рядки.
   Скоуп по кореневому CssClass гілки (.prj-idx-*), кольори статусів — із токенів --status-*
   (info/warning/success + нейтраль для «Не запущено»), у тон TagLabel-стилям картки. */

:root {
    /* нейтраль для статусу «Не запущено» (lightgray) — окремо від -bg токенів */
    --prj-idle: #9aa4b2;
    --prj-idle-bg: #eef0f3;
    --prj-bar-track: #e7ebf1;
    --prj-bar-accent: var(--status-info, #2a6db5);
}

/* ===== Прогрес/стек-бар (спільний для всіх режимів) ===== */
.prj-idx .prj-bar {
    height: 10px;
    border-radius: 6px;
    background: var(--prj-bar-track);
    overflow: hidden;
}
.prj-idx .prj-bar.prj-bar-mini { height: 5px; border-radius: 3px; }
.prj-idx .prj-bar-fill {
    height: 100%;
    border-radius: inherit;
    background: var(--prj-bar-accent);
    min-width: 2px;
    transition: width .2s ease;
}

/* знак балансу ГК */
.prj-idx .prj-neg { color: var(--status-danger, #c0392b); font-weight: 600; }
.prj-idx .prj-pos { color: var(--status-success, #2e9e6b); font-weight: 600; }

/* ===== 1. Картки: компактна структурована плитка (.prj-tile*) ===== */
/* Адаптивна сітка 3 → 2 → 1 (перекриваємо інлайн grid-template-columns від A2v10 Grid). Плитка не вужча ~320px. */
.prj-tiles {
    grid-template-columns: repeat(3, minmax(320px, 1fr)) !important;
    align-items: stretch;
}
@media (max-width: 1500px) {
    .prj-tiles { grid-template-columns: repeat(2, minmax(320px, 1fr)) !important; }
}
@media (max-width: 1000px) {
    .prj-tiles { grid-template-columns: minmax(0, 1fr) !important; }
}

/* Плитка: єдиний нейтральний фон, один border, малий radius, легкий hover; дії притиснуті вниз (рівні плитки в ряду) */
.prj-tiles .prj-tile {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    background: #fff;
    border: 1px solid #dde2e9;
    border-radius: 8px;
    padding: 0.75rem 0.85rem 0.7rem;
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.prj-tiles .prj-tile:hover {
    border-color: #c2ccd8;
    box-shadow: 0 2px 8px rgba(20, 30, 45, 0.08);
}
/* шахматна раскраска фону (щоб сусідні плитки не зливались). На 3 колонки — справжня клітка;
   фарбуємо лише фон, рамку/hover не чіпаємо. */
.prj-tiles .prj-tile:nth-child(odd)  { background: #dce8f8; }
.prj-tiles .prj-tile:nth-child(even) { background: #eceef2; }

/* Header: назва — головний елемент (2 рядки + ellipsis, повна назва в title), статус закріплений справа зверху;
   прибираємо важку підкладку card-header, передбачувана мінімальна висота. */
.prj-tiles .prj-tile > .card-header {
    padding: 0;
    background: none;
    border: none;
    font-weight: inherit;
}
.prj-tiles .prj-tile-head {
    align-items: start;
}
.prj-tiles .prj-tile-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
    font-size: 0.98rem;
    line-height: 1.3;
    color: #1f5da3;
}

/* Метадані: вторинний, менш контрастний текст; компактні рядки з іконкою */
.prj-tiles .prj-tile-meta {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.prj-tiles .prj-tile-sub {
    color: #6b7480;
    font-size: 0.82rem;
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.prj-tiles .prj-tile-sub .ico { margin-right: 0.25rem; }

/* KPI: підпис невелика/приглушена, значення заметне, вирівняне праворуч, без переносу (баланс — .prj-neg/.prj-pos вище) */
.prj-tiles .prj-tile-kpi { align-items: baseline; }
.prj-tiles .prj-tile-kpi-l { color: #6b7480; font-size: 0.8rem; }
.prj-tiles .prj-tile-kpi-v {
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Прогрес: підпис + бар + %; ширина заповнення = $ProgressPct (0..100) */
.prj-tiles .prj-tile-prog { align-items: center; }
.prj-tiles .prj-tile-bar {
    height: 6px;
    border-radius: 3px;
    background: #e7ebf1;
    overflow: hidden;
}
.prj-tiles .prj-tile-bar-fill {
    height: 100%;
    border-radius: 3px;
    background: #2a6db5;
    transition: width 0.2s ease;
}

/* Дії: закріплені внизу плитки незалежно від висоти заголовка/реквізитів, без важкої білої смуги */
.prj-tiles .prj-tile-actions {
    margin-top: auto;
    padding-top: 0.1rem;
    justify-content: start;
}

/* ===== 2. Kanban за статусом ===== */
.prj-idx-kanban .prj-kcol {
    background: #eef1f5;
    border-radius: 8px;
    padding: .55rem;
    align-self: start;
}
/* заголовок колонки — фон/смуга за статусом (у тон lane-header з kanban.css) */
.prj-idx-kanban .prj-kcol > .prj-st-lightgray,
.prj-idx-kanban .prj-kcol > .prj-st-warning,
.prj-idx-kanban .prj-kcol > .prj-st-info,
.prj-idx-kanban .prj-kcol > .prj-st-success {
    padding: .35rem .55rem;
    border-radius: 5px;
    font-weight: 600;
}
.prj-idx-kanban .prj-st-lightgray { background: var(--prj-idle-bg); border-bottom: 2px solid var(--prj-idle); }
.prj-idx-kanban .prj-st-warning   { background: var(--status-warning-bg); border-bottom: 2px solid var(--status-warning); }
.prj-idx-kanban .prj-st-info      { background: var(--status-info-bg); border-bottom: 2px solid var(--status-info); }
.prj-idx-kanban .prj-st-success   { background: var(--status-success-bg); border-bottom: 2px solid var(--status-success); }
.prj-idx-kanban .prj-kcol-count { color: #8b95a3; font-weight: 400; }

/* картка канбану: ліва статусна смуга (A2v10 Card рендериться як div.card, не .a2-card) */
.prj-idx-kanban .prj-kcol .card {
    margin-top: .5rem;
    border-left: 3px solid var(--prj-idle);
}
.prj-idx-kanban .card.prj-st-warning { border-left-color: var(--status-warning); }
.prj-idx-kanban .card.prj-st-info    { border-left-color: var(--status-info); }
.prj-idx-kanban .card.prj-st-success { border-left-color: var(--status-success); }

/* ===== 3. Рядки-смуги ===== */
.prj-idx-rows .prj-row {
    padding: .5rem .75rem;
    border-bottom: 1px solid #eef1f5;
    align-items: center;
}
.prj-idx-rows .prj-row-head {
    font-size: .78em;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #7a8595;
    background: #fafbfc;
    border-bottom: 1px solid #e6ebf1;
}
.prj-idx-rows .prj-row:not(.prj-row-head):hover { background: #f4f8fc; }

/* ===== 4. Портфель (#17143) =====
   Ліва смуга рядка = стан світлофора. Станів ЧОТИРИ: четвертий — «бюджет не заповнено», нейтральний
   сірий. Він не косметика: бюджетний сценарій заповнений у меншості проєктів, і без окремого стану
   екран був би червоним від артефакту даних, а не від збитковості. Кольори — з тих самих --status-*
   токенів, що TagLabel статусів, щоб «червоне» на всіх екранах означало одне й те саме. */
.prj-idx-portfolio .prj-pf-totals {
    padding: .75rem 1rem;
    margin-bottom: .75rem;
    background: #fafbfc;
    border: 1px solid #e6ebf1;
    border-radius: 8px;
    align-items: start;
}
.prj-idx-portfolio .prj-pf-tl {
    font-size: .78em;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #7a8595;
}
.prj-idx-portfolio .prj-pf-tv { font-size: 1.35em; font-weight: 600; }
/* Зноска під підсумковою маржею: вона рахується лише по проєктах із бюджетом */
.prj-idx-portfolio .prj-pf-note { font-size: .76em; line-height: 1.2; }
.prj-idx-portfolio .prj-pf-sev { line-height: 1.35; }
.prj-idx-portfolio .prj-pf-sev span:first-child {
    display: inline-block;
    min-width: 1.6rem;
    font-weight: 600;
    text-align: right;
}
.prj-idx-portfolio .prj-sev-dot-bad  { color: var(--status-danger, #c0392b); }
.prj-idx-portfolio .prj-sev-dot-warn { color: var(--status-warning, #d68910); }
.prj-idx-portfolio .prj-sev-dot-ok   { color: var(--status-success, #27924f); }
.prj-idx-portfolio .prj-sev-dot-none { color: var(--prj-idle); }

.prj-idx-portfolio .prj-pf-row {
    padding: .5rem .75rem;
    border-bottom: 1px solid #eef1f5;
    border-left: 3px solid transparent;
    align-items: center;
}
.prj-idx-portfolio .prj-pf-head {
    font-size: .78em;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #7a8595;
    background: #fafbfc;
    border-bottom: 1px solid #e6ebf1;
}
.prj-idx-portfolio .prj-pf-row:not(.prj-pf-head):hover { background: #f4f8fc; }
.prj-idx-portfolio .prj-pf-margin { font-weight: 600; }
.prj-idx-portfolio .prj-sev-bad  { border-left-color: var(--status-danger, #c0392b); }
.prj-idx-portfolio .prj-sev-warn { border-left-color: var(--status-warning, #d68910); }
.prj-idx-portfolio .prj-sev-ok   { border-left-color: var(--status-success, #27924f); }
.prj-idx-portfolio .prj-sev-none { border-left-color: var(--prj-idle); }
.prj-idx-portfolio .prj-sev-bad  .prj-pf-margin { color: var(--status-danger, #c0392b); }
.prj-idx-portfolio .prj-sev-warn .prj-pf-margin { color: var(--status-warning, #d68910); }
.prj-idx-portfolio .prj-sev-none .prj-pf-margin { color: var(--prj-idle); }
/*+#17145 — друга вісь світлофара: відставання за строками. Власний префікс prj-dsev-, а НЕ
   успадкування від prj-sev-* рядка: колір рядка несе МАРЖУ, і проєкт цілком нормально буває
   прибутковим та зірваним за строками одночасно. Якби відставання фарбувалось каскадом від
   класу рядка, воно просто повторювало б колір маржі й не несло б жодної нової інформації. */
/*+#17326 — третя вісь (індекси освоєння CPI/SPI, префікс prj-isev-) — з тієї ж причини окремий клас,
   але ТА САМА палітра: одна декларація на дві осі, щоб зміна кольору не розвела їх. */
.prj-idx-portfolio .prj-pf-delay { font-weight: 600; }
.prj-idx-portfolio .prj-pf-index { font-weight: 600; white-space: nowrap; }
.prj-idx-portfolio .prj-dsev-bad,  .prj-idx-portfolio .prj-isev-bad  { color: var(--status-danger, #c0392b); }
.prj-idx-portfolio .prj-dsev-warn, .prj-idx-portfolio .prj-isev-warn { color: var(--status-warning, #d68910); }
.prj-idx-portfolio .prj-dsev-ok,   .prj-idx-portfolio .prj-isev-ok   { color: var(--status-success, #27924f); }
.prj-idx-portfolio .prj-dsev-none, .prj-idx-portfolio .prj-isev-none { color: var(--prj-idle); }
/* +Kamala. claude. 2026-06-25. #16233 (фідбек) — список проєктів: будь-яка текстова комірка максимум у 2 рядки.
   Прості текстові колонки клемпляться платформенним LineClamp="2" (він же ставить tooltip із повним значенням).
   Колонка-посилання «Найменування» рендериться як <a> і платформенний LineClamp до неї не застосовується,
   тому клемпимо її окремим правилом (scoped по класу гриду). */

.prj-index-grid table.data-grid > tbody > tr > td > a {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: break-word;
}

/* +Kamala. claude. 2026-08-07. #16798 — плашка статусу «На погодженні» (~100px) вилазила за колонку
   «Статус об'єкта» (Width="6rem" = 90px, ~75px під контент) і малювалась поверх сусіднього «Бюджету»:
   платформенний .tag-label має white-space: nowrap, а грід у table-layout: fixed (column-resize.ts)
   з overflow: visible — оголошена ширина є жорсткою стелею тільки для КОМІРКИ, не для вмісту.
   Правило скоуплене по .prj-index-grid (клас стоїть лише на <DataGrid> режиму «Список»), бо ГЕОМЕТРІЮ
   .tag-label глобально чіпати не можна — заборона #16727 у tag-label.css: ширини колонок у
   act/invoice (#16640) і plan/basicplan (#16698) розраховані під платформенні значення.
   white-space: normal переносить плашку по пробілу в 2 рядки — 0px приросту ширини, бюджет #16653
   (1286px при 1293px на 1440px) не чіпаємо, а висота рядка вже двохрядкова через «Собів./Продаж».
   max-width: 100% — не косметика: без нього shrink-to-fit inline-block дає ширину не менше min-content
   (найдовше слово), і локаль, де слово довше за комірку (fr «d'approbation» ~83px проти ~75px),
   вилізла б знову; з кепом слово переноситься всередині плашки за рахунок глобального
   overflow-wrap: break-word (#16785, site.css). overflow: hidden — страховка на випадок вмісту,
   який не переноситься взагалі.
   Паддінг 6px -> 3px (теж ТІЛЬКИ в цьому гріді): комірка дає плашці 75px, з платформенними 6px по
   боках на текст лишається 63px, а «погодженні» — 68px, тож слово рвалося ПОСЕРЕДИНІ («погоджен/ні»,
   3 рядки). З 3px доступно 69px — слово ціле, плашка у 2 рядки, висота рядка не росте. Звуження
   паддінгу в скоупі безпечне для #16727 у зворотний бік: воно робить плашку ВУЖЧОЮ, ширини колонок
   від цього не переповнюються.
   Локалі з довшим неподільним словом (ru «согласовании» 80px, de «Genehmigung» 80px,
   fr «d'approbation» 80px) у 69px не влазять за жодного розумного шрифту й переносяться всередині
   слова — значення лишається повним і в межах комірки, що і є вимогою тікета. */
.prj-index-grid table.data-grid > tbody > tr > td .tag-label {
    white-space: normal;
    max-width: 100%;
    overflow: hidden;
    padding-left: 3px;
    padding-right: 3px;
}
/* claude. 2026-06-16. План робіт — date-range picker рядка роботи (a2-range-picker). */

.rp-root { display: inline-flex; width: 100%; }

/* «Пілюля» у клітинці */
.rp-pill {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	max-width: 100%;
	padding: 2px 6px;
	border: 1px solid transparent;
	border-radius: 4px;
	cursor: pointer;
	font-size: 13px;
	line-height: 1.4;
	white-space: nowrap;
	color: var(--text-color, #1f2937);
}
.rp-pill:hover { background: var(--hover-bg, #f1f5f9); border-color: var(--border-color, #d1d5db); }
.rp-ico { flex: 0 0 auto; opacity: .6; }
.rp-pill-text { overflow: hidden; text-overflow: ellipsis; }
.rp-pill-text.rp-empty { color: var(--text-muted, #9ca3af); }

.rp-disabled .rp-pill { cursor: default; opacity: .5; }
.rp-disabled .rp-pill:hover { background: transparent; border-color: transparent; }

/* Неповний період (задана лише одна дата) — червоний сигнал: «Провести» блокується валідатором,
   а саме поле сховане у пілюлі. claude 2026-06-17 */
.rp-pill.rp-incomplete {
	color: var(--negative-color, #dc2626);
	border-color: var(--negative-color, #dc2626);
	background: var(--negative-bg, #fef2f2);
}
.rp-pill.rp-incomplete .rp-pill-text,
.rp-pill.rp-incomplete .rp-ico { color: inherit; opacity: 1; }
.rp-pill.rp-incomplete:hover { background: var(--negative-bg, #fee2e2); border-color: var(--negative-color, #dc2626); }
.rp-warn { flex: 0 0 auto; font-size: 12px; line-height: 1; }

/* Дропдаун (position:fixed задається інлайн через popStyle — поза overflow-предками) */
.rp-pop {
	position: fixed;
	z-index: 1000;
	padding: 10px;
	background: var(--card-bg, #fff);
	border: 1px solid var(--border-color, #d1d5db);
	border-radius: 6px;
	box-shadow: 0 6px 24px rgba(0, 0, 0, .16);
	font-size: 13px;
}

/* Два календарі поруч (вибір діапазону «протягуванням») */
.rp-cals { display: flex; gap: 12px; align-items: flex-start; }

/* Підсвітка діапазону у платформеному a2-calendar (td > a з класами active/period-start/period-end).
   Дублюємо тут, бо платформені правила скоуплені під .period-picker, а наш дропдаун — .rp-pop. */
.rp-pop .calendar-pane td > a {
	display: block;
	border-radius: 3px;
	cursor: pointer;
}
.rp-pop .calendar-pane td.active > a { background: var(--range-fill, #dbeafe); border-radius: 0; }
.rp-pop .calendar-pane td.period-start > a,
.rp-pop .calendar-pane td.period-end > a {
	background: var(--primary-color, #2563eb);
	color: #fff;
	border-radius: 4px;
}
.rp-pop .calendar-pane td.active.period-start > a { border-radius: 4px 0 0 4px; }
.rp-pop .calendar-pane td.active.period-end > a { border-radius: 0 4px 4px 0; }
.rp-pop .calendar-pane td.other > a { color: var(--text-muted, #cbd5e1); }
.rp-pop .calendar-pane td > a:hover { background: var(--hover-bg, #eef2f7); }
.rp-pop .calendar-pane td.period-start > a:hover,
.rp-pop .calendar-pane td.period-end > a:hover { background: var(--primary-hover, #1d4ed8); }

/* Пресети */
.rp-presets { display: flex; gap: 6px; margin-top: 10px; }
.rp-preset {
	flex: 1 1 0;
	padding: 4px 6px;
	border: 1px solid var(--border-color, #d1d5db);
	border-radius: 4px;
	background: var(--btn-bg, #f9fafb);
	cursor: pointer;
	font-size: 12px;
}
.rp-preset:hover { background: var(--hover-bg, #eef2f7); }

/* Підвал */
.rp-pop-edit { display: flex; align-items: center; gap: 6px; margin-top: 10px; }
.rp-date-in {
	width: 92px;
	padding: 3px 6px;
	border: 1px solid var(--border-color, #d1d5db);
	border-radius: 4px;
	font-size: 12px;
	text-align: center;
	box-sizing: border-box;
}
.rp-date-in:focus { outline: none; border-color: var(--primary-color, #2563eb); }
.rp-dash { color: var(--text-muted, #6b7280); }

.rp-pop-foot { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.rp-dur { font-size: 12px; color: var(--text-muted, #6b7280); margin-left: 4px; }
.rp-spacer { flex: 1 1 auto; }
.rp-btn {
	padding: 4px 10px;
	border: 1px solid var(--border-color, #d1d5db);
	border-radius: 4px;
	background: var(--btn-bg, #fff);
	cursor: pointer;
	font-size: 12px;
}
.rp-btn:hover { background: var(--hover-bg, #f1f5f9); }
.rp-btn-primary {
	background: var(--primary-color, #2563eb);
	border-color: var(--primary-color, #2563eb);
	color: #fff;
}
.rp-btn-primary:hover { background: var(--primary-hover, #1d4ed8); }
.rp-btn-primary:disabled { opacity: .5; cursor: default; }
/* +Kamala. claude. 2026-08-20. #12007 — власник ресурсу кольором рядка у ТЧ ресурсів плану робіт
   і акта. Клас рядка дають computed'и TResources.$ResMark / TRow_Res.$AllocMark.

   Чому не платформенні мітки 'warning'/'success': їх заливка розрахована на разовий акцент, а не на
   постійний ознаковий колір — жовта йде з alpha 0.07 (rgb 255,252,237 поверх білого), тобто на око
   не відрізняється від білого рядка. Зелена ж іде з 0.25 і виглядає втричі сильніше за жовту, тож
   три стани читались би як два. Власні класи дають однакову вагу обом кольорам і не конфліктують із
   'info', яким у плані позначено рядки, закриті актами (#16045).

   Генпідрядник кольору не має навмисно: це фактичний дефолт нового рядка в обох формах, ~98% рядків
   плану. Фарбувати його означало б залити таблицю суцільним кольором. */

.a2-table tr.res-own-sub > td,
table.data-grid > tbody > tr.res-own-sub > td {
    background-color: #fff4d1;
}

.a2-table tr.res-own-cust > td,
table.data-grid > tbody > tr.res-own-cust > td {
    background-color: #e6f5e6;
}

/* Поля вводу не мають затуляти заливку. У ТЧ акта це вже роблять класи TableRow_cpmsrows*
   (resource-statement.css), а в ТЧ ресурсів плану поля йдуть без класу — і непрозорий білий
   input-group з'їдав близько 78% ширини рядка, лишаючи від кольору самі проміжки між колонками.
   Звужено до пофарбованих рядків, щоб не чіпати вигляд решти таблиці. */
.a2-table tr.res-own-sub > td .input-group,
.a2-table tr.res-own-cust > td .input-group {
    background-color: transparent;
}
/* Ресурсна відомість: вид рядків ТЧ ресурсів (звичайні/основні/закреслені) та
   статус-бейдж «Закрито актами» поряд із назвою. Винесено з main_cpms.css. */

/* ---- Рядки ТЧ ресурсів: поля read-only-вигляду (без рамки/фону) ---- */
.TableRow_cpmsrows.control-group .input-group {
    background-color: transparent;
    border:none;
}

.TableRow_cpmsrowsPrime.control-group .input-group {
    background-color: transparent;
    border: none;
    background-color: #d8ffd880;
}

.TableRow_cpmsrows_line.control-group .input-group {
    text-decoration: line-through;
    background-color: transparent;
    border: none;
}

/* +Kamala. claude. 2026-06-18. #16045 (фідбек) — статус «закрито актами»: лише замок-індикатор поряд із назвою
   (без тексту-бейджа, за зауваженням тестера). Назва — в один рядок з обрізанням «…». */
.res-name-closed {
    display: flex;
    align-items: center;
    gap: .4rem;
    width: 100%;
    /* +Kamala. claude. 2026-08-18. #16964 — стеля ширини блоку назви. Платформа тримає таблиці в
       table-layout:auto, тож ширину колонки диктує вміст: nowrap-назва на 160+ символів давала
       max-content у ~1200px і виштовхувала числові колонки за екран, а обіцяне «…» ніколи не
       спрацьовувало (контейнер завжди ширший за текст). max-width обрізає саме внесок у
       intrinsic-ширину колонки → колонка більше не розпирає таблицю, а .res-name-text отримує
       кінцеву ширину і показує «…»; повне найменування лишається в тултипі (Tip у XAML). */
    max-width: 30rem;
}
/* назва займає весь доступний простір → замок/око притиснуті праворуч (в одну лінію з «...✎» редагованих рядків);
   довге найменування — в один рядок з «…» (повне — у тултипі), без переносу в стовпчик */
.res-name-text {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* замок-індикатор закритого актами рядка — приглушений, не стискається */
.res-lock {
    color: #8a94a6;
    flex: 0 0 auto;
}

/* Закриті актами рядки: мʼяка підсвітка + курсор not-allowed. Розмітку (лінії) тримаємо єдиною з плановими
   рядками — GridLines таблиці дає однакові лінії, тож рамки disabled-полів НЕ гасимо (інакше закриті рядки
   виглядали «без розмітки»). */
.res-table tr.info > td {
    background-color: #f2f5fa;
}
.res-table tr.info td .control-group.disabled input {
    cursor: not-allowed;
}

/* +Kamala. claude. 2026-06-20. #16235 — компактний режим таблиці кошторисних даних: дрібніший шрифт і
   менші відступи комірок, щоб числові колонки (Норма витрат, Ціна, Сума, Ціна/Вартість продажу) вміщалися
   без горизонтальної прокрутки. Скоуп — лише ця таблиця (вкладка «Розподіл» res-table не має).
   +Kamala. claude. 2026-08-19. #16995 — правила не діяли: при StickyHeaders="True" платформа вішає CssClass
   на обгортку div.a2-sticky-container (Table.cs: <table> рендериться з mergeAttrs:false), тож корінь
   селектора — .res-table > table.a2-table, а не table.res-table. Комірки заголовка — теж td: контрол
   <Table> рендерить th ніколи (TableCell.cs). Специфічність (0,2,4) перебиває платформенні (0,1,3)
   з themes/tabbed/Table.less незалежно від порядку завантаження стилів. */
.res-table > table.a2-table {
    font-size: 12px;
}
.res-table > table.a2-table > thead > tr > td,
.res-table > table.a2-table > tbody > tr > td,
.res-table > table.a2-table > tfoot > tr > td {
    padding: 2px 4px;
}
.res-table .control-group input {
    font-size: 12px;
}
/* +Kamala. claude. 2026-06-20. #16235 — РГК: помісячна WBS-сітка-дерево (a2-rgk-sheet) */

.rgk-sheet {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	font-size: 0.85rem;
}

/* верхня панель: слайдер рівнів + навігація вікна місяців + загальний підсумок */
.rgk-sheet .rgk-bar {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.3rem 0.5rem;
	flex: 0 0 auto;
	flex-wrap: wrap;
}
.rgk-sheet .rgk-lvl { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--text-muted, #6b7280); }
.rgk-sheet .rgk-slider { width: 9rem; vertical-align: middle; }
.rgk-sheet .rgk-lvl b { color: var(--text-color, #1f2937); }
.rgk-sheet .rgk-sep { width: 1px; height: 1.2rem; background: var(--border-color, #d0d3d9); }
.rgk-sheet .rgk-navbtn {
	border: 1px solid var(--border-color, #d0d3d9);
	background: var(--table-header-bg, #f3f4f6);
	border-radius: 4px;
	padding: 2px 8px;
	cursor: pointer;
	font-size: 0.8rem;
	white-space: nowrap;
}
.rgk-sheet .rgk-navbtn:hover { background: #e8eaef; }
/* +Kamala. claude. 2026-07-10. #16235 (фідбек) — кнопка «Заповнити з плану» на проведеному документі
   нативно disabled, але без стилю виглядала активною (ще й підсвічувалась на :hover) — користувач
   натискав і нічого не відбувалось. Гасимо вигляд і hover. */
.rgk-sheet .rgk-navbtn:disabled { opacity: .45; cursor: not-allowed; }
.rgk-sheet .rgk-navbtn:disabled:hover { background: var(--table-header-bg, #f3f4f6); }
.rgk-sheet .rgk-range { color: var(--text-muted, #6b7280); white-space: nowrap; }
.rgk-sheet .rgk-grand { margin-left: auto; color: var(--text-muted, #6b7280); white-space: nowrap; }
.rgk-sheet .rgk-grand b { color: var(--text-color, #1f2937); }

.rgk-sheet .rgk-scroll {
	flex: 1 1 auto;
	overflow: auto;
	border: 1px solid var(--border-color, #d0d3d9);
}

.rgk-table {
	border-collapse: separate;
	border-spacing: 0;
	width: max-content;
	min-width: 100%;
}

.rgk-table th,
.rgk-table td {
	border-right: 1px solid var(--border-color, #d0d3d9);
	border-bottom: 1px solid var(--border-color, #d0d3d9);
	padding: 2px 6px;
	text-align: right;
	white-space: nowrap;
	background: #fff;
	box-sizing: border-box;
}

/* липка шапка */
.rgk-table thead th {
	position: sticky;
	top: 0;
	z-index: 4;
	background: var(--table-header-bg, #f3f4f6);
	font-weight: 600;
	text-align: center;
	height: 1.8rem;
}

/* закріплені колонки зліва: Найменування (0), Стаття (26em), ПК (38em), Рахунок (41.5em), Разом (53.5em) —
   підсумок перед місяцями (#16235 фідбек 4, зам.1; #16417 S5 — вставлено ПК + Рахунок) */
.rgk-table .rgk-frz2 { position: sticky; left: 0;     width: 26em; text-align: left; z-index: 3; }
.rgk-table .rgk-frz3 { position: sticky; left: 26em;  width: 12em; text-align: left; z-index: 3; }
.rgk-table .rgk-frzpk { position: sticky; left: 38em;  width: 3.5em; text-align: center; z-index: 3; }
.rgk-table .rgk-frzacc { position: sticky; left: 41.5em; width: 12em; text-align: left; z-index: 3;
	border-right: 2px solid var(--border-color, #c2c7cf); }
.rgk-table .rgk-frzt { position: sticky; left: 53.5em;  width: 7.5em; font-weight: 600; z-index: 3;
	border-right: 2px solid var(--border-color, #c2c7cf); }
.rgk-table thead .rgk-frz2,
.rgk-table thead .rgk-frz3,
.rgk-table thead .rgk-frzpk,
.rgk-table thead .rgk-frzacc,
.rgk-table thead .rgk-frzt { z-index: 6; }

/* рядок проєкту (синій підсумок) */
.rgk-table .rgk-proj td { background: #e8f0fe; font-weight: 600; color: #1a3e72; }
.rgk-table .rgk-proj .rgk-name b { color: #1a3e72; }

/* групи / листи */
.rgk-table tr.rgk-group td { background: #f7f8fa; font-weight: 600; }
.rgk-table tr.rgk-group .rgk-cell.rgk-ro { color: #374151; }
.rgk-table tr.rgk-leaf td { background: #fff; }
.rgk-table .rgk-code { color: var(--text-muted, #9ca3af); margin-right: 0.25rem; }
.rgk-table .rgk-name-text { display: inline-block; }

/* зебра/hover лише для листів */
.rgk-table tbody tr.rgk-leaf:hover td { background: #f6f8fb; }

/* місячні колонки */
.rgk-table .rgk-mh { width: 5.5em; min-width: 5.5em; }
.rgk-table .rgk-cell { width: 5.5em; min-width: 5.5em; cursor: cell; }
.rgk-table .rgk-cell.rgk-ro { cursor: default; }
.rgk-table .rgk-cell.rgk-has { color: var(--text-color, #1f2937); }
.rgk-table .rgk-cell.rgk-active { outline: 2px solid var(--accent-color, #2563eb); outline-offset: -2px; padding: 0; }

.rgk-input {
	width: 100%;
	height: 100%;
	border: none;
	outline: none;
	text-align: right;
	font: inherit;
	padding: 2px 6px;
	box-sizing: border-box;
	background: #fff;
}

/* колонки «Стаття РГК» / «Рахунок» (#16417 S5) — клік для вибору */
.rgk-item.rgk-pick, .rgk-acc.rgk-pick { cursor: pointer; }
.rgk-item.rgk-pick:hover, .rgk-acc.rgk-pick:hover { background: #eef4ff; }
.rgk-item .rgk-item-empty, .rgk-acc .rgk-item-empty { color: var(--text-muted, #9ca3af); font-style: italic; }
.rgk-item .rgk-item-clear, .rgk-acc .rgk-item-clear {
	float: right;
	color: var(--text-muted, #9ca3af);
	cursor: pointer;
	padding: 0 0.2em;
	visibility: hidden;
}
.rgk-table tr:hover .rgk-item-clear { visibility: visible; }
.rgk-item .rgk-item-clear:hover, .rgk-acc .rgk-item-clear:hover { color: var(--danger-color, #dc2626); }
/* чекбокс ПК — форсуємо нативний вигляд. Платформне правило `input[type="checkbox"]:not(.switch)`
   (tabbed.min.css) ховає голий чекбокс: opacity:0; position:absolute; width/height:0 — для нього
   малюється кастомний вид через label. У нас голий input без обгортки, тож повертаємо нативний.
   Селектор з [type] дає специфічність (0,3,1) — перебиває платформний (0,2,1) без !important (#16417). */
.rgk-table input[type="checkbox"].rgk-pk-cb {
	position: static;
	left: auto; top: auto;
	width: 1em; height: 1em;
	margin: 0 auto;
	opacity: 1;
	z-index: auto;
	-webkit-appearance: checkbox;
	appearance: checkbox;
	cursor: pointer;
}
.rgk-table input[type="checkbox"].rgk-pk-cb:disabled { cursor: not-allowed; opacity: .5; }

.rgk-empty td {
	text-align: center;
	color: var(--text-muted, #6b7280);
	padding: 1.5rem;
	font-style: italic;
}

.rgk-locked .rgk-cell { background: #fafbfc; }
.rgk-locked .rgk-proj td { background: #e8f0fe; }
/* Work Schedule grid styles */
.schedule-grid .data-grid-cell {
	padding: 1px 2px;
}

.schedule-grid .data-grid-cell input[type="text"] {
	text-align: center;
	width: 2.5rem;
	min-width: 2.2rem;
	padding: 0 2px;
	border-color: transparent;
}

.schedule-grid .data-grid-cell:hover input[type="text"] {
	border-color: #ccc;
}

.schedule-grid th > div {
	text-align: center;
}

/* Палітра типів днів узгоджена з виробничим календарем (production-calendar.css),
   #16097 п.2 — позначати субота/вихідний/свято/передсвятковий.
   Селектори навмисно специфічні (.schedule-grid td.cell-editable.sc-*),
   щоб перебити платформне `table.data-grid td.cell-editable{background:#fffff8}`
   (0-2-1); інакше заливка типів днів не видна. */

/* Робочий день */
.schedule-grid td.cell-editable.sc-work {
	background-color: #d0ebff;
}

/* Субота */
.schedule-grid td.cell-editable.sc-saturday {
	background-color: #ced4da;
}

/* Вихідний (неділя) / день відпочинку */
.schedule-grid td.cell-editable.sc-weekend {
	background-color: #ffc9c9;
}

/* Свято */
.schedule-grid td.cell-editable.sc-holiday {
	background-color: #b2f2bb;
}

/* Передсвятковий (скорочений) */
.schedule-grid td.cell-editable.sc-preholiday {
	background-color: #ffe066;
}

/* Day beyond last day of month — disabled grey */
.schedule-grid td.sc-disabled {
	background-color: #e9ecef;
}

.schedule-grid td.sc-disabled input[type="text"] {
	pointer-events: none;
	opacity: 0.4;
}

/* +Kamala. claude. 2026-08-01. #16722 (зауваження) — видима підсвітка помилкової комірки циклу змін.
   Платформа ставить класи правильно (td.error + правило з rgba-тінтом), але всередині комірки лежить
   .input-group з ВЛАСНИМ непрозорим білим фоном — він перекриває тінт, і помилка візуально не видно
   (те саме стосувалось колонок Нічні/Вечірні з #16266). Фарбуємо сам редактор, а не тло під ним. */
.cycle-grid td.error .input-group,
.cycle-grid td.error input[type="text"] {
	background-color: #fdecec;
}

.cycle-grid td.error input[type="text"] {
	outline: 1px solid #e08b8b;
}
/* claude. 2026-07-10. #16208. Накопичувальний калькулятор (selection-calc.js): кнопка в шапці +
   панель зі стрічкою. Панель — прямий нащадок body з position:fixed, бо всередині сторінки її ріжуть
   overflow-кліпери DataGrid/TabPanel (#16099, #16235). z-index 50 за довідником шарів у tokens.css:
   вище тулбара (9), нижче модального стека (99/100). Кольори — платформені змінні з фолбеком, як у
   grid-footer.css. */

/* ---- кнопка в шапці ------------------------------------------------------------------------- */

.mdi-header .a2-calc-btn {
	display: inline-flex;
	align-items: center;
	gap: .25rem;
	padding: 0 10px;
	color: inherit;
	cursor: pointer;
}

.mdi-header .a2-calc-btn.active {
	background-color: var(--mdi-menu-hover, #2573a8);
}

.a2-calc-btn .a2-calc-count {
	min-width: 1.1rem;
	padding: 0 .3rem;
	border-radius: .6rem;
	background-color: #fff;
	color: var(--nav900, #1a4a7a);
	font-size: .7rem;
	font-weight: 700;
	line-height: 1.1rem;
	text-align: center;
}

/* ---- панель -------------------------------------------------------------------------------- */

.a2-calc {
	display: none;
	position: fixed;
	top: 3rem;
	right: .75rem;
	z-index: 50;
	width: 17rem;
	overflow: hidden;
	border: 1px solid var(--border-color, #dfe3e8);
	border-radius: 6px;
	background-color: var(--main-bg-color, #fff);
	box-shadow: 0 4px 18px rgba(0, 0, 0, .18);
	font-size: .85rem;
}

.a2-calc.open {
	display: block;
}

.a2-calc-disp {
	padding: .5rem .75rem;
	border-bottom: 1px solid var(--border-color, #dfe3e8);
	background-color: var(--table-header-bg, #f5f7f9);
	text-align: right;
}

.a2-calc-disp small {
	display: block;
	color: var(--text-muted, #6b7785);
	font-size: .68rem;
	letter-spacing: .04em;
	text-transform: uppercase;
}

.a2-calc-total {
	font-size: 1.35rem;
	font-variant-numeric: tabular-nums;
}

/* ---- стрічка ------------------------------------------------------------------------------- */

.a2-calc-tape {
	max-height: 13rem;
	overflow-y: auto;
}

.a2-calc-empty {
	padding: 1rem .75rem;
	color: var(--text-muted, #6b7785);
	line-height: 1.5;
	text-align: center;
}

.a2-calc-row {
	display: flex;
	align-items: center;
	gap: .5rem;
	padding: .25rem .5rem .25rem .75rem;
	border-bottom: 1px solid var(--border-color, #dfe3e8);
}

.a2-calc-sign {
	width: .7rem;
	color: var(--status-success, #2e7d32);
	font-weight: 700;
}

.a2-calc-row.op-minus .a2-calc-sign {
	color: var(--status-danger, #c62828);
}

.a2-calc-row.op-mul .a2-calc-sign,
.a2-calc-row.op-div .a2-calc-sign {
	color: var(--text-link, #2b6ca3);
}

.a2-calc-val {
	flex: 1;
	font-variant-numeric: tabular-nums;
	text-align: right;
}

.a2-calc-src {
	max-width: 6rem;
	overflow: hidden;
	color: var(--text-muted, #6b7785);
	font-size: .72rem;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.a2-calc-del {
	padding: 0 .15rem;
	border: 0;
	background: none;
	color: var(--text-muted, #6b7785);
	cursor: pointer;
	line-height: 1;
}

.a2-calc-del:hover {
	color: var(--status-danger, #c62828);
}

/* ---- ввід і дії ---------------------------------------------------------------------------- */

.a2-calc-entry,
.a2-calc-acts {
	display: flex;
	gap: .35rem;
	padding: .5rem;
}

.a2-calc-entry {
	border-top: 1px solid var(--border-color, #dfe3e8);
}

.a2-calc-acts {
	padding-top: 0;
}

.a2-calc-acts button {
	flex: 1;
}

.a2-calc-manual {
	flex: 1;
	min-width: 0;
	padding: .25rem .4rem;
	border: 1px solid var(--border-color, #dfe3e8);
	border-radius: 4px;
	font-variant-numeric: tabular-nums;
	text-align: right;
}

/* чотири кнопки операцій — рівні квадратики, щоб не з'їдали ширину поля вводу */
.a2-calc-op {
	flex: 0 0 auto;
	width: 1.7rem;
	padding: .25rem 0 !important;
	font-weight: 700;
}

.a2-calc button {
	padding: .25rem .5rem;
	border: 1px solid var(--border-color, #dfe3e8);
	border-radius: 4px;
	background-color: var(--main-bg-color, #fff);
	cursor: pointer;
	white-space: nowrap;
}

.a2-calc button:hover {
	border-color: var(--text-link, #2b6ca3);
	color: var(--text-link, #2b6ca3);
}

.a2-calc-copy {
	border-color: var(--text-link, #2b6ca3) !important;
	background-color: var(--text-link, #2b6ca3) !important;
	color: #fff !important;
}

.a2-calc-hint {
	padding: .35rem .75rem;
	border-top: 1px solid var(--border-color, #dfe3e8);
	background-color: var(--table-header-bg, #f5f7f9);
	color: var(--text-muted, #6b7785);
	font-size: .7rem;
}

/* ---- режим накопичення --------------------------------------------------------------------- */

/* Клас a2-calc-hot вішає JS на наведенні — лише на комірки, значення яких справді число. */
body.a2-calc-armed td.a2-calc-hot {
	background-color: #fff8e1;
	box-shadow: inset 0 0 0 1px #e5a800;
	cursor: copy;
}

td.a2-calc-taken {
	background-color: #fff8e1;
	box-shadow: inset 0 0 0 1px #e5a800;
}

/* Комірки-редактори: поле вводу має власний фон і перекрило б підсвітку td. У режимі накопичення
   фокус у поле не потрапляє (mousedown скасовано), тож курсор теж має бути «копіювати», не «текст». */
body.a2-calc-armed td.a2-calc-hot input,
body.a2-calc-armed td.a2-calc-hot textarea,
td.a2-calc-taken input,
td.a2-calc-taken textarea {
	background-color: transparent;
}

body.a2-calc-armed td.a2-calc-hot input,
body.a2-calc-armed td.a2-calc-hot textarea {
	cursor: copy;
}
/* Sheet-звіти (sticky-шапка/підвал, заморожені колонки «report-freeze», блок «Підсумки плану»).
   Винесено з main_cpms.css під час рефакторингу _assets. */

/* Sticky headers for Sheet tables */
/*+Kamala. claude. 2026-05-31. #11096 — вертикальний скрол + липка шапка для всіх sheet-звітів.
   Контейнер прокрутки — <Block CssClass="sheet-page sticky-sheet-container"> з <table class="sheet">.
   Було: правила цілили в неіснуючий клас .sheet-page-wrapper (Block віддає .sheet-page), тож
   обмеження висоти не діяло і звіт не скролився по вертикалі. Тепер ціль — .sheet-page.sticky-sheet-container
   (вища специфічність, щоб перебити платформні .sheet-page/.block; appstyles вантажиться після tabbed.css).
   Контейнер отримує власну висоту + overflow → шапка thead (нижче) лишається липкою при прокрутці. */
.sticky-sheet-container,
.sheet-page.sticky-sheet-container {
    overflow: auto;
    /* 100% від page-content (його висоту задає page-grid) → контейнер займає всю доступну
       область вкладки і скролиться сам. Без магічних calc(100vh - Npx), що не вгадують висоту
       шапки/тулбару й лишають порожнечу або, навпаки, виштовхують контейнер за екран. */
    max-height: 100%;
    /*+Kamala. claude. 2026-06-15. #11096 — фікс: випадаючі меню/селектори тулбару «западали»
       під контент звіту. Sticky-комірки sheet (thead z-index:7, заморожені колонки .frz z-index:8)
       НЕ замкнені у власному stacking-context (ні .page-content, ні цей контейнер його не створювали),
       тож спливали в КОРЕНЕВИЙ stacking і перекривали попапи тулбару, замкнені на z-index:2
       (.page.page-grid > .page-toolbar з toolbar.css #16134). isolation:isolate робить контейнер
       stacking-context → весь sheet-z залишається всередині й більше не конкурує з тулбаром.
       Не чіпає sticky-позиціонування ані внутрішній порядок sheet (thead над тілом, frozen-колонки). */
    isolation: isolate;
    /*-Kamala. claude. 2026-06-15. #11096 */
}
/*-Kamala. claude. 2026-05-31. #11096 */

.sticky-sheet-container table.sheet thead {
    position: sticky;
    top: 0;
    z-index: 7;
}

.sticky-sheet-container table.sheet thead tr {
    background-color: var(--background, white);
}

.sticky-sheet-container table.sheet thead tr.row-header {
    background-color: #e7e7e7;
}

.sticky-sheet-container table.sheet tfoot {
    position: sticky;
    bottom: 0;
    z-index: 7;
}

.sticky-sheet-container table.sheet tfoot tr {
    background-color: var(--background, white);
}

/*+Kamala. claude. 2026-05-31. #11096 — колонка «Найменування» (SheetCell CssClass="sheet-name-cell"):
   довгі назви робіт у дереві переносилися на багато рядків і роздували висоту. Тепер назва — в один
   рядок з трикрапкою, повна назва — у нативному тултипі (Hyperlink Tip="{Bind Name}" → :title).
   table-layout:fixed тримає ширину колонки (звужена до 15rem), тож обрізання не розпирає таблицю.
   max-width:0 + min-width:0 у flex-контейнері дозволяють посиланню стиснутись і показати ellipsis;
   теги-бейджі (Finish/Partly) лишаються видимими (flex-shrink:0). */
.sticky-sheet-container .sheet-name-cell {
    max-width: 0;
}
.sticky-sheet-container .sheet-name-cell .stack-panel.horizontal {
    min-width: 0;
    max-width: 100%;
    flex-wrap: nowrap;
}
.sticky-sheet-container .sheet-name-cell a.a2-hyperlink {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sticky-sheet-container .sheet-name-cell .stack-panel.horizontal > :not(a.a2-hyperlink) {
    flex: 0 0 auto;
    /*+Kamala. claude. 2026-06-17. #16152 — тег стану робіт прижато до правого краю колонки
       «Найменування» (окремий «стовпчик» статусів) + візуальний відступ від назви.
       margin-left:auto з'їдає вільний простір flex-рядка → бейдж завжди праворуч. */
    margin-left: auto;
    margin-right: 0.25rem;
}
/*-Kamala. claude. 2026-05-31. #11096 */

/*+Kamala. claude. 2026-06-17. #16152 — фільтр «Стан робіт» рівним стовпчиком у Taskpad:
   inline-чекбокси переносилися у 2 рядки; flex-column + gap дають по одному в рядку, ліворуч. */
.work-status-filter {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    margin-bottom: 0.25rem;
}

/*+Kamala. claude. 2026-05-31. #11096 — покращення звіту «Дані проєкту: Ієрархія» (report-freeze).
   table-layout:fixed обовʼязковий для коректних left-офсетів закріплених колонок (ширини colgroup
   стають авторитетними). Числові колонки задані достатньо широкими (8rem) + nowrap, щоб великі суми
   не обрізались. Закріплення зліва: лише «Найменування» (frz-name, left:0) — колонка № при скролі
   ховається під назвою, решта колонок прокручуються. Спроба закріпити 4 колонки давала криву межу.
   ВАЖЛИВО: при table-layout:fixed із width:auto Chrome НЕ дотримується <col style="width"> і
   розподіляє колонки за вмістом (у режимі «всі колонки» Найменування стискалось до ~113px замість
   35rem). Тому таблиці потрібна явна ширина: width:max-content прирівнює її до суми заданих ширин
   колонок (горизонтальний скрол + колонки точно за SheetColumn.Width), а min-width:100% розтягує на
   весь контейнер у режимах із малою к-стю колонок (зайве місце розподіляється пропорційно). */
.report-freeze table.sheet {
    table-layout: fixed;
    width: max-content;
    min-width: 100%;
}
.report-freeze table.sheet td,
.report-freeze table.sheet th {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* комірка назви лишається з власним ellipsis-механізмом (sheet-name-cell вище).
   table.sheet у селекторі — щоб перебити overflow:hidden із правила td/th вище (вища специфічність). */
.report-freeze table.sheet .sheet-name-cell {
    overflow: visible;
}

/* --- Закріплена колонка «Найменування» + гутер № (горизонтальний скрол).
   Sticky на одній НЕ-першій комірці не клампиться у цій таблиці — тому закріплюємо й № (2rem),
   це лише гутер з трикутником згортання, а не дата-колонка. Офсети = кумулятивні Width:
   № left:0 (2rem), Найменування left:2rem. --- */
.report-freeze table.sheet .frz {
    position: sticky;
    z-index: 6;
    background-color: var(--background, #fff);
}
.report-freeze table.sheet .frz-0    { left: 0; }
.report-freeze table.sheet .frz-name {
    left: 2rem;
    /* права грань закріплення — тонкий розділювач */
    box-shadow: 1px 0 0 0 var(--border, #d0d0d0);
}
/* кут «шапка × закріплення» має бути поверх усього */
.report-freeze table.sheet thead .frz {
    z-index: 8;
}
/* закріплені комірки наслідують підсвітку рядків (групи/заголовки) */
.report-freeze table.sheet thead tr.row-header .frz {
    background-color: #e7e7e7;
}
.report-freeze table.sheet tbody tr.group .frz {
    background-color: #eef4ee;
}

/* --- Виділення батьківських/групових рядків --- */
.report-freeze table.sheet tbody tr.group {
    background-color: #eef4ee;
}
.report-freeze table.sheet tbody tr.group .a2-hyperlink {
    font-weight: 600;
}
/* рядок-заголовок звіту (назва + проєкт) */
.report-freeze table.sheet tbody tr.row-title {
    font-weight: 600;
}

/* --- Приглушені нулі для числових колонок --- */
.report-freeze table.sheet td[data-type="currency"] {
    font-variant-numeric: tabular-nums;
}

/* --- Маржа: відʼємна — червона (NegativeRed=True → клас .negative-red від платформи),
   додатна — спокійний бірюзовий. Нуль лишається стандартним приглушеним (HideZeros не вмикаємо
   для маржі, бо 0 маржа теж інформативна). --- */
.report-freeze table.sheet td.col-margin {
    font-weight: 600;
    color: #117a65;
}
.report-freeze table.sheet td.col-margin.negative-red {
    color: #c0392b;
}

/* --- Згруповані фільтри у правій панелі --- */
.filter-group-caption {
    display: block;
    font-weight: 600;
    color: #5a6b7b;
    margin-top: .25rem;
}
/*+Kamala. claude. 2026-09-25. #17638 — підпис фільтра всередині StackPanel (компонент DeletionMarkFilter):
   платформний .a2-label має align-self:center і у flex-колонці стає по центру, а не зліва, як
   сусідні підписи прямо в taskpad-body. */
.stack-panel > .filter-group-caption {
    align-self: stretch;
}
/*-Kamala. claude. 2026-05-31. #11096 */

/*+Kamala. claude. 2026-07-10. #16312 — друк широкого sheet-звіту «Список робіт» (21 колонка).
   Іменована @page (CSS `page`) прив'язує альбомну орієнтацію ЛИШЕ до цього блоку — глобальний
   @page зробив би альбомними всі друки застосунку (appstyles вантажиться на кожній сторінці).
   Ширини колонок задані інлайном у <col style="width:30rem"> → перебиваємо !important, інакше
   таблиця лишається 1756px. За заміром min-content 21 колонки при 8px = 917px < 1062px
   (A4 landscape мінус поля 8mm), тож width:100% вкладається без обрізання; довгі назви переносяться,
   суми — nowrap. Firefox не підтримує іменовані @page → друкує у книжковій, орієнтацію обирає користувач. */
@media print {
    @page report-fit {
        size: A4 landscape;
        margin: 8mm;
    }
    .report-print-fit {
        page: report-fit;
        overflow: visible !important;
        max-height: none !important;
    }
    .report-print-fit table.sheet {
        width: 100% !important;
        table-layout: auto;
        font-size: 8px;
    }
    .report-print-fit table.sheet col {
        width: auto !important;
    }
    .report-print-fit table.sheet th,
    .report-print-fit table.sheet td {
        padding: 0 2px !important;
    }
    .report-print-fit table.sheet td[data-type="currency"] {
        white-space: nowrap !important;
    }
}
/*-Kamala. claude. 2026-07-10. #16312 */

/*+Kamala. claude. 2026-06-15. #15872 — єдиний блок «Підсумки плану» в тулбарі дерева робіт */
.plan-totals-bar {
    display: inline-flex;
    align-items: stretch;
    margin-left: .75rem;
    border: 1px solid #d4dce6;
    border-radius: 6px;
    background: #fff;
}
/* кнопка лишається кнопкою, але без власної рамки — її роль грає рамка блоку.
   НЕ використовуємо overflow:hidden на блоці — воно обрізає випадайку «Підсумки плану». */
.plan-totals-bar > .btn {
    border: none;
    border-right: 1px solid #d4dce6;
    border-radius: 5px 0 0 5px;
    margin: 0;
}
.plan-totals-bar .pt-chip {
    display: inline-flex;
    align-items: baseline;
    gap: .4rem;
    padding: 0 .85rem;
    white-space: nowrap;
    border-left: 1px solid #e7ecf3;
}
.plan-totals-bar .pt-chip:first-of-type {
    border-left: none;
}
.plan-totals-bar .pt-cap {
    font-size: 12px;
    color: #8a96a8;
}
.plan-totals-bar .pt-val {
    font-weight: 600;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}
/* собівартість — приглушена (другорядна), продаж/маржа — головні */
.plan-totals-bar .pt-muted .pt-cap,
.plan-totals-bar .pt-muted .pt-val {
    font-weight: 500;
    color: #8a96a8;
}
.plan-totals-bar .pt-empty {
    font-size: 13px;
    font-style: italic;
    color: #aab4c2;
}
/*-Kamala. claude. 2026-06-15. #15872 */
/* Навігаційні :root-змінні та базовий шрифт винесено до tokens.css. */

/* Wider sidebar navigation panel */
.mdi-navbar {
  min-width: 90px;
}

.mdi-navbar .bar li {
  max-width: 82px;
}

/* Larger font for sidebar menu labels */
.mdi-navbar .bar li .menu-text {
  font-size: 12px;
  line-height: 1.15;
}

/* Larger font for form labels */
.control-group label {
  font-size: 95%;
}

/* Larger font for small text elements */
.small {
  font-size: 0.9em;
}

table.data-grid td.small {
  font-size: 0.9rem;
}

/* Read-only info field — dashed border + light background */
.readonly-info textarea,
.readonly-info input[type="text"] {
  background-color: #f5f8fc !important;
  border: 1px dashed #b0c4de !important;
  color: #555 !important;
}

/* Menu customization indent levels */
.menu-indent-1 {
  padding-left: 24px;
}

.menu-indent-2 {
  padding-left: 48px;
}

.menu-indent-3 {
  padding-left: 72px;
}

/* Editable cells in data grids — subtle highlight */
table.data-grid td.cell-editable {
  background-color: #fffff8;
}

table.data-grid tr:hover td.cell-editable {
  background-color: #fffde6;
}

/* Homepage taskpad - add top padding to prevent overlap with collapse button */
.homepage .taskpad .taskpad-body {
  padding-top: 0.5rem;
}

.homepage .taskpad .taskpad-body h1:first-child {
  margin-top: 0;
  padding-left: 2rem;
}

/* +Kamala. claude. 2026-06-15. #16212 — спільний фікс: колапс-хендл
   (.taskpad-collapse-handle, position:absolute у лівому-верхньому куті) накладався на
   перший контрол будь-якої РОЗГОРНУТОЇ сторінкової панелі відборів (мітку обрізав
   шеврон). Резервуємо місце зверху для всіх .page-taskpad (аналогічно фіксу .homepage). */
.page-taskpad.taskpad.expanded > .taskpad-body {
  padding-top: 1.75rem;
}

/* Лента оновлень має скролитися всередині таскпада, а не тягнути висоту всієї
   хом-сторінки. Платформений клас .taskpad.overflow ставить body на overflow:visible
   (advance.css), через що довгий changelog скролив сторінку цілком. Повертаємо
   власний скрол для стрічки (специфічність 0-4-0 перебиває платформну 0-3-0). */
.homepage .taskpad.overflow .taskpad-body {
  overflow-y: auto;
  height: 100%;
  min-height: 0;
}

/* +claude. 2026-08-09. Спільний фікс розкладки сторінок з ЛІВИМ Taskpad (Position="Left").
   Платформа (tabbed.css) розрахована на taskpad СПРАВА: .page-grid { grid-template-columns: 1fr auto },
   а для .taskpad-left лише перекидає grid-column, не міняючи розміри треків. Наслідки — два:
   1) панель потрапляє у широку 1fr-колонку, а контент тулиться в auto;
   2) .page-taskpad { grid-row: 1 / span 2 } опиняється в ОДНІЙ клітинці з .page-toolbar
      { grid-column: 1; grid-row: 1 } — тулбар і панель накладаються (видно лише на сторінках з
      <Page.Toolbar>, але правило безпечне і без нього: порожній auto-рядок 1 має нульову висоту).
   Правила page-agnostic (структурні класи платформи, без :has()-скоупу під конкретну сторінку) —
   як і .page.page-grid.taskpad-left > .a2-grid-footer у grid-footer.css. Платформу не форкаємо.
   Історія: #16147 (файловий менеджер) + #16868 (прибуткова накладна) мали цей обхід кожен у своєму
   per-page CSS з різним скоупом; консолідовано сюди. ── */
.page.page-grid.taskpad-left {
  /* auto — ширину колонки задає сам a2-taskpad інлайн-стилем (initial-width розгорнутої, нічого
     згорнутої), тож одне правило обслуговує обидва стани. */
  grid-template-columns: auto minmax(0, 1fr);
}
.page.page-grid.taskpad-left > .page-toolbar {
  grid-column: 1 / -1;
}
.page.page-grid.taskpad-left > .page-taskpad {
  /* Рядок 2, до контенту (тулбар лишається сам у рядку 1). min-height:0 обов'язковий: grid-item за
     замовчуванням має min-height:auto, і висока панель роздула б 1fr-рядок під СВІЙ вміст — сторінка
     виросла б за вікно. З нулем рядок тримає висоту вікна, а зайве бере на себе скрол .taskpad-body. */
  grid-row: 2;
  min-height: 0;
}
.page.page-grid.taskpad-left > .page-taskpad > .taskpad-body {
  /* Платформа вішає на панель клас .overflow незалежно від XAML-властивості Overflow, а
     `.taskpad.overflow .taskpad-body { overflow: visible }` знімає штатний скрол тіла — без цього
     правила довга панель просто вилазить за нижній край сторінки (пор. .homepage вище).
     По горизонталі — hidden: вертикальна смуга з'їдає ~15px, і поля на повну ширину панелі
     породжували б ДРУГИЙ, горизонтальний скрол. */
  overflow-y: auto;
  overflow-x: hidden;
  height: 100%;
  min-height: 0;
}
.page.page-grid.taskpad-left > .page-pager {
  /* Платформа кладе пейджер у колонку 1 — під панель. Контент у колонці 2, тож і пейджер туди. */
  grid-column: 2;
}

/* +claude. 2026-07-16. #16428 (фідбек) — рядок «підпис … значення» у панелях сальдо грошових
   списків (лейаут як у 1С МБ). Готового спільного класу в проєкті немає: .fm-count і .pt-cap
   заскоуплені під файлменеджер і смугу підсумків плану. */
.msaldo-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
  padding: 2px 0;
}

.msaldo-cap {
  font-size: 12px;
  color: #8a96a8;
}

.msaldo-val {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.msaldo-row.msaldo-total {
  border-top: 1px solid #eaeef3;
  margin-top: 3px;
  padding-top: 5px;
}

/* номер рахунку/каси під заголовком «Відомість за <дата>» */
.msaldo-acct {
  font-size: 11.5px;
  color: #8a96a8;
  word-break: break-all;
  padding-bottom: 3px;
}

.msaldo-date {
  margin-left: .35rem;
}

/*+claude. 2026-09-06. #17281 — заголовок панелі сальдо в один рядок. Платформний .panel-header має
   фіксовану height:30px при overflow:visible, тож заголовок, що не вліз у ширину таскпада (20rem),
   переноситься і НАЇЖДЖАЄ на вміст панелі — на реєстрі авансових звітів це накрило ім'я співробітника
   (знято скріншотом). Текст заголовка вкорочено, а це правило страхує від рецидиву в довшій локалі. */
.msaldo-panel .panel-header {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Домашня сторінка. #17225: колаж home.png і .bigheader прибрано — сторінка тепер набір
   віджетів (_assets/home.css); картинка компанії повернеться окремим віджетом (#17227). ---- */
.homepage {
    background-color: #f3f4f6;
}

.side-bar {
    background-color:azure;
}

/* +Kamala. claude. 2026-06-18. #16224 — пейджер index-сторінок без верхньої межі/відступу (для
   pager-only сторінок, що ще мають <Page.Pager>). Колишнє правило .page-size-bottom прибране
   2026-06-30: плашку «На сторінку» замінив самодостатній Vue-компонент a2-grid-footer
   (_assets/grid-footer.css), що сам рендерить пейджер+розмір. */
.page.page-grid > .page-pager {
  border-top: none;
  padding-top: 0;
}

/* #16380. Кнопка «Історія» у шапці navpane — це <Popover> (.popover-wrapper), а не <Button>:
   платформа рендерить його display:block з іконкою, притиснутою до верху 40px-блока, тож іконка
   стоїть на ~10px вище за сусідні кнопки (робот/зірка/дзвінок). Центруємо по вертикалі, як кнопки. */
.mdi-header .partial-block .popover-wrapper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;   /* дорівнює .btn-icon у шапці (tabbed.css) — інакше іконка зажата між сусідами */
  height: 40px;
  vertical-align: top;
}

/* #16380. Іконка Popover рендериться синім «link»-кольором — приводимо до білого, як сусідні
   кнопки шапки (.mdi-header color:white), + прибираємо hint-акцент при ховері. */
.mdi-header .partial-block .popover-wrapper .po-ico {
  color: white;
}
.mdi-header .partial-block .popover-wrapper:hover .po-ico {
  color: var(--nav-accent);
}

/* #16437: FieldSet без явної Orientation рендериться нативним <fieldset class="field-set vertical"> —
   novaera.css стилізує лише .field-set.center (space-around флекс), тож дефолтна (vertical)
   орієнтація лишалась з UA-стилем браузера (groove-рамка) і виглядала «приклеєною по помилці»,
   випадаючи зі стилю картки. Приводимо до тієї ж флет-рамки, що й .code-border (novaera.css).
   Свідомо ГЛОБАЛЬНО (не scoped) — фікс для УСІХ FieldSet проєкту, а не лише картки рахунку. */
fieldset.field-set.vertical {
  margin: 0;
  padding: 0.6rem 0.8rem 0.8rem 0.8rem;
  border: 1px solid var(--neutral300);
  border-radius: 4px;
}
fieldset.field-set.vertical > legend {
  padding: 0 0.4rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--neutral500);
}

/* #16439 — форма рахунку (/act/invoice/edit), лейаут «Документ + сайдбар»: вкладок немає, ліва колонка =
   реквізити + позиції одним потоком, правий липкий rail = статус, підсумки, історія погодження.
   Усе scoped під .inv-layout / .inv-rail / .inv-pos-grid, щоб не зачіпати інші форми (tree-grid,
   empty-panel, Static — контроли загальні). */

/* #16968 — cap 1720px знято: ліва панель реквізитів (330px) і rail (300px) з'їдають ~640px, і під
   cap'ом дереву позицій лишалось би ~1120px замість потрібних ~1320px (та сама тіснота, через яку
   #16439 колись винесло позиції на окрему вкладку). Без cap'а на 1920+ місця вистачає; на вужчих
   екранах лишається горизонтальний скрол у самому дереві — свідома ціна закріпленої шапки.
   height:100% — тіло форми тримає висоту вікна, а скролять уже середина й rail кожен у себе. */
.inv-layout {
  height: 100%;
  /* Платформний .grid ставить align-items:flex-end — у рядку висотою у вікно вміст притискався б до
     низу (спіймано в браузері: тулбар позицій висів унизу сторінки). */
  align-items: stretch;
}
/* Обидві зони — В ОДНОМУ рядку. Rows="1*" самого по собі МАЛО: rail стоїть у розмітці перед Switch'ем
   і має grid-column:2, тож авто-розкладка (курсор не ходить назад) кидала середину з grid-column:1 у
   НАСТУПНИЙ рядок — сітка мовчки ставала на два рядки, а середина з'їжджала під rail. */
.inv-layout > * { grid-row: 1; }

/* #16968 тримав тут два правила-схлопувача:
       .inv-head .grid     { grid-template-columns: 1fr !important; }
       .inv-head .grid > * { grid-column: 1 !important; }
   Панель реквізитів (23rem) успадкувала розмітку ШИРОКОЇ форми — сітки з фіксованими треками
   (`Columns="Auto, 150px, 130px, 110px, Auto, 1*"`, сумарно за 390px), і схлопувач не давав їм
   розсунути панель. #17505 прибрав їх обидва РАЗОМ із причиною: у самій розмітці панелі фіксованих
   треків більше немає (реквізити — стовпчик, дві пари — чесні `Columns="1fr,1fr"`, як у п'яти
   сестринських форм з таким самим лівим Taskpad: materials/goodsreceipt, stocksale, stocktransfer,
   stockwriteoff, supplierreturn — жодна з них схлопувача не має і не потребувала).
   Заразом пішла й прихована ціна схлопування: A2v10 рендерить Grid.Gap ОДНИМ шорткатом `grid-gap`
   (Xaml/Layouts/Grid.cs), тобто row-gap і column-gap відразу, — тож міжколонкові 0.75rem/1.25rem з
   розмітки після схлопування працювали як МІЖРЯДКОВІ й роздували панель (заміряно 64px).
   Разом із схлопувачем прибрано `.inv-head .tag-label { justify-self: start }`: бейдж проведення
   тепер не grid-item (він у flex-рядку `.inv-ident-row` нижче), а поза grid'ом justify-self мертвий. */

/* #17505 — ідентифікація документа: заголовок, а під ним № і бейдж проведення В ОДНОМУ рядку.
   Раніше це був Grid, і схлопувач вище розкладав чотири елементи у чотири рядки — 126px на самий
   лише заголовок. Прийом і вигляд — як у панелі прибуткової накладної (.gr-title/.gr-num/.gr-side-state
   у goodsreceipt.css), але в один рядок: там № і бейджі стоять двома окремими рядками. */
.inv-head .inv-ident-title {
  margin: 0;
  /* 1.15rem і темний колір — щоб назва документа важила БІЛЬШЕ за номер у сусідньому полі вводу
     (UI-рев'ю #17505: на 1.05rem сірий заголовок читався блідішим за чорне «00002»).
     Колір той самий, що в заголовка панелі прибуткової накладної (.gr-title у goodsreceipt.css). */
  font-size: 1.15rem;
  font-weight: 600;
  color: #2c3e50;
}
.inv-head .inv-ident-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.25rem;
}
/* Номер — частина заголовка документа, а не поле вводу серед інших: ширина за вмістом, решта рядка
   лишається бейджу. field-sizing — Chrome 123+; фолбек у старих браузерах — дефолтна ширина input. */
.inv-head .inv-ident-row .control-group {
  flex: 0 1 auto;
  margin: 0;
}
.inv-head .inv-ident-row input {
  field-sizing: content;
  width: auto;
  min-width: 5rem;
  max-width: 100%;
  text-overflow: ellipsis;
}

/* #17505 — підписи полів і рамки груп у панелі дрібніші за форменні. Панель — не повноширинна форма:
   13 реквізитів × зайві 4px підпису плюс три рамки FieldSet з легендами коштували ~85px висоти,
   тобто півтора реквізити під обрізом на рівному місці. Підпис лишається підписом поля (0.78rem,
   звичайний регістр) — це не заголовок секції, як uppercase-.inv-railh у rail'і нижче. */
.inv-head .control-group > label {
  font-size: 0.78rem;
  margin-bottom: 1px;
}
.inv-head fieldset.field-set {
  padding: 6px 10px 10px;
}
.inv-head fieldset.field-set > legend {
  font-size: 0.8rem;
}

/* #16442 (п.1): перемикач напрямку — SEGMENTED CONTROL із двох кнопок. Кнопки, а не radio, бо radio
   має власний DOM-стан (v-model) і перемикався ще до підтвердження; тут «активність» — лише клас,
   який рахується з Invoice.Direction (див. askDirection у edit.template.ts).
   Режим документа має читатись з першого погляду, тож активний сегмент — суцільна заливка акцентом,
   неактивний — пласка кнопка на тлі групи. `display:inline-flex` у .inv-dir нічого не звужує: це
   flex-item у колонковому .inv-dir-col, а такий елемент блокіфікується і тягнеться на всю ширину
   панелі. Так і лишаємо — два сегменти на всю ширину читаються як перемикач режиму документа; щоб
   група стала за вмістом, знадобився б `align-items: flex-start` на .inv-dir-col. */
.inv-dir-col {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.inv-dir {
  display: inline-flex;
  align-items: stretch;
  padding: 2px;
  gap: 2px;
  border: 1px solid var(--neutral300, #cbd2da);
  border-radius: 7px;
  background: var(--neutral100, #f6f8fa);
}
/* .btn — платформний клас Button; гасимо його рамку/фон, геометрію задає група вище */
.inv-dir .btn.inv-seg {
  margin: 0;
  border: none;
  background: none;
  border-radius: 5px;
  padding: 0.3rem 1.1rem;
  font-weight: 600;
  color: var(--neutral500, #6b7280);
  box-shadow: none;
}
.inv-dir .btn.inv-seg:hover:not(.is-active) { background: var(--neutral200, #e5e7eb); }
.inv-dir .btn.inv-seg.is-active {
  background: var(--accent-color, #2563eb);
  color: #fff;
}
.inv-dir-hint {
  font-size: 0.85rem;
  color: var(--neutral500, #6b7280);
}
/* п.4: дія поруч із поясненням про незаповнену картку — лінк у той самий приглушений рядок */
.inv-dir-hint > a { margin-left: 0.4rem; }

/* п.6: «Очистити все» — ВТОРИННА небезпечна дія: не суцільний червоний (він перетягував увагу з
   основних дій панелі), а обведення. Небезпека читається, домінування — ні. */
.btn.inv-danger-2 {
  color: var(--red600, #c0392b);
  border-color: var(--red300, #e6a99f);
}
.btn.inv-danger-2:hover { background: var(--red50, #fdf0ee); }

/* grid-item за замовчуванням має min-width:auto (= min-content) → широкий вміст лівої колонки роздував би
   трек «1*» до вмісту й виштовхував rail за правий край в'юпорта (сайдбар стає недосяжним — спіймано в
   браузері, коли позиції ще жили в цій же колонці). min-width:0 дозволяє треку стиснутись до контейнера. */
.inv-layout > *, .inv-links-panel > * { min-width: 0; min-height: 0; }
/* Те саме всередині вкладок: у tree-grid'а є свій горизонтальний скрол (.tg-scroll), але grid-item за
   замовчуванням має min-width:auto, тож .tg-root роздувався до ширини таблиці й НАЇЖДЖАВ на rail
   (виміряно: таблиця виходила на 117px під сайдбар). З нулем зайву ширину бере на себе скрол грида. */
.inv-pos-grid > *, .inv-goods-grid > * { min-width: 0; }

/* Rail: липне до скролера сторінки. align-self:start обов'язковий — розтягнутий на всю висоту рядка
   grid-елемент нікуди не «липне» (sticky не має куди рухатись у власному контейнері).
   #16442 (п.8): візуальна вага панелі зменшена — вона супровідна, а не рівноправна з документом:
   без власного фону й рамки (лишилась одна розділова лінія зліва), менші відступи. Картка підсумків
   усередині лишається обведеною — це єдиний блок rail'а зі значеннями, які читають. */
.inv-rail {
  /* #16968: rail живе у клітинці повної висоти (тіло — Rows="1*" + height:100%), тож sticky йому вже
     нема куди «липнути» — натомість власний скрол, інакше довга історія погодження розсуває сторінку. */
  align-self: stretch;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0 0 0 1rem;
  border-left: 1px solid var(--neutral200, #e5e7eb);
}
.inv-railh {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--neutral500, #6b7280);
  margin-top: 0.35rem;
}
.inv-rail > .inv-railh:first-child { margin-top: 0; }

/* Підсумки (Разом / Сума-грн / ПДВ / Всього) — картка «значень», не полів вводу: Static рендерить
   <div.input-group.static><span.static-input>, тож гасимо рамку групи й лишаємо саме число. */
.inv-totals {
  border: 1px solid var(--neutral200, #e5e7eb);
  border-radius: 6px;
  background: var(--table-bg, #fff);
  padding: 0.5rem 0.7rem;
}
.inv-tot-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.15rem 0;
  font-size: 0.85rem;
  color: var(--neutral500, #6b7280);
}
.inv-tot-row .input-group {
  border: none;
  background: none;
  padding: 0;
  min-height: 0;
}
.inv-tot-row .static-input {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--neutral800, #1f2937);
}
.inv-tot-grand {
  border-top: 1px solid var(--neutral200, #e5e7eb);
  margin-top: 0.3rem;
  padding-top: 0.45rem;
}
.inv-tot-grand .static-input { font-size: 1.15rem; }

/* Історія погодження — компактний таймлайн (замість вкладки з DataGrid). */
.inv-timeline { display: flex; flex-direction: column; gap: 0.6rem; }
.inv-tl-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 0.5rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--neutral300, #cbd2da);
  font-size: 0.8rem;
}
/* #16570 — рядок заявки в rail'і рахунку має третю, вузьку колонку під дію «відв'язати».
   Рядки, що спанять (.inv-tl-date / .inv-tl-cmt), уже стоять на grid-column: 1 / -1 → правити не треба. */
.inv-tl-item.inv-tl-act { grid-template-columns: 1fr auto auto; align-items: center; }
.inv-tl-status { font-weight: 600; color: var(--neutral800, #1f2937); }
.inv-tl-user { text-align: right; color: var(--neutral500, #6b7280); }
.inv-tl-date { grid-column: 1 / -1; font-size: 0.72rem; color: var(--neutral400, #9ca3af); }
.inv-tl-cmt { grid-column: 1 / -1; color: var(--neutral500, #6b7280); font-style: italic; }

/* Порожня історія (#16442 п.8) — нормальний стан нового документа, а не порожнеча, яку треба
   підсвічувати рамкою й іконкою на пів-rail'а: один приглушений рядок. */
.inv-tl-empty {
  font-size: 0.8rem;
  font-style: italic;
  color: var(--neutral400, #9ca3af);
  padding: 0.15rem 0 0.35rem;
}

/* #17148 — те саме приглушене пояснення, що й .inv-tl-empty (ставиться ДРУГИМ класом поряд з ним),
   плюс три оверрайди під випадне меню: відступи як у .dropdown-item, обмежена ширина і явний
   перенос — причина блокування це ціле речення, а не підпис пункту. */
.inv-menu-note {
  padding: 0.25em 1em 0.5em;
  max-width: 22rem;
  white-space: normal;
}

/* Позиції (a2-tree-grid): дерево заповнює доступну ширину (без порожнечі справа — table-layout:fixed
   з min-width:100% розподіляє надлишок пропорційно, найширші Позиція/Примітка тягнуться найбільше). */
.inv-pos-grid .tg-table { min-width: 100%; }
/* Примітка (7-й стовпець buildTreeCols) — повний текст переносом, а не обрізанням ellipsis.
   ponytail: індекс вшито; при зміні порядку колонок у $TreeCols — оновити (після злиття
   «Розподіл»+«Звірка» у «Стан розподілу» (#16442 п.6) стовпців стало на один менше). */
.inv-pos-grid .tg-table td:nth-child(7) { white-space: normal; }
/* Сильніше виділення позиції-батька від дочірніх рядків (лівий акцент поверх сірого фону tg-group). */
.inv-pos-grid .tg-table tr.tg-group td:first-child { box-shadow: inset 3px 0 0 var(--accent-color, #2563eb); }

/* #16442 (п.6): сума ПОЗИЦІЇ входить у підсумок, сума дочірнього рядка — це ЧАСТИНА тієї ж суми
   (розбивка по WBS / розподіл на проєкти), а не додаткові гроші. Однаково набрані числа читались як
   «і те, і те додається» → підсумок здавався вдвічі меншим за суму стовпця. Тому сума позиції —
   звичайна й контрастна, а сума дитини — приглушена й у дужках (::before/::after, бо число рендерить
   спільний компонент). Дужки — універсальний знак «частина цілого», без нових колонок і пояснень.
   ponytail: індекс стовпця «Сума» (5) вшито — при зміні порядку колонок у $TreeCols оновити. */
.inv-pos-grid .tg-table tr.tg-group td:nth-child(5) { font-weight: 600; }
.inv-pos-grid .tg-table tr.tg-leaf td:nth-child(5) {
  color: var(--neutral500, #6b7280);
  font-style: italic;
}
.inv-pos-grid .tg-table tr.tg-leaf td:nth-child(5)::before { content: '('; }
.inv-pos-grid .tg-table tr.tg-leaf td:nth-child(5)::after { content: ')'; }

/* п.5: підсумок під деревом — Σ ПОЗИЦІЙ (дочірні рядки не додаються, див. $Total).
   #16680: .doc-tab-total — той самий підсумок під ТЧ вкладки будь-якого документа (перший споживач —
   materials/avansreport, чотири вкладки). Клас загальний за поведінкою, тож замість копії правил
   просто розширено селектор; invoice-специфічне ІМʼЯ лишається для самого рахунку. */
.inv-pos-total,
.doc-tab-total {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 0.4rem;
  padding: 0.25rem 0.6rem;
  border-top: 1px solid var(--neutral200, #e5e7eb);
  font-size: 0.9rem;
  color: var(--neutral500, #6b7280);
}
.inv-pos-total .input-group,
.doc-tab-total .input-group { border: none; background: none; padding: 0; min-height: 0; }
.inv-pos-total .static-input,
.doc-tab-total .static-input {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--neutral800, #1f2937);
}

/* #17267 — підзаголовок секції ВНУТРІШНЬОГО блоку вкладки. Привід: у «Додатково» авансового звіту
   під підсумком .doc-tab-total стоїть ще й read-only PropertyGrid службових реквізитів, і без
   відбивки він читався як випадково відрендерена розмітка (зауваження ui-review, зміряний зазор
   ≈7px тим самим шрифтом). Клас загальний за поведінкою — «підпис секції всередині вкладки», —
   тож лежить поруч із .doc-tab-total, а не в модулі документа. */
.doc-tab-subhead {
  margin-top: 0.9rem;
  padding: 0 0.6rem 0.25rem;
  border-bottom: 1px solid var(--neutral200, #e5e7eb);
  font-size: 0.85rem;
  color: var(--neutral500, #6b7280);
}

/* #17071 — другий рядок шапки панелі прив'язки («Прив'язано: сума · к-сть»). Модифікатор ПОВЕРХ
   .inv-pos-total, а не власний блок: сам .inv-pos-total ділиться з .doc-tab-total і з підвалом вкладки
   «Позиції», правити його не можна. Прибираємо лише верхню лінію — інакше два однакових блоки поспіль
   малюють подвійну риску між рядками, які читаються як одна шапка. */
.inv-pos-total.inv-link-linked {
  border-top: none;
  padding-top: 0;
}

/* #17073 — панель зв'язків під ТЧ «Товари» (див. edit.view.xaml). Висота — частка вьюпорта, грід позицій
   прокручується всередині (min-height:0 — у правилі .inv-layout > * вище). */
.inv-links-panel {
  height: clamp(12rem, 38vh, 24rem);
  border-top: 2px solid var(--neutral200, #e5e7eb);
  padding-top: 0.5rem;
}
/* низький екран (ноутбук 1366×768 мінус хром браузера): на 38vh ТЧ товарів лишався ОДИН рядок (смоук) */
@media (max-height: 760px) {
  .inv-links-panel { height: 30vh; min-height: 11rem; }
}

/* #16588 — товарна ТЧ рахунку («Товари / Послуги»): 13 колонок у вьюпорт не влазять. Платформений
   .data-grid-container має overflow-x:hidden, тож без цього блоку table-layout:auto просто СТИСКАВ усі
   колонки (задані Width лише міняли пропорції стиснення): «Повна назва» різалась посеред слова, «Склад»
   не показував назву цілком. Той самий приём, що для індекс-списків (.cat-index-grid/.doc-index-grid у
   _assets/datagrid.css): натуральна ширина в один рядок + горизонтальний скрол САМОЇ таблиці. */
.inv-goods-grid .data-grid-container { overflow-x: auto; }
.inv-goods-grid table.data-grid > thead > tr > th,
.inv-goods-grid table.data-grid > tbody > tr > td,
.pay-rows-grid table.data-grid > thead > tr > th,
.pay-rows-grid table.data-grid > tbody > tr > td { white-space: nowrap; }
/* #17073: панель зв'язків лежить УСЕРЕДИНІ .inv-goods-grid і успадкувала б nowrap — назви позицій
   переносимо, як було в діалозі; шапка панелі — щільна й темніша за звичайний підпис секції */
.inv-links-panel table.data-grid > tbody > tr > td { white-space: normal; }
.inv-links-panel .doc-tab-subhead {
  margin-top: 0;
  border-bottom: none;
  font-weight: 600;
  color: var(--neutral800, #1f2937);
}
.inv-links-panel .inv-pos-total { padding-top: 0; padding-bottom: 0.15rem; }

/* #17509 — ТЧ платежу (money/payment/edit, Money_RowsGrid) ділить з .inv-goods-grid правило nowrap вище;
   скрол по X дає сам FixedHeader (платформа ставить overflow:auto на .data-grid-container.fixed-header),
   ширину колонок — MinWidth у розмітці, висоту кліпера — ланцюг повної висоти в XAML. Вирівнювання
   числових th під FixedHeader — у datagrid.css поряд із .settlements-grid.
   Панель RowDetails (класифікатори + слід розподілу) — звичайний td того самого tbody, і nowrap її
   склеїв би; повертаємо перенос (та сама пастка, що #17073 у .inv-links-panel). Те саме для таблиць
   ItemsPanel у випадайках селекторів — вони рендеряться інлайн у комірці й успадкували б nowrap
   (власний Wrap="NoWrap" колонок панелі при цьому діє, як і раніше). */
/* Ланка ланцюга висоти, якої з XAML не дістати: .tab-panel.full-page — CSS-grid, і її рядок контенту
   (1fr з автомінімумом auto) ріс під вміст — з розкритими деталями .tab-content ставав 860px у панелі
   на 360px, і скролилась уся панель разом із шапкою гріда (ui-review, 1366×768). minmax(0,1fr) тримає
   .tab-content у висоті панелі, і скрол лишається в тілі гріда. */
.tab-panel.full-page.pay-tabs { grid-template-rows: auto minmax(0, 1fr); }
.pay-rows-grid table.data-grid > tbody > tr.row-details > td,
.pay-rows-grid .selector-pane table.data-grid > tbody > tr > td { white-space: normal; }

/* Вузький екран: rail з колонки — під документ, звичайним потоком. !important — і сітку, і позицію rail
   A2v10 рендерить ІНЛАЙН-стилями (grid-template-columns у Xaml/Layouts/Grid.cs; grid-column: 2 з
   Grid.Col="2"), інакше медіа-правило не перебило б. Одного grid-template-columns МАЛО: інлайновий
   grid-column:2 лишає rail у другій (неявній) колонці — тому явно повертаємо його в першу. */
@media (max-width: 1100px) {
  /* #16968: разом із колонками треба скинути й інлайнові grid-template-rows:1fr та height:100% —
     інакше rail і середина опиняються в ОДНОМУ рядку висотою у вікно й накладаються. */
  .inv-layout {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto auto !important;
    height: auto !important;
  }
  .inv-layout > * { grid-row: auto; }
  .inv-rail {
    grid-column: 1 !important;
    position: static;
    overflow-y: visible;
  }
}

/* #11180 (фідбек 3) — картка «Переміщення ДС»: Selector.ShowClear не підтримує {Bind} на платформі
   (a2-selector clearVisible() не враховує disabled), тому на заблокованому проведеному документі іконку
   «×» ховаємо CSS-класом (transfer-locked-selector — обираємо через TS $LockedClass) замість реактивного
   пропу. Клас скопований лише на цій формі, глобально на інші Selector не впливає.
   !important обов'язковий: платформне tabbed.css `.control-group .input-group > a { display: inline-block; }`
   специфічніше (2 класи + елемент) за наш `.transfer-locked-selector .selector-clear` (2 класи) і без
   !important переважує його в каскаді незалежно від порядку підключення файлів. */
.transfer-locked-selector .selector-clear { display: none !important; }

/* Командна панель картки документа: платформний .toolbar задає лише row-gap, кнопки стоять впритул
   («Провести та закрити»|«Провести» читались як одна кнопка). Додаємо горизонтальний проміжок. */
.toolbar.doc-toolbar { column-gap: 6px; }

/* #11180 (UX-рефакторинг 2026-07-22) — картка «Переміщення ДС» (/money/transfer/edit): сценарій
   «джерело → отримувач». Усе scoped під .transfer-form, глобальні контроли не зачіпаємо.
   Специфічність 3 класи (.transfer-form .x > .y) свідомо ВИЩА за платформні 2-класові правила
   (.control-group .input-group), інакше довелось би тягнути !important. */

/* Розумна максимальна ширина, притиснута до лівого краю (як решта карток документів): поля не
   розтягуються на все вікно, але й не «плавають» посередині. */
.transfer-form { max-width: 64rem; margin: 0; }
/* grid-item за замовчуванням має min-width:auto (= min-content) → довга назва рахунку роздувала б трек
   і давала горизонтальний скрол замість стиснення колонки. */
.transfer-form .tr-dir > *,
.transfer-form .tr-fin > * { min-width: 0; }

/* Підписи стоять ЗЛІВА окремою колонкою сітки, тож власний нижній відступ контрола зайвий —
   вертикальний ритм задає row-gap сітки (інакше рядки «поле + залишок» розповзаються). */
.transfer-form .tr-dir .control-group,
.transfer-form .tr-fin .control-group { margin-bottom: 0; }

/* Підпис секції («Звідки» / «Куди» / «Сума та курс») — легкий, без рамки FieldSet:
   рамки навколо двох сусідніх блоків читались як окремі таблиці, а не як два боки однієї операції. */
.transfer-form .tr-sect {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--neutral700);
  margin-bottom: 0.6rem;
}
/* Роздільник перед фінансовим блоком — межа на самому підписі, без окремого елемента в розмітці. */
.transfer-form .tr-sep {
  border-top: 1px solid var(--neutral300);
  padding-top: 0.9rem;
  margin-top: 0.5rem;
}
/* Обов'язковість — зірочка на ПІДПИСІ (у самих контролів лишається Required=True для валідації). */
.transfer-form .tr-req::after { content: " *"; color: var(--danger-base); }

/* Залишок — ВТОРИННИЙ рядок свого поля: менший кегль, приглушений колір, від'ємний верхній відступ
   підтягує його впритул під селектор. */
.transfer-form .tr-bal {
  align-items: baseline;
  margin: -0.35rem 0 0 0;
  font-size: 0.82rem;
  color: var(--neutral700);
}
.transfer-form .tr-bal .control-group { margin-bottom: 0; }
.transfer-form .tr-bal .input-group.static { line-height: inherit; }
/* Число + код валюти — власний flex-бокс: перенос рядка МІЖ ними неможливий за побудовою. */
.transfer-form .tr-bal-val { align-items: baseline; flex: 0 0 auto; white-space: nowrap; }

/* Сума / курс / база. Код валюти приклеєний до поля правою «пігулкою» — єдина рамка на двох елементах.
   align-self:start на колонках обов'язковий: розтягнутий на висоту рядка flex-бокс із align-items:flex-end
   опускав би «Суму» нижче за сусідній «Курс» (підписи полів переставали стояти в один рядок). */
.transfer-form .tr-fin > * { align-self: start; }
.transfer-form .tr-amount { align-items: flex-end; height: fit-content; }
.transfer-form .tr-amount > .control-group { margin-bottom: 0; }
/* Поле займає всю ширину колонки, «пігулка» валюти лишається приклеєною праворуч: Static сам по собі
   стискається до ширини тексту, через що сума в базовій валюті виглядала обрізаним віконцем. */
.transfer-form .tr-amount > .control-group:first-child { flex: 1 1 auto; min-width: 0; }
.transfer-form .tr-amount > .control-group:first-child > .input-group {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.transfer-form .tr-cur > .input-group {
  border: 1px solid var(--neutral400);
  border-left: none;
  border-radius: 0 4px 4px 0;
  padding: 0 0.6rem;
  /* поки валюта невідома (новий документ) «пігулка» лишається порожньою — фіксована мінімальна
     ширина не дає їй схлопнутись у смужку, що читалась би як дефект рендера */
  min-width: 3rem;
  justify-content: center;
}
/* Порожня «пігулка» (валюта ще не визначена) отримує прочерк: пуста заливка читалась як обломаний
   контрол. Символ — у CSS, а не в моделі: це стан «немає значення», а не текст для перекладу. */
.transfer-form .tr-cur .static-input:empty::after {
  content: "—";
  color: var(--neutral500);
  background-color: var(--neutral100);
  color: var(--neutral800);
  font-weight: 600;
}
/* «Сума» — головне поле блоку. */
.transfer-form .tr-main > .input-group input { font-size: 1.1rem; font-weight: 600; }
/* Обчислюване read-only значення відрізняється від полів вводу заливкою. */
.transfer-form .tr-ro > .input-group { background-color: var(--neutral100); }
/* Довідковий рядок (напрямок курсу) — той самий вторинний стиль, що й залишки. */
.transfer-form .tr-hint {
  margin-top: -0.35rem;
  font-size: 0.82rem;
  color: var(--neutral700);
}

/* Вузький екран: блоки напрямку і фінансові поля складаються в колонку.
   !important — сітку A2v10 рендерить ІНЛАЙН-стилем (Grid.cs), інакше медіа-правило не перебило б;
   інлайновий grid-column з Grid.Col лишає елементи у своїх колонках, тому скидаємо і його. */
@media (max-width: 900px) {
  .transfer-form .tr-dir,
  .transfer-form .tr-fin { grid-template-columns: 1fr !important; }
  .transfer-form .tr-dir > *,
  .transfer-form .tr-fin > * { grid-column: 1 !important; }
}

/* #16499 (фідбек власника) — представлення документа окремим рядком над формою (як у 1С-макеті ПКО):
   заголовок MDI-вкладки обрізається до «Надходження в...» і на кількох відкритих документах не
   інформативний. Платформний .a2-header має color:#999 і h3-розмір, через що рядок губиться на тлі
   форми — піднімаємо його до повноцінного заголовка картки. Клас навішується явно (CssClass),
   тож інші .a2-header у застосунку не зачеплені. */
.a2-header.doc-title {
  color: #22303f;
  font-size: 1.35rem;
  margin-bottom: 0.6rem;
}

/* #16549 — вкладки картки документа (TabPanel FullPage, CssClass="doc-tabs"): знімаємо overflow з
   УСІХ трьох рівнів панелі. Випадайка Selector у нижніх рядках ТЧ малюється всередині комірки
   (portal у платформі немає), тож її ріже будь-який предок зі скролом. Ланцюжок кліперів на картці
   документа: .data-grid-container (лікується CssClass="DataGrid_overflow", #16099) -> .tab-item ->
   .tab-panel.full-page. Знято всі: скрол лишається на .page-content, який ЛЕЖИТЬ НИЖЧЕ панелі й
   тому її не обрізає, а сторінка скролиться цілком (money/payment так жив до #17509, тепер — ні).
   Scoped класом: інші TabPanel застосунку (де вкладка сама має бути скролером) не зачеплені. */
.tab-panel.doc-tabs,
.tab-panel.doc-tabs .tab-content,
.tab-panel.doc-tabs .tab-item {
  overflow: visible;
}

/* #17493 — еліпсис в обрізаному полі селектора рядка ТЧ. Те саме правило, що #17203 у
   _assets/goodsreceipt.css, але те прив'язане до .gr-doc, а картка авансового звіту — єдиний
   споживач .doc-tabs і під .gr-doc не підпадає, тож до неї воно НЕ доїжджало. Побачили це, коли
   «олівець» забрав із комірки ще 27px: у «Запасах» під текст «Проєкту» лишилось 37px і
   «Елеватор на Сумщині» обривалось на «Елеı» — посеред літери, без жодної ознаки обрізання
   (виміряно на 1366 і 1440). Повне значення дає Tip на самих селекторах; еліпсис лишає видимим
   сам ФАКТ обрізання, і це єдиний сигнал у проведеному документі, де інпут disabled і текст у
   ньому не проскролити.
   БЕЗ `[type="text"]`: платформа рендерить поле селектора як голий <input> без атрибута type
   (text — лише дефолт IDL), тож `input[type="text"]` не збігається НІ З ЧИМ — та сама пастка,
   що описана в goodsreceipt.css. */
.doc-tabs .data-grid-container .input-group input {
  text-overflow: ellipsis;
}

/* #15958 (зам.7) — Popover усередині контрола на read-only формі. Платформа гасить увесь control-group
   (.control-group.disabled:not(.rendershow) { pointer-events: none }), і разом із полем помирає вкладений
   Popover — «глазик» розшифровки роботи, закритої актом, чипи-підказки тощо. Popover команд запису не має,
   це суто перегляд, тож повертаємо йому кліки. Саме поле лишається readonly (native-атрибут на input/
   textarea), кнопка вибору «…» — далі погашена правилом .control-group.disabled a; виняток для
   «олівця» — окремим правилом нижче (#17283). */
.control-group.disabled .popover-wrapper,
.control-group.disabled .popover-wrapper .popover-title {
  pointer-events: auto;
}

/* #17283 — у ПРОВЕДЕНОМУ документі не подивитись, на що він посилається. Платформа навішує
   :disabled контрола на КОЖНУ його кнопку-add-on (Control.RenderAddOns, replaceExisting), а тема
   гасить їх кліки (.control-group.disabled a:not(.rendershow) { pointer-events: none; opacity: .5 }).
   Під роздачу разом із «…» (вибрати інше значення — гасити правильно) потрапляє й «олівець»
   (відкрити картку елемента / документа-підстави), який нічого не змінює.
   Ділення саме за іконкою, а не за розміткою: конвенція застосунку однозначна — Ellipsis = вибрати,
   Edit = відкрити картку, і серед add-on'ів з ico-edit лежать РІВНО дві команди, Open і
   Dialog Action=Edit (перевірено по всіх 146 файлах розмітки; жодної, що пише дані, серед них немає).
   Альтернатива — Render="Show" + CheckArgument=True на кожному add-on'і — це 292 правки розмітки,
   яка валідується лише в рантаймі, заради одного й того самого ефекту.
   Специфічність (0,4,2) перекриває і a[disabled] (0,1,1), і платформене
   .control-group.disabled a:not(.rendershow) (0,3,1) — !important не потрібен. pointer-events
   дитини перебиває none батька; той самий механізм працює у правилі #15958 вище.
   ОБМЕЖЕННЯ, про яке треба знати при правці розмітки: правило чіпляється за ФОРМУ, а не за намір.
   Якщо add-on'у з «олівцем» колись додадуть <Hyperlink.DropDown>, клас add-on поїде на обгортку
   <div class="dropdown hlink-dd-wrapper add-on">, а внутрішній <a> лишиться без нього
   (Hyperlink.cs: RenderHyperlink викликається з onRender=null) — селектор мовчки перестане
   збігатись, і та кнопка знову помре на проведеному документі. Зараз таких немає ЖОДНОЇ
   (перевірено по всіх <*.AddOns> у MainApp), тож ускладнювати селектор передчасно. */
.control-group.disabled a.add-on:has(> i.ico-edit) {
  pointer-events: auto;
  opacity: 1;
  cursor: pointer;
}

/* #16785 — слова рвуться посеред слова («Контраген/т», «Налаштуванн/я»). Платформа оголошує
   word-break: break-word на глобальному `span` (themes/tabbed/Normalize.less:52 -> tabbed.css:942) і на
   комірці гріда (DataGrid.less:105 -> tabbed.css:3184; рядком вище там break-all «EDGE fix», діє саме
   наступний break-word). break-word ≡ overflow-wrap: anywhere, а anywhere
   ВРАХОВУЄТЬСЯ при розрахунку min-content, тож table-layout:auto має право стиснути колонку вужче за
   найдовше слово — і слово рветься.
   Чому не голий word-break: normal (варіант із постановки): він знімає й перенос ФІЗИЧНО задовгих
   беспробільних значень — URL, e-mail, код без пробілів вилазить за комірку (заміряно на файлменеджері:
   +331 / +171 / +253 px поверх сусідньої колонки).
   Тому normal + overflow-wrap: break-word: на відміну від anywhere, break-word у min-content не бере
   участі — колонка не стискається вужче за найдовше слово (звичайні слова цілі), але слово, яке все одно
   не влізло, переноситься всередині комірки. Заміряно посимвольно через Range.getBoundingClientRect:
   filemanager 34 -> 0 розривів, basicplan 5 -> 0, бічне меню 1 -> 0; вихід за комірку 0 px.
   keep-all не годиться — воно про CJK, для кирилиці/латиниці еквівалентне normal.
   Потрібні ОБИДВА селектори: .dg-cell теж <span>, і платформене правило на ньому специфічніше за голий
   span. Другий селектор тут — ДОСЛІВНА копія платформеного, тобто специфічність РІВНА (0,2,4), і
   перемагає він виключно порядком підключення: _Layout.tabbed.cshtml підключає тему, а потім
   AppStyleSheetsLink() (/_shell/appstyles). Запасу по специфічності немає — якщо порядок колись
   зміниться, правило треба буде посилювати, а не сподіватись на каскад. !important не ставимо саме тому,
   що поточний порядок гарантований розміткою layout'а для всіх тем, включно з мобільною.
   Точкові латки з вищою специфічністю не зачеплені: .chat-message (chat.css), .msaldo-acct (site.css);
   заголовок гріда .h-holder має white-space: nowrap, тож word-break на нього не впливає взагалі. */
span {
  word-break: normal;
  overflow-wrap: break-word;
}

table.data-grid > tbody > tr > td .dg-cell {
  word-break: normal;
  overflow-wrap: break-word;
}
/* Панель «Залишки по складах» (колонка ③, #17087 першоджерело) — СПІЛЬНІ стилі трьох документів:
   переміщення ТМЦ, реалізація запасів і списання товарів/матеріалів. Розмітку панелі тримає
   _components/ComponentDictionary.xaml (StockRemPanel), логіку — _components/stockRemainders.ts;
   #17219 звів сюди імена: файл був stocktransfer.css, класи були .st-rem* / .st-deficit.
   Реквізити (ліва панель) і полотно документа стилює _assets/goodsreceipt.css (.gr-side/.gr-doc) —
   ті класи спільні для документів і тут не дублюються. Усе нижче scoped під .stock-rem, крім
   .stock-deficit: він живе в підвалі товарної частини, а не в панелі. */

.stock-rem {
    /* 24rem — та сама логіка, що у 23rem лівої панелі: вміщує назву номенклатури + число, але не
       з'їдає полотно, заради якого форму й перекроювали (#17040). Ширина ТУТ, а не в Grid.Columns
       сторінки: трек там Auto, щоб схована панель не лишала порожньої смуги. */
    width: 24rem;
    min-width: 24rem;
    border-left: 1px solid var(--border-color, #dcdcdc);
    background: var(--bg-color-light, #fbfbfb);
    /* Власний скрол дістає лише таблиця всередині; сама панель висоту сторінки не роздуває. */
    overflow: hidden;
}

/* Обгортка CollectionView (.cw) — грід-елемент, а в грід-елемента min-width за замовчуванням auto,
   тобто «не вужче свого вмісту». Через це панель у 360px тримала всередині 375px, і праву колонку
   таблиці (кнопку «+») зрізало межею панелі — мовчки, бо overflow тут hidden. Виміряно:
   .stock-rem cw=359 проти вкладеної .cw w=375. */
.stock-rem > .cw,
.stock-rem > .cw > .grid,
.stock-rem > .cw > .grid > * {
    min-width: 0;
}

/* Скрол дістає ЛИШЕ таблицю. Без цього при найменшому переповненні їхала вся панель разом із
   заголовком, фільтрами й підвалом — у підписів зрізало перші літери («Пошук» → «ошук»), і стан
   тримався до згортання панелі. min-height/min-width: 0 обов'язкові — грід-елемент за замовчуванням
   не стискається менше свого вмісту, тож overflow на ньому інакше не спрацьовує. */
.stock-rem-grid {
    overflow: auto;
    min-height: 0;
    min-width: 0;
}

/* Назва складу другим рядком у клітинці номенклатури (режим «всі склади») — замість власної
   колонки, якої панель на 24rem не витримує. */
.stock-rem-wh {
    font-size: .85em;
    color: var(--text-color-muted, #6b7280);
    /* Один рядок із трикрапкою: назва складу, перенесена по словах, лишала «22» на окремому рядку
       і роздувала висоту кожного рядка панелі. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stock-rem-head {
    padding: .75rem 1rem .25rem 1rem;
}

.stock-rem-filters {
    padding: 0 1rem .5rem 1rem;
    border-bottom: 1px solid var(--border-color, #dcdcdc);
    /* Явна колонка minmax(0,1fr): без неї єдина колонка гріда — auto, тобто по max-content, і блок
       фільтрів розпирало до 375px у 359px панелі — підписам зрізало перші літери. Разом із
       min-width:0 на дітях це єдине, що дозволяє полям стиснутись до ширини панелі. */
    grid-template-columns: minmax(0, 1fr);
}

.stock-rem-filters > * {
    min-width: 0;
}

/* Селектори й дати всередині 24rem: поле на всю ширину панелі, інакше кожен контрол міряє себе
   по вмісту і колонка фільтрів виглядає драбинкою. */
.stock-rem-filters .control-group,
.stock-rem-filters .control-group input,
.stock-rem-filters .control-group select {
    width: 100%;
}

/* Дефіцит у підвалі ② — той самий червоний, що й позначка рядка (Mark="danger"), щоб число внизу
   і підсвічений рядок читались як одне повідомлення. */
.stock-deficit {
    color: var(--danger-color, #c0392b);
    font-weight: 600;
}

/* Колонку «Є на складі» на вузьких екранах НЕ ховаємо, хоч і була така спроба. Виміряно на 1280:
   меню (~230) + панель реквізитів (345) + панель залишків (360) лишають товарній частині ~412px
   під таблицю в 666px — тобто одна колонка нічого не рятує, а на екрані, де користувач згорнув
   панель реквізитів, вона зникала б за наявності вільного місця. Три колонки одночасно — режим для
   широкого екрана; на вузькому будь-яка бічна панель згортається одним кліком, і таблиця вміщується
   повністю. Горизонтальний скрол у гріді при цьому працює (data-grid-container: overflow-x auto). */
/*+Kamala. claude. 2026-07-31. #16727 — контраст тегів статусів.
  Платформенна тема (A2v10 themes/tabbed/Text.less) дає нечитабельні нейтральні теги:
    .tag-label.lightgray  — білий текст на #ccc            → контраст ~1.6:1
    .tag-label.outline    — білий фон + текст #ccc         → контраст ~1.6:1
  і водночас заливає warning/info/success ПОВНИМ кольором, тож рідкісні стани кричать,
  а найчастіші («Чернетка», «Вхідний», «Не отримано», «Не оплачено») не читаються.

  Єдиний стиль «soft chip» для всіх варіантів: пастельна заливка + темний текст того ж
  відтінку + тонка рамка. Текст виходить на 6:1+ (WCAG AA вимагає 4.5:1), а «світлофорність»
  ПАДАЄ — яскравих суцільних заливок більше немає, колір лишається сигналом, але не кричить.

  ГЕОМЕТРІЮ НЕ ЧІПАТИ (паддінг, шрифт, РАМКУ): ширини колонок гридів (напр. act/invoice/index.view.xaml,
  #16640; plan/basicplan, #16698) розраховані під платформенні значення — +2px рвуть «На погодженні»
  у два рядки. Тому обвідка ЗАЛИТИХ тегів — `box-shadow: inset`, а не `border`: у платформи залитий
  .tag-label бордюра НЕ МАЄ взагалі (advance.css: `border` є лише у `.tag-label.outline`), тож
  `border: 1px solid` додав би кожному тегу застосунку +2px ширини й висоти. Inset-тінь малює ту саму
  лінію в 1px, але поза потоком розкладки — розмір чіпа лишається платформенним.
  Бонус: у друкові (objectsummary-report.css гасить фони тегів) inset-тінь зникає разом із фоном,
  як і належить, тоді як border лишався б чорною рамкою навколо порожнього місця.

  КОНТУРНІ (.outline) — навпаки, через `border-color`: платформа вже дала їм `border: 1px solid
  currentColor`, бордюр у їхній геометрії вже врахований, і ми правимо лише його КОЛІР.

  Некриті кольори (purple/teal/gold/…) лишаються платформенними навмисно: вони маркують
  довільні сутності (мітки, теги задач), а не стани документа, і 0,3,0-специфічність
  .tag-label.<color>.outline перебиває загальне правило .tag-label.outline нижче.

  РІЗНИЦЯ ЗАЛИТИЙ/КОНТУРНИЙ ЗБЕРЕЖЕНА (code-review #16727): Outline="True" у реєстрі рахунків
  (index.view.xaml, #16626) стоїть саме для того, щоб сусідні колонки-теги в нейтральному стані
  («Вхідний» + «Чернетка») відрізнялись ФОРМОЮ, не займаючи ще один колір палітри. Тому контурний
  варіант лишається без заливки — правиться тільки колір тексту й рамки, щоб він читався. */

/* Нейтраль */
.tag-label.lightgray {
    background-color: #e9edf2;
    color: #4c5666;
    box-shadow: inset 0 0 0 1px #d3d9e2;
}

/* Контурний лишається БЕЗ заливки: var(--bgWhite) тут не косметика, а необхідність — правило
   .tag-label.lightgray вище має ту саму специфічність 0,2,0, що й платформенне .outline, але
   їде пізніше в каскаді, тож без явного фону контурний тег отримав би сіру заливку і став би
   не відрізнити від суцільного. Загальне правило ловить і тег без кольорового класу
   (у темі він теж сірий #8f94b0). */
.tag-label.outline {
    background-color: var(--bgWhite);
    color: #4c5666;
}

/* border-color задається ЛИШЕ тут, а не в загальному .outline вище: у темі рамка контурного тега —
   `1px solid currentColor`, тож некриті кольори (purple/teal/gold/…) малюють її своїм кольором.
   Нейтральний сірий у загальному правилі забрав би її в них разом із власним відтінком. */
.tag-label.lightgray.outline {
    background-color: var(--bgWhite);
    color: #4c5666;
    border-color: #b9c1cc;
}

.tag-label.warning,
.tag-label.orange {
    background-color: #fbeed3;
    color: #845400;
    box-shadow: inset 0 0 0 1px #ecca92;
}

.tag-label.warning.outline,
.tag-label.orange.outline {
    background-color: var(--bgWhite);
    color: #845400;
    border-color: #e0b062;
}

.tag-label.info,
.tag-label.cyan {
    background-color: #dfebfa;
    color: #15558f;
    box-shadow: inset 0 0 0 1px #b4d2f0;
}

.tag-label.info.outline,
.tag-label.cyan.outline {
    background-color: var(--bgWhite);
    color: #15558f;
    border-color: #8fbbe6;
}

.tag-label.success,
.tag-label.green {
    background-color: #e0f2dc;
    color: #276423;
    box-shadow: inset 0 0 0 1px #b5dcae;
}

.tag-label.success.outline,
.tag-label.green.outline {
    background-color: var(--bgWhite);
    color: #276423;
    border-color: #8fc389;
}

.tag-label.danger,
.tag-label.red,
.tag-label.error {
    background-color: #fbe3e3;
    color: #93201f;
    box-shadow: inset 0 0 0 1px #eebcbc;
}

.tag-label.danger.outline,
.tag-label.red.outline,
.tag-label.error.outline {
    background-color: var(--bgWhite);
    color: #93201f;
    border-color: #e09a9a;
}
/* Task list: progress mini bar */
.progress-mini {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.progress-mini-track {
  height: 6px;
  border-radius: 3px;
  width: 50px;
  background: var(--bg-muted, #e8e8e8);
  overflow: hidden;
}
.progress-mini-fill {
  height: 100%;
  border-radius: 3px;
  background: var(--color-info, #42a5f5);
  transition: width 0.3s;
}
.progress-mini-fill.complete {
  background: var(--color-success, #66bb6a);
}

/* Task list: quick state change dropdown */
.quick-state-dropdown {
  position: fixed;
  z-index: 9999;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
  padding: 4px 0;
  min-width: 120px;
}
.quick-state-item {
  padding: 4px 12px;
  cursor: pointer;
}
.quick-state-item:hover {
  background: #f5f5f5;
}

/* Task list: clickable status badge */
.status-clickable {
  cursor: pointer;
}

/* Task list: unassigned indicator */
.task-unassigned {
  color: #999;
  font-style: italic;
}
/* Task Reports Styles */

.task-report-page {
    background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%);
    min-height: 100vh;
}

/* Status bar chart */
.status-bar-container {
    display: flex;
    height: 32px;
    border-radius: 4px;
    overflow: hidden;
    margin: 4px 0;
}

.status-bar-segment {
    transition: width 0.5s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 0.8rem;
    font-weight: 600;
    min-width: 24px;
}

.bg-info { background: var(--status-info); }
.bg-warning { background: var(--status-warning); }
.bg-success { background: var(--status-success); }
.bg-danger { background: var(--status-danger); }

/* Status dots */
.status-dot.info { background: var(--status-info); }
.status-dot.warning { background: var(--status-warning); }
.status-dot.success { background: var(--status-success); }
.status-dot.danger { background: var(--status-danger); }

/* Priority bars */
.priority-bar {
    height: 100%;
    border-radius: 4px;
    transition: width 0.5s ease;
}

.priority-bar.critical { background: linear-gradient(90deg, var(--status-danger), #E53935); }
.priority-bar.high { background: linear-gradient(90deg, var(--status-warning), #FB8C00); }
.priority-bar.normal { background: linear-gradient(90deg, var(--status-info), #1E88E5); }
.priority-bar.low { background: linear-gradient(90deg, #9E9E9E, #BDBDBD); }

/* Trend bars */
.trend-bar {
    min-width: 16px;
    border-radius: 2px 2px 0 0;
    transition: height 0.5s ease;
}

.trend-bar.created { background: var(--status-info); }
.trend-bar.completed { background: var(--status-success); }

/* Overdue deadline in DatePicker */
.date-picker.text-color-danger input {
    color: #a94442;
    font-weight: 600;
}

/* Data table */
.data-table th {
    position: sticky;
    top: 0;
    z-index: 1;
}

/* #16219 — пілюлі активного дрилдаун-відбору (bucket/класифікатор) на сторінці списку задач */
.task-filter-chip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    padding: 5px 12px;
    margin: 2px 0 6px;
    background: #eef3fb;
    border: 1px solid #cfe0f5;
    border-radius: 6px;
    font-size: 0.85rem;
}
.task-filter-chip .chip-pill {
    font-weight: 600;
    color: #1976d2;
}
.task-filter-chip .chip-clear {
    margin-right: 10px;
    color: #888;
}
.task-filter-chip .chip-clear:hover {
    color: #d32f2f;
}
/* +Kamala. claude. 2026-06-06. #16101 — Nova Era-стиль табель-борд (a2-timeboard) */
/* +Kamala. claude. 2026-07-06. #16280 — агрегат по працівнику: бейджі проектів, крапка-маркер
   мультипроектних днів, модалка дня з розподілом проект×години (замість інлайн-дропдауна). */

.time-board {
	position: relative;
	height: 100%;
	font-size: 0.85rem;
	/* #17138 — БЕЗ min-width:0 липкі колонки не липнуть узагалі. Борд — елемент грида форми, а в
	   грида дефолт min-width:auto: борд роздувався до ширини таблиці (1775px у гриді на 1346px),
	   тож .tb-scroll ніколи не був скрол-контейнером (scrollWidth == clientWidth), і position:
	   sticky не мав відносно чого прилипати — їхала вся панель разом із тулбаром. Дефект був і до
	   цієї задачі (перевірено на :7090 з кодом master), лікується саме тут. */
	min-width: 0;
	/* #17138 — ширини двох перших липких колонок: від них рахується left третьої («Проекти»).
	   Раніше це були три синхронізовані вручну числа, і зміна ширини #-колонки тихо ламала
	   липкість «Проектів» — тепер зв'язок виражений calc(), а не коментарем. */
	--tb-no-w: 3.4rem;
	--tb-emp-w: 13rem;
}

/* #16280 — розкладка: колапсибельний сайдбар + грид */
/* #17163 — height: auto замість 100%. Борд сидить у треку «1*», який сам міряється по вмісту
   (див. коментар до .tb-detail), тож 100% тут — це «розтягнись на висоту, яку ти ж і задав»:
   сітка на 3 працівників роздувалась із 178px до 600px, лишаючи ~440px мертвої білої зони, а
   панель розшифровки виштовхувалась ЗА межі борда. Вертикального скролу це 100% не давало ніколи
   (виміряно: .tb-scroll 600px при вмісті 584px, scrollHeight <= clientHeight); горизонтальний
   скрол 31 колонки дня живе на .tb-scroll і від height не залежить. */
.time-board .tb-layout { display: flex; height: auto; align-items: stretch; }

.time-board .tb-scroll {
	overflow: auto;
	height: 100%;
	flex: 1; min-width: 0;
	border: 1px solid var(--border-color, #d0d3d9);
}

/* #16280 — сайдбар «Швидке заповнення» */
.time-board .tb-side {
	flex: 0 0 15rem; width: 15rem; box-sizing: border-box;
	border: 1px solid var(--border-color, #d0d3d9); border-right: none;
	background: #fafbfc; overflow: auto;
	transition: flex-basis 0.15s ease, width 0.15s ease;
}
.time-board .tb-side.tb-side-collapsed { flex-basis: 2.2rem; width: 2.2rem; }
.time-board .tb-side-head {
	display: flex; align-items: center; gap: 0.4rem;
	padding: 0.4rem 0.5rem; border-bottom: 1px solid #eceef2;
	position: sticky; top: 0; background: #fafbfc; z-index: 1;
}
.time-board .tb-side-title { font-weight: 700; font-size: 0.8rem; flex: 1; }
.time-board .tb-side-toggle {
	cursor: pointer; color: #1846a8; font-weight: 700; user-select: none;
	padding: 0 0.3rem; border-radius: 3px; font-size: 0.95rem;
}
.time-board .tb-side-toggle:hover { background: #e8f0fe; }
.time-board .tb-side-collapsed .tb-side-toggle { margin: 0 auto; }
.time-board .tb-side-body { padding: 0.5rem 0.6rem 0.8rem; }
.time-board .tb-qf-lbl {
	display: block; margin: 0.5rem 0 0.15rem; font-size: 0.72rem;
	color: #6b7280; font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em;
}
.time-board .tb-qf-in, .time-board .tb-qf-proj {
	width: 100%; box-sizing: border-box; padding: 0.25rem 0.4rem;
	border: 1px solid #d0d3d9; border-radius: 4px; background: #fff; font-size: 0.8rem;
}
.time-board .tb-qf-proj { cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.time-board .tb-qf-proj:hover { border-color: #2f6fed; }
.time-board .tb-qf-proj-empty { border-color: #e0a800; background: #fff8e1; }
.time-board .tb-qf-range { display: flex; align-items: center; gap: 0.3rem; }
.time-board .tb-qf-day {
	width: 3.2rem; box-sizing: border-box; padding: 0.25rem 0.3rem;
	border: 1px solid #d0d3d9; border-radius: 4px; font-size: 0.8rem;
}
.time-board .tb-qf-check {
	display: flex; align-items: center; gap: 0.35rem;
	margin-top: 0.6rem; font-size: 0.78rem; cursor: pointer;
}
.time-board .tb-qf-apply { width: 100%; margin-top: 0.8rem; }
.time-board .tb-qf-apply:disabled { opacity: 0.5; cursor: default; }

.time-board .tb-table {
	border-collapse: collapse;
	width: max-content;
	min-width: 100%;
}

.time-board th,
.time-board td {
	border: 1px solid var(--border-color, #d0d3d9);
	padding: 2px 4px;
	text-align: center;
	white-space: nowrap;
}

/* Липка шапка (двома рядами) */
.time-board thead th {
	position: sticky;
	box-sizing: border-box;
	background: var(--table-header-bg, #f3f4f6);
	font-weight: 600;
	z-index: 2;
}
/* box-sizing:border-box → висота th включає padding/border, тож top 2-го ряду = висоті 1-го (flush) */
.time-board .tb-hdr-top th { top: 0; height: 1.7rem; }
.time-board .tb-hdr-days th { top: 1.7rem; }

.time-board .tb-days-group,
.time-board .tb-grp-sep { border-left: 2px solid #9aa0a6; }

/* День-заголовок: два рядки (день тижня + число) */
.time-board .tb-dh { min-width: 1.9rem; line-height: 1.05; }
.time-board .tb-dh .tb-dow { display: block; font-size: 0.68rem; color: #6b7280; font-weight: 400; }
.time-board .tb-dh .tb-dnum { display: block; }
.time-board .tb-dh.tb-wknd { background: #e8eaed; }
.time-board .tb-dh.tb-wknd .tb-dow { color: #c0392b; }
/* #17138 — поточний день: при 31 колонці орієнтуватись доводилось рахунком */
.time-board .tb-dh.tb-dh-today { background: #fff3cd; box-shadow: inset 0 -2px 0 #e6a700; }
.time-board .tb-dh.tb-dh-today .tb-dnum { color: #8a6100; }

/* Колонка # (прапорець + номер) та Працівник — липкі зліва (ширини — у змінних на .time-board) */
.time-board .tb-no {
	position: sticky; left: 0; z-index: 3;
	background: #fff; color: #6b7280;
	width: var(--tb-no-w); min-width: var(--tb-no-w); max-width: var(--tb-no-w);
}
/* БЕЗ display:flex: у клітинці таблиці він вибиває її з табличної розкладки — колонки шапки
   роз'їжджаються відносно тіла (перевірено в браузері: th «#» отримував ширину «Працівника»).
   Прапорець і «#» — інлайнові, центрує їх звичайне text-align: center з .time-board td. */
/* Голий чекбокс платформа ховає: `input[type="checkbox"]:not(.switch)` у tabbed.min.css робить
   opacity:0 + position:absolute + нульовий розмір, бо очікує label-обгортку з власним виглядом.
   Обгортки тут немає, тож повертаємо нативний вигляд — той самий прийом і специфічність, що в
   _assets/needs-analysis.css (.na-cb): селектор із [type] дає (0,3,1) і перебиває платформний
   (0,2,1) без !important. Без цього прапорці просто невидимі (перевірено в браузері). */
.time-board input[type="checkbox"].tb-chk {
	position: static; left: auto; top: auto;
	width: 1em; height: 1em; opacity: 1; z-index: auto;
	-webkit-appearance: checkbox; appearance: checkbox;
	margin: 0 0.15rem 0 0; cursor: pointer; vertical-align: middle;
}
.time-board .tb-no-hash { cursor: pointer; vertical-align: middle; }
.time-board .tb-emp {
	position: sticky; left: var(--tb-no-w); z-index: 3;
	/* фіксована ширина (не діапазон) — щоб 3-я sticky-колонка «Проекти» мала детермінований left */
	background: #fff;
	width: var(--tb-emp-w); min-width: var(--tb-emp-w); max-width: var(--tb-emp-w);
	text-align: left; cursor: pointer;
}
.time-board td.tb-emp { display: flex; align-items: center; gap: 0.25rem; }
.time-board .tb-emp-info { flex: 1; min-width: 0; }

/* Колонка «Проекти» — 3-я липка зліва: left = ширина «#» + ширина «Працівник» */
.time-board .tb-proj {
	position: sticky; left: calc(var(--tb-no-w) + var(--tb-emp-w)); z-index: 3;
	background: #fff; width: 12rem; min-width: 12rem; max-width: 12rem;
	text-align: left; white-space: normal; line-height: 1.4;
}
/* #16097 (фідбек Гульнари): повна назва проекту + кольорова крапка + відпрацьовані години
   (раніше — 3-літерний бейдж, назва читалась лише в title при наведенні) */
.time-board .tb-proj-item {
	display: flex; align-items: baseline; gap: 0.3rem; font-size: 0.72rem;
}
.time-board .tb-proj-dot {
	flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; align-self: center;
}
/* назва переноситься, а не обрізається — саме «видно лише при наведенні» й було зауваженням */
.time-board .tb-proj-name {
	flex: 1; min-width: 0; color: #1f2937;
	white-space: normal; overflow-wrap: anywhere;
}
.time-board .tb-proj-h { flex: none; color: #6b7280; font-weight: 700; }
/* години поза проектом — для балансу з підсумком «Год», але приглушено */
.time-board .tb-proj-noproj .tb-proj-name { color: #9aa0a6; font-style: italic; }
.time-board .tb-proj-empty { color: #c0c4cc; }

/* Інлайн-операції рядка: зʼявляються при наведенні (рядок вгору / вниз / видалити, #17138).
   Рядком, а не колонкою: трьома іконками стовпчик переріс би висоту рядка. */
.time-board .tb-row-actions {
	display: flex; flex-direction: row; gap: 1px; flex: none;
	opacity: 0; transition: opacity 0.1s;
}
.time-board tr:hover .tb-row-actions { opacity: 1; }
.time-board .tb-act {
	font-size: 0.7rem; line-height: 1; padding: 2px 3px; cursor: pointer;
	color: #4b5563; border-radius: 2px; user-select: none;
}
.time-board .tb-act:hover { background: #e3f0ff; color: #1846a8; }
.time-board .tb-act-del:hover { background: #fde8e8; color: #c0392b; }
/* крайній рядок: стрілка лишається на місці (не стрибає розкладка), але мертва */
.time-board .tb-act-off { color: #c8ccd2; cursor: default; pointer-events: none; }
.time-board thead .tb-no,
.time-board thead .tb-emp,
.time-board thead .tb-proj { z-index: 4; background: var(--table-header-bg, #f3f4f6); }

/* #17138 — ПІБ = посилання на картку працівника */
.time-board a.tb-emp-name {
	display: block; font-weight: 600; white-space: normal;
	color: var(--link-color, #1846a8); text-decoration: none; cursor: pointer;
}
.time-board a.tb-emp-name:hover { text-decoration: underline; }
.time-board .tb-emp-sched { font-size: 0.72rem; color: #6b7280; }
.time-board .tb-emp-sched .ico { font-size: 0.72rem; }

/* Рядок виділення */
.time-board tr.tb-sel .tb-no,
.time-board tr.tb-sel .tb-emp,
.time-board tr.tb-sel .tb-proj { background: #e3f0ff; }
.time-board tr.tb-sel td { background: #f0f7ff; }

/* #17138 — рядок, відмічений прапорцем (набір для групових команд) */
.time-board tr.tb-chk-row .tb-no,
.time-board tr.tb-chk-row .tb-emp,
.time-board tr.tb-chk-row .tb-proj { background: #eaf3ff; }

/* Клітинки днів */
.time-board .tb-cell {
	position: relative;   /* #16280 — під крапку-маркер */
	min-width: 1.9rem; cursor: pointer; font-weight: 600;
	user-select: none;
}
/* #16097 — у затвердженому табелі клітинка клікабельна (перегляд розподілу дня по проектах) */
.time-board .tb-cell:hover { outline: 2px solid #2f6fed; outline-offset: -2px; }
/* #17138 — клас tb-locked проставлявся з #16101, але жодного правила під нього не було: проведений
   табель виглядав точно як редагований. Клітинку не глушимо (клік = перегляд розподілу дня, #16097),
   але обвід сірий, а не «редагований» синій, і сама сітка на приглушеній підложці. */
.time-board.tb-locked .tb-table { background: #fafafb; }
.time-board.tb-locked .tb-cell:hover { outline-color: #9aa0a6; }
.time-board.tb-locked .tb-cell { cursor: zoom-in; }
/* #16280 — крапка-маркер: день, де години розподілені на >1 проект */
.time-board .tb-cell-multi::after {
	content: ''; position: absolute; top: 1px; right: 1px;
	width: 5px; height: 5px; border-radius: 50%;
	background: #1846a8; box-shadow: 0 0 0 1px #fff;
}

/* #16722 — кутик-маркер: день має заданий інтервал зміни «з-по» */
.time-board .tb-cell-shift::before {
	content: ''; position: absolute; left: 0; bottom: 0;
	border-width: 0 0 6px 6px; border-style: solid;
	border-color: transparent transparent #1846a8 transparent;
}

/* Підсумкові колонки */
.time-board .tb-tot { font-variant-numeric: tabular-nums; min-width: 2.2rem; }
.time-board .tb-abs { color: #c0392b; }
/* #16722 — місячні підсумки вечірніх/нічних (лише коли в табелі є змінний графік) */
.time-board .tb-eve { color: #a06a00; }
.time-board .tb-night { color: #1846a8; }

/* #16722 — рядок інтервалу зміни в модалці дня */
.tb-shift-row {
	display: flex; align-items: center; gap: 0.4rem;
	padding: 0.4rem 0.2rem 0.6rem; margin-bottom: 0.4rem;
	border-bottom: 1px dashed #d6d9de; flex-wrap: wrap;
}
.tb-shift-lbl { font-weight: 600; color: #4b5563; }
.tb-shift-in {
	width: 7rem; padding: 0.2rem 0.35rem;
	border: 1px solid #cfd4dc; border-radius: 3px;
	font-variant-numeric: tabular-nums;
}
.tb-shift-dash { color: #9aa0a6; }
.tb-shift-split { margin-left: auto; font-weight: 600; color: #1846a8; }
.tb-shift-total { font-style: normal; font-weight: 400; color: #6b7280; }
.tb-shift-hint { margin-left: auto; color: #9aa0a6; font-size: 0.85em; }

.time-board .tb-foot th { position: sticky; bottom: 0; background: #f3f4f6; font-weight: 700; }
.time-board .tb-foot-lbl { text-align: right; }
.time-board .tb-empty td { padding: 1rem; color: #6b7280; font-style: italic; }

/* Кольори кодів (клітинка) — палітра спільна з .timesheet-grid */
.time-board td.tc-work     { background-color: #a5d6a7 !important; }
.time-board td.tc-trip     { background-color: #ffe082 !important; }
.time-board td.tc-sick     { background-color: #90caf9 !important; }
.time-board td.tc-vacation { background-color: #ce93d8 !important; }
.time-board td.tc-absent   { background-color: #ef9a9a !important; }
.time-board td.tc-other    { background-color: #b0bec5 !important; }
.time-board td.tc-weekend  { background-color: #e0e0e0 !important; }

/* Бейдж коду (літера у кольоровому квадраті) — модалка/легенда */
.tb-code-badge {
	display: inline-block; width: 1.5rem; height: 1.5rem; line-height: 1.5rem;
	text-align: center; font-weight: 700; border-radius: 3px; color: #1f2937;
}
.tb-code-badge.tc-work     { background-color: #a5d6a7; }
.tb-code-badge.tc-trip     { background-color: #ffe082; }
.tb-code-badge.tc-sick     { background-color: #90caf9; }
.tb-code-badge.tc-vacation { background-color: #ce93d8; }
.tb-code-badge.tc-absent   { background-color: #ef9a9a; }
.tb-code-badge.tc-other    { background-color: #b0bec5; }

/* ---- #16280 — Модалка дня (проект×години) ---- */
.tb-modal-backdrop {
	position: fixed; inset: 0; z-index: 120;
	background: rgba(15, 23, 42, 0.35);
	display: flex; align-items: center; justify-content: center;
}
/* #16280 — модалка ховається на час browse-діалогу вибору проекту (щоб не перекривати його) */
.tb-modal-backdrop.tb-modal-hidden { display: none; }

/* #16280 — підсвічування набору клітинок (Ctrl/Shift/drag). inset box-shadow — напівпрозоре синє
   накладання ПОВЕРХ кольору коду (tc-* мають !important на background) */
.time-board .tb-cell.tb-cell-sel {
	outline: 2px solid #1846a8; outline-offset: -2px;
	box-shadow: inset 0 0 0 100px rgba(47, 111, 237, 0.28);
}

/* #16280 — bulk-поп для набору клітинок (position:fixed → поза кліппінгом грида) */
ul.tb-bulk-menu {
	position: fixed; z-index: 130; min-width: 14rem;
	margin: 0; padding: 0.25rem 0; list-style: none;
	background: #fff; border: 1px solid #c0c4cc; border-radius: 4px;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18); font-size: 0.85rem;
}
ul.tb-bulk-menu .tb-bulk-head { padding: 0.3rem 0.75rem; font-weight: 600; border-bottom: 1px solid #eceef2; }
ul.tb-bulk-menu .tb-bulk-work {
	display: flex; align-items: center; gap: 0.4rem;
	padding: 0.4rem 0.75rem; border-bottom: 1px solid #eceef2;
}
ul.tb-bulk-menu .tb-bulk-work-name { flex: 1; }
ul.tb-bulk-menu .tb-bulk-hours {
	width: 3.2rem; text-align: right; border: 1px solid #c0c4cc; border-radius: 3px; padding: 1px 4px;
}
ul.tb-bulk-menu .tb-bulk-unit { color: #6b7280; }
ul.tb-bulk-menu .tb-bulk-ok {
	border: 1px solid #1846a8; background: #1846a8; color: #fff;
	border-radius: 3px; padding: 1px 8px; cursor: pointer;
}
ul.tb-bulk-menu .tb-bulk-hint {
	padding: 0.2rem 0.75rem; font-size: 0.7rem; color: #9aa0a6;
	border-bottom: 1px solid #eceef2; line-height: 1.25;
}
ul.tb-bulk-menu .tb-bulk-code,
ul.tb-bulk-menu .tb-bulk-clear {
	padding: 0.35rem 0.75rem; cursor: pointer; display: flex; align-items: center; gap: 0.5rem;
}
ul.tb-bulk-menu .tb-bulk-code:hover,
ul.tb-bulk-menu .tb-bulk-clear:hover { background: #f0f4fb; }
ul.tb-bulk-menu .tb-bulk-clear { border-top: 1px solid #eceef2; color: #6b7280; justify-content: center; }
.tb-modal {
	background: #fff; border-radius: 6px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
	width: 30rem; max-width: 92vw; max-height: 88vh; overflow: auto;
	font-size: 0.85rem;
}
.tb-modal-head {
	display: flex; align-items: baseline; gap: 0.6rem;
	padding: 0.7rem 1rem; border-bottom: 1px solid #eceef2;
}
.tb-modal-emp { font-weight: 700; font-size: 0.95rem; }
.tb-modal-date { color: #6b7280; font-size: 0.8rem; }
.tb-modal-x { margin-left: auto; cursor: pointer; color: #9aa0a6; font-size: 1rem; }
.tb-modal-x:hover { color: #c0392b; }

.tb-modal-types {
	display: flex; flex-wrap: wrap; gap: 0.35rem;
	padding: 0.7rem 1rem; border-bottom: 1px solid #eceef2;
}
.tb-type-btn {
	display: inline-flex; align-items: center; gap: 0.3rem;
	padding: 0.2rem 0.5rem 0.2rem 0.2rem; border: 1px solid #d0d3d9;
	border-radius: 4px; background: #fff; cursor: pointer; font-size: 0.78rem;
}
.tb-type-btn:hover { border-color: #2f6fed; }
.tb-type-btn.tb-type-on { border-color: #1846a8; background: #e8f0fe; font-weight: 600; }
.tb-type-btn .tb-code-badge { width: 1.25rem; height: 1.25rem; line-height: 1.25rem; font-size: 0.72rem; }

.tb-modal-body { padding: 0.8rem 1rem; }
.tb-modal-abs { color: #4b5563; }
.tb-modal-projrow {
	display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.4rem;
}
.tb-modal-proj {
	flex: 1; min-width: 0; padding: 0.25rem 0.5rem; cursor: pointer;
	border: 1px solid #d0d3d9; border-radius: 4px; background: #f8fafc;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tb-modal-proj:hover { border-color: #2f6fed; }
/* #16097 — модалка дня у затвердженому табелі: лише перегляд */
.tb-modal-ro {
	padding: 0.4rem 1rem; background: #fff8e1; border-bottom: 1px solid #f0e2b0;
	color: #7a5c00; font-size: 0.78rem; font-weight: 600;
}
.tb-modal-proj-ro { cursor: default; }
.tb-modal-proj-ro:hover { border-color: #d0d3d9; }
.tb-modal-hours[readonly] { background: #f3f4f6; color: #4b5563; }
.tb-modal-empty { color: #9aa0a6; }
.tb-modal-proj-pick { color: #9aa0a6; }
.tb-modal-noproj .tb-modal-proj { border-color: #e0a800; background: #fff8e1; }
.tb-modal-hours {
	width: 3.5rem; text-align: right; padding: 0.25rem 0.4rem;
	border: 1px solid #d0d3d9; border-radius: 4px;
}
.tb-modal-unit { color: #6b7280; }
.tb-modal-rm { cursor: pointer; color: #b0b6bf; padding: 0 2px; }
.tb-modal-rm:hover { color: #c0392b; }
.tb-modal-add {
	margin-top: 0.2rem; padding: 0.25rem 0.5rem; border: 1px dashed #b0b6bf;
	border-radius: 4px; background: #fff; cursor: pointer; color: #1846a8; font-size: 0.78rem;
}
.tb-modal-add:hover { border-color: #1846a8; background: #f0f7ff; }
.tb-modal-total { margin-top: 0.6rem; color: #374151; }
.tb-modal-total.tb-modal-over { color: #c0392b; }
.tb-modal-warn { font-weight: 600; }

.tb-modal-foot {
	display: flex; align-items: center; gap: 0.5rem;
	padding: 0.7rem 1rem; border-top: 1px solid #eceef2;
}
.tb-modal-spacer { flex: 1; }
.tb-btn {
	padding: 0.3rem 0.9rem; border: 1px solid #d0d3d9; border-radius: 4px;
	background: #fff; cursor: pointer; font-size: 0.82rem;
}
.tb-btn:hover { border-color: #9aa0a6; }
.tb-btn-primary { background: #1846a8; border-color: #1846a8; color: #fff; font-weight: 600; }
.tb-btn-primary:hover { background: #143a8c; }
.tb-btn-clear { color: #c0392b; }
.tb-btn-clear:hover { background: #fde8e8; border-color: #c0392b; }

/* +Kamala. claude. 2026-09-03. #17163 — панель «Розшифровка за днями» під сіткою.
   ВИСОТУ ПАНЕЛІ КАПАЄМО В rem, А НЕ У ВІДСОТКАХ. Форма табеля НЕ має фіксованої рамки: рядок
   «1*» гріда вкладки лежить у .page-content з висотою auto, тож `height: 100%` борда резолвиться
   в content-height (виміряно: борд на 3 працівників = 178px, .page-content не переповнений).
   Відсотковий max-height проти невизначеної висоти ІГНОРУЄТЬСЯ при intrinsic-сайзингу — панель
   віддавала у трек усі свої ~1170px, рядок роздувався 178px → 1023px і форма отримувала 403px
   переповнення (виміряно на 1440×900). Кап у rem в intrinsic-сайзинг враховується. */
.time-board .tb-detail {
	margin-top: 0.4rem; border: 1px solid var(--border-color, #d0d3d9);
	border-radius: 4px; background: #fff; overflow: hidden;
}
.time-board .tb-dt-head {
	display: flex; align-items: center; gap: 0.5rem;
	padding: 0.35rem 0.6rem; background: #f5f7fa; border-bottom: 1px solid #eceef2;
}
.time-board .tb-detail-collapsed .tb-dt-head { border-bottom: none; }
.time-board .tb-dt-toggle {
	cursor: pointer; color: #1846a8; font-size: 0.7rem; user-select: none;
	padding: 0 0.25rem; border-radius: 3px;
}
.time-board .tb-dt-toggle:hover { background: #e8f0fe; }
.time-board .tb-dt-title { font-weight: 700; }
.time-board .tb-dt-emp { color: #374151; }
.time-board .tb-dt-emp i { color: #6b7280; font-style: normal; }
.time-board .tb-dt-spacer { flex: 1; }
.time-board .tb-dt-modes { display: flex; gap: 0.25rem; }
.time-board .tb-dt-mode {
	padding: 0.15rem 0.55rem; border: 1px solid #d0d3d9; border-radius: 4px;
	background: #fff; cursor: pointer; font-size: 0.78rem; white-space: nowrap;
}
.time-board .tb-dt-mode:hover { border-color: #9aa0a6; }
.time-board .tb-dt-mode-on { background: #1846a8; border-color: #1846a8; color: #fff; font-weight: 600; }
/* Скролиться САМЕ список днів; підсумок періоду лишається під ним завжди на очах. */
.time-board .tb-dt-scroll { max-height: 20rem; overflow: auto; }
.time-board .tb-dt-none { padding: 0.8rem; color: #6b7280; text-align: center; }

/* Рамки/центрування/nowrap скидаємо явно: узагальнене `.time-board th, .time-board td` вище
   малює рамку з усіх боків і центрує — для списку днів потрібні лише лінійки між рядками. */
.time-board .tb-dt-table { width: 100%; border-collapse: collapse; }
.time-board .tb-dt-table th,
.time-board .tb-dt-table td {
	border: none; text-align: left; white-space: normal;
	padding: 0.3rem 0.5rem; border-bottom: 1px solid #f2f4f7; vertical-align: middle;
}
.time-board .tb-dt-table th {
	position: sticky; top: 0; z-index: 1; background: #fafbfc;
	font-size: 0.72rem; color: #6b7280; font-weight: 600; text-transform: uppercase;
	padding: 0.25rem 0.5rem; border-bottom: 1px solid #eceef2; white-space: nowrap;
}
.time-board .tb-dt-table tbody tr { cursor: pointer; }
.time-board .tb-dt-table tbody tr:hover td { background: #f0f7ff; }
.time-board .tb-dt-table .tb-dt-wknd td { background: #fbfbfd; }
.time-board .tb-dt-table .tb-dt-c-date { width: 5rem; white-space: nowrap; }
.time-board .tb-dt-table .tb-dt-c-date i { font-style: normal; color: #6b7280; margin-left: 0.35rem; }
.time-board .tb-dt-table .tb-dt-c-shift {
	width: 9rem; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.time-board .tb-dt-table .tb-dt-c-hours { width: 4rem; text-align: right; font-weight: 600; }
.time-board .tb-dt-table .tb-dt-c-bar { width: 30%; min-width: 8rem; }
.time-board .tb-dt-table .tb-dt-none { text-align: center; }
.time-board .tb-dt-dash { color: #b0b6bf; }

/* Смуга розподілу: пропорції ГОДИН, не годинник (у системі нема часу по проекту).
   Підпис усередині сегмента вмикається порогом у ВІДСОТКАХ (14% у рядку дня, 8% у широкій
   підсумковій смузі): пороги різні саме тому, що однаковий відсоток дає різну ширину в пікселях,
   а підпис, який не влазить, гірший за його відсутність. */
.time-board .tb-dt-bar {
	display: flex; height: 1.15rem; border-radius: 3px; overflow: hidden; background: #eef0f4;
}
.time-board .tb-dt-bar-big { height: 1.5rem; }
.time-board .tb-dt-seg {
	display: flex; align-items: center; justify-content: center; overflow: hidden;
	color: #fff; font-size: 0.7rem; font-weight: 600; text-shadow: 0 1px 1px rgba(0,0,0,0.25);
	min-width: 2px;
}
.time-board .tb-dt-seg + .tb-dt-seg { border-left: 1px solid rgba(255,255,255,0.7); }

.time-board .tb-dt-chip {
	display: inline-flex; align-items: center; gap: 0.3rem; margin: 0.1rem 0.3rem 0.1rem 0;
	padding: 0.1rem 0.5rem; border-radius: 999px; background: #f2f4f7; font-size: 0.78rem;
	max-width: 100%;
}
.time-board .tb-dt-chip .tb-proj-dot,
.time-board .tb-dt-leg .tb-proj-dot { display: inline-block; flex: none; }
.time-board .tb-dt-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.time-board .tb-dt-total { padding: 0.5rem 0.6rem 0.7rem; border-top: 1px solid #eceef2; }
.time-board .tb-dt-total-lbl { font-size: 0.75rem; color: #6b7280; margin-bottom: 0.3rem; }
.time-board .tb-dt-total-lbl b { color: #1f2937; }
.time-board .tb-dt-legend {
	display: flex; flex-wrap: wrap; gap: 0.15rem 1rem; margin-top: 0.35rem; font-size: 0.75rem;
}
.time-board .tb-dt-leg { display: inline-flex; align-items: center; gap: 0.3rem; color: #6b7280; }
.time-board .tb-dt-leg b { color: #1f2937; }
/* Timesheet — інформаційний рядок над табель-бордом (#16098).
   Сітка днів і клітинки тепер у компоненті a2-timeboard (див. timeboard.css, #16101). */

/* Info row: розрядка між підписом і значенням, інакше "ОрганізаціяОрганізація 1" зливаються.
   #17138 — рядок розсипався на чотири: <Separator /> платформа малює блоковим <div class="divider">,
   і кожен роздільник переносив рядок. Правило нижче цілилось у .separator, якого в DOM немає.
   Лікуємо розкладкою (flex), а не полями: divider стає вертикальною рискою всередині рядка. */
.timesheet-inforow {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.15rem 0.4rem;
}
.timesheet-inforow .divider {
	/* flex: none обовʼязковий — платформений .divider приходить з flex: 2 1 auto і в flex-рядку
	   розтягується в сіру смугу на пів-екрана замість вертикальної рисочки. */
	flex: 0 0 auto;
	align-self: center;
	width: 1px;
	height: 0.9rem;
	margin: 0 0.3rem;
	background: var(--border-color, #d0d3d9);
}
/* реквізити на початку рядка можуть бути незаповнені (їх Span-и під If) — тоді рядок не має
   починатись із риски; дешевше правилом, ніж «попереду щось є»-умовою на кожному Separator */
.timesheet-inforow .divider:first-child { display: none; }

/* Payroll #16325: розкривна деталь — світла підложка + акцент зліва (inset, без зсуву розмітки),
   щоб деталь читалась як вкладена панель, а не як ще рядки master-гріду. */
.payroll-master-grid tr.row-details > td.details-cell {
	background-color: #f6f8fa;
	box-shadow: inset 3px 0 0 #94a3b8;
}
/* Шеврон-афорданс розкривності на рядку master-гріду */
.payroll-expand-hint {
	color: #94a3b8;
	margin-right: 0.3rem;
	font-size: 0.85em;
}
/* Ім'я поруч із шевроном: атомарний inline-flex гіперлінка не вміщується біля іконки
   і цілком падає на новий рядок — даємо тексту обтікати іконку. */
.payroll-expand-hint + a.a2-hyperlink {
	display: inline;
}

/* Payroll #16325: погодинна деталь (розкривний рядок) — поля вводу (вид часу, години)
   зливаються з таблицею, бо платформа малює .input-group з прозорим бордюром (видимий лише
   у фокусі). Робимо бордюр видимим у спокої, щоб одразу читалось як елемент керування;
   read-only клітинки (Ставка/Коеф — звичайний текст, без .input-group) лишаються без рамки. */
.payroll-hours-detail .input-group {
	border-color: #cbd5e1;
	border-radius: 3px;
	background-color: #fff;
}
.payroll-hours-detail .input-group:hover,
.payroll-hours-detail .input-group:focus-within {
	border-color: #64748b;
}
/* ============================================================================
   Design tokens — єдине джерело спільних змінних теми: кольори навігації,
   базовий шрифт, семантичні статус-кольори; плюс довідник z-index-шарів.
   Винесено з site.css під час рефакторингу _assets. Підхоплюється A2v10
   автоматично (/_shell/appstyles). :root-змінні порядко-незалежні: оголошені
   один раз, var() резолвиться по всьому документу незалежно від порядку файлів.
   ============================================================================ */

:root {
  /* Navigation colors (blue theme) */
  --nav900: #1a4a7a;
  --nav800: #2573a8;
  --nav700: #4a90c2;
  --nav-bg: #2573a8;
  --nav-icon: #ffffffd0;
  --nav-text: #ffffffe8;
  --nav-line: #ffffff7d;
  --nav-accent: #96c0f3;
  --mdi-menu-bg: #1a4a7a;
  --mdi-menu-text: #ffffffe8;
  --mdi-menu-hover: #2573a8;
  --mdi-menu-light: #ffffffb0;
  --mdi-menu-line: #ffffff7d;

  /* Increased base font size for better readability */
  --fontSize: 15px;

  /* Семантичні статус-кольори (Material). Спільні для дашборду (dashboard.css),
     звіту по задачах (task-reports.css) і канбану (kanban.css) — змінювати тут,
     а не по файлах. Світлі тінти (*-bg) — фон бейджів/смуг/заголовків смуг. */
  --status-info: #2196F3;
  --status-warning: #FF9800;
  --status-success: #4CAF50;
  --status-danger: #F44336;
  --status-info-bg: #E3F2FD;
  --status-warning-bg: #FFF3E0;
  --status-success-bg: #E8F5E9;
  --status-danger-bg: #FFEBEE;
}

/* ----------------------------------------------------------------------------
   Довідник z-index-шарів (значення задаються у відповідних компонентних файлах,
   тут лише карта, щоб не конфліктувати при доробках):
     .toolbar ................................. 8    (toolbar.css)
     .page.page-grid > .page-toolbar .......... 9    (toolbar.css #16134/#16152)
     sheet thead / .frz ....................... 7/8  (sheet-report.css #11096)
     .gantt-popover ........................... 10   (gantt.css)
     .gantt-context-menu / .gantt-dep-dialog .. 20   (gantt.css)
     .inline-modal-wrapper .................... 99   (modal.css)
     модальний стек ........................... 100
     .toolbar:has(.dropdown.show) ............. 1001 (toolbar.css #15881)
     type-ahead Selector ...................... 1070 (платформа)
     .ms-backdrop (пошук по меню) ............. 1100 (menu-search.css #16494)
     .hk-sheet-backdrop (шпаргалка клавіш) .... 1110 (hotkeys.css #17722)

   ПРИМІТКА (навмисно НЕ уніфіковано): палітри типів днів у графіка роботи
   (schedule.css, .sc-*), виробничого календаря (production-calendar.css, .pc-*)
   і табель-борду (timeboard.css) — РІЗНІ візуальні рішення (різні hex, текст,
   підкреслення). Зведення їх до спільних змінних змінило б вигляд — не робити.
   Так само payroll-readiness.css має власну (flat-UI) палітру статусів.
   ---------------------------------------------------------------------------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: 2px 4px;
  overflow: visible;
  background-color: #cfd6e5;
  color: #555;
  z-index: 8;
}
.toolbar .checkbox {
  margin: 0 6px;
}
.toolbar.no-wrap {
  flex-wrap: nowrap;
}
.toolbar > .control-group.first-elem label {
  margin-left: 6px;
}
.toolbar.transparent {
  background-color: transparent;
  padding: 2px 2px 2px 0;
}
.toolbar.transparent .btn-tb {
  color: #208cf8;
}
.toolbar.transparent > .divider {
  border-right-color: #e3e7f0;
  background-color: #f7f8fb;
}
.toolbar.transparent .dropdown.show .btn {
  background: white;
  border: 1px dotted #ccc;
}
.toolbar.light {
  background-color: white;
}
.toolbar.light > .divider {
  border-right-color: #ececec;
  background-color: #fcfcfc;
}
.toolbar.light .dropdown.show .btn {
  background: white;
  border: 1px dotted #ccc;
}
.toolbar > .btn,
.toolbar > .dropdown > .btn {
  padding: 4px 6px 5px 6px;
}
.toolbar > .dropdown > .btn-caret {
  border-left-color: #bbc5da;
}
.toolbar .btn-caret {
  background-color: transparent;
}
.toolbar .btn-caret:hover {
  background-color: #fdf4bf;
  border-color: #e5c365;
  outline: none;
}
.toolbar .a2-header {
  margin: 0;
  align-self: baseline;
}
.toolbar > .divider {
  flex-grow: 0;
  display: inline-block;
  width: 2px;
  border-right: 1px solid #e0e4ee;
  align-self: stretch;
  background-color: #9dacca;
  margin: 2px 4px;
}
.toolbar > .control-group {
  display: inline-flex;
  margin: 2px 0;
  align-self: baseline;
  background-color: transparent;
}
.toolbar > .control-group .input-group {
  min-height: 28px;
}
.toolbar > .control-group label {
  align-self: center;
  margin: 0 6px 0 2px;
  font-size: 100%;
  white-space: nowrap;
  line-height: 1;
}
.toolbar .control-group + .control-group {
  margin-left: 6px;
}
/* #16134 — попап валідатора (.validator: position:absolute; top:100%) у контролі тулбару шапки
   звисав униз і ховався ПІД .page-content (grid-row 2, position:relative, далі в DOM → перекриває).
   Піднімаємо stacking самого .page-toolbar, щоб повідомлення валідаторів у тулбарі сторінки
   (статус Табеля тощо) показувались поверх контенту, а не обрізались. Загальний фікс для всіх карток.

   #16152 — z-index підняли з 2 до 9. Тулбар контенту вкладки (наприклад «Додати співробітника»
   у Нарахуванні ЗП) — це grid-item у .page-content, а grid-items застосовують z-index без position;
   .toolbar має z-index:8. Ані .page-content, ані .page не є stacking-контекстом, тож той z:8 спливає
   у корінь і перекривав дропдаун-меню «...» (кебаб) тулбару шапки, обрізаючи пункт «Оновити».
   (Фікс #15881 `.toolbar:has(.dropdown.show){z:1001}` тут не діяв: на сторінці тулбар замкнено в
   цій .page-toolbar-обгортці, z:1001 не виходить за її контекст — лиш у діалогах без обгортки.)
   z:9 (> 8) тримає тулбар шапки поверх тулбарів контенту, але НИЖЧЕ за все контентне з z>=10
   (gantt-popover z:10, gantt-context/діалоги z:20, модалки z:99/100, type-ahead Selector z:1070) —
   щоб не перекрити ті попапи. Загальний фікс для всіх карток-сторінок. */
.page.page-grid > .page-toolbar {
  position: relative;
  z-index: 9;
}

/*+Kamala. claude. 22.04.2026. #15881
  Проблема: панель випадаючого меню (наприклад "Друк" у діалозі акту)
  перекривається сусіднім тулбаром нижче (наприклад "+Додати роботу").
  Причина — stacking context: .toolbar має z-index: 8, а його парент —
  grid-контейнер (.grid.page-toolbar, .cw > .grid), через що кожен
  toolbar стає grid/flex-item з власним stacking context на рівні z=8.
  У root-stacking два toolbar'и конкурують за z=8, document-order виграє
  сусідній — і сусід рендериться поверх dropdown-menu всередині нашого.

  Фікс: підняти z-index самого .toolbar, що містить відкритий dropdown,
  через :has(). Тоді цей toolbar на рівні root-stacking (z=1001) буде
  вище за sibling-toolbar (z=8), і dropdown-menu всередині нього буде
  повністю видимий. */
.toolbar:has(.dropdown.show) {
    z-index: 1001;
}
/*-Kamala. claude. 22.04.2026. #15881 */

/*+Kamala. claude. 2026-08-22. #17058
  Проблема: у тулбарі з довгим рядком відборів (report/advancesettlements на 1440px)
  «Закрити» не влазить у перший рядок і переноситься на другий, де прилипає ВЛІВО.
  Дефект НЕ від «Колонок» — відтворюється й на master без цієї кнопки.
  Причина: платформний ToolbarAligner — це <div class="aligner"> з flex-grow:1.
  flex-grow розтягує aligner лише в МЕЖАХ свого рядка; коли переносу зазнає елемент
  ПІСЛЯ aligner'а, він опиняється на новому рядку сам, без жодного розпірника зліва.
  Фікс: auto-маржа на першому елементі після aligner'а. Вона діє в кожному рядку
  окремо, тож правий блок тулбара тримається праворуч і після переносу.
  Коли все влазить в один рядок, auto-маржа з'їдає той самий вільний простір, що й
  flex-grow aligner'а — розкладка не змінюється (перевірено на 1920/1440/1100). */
.toolbar > .aligner + * {
  margin-left: auto;
}
/*-Kamala. claude. 2026-08-22. #17058 */

/*+Kamala. claude. 2026-09-14. #17419
  Проблема: <TagsFilter> у тулбарі (report/payrollcontrol) при кількох вибраних тегах переносив їх
  за межі поля — теги налазили на наступний ряд тулбара й сусідні контроли; довга назва тегу
  вилазила за ширину поля.
  Причина: платформне .toolbar > .control-group .input-group { height: 2.2em } — фіксована висота
  поля, а .tags-items у ньому flex-wrap.
  Фікс: поле тегів росте за висотою, довга назва тегу — трикрапкою. Вирівнювання сусідів у рядку,
  що став вищим, — справа сторінки (payrollcontrol-report.css). */
.toolbar > .tags-control .input-group {
  height: auto;
  line-height: normal;
  min-width: 0;
}
.toolbar > .tags-control .tags-items {
  min-width: 0;
  padding: 1px 0;
}
.toolbar > .tags-control .tags-items li {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  min-width: 0;
}
.toolbar > .tags-control .tags-items li > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/*-Kamala. claude. 2026-09-14. #17419 */
/* +Kamala. claude. 2026-07-16. #16412 — підсвітка drag&drop у платформеному <TreeView>
   (логіка — _components/tree-dnd.ts). Класи вішаються на <li> вузла-цілі. */

/* рядок, який тягнуть */
.tree-view li.a2-dnd-drag > .overlay { opacity: 0.45; }

/* «вкласти всередину» — підсвічуємо весь вузол; box-shadow, а не border: border змінив би висоту
   рядка й дерево смикалось би прямо під курсором. */
.tree-view li.a2-dnd-into > .overlay {
	background: #dbeafe;
	box-shadow: inset 0 0 0 1px var(--accent-color, #2563eb);
	border-radius: 3px;
}

/* «перед / після» — лінія по відповідній межі вузла */
.tree-view li.a2-dnd-before > .overlay { box-shadow: inset 0 2px 0 0 var(--accent-color, #2563eb); }
.tree-view li.a2-dnd-after > .overlay { box-shadow: inset 0 -2px 0 0 var(--accent-color, #2563eb); }

.tree-view li[draggable="true"] > .overlay { cursor: grab; }
/* +Kamala. claude. 2026-07-05. a2-tree-grid — універсальне «дерево з колонками» (аналог ДереваЗначень 1С) */

/* Прилипання (sticky) тулбара, шапки й закріплених стовпців рахується від СКРОЛЕРА СТОРІНКИ (.page):
   report-сторінка (без Page.Toolbar) скролить сама сторінка. Тому власний overflow-контейнер НЕ
   робимо — інакше він виростає під увесь контент, не скролить сам, і sticky прилипає до нього ж (=нікуди). */
.tg-root {
	position: relative;
	font-size: 0.85rem;
}

/* #17399 без scrollself скролить предок, а sticky не виходить за containing block: корінь розтягуємо по
   таблиці, а тулбар звужуємо до видимої ширини скролера (--tg-view-w з JS) — тоді йому є куди липнути. */
.tg-root:not(.tg-scrollself) {
	width: max-content;
	min-width: 100%;
}
.tg-root:not(.tg-scrollself) .tg-bar { width: var(--tg-view-w, auto); }

/* верхня панель: липка зверху І зліва (кнопки лишаються у видимому кутку при будь-якому скролі).
   Висоту меряємо у JS → --tg-bar-h → зсув шапки під тулбар. */
.tg-root .tg-bar {
	position: sticky;
	top: 0;
	left: 0;
	z-index: 8;                                          /* вище шапки (4/6) та frozen-клітинок */
	display: flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.3rem 0.5rem;
	flex-wrap: wrap;
	box-sizing: border-box;
	background: var(--table-bg, #fff);
	border-bottom: 1px solid var(--border-color, #d0d3d9);
}
.tg-root .tg-btn {
	border: 1px solid var(--border-color, #d0d3d9);
	background: var(--table-header-bg, #f3f4f6);
	border-radius: 4px;
	padding: 2px 8px;
	cursor: pointer;
	font-size: 0.8rem;
	white-space: nowrap;
}
.tg-root .tg-btn:hover { background: #e8eaef; }
.tg-root .tg-btn-on { background: var(--accent-color, #2563eb); color: #fff; border-color: var(--accent-color, #2563eb); }
.tg-root .tg-lvl { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--text-muted, #6b7280); margin-left: 0.4rem; }
.tg-root .tg-btn-lvl { padding: 2px 7px; }

.tg-root .tg-scroll {
	width: max-content;      /* обгортає таблицю по її ширині, щоб рамка не обрізалась по ширині сторінки */
	min-width: 100%;
	box-sizing: border-box;  /* рамка всередині min-width:100% — інакше блок на 2 px ширший за корінь */
	border: 1px solid var(--border-color, #d0d3d9);
}

/* режим scrollself: власний обмежений скрол-контейнер (для вбудови у вкладку карти/діалог).
   .tg-scroll стає скролером обох осей; тулбар — flex-шапка (не sticky); шапка таблиці липне до .tg-scroll. */
.tg-root.tg-scrollself {
	height: 100%;
	display: flex;
	flex-direction: column;
}
.tg-scrollself .tg-bar { position: static; flex: 0 0 auto; }
.tg-scrollself .tg-scroll {
	flex: 1 1 auto;
	width: auto;
	min-width: 0;
	overflow: auto;
}
.tg-scrollself .tg-table thead th { top: 0; }   /* липне до .tg-scroll (тулбар зовні скролу) */

.tg-table {
	border-collapse: separate;
	border-spacing: 0;
	/* ширину задає інлайн tableStyle (calc суми ширин стовпців); table-layout:fixed → стовпці точно
	   за colgroup, контент обрізається. НЕ max-content: воно розширює стовпець під найдовший текст. */
	table-layout: fixed;
}

.tg-table th,
.tg-table td {
	border-right: 1px solid var(--border-color, #d0d3d9);
	border-bottom: 1px solid var(--border-color, #d0d3d9);
	padding: 2px 6px;
	text-align: left;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	background: #fff;
	box-sizing: border-box;
}

/* липка шапка — під тулбаром (top = виміряна висота тулбара --tg-bar-h) */
.tg-table thead th {
	position: sticky;
	top: var(--tg-bar-h, 0px);
	z-index: 4;
	background: var(--table-header-bg, #f3f4f6);
	font-weight: 600;
	text-align: center;
	height: 1.8rem;
}

/* ручка ресайзу стовпця — права межа заголовка (th вже sticky = positioned, absolute ловиться на нього) */
.tg-table thead th { overflow: hidden; }
.tg-table thead th .tg-h-text { display: block; overflow: hidden; text-overflow: ellipsis; }
.tg-table .tg-resizer {
	position: absolute;
	top: 0;
	right: 0;
	width: 6px;
	height: 100%;
	cursor: col-resize;
	user-select: none;
	z-index: 1;
}
.tg-table .tg-resizer:hover { background: var(--accent-color, #2563eb); opacity: 0.35; }
body.tg-resizing, body.tg-resizing * { cursor: col-resize !important; user-select: none !important; }

/* закріплені зліва стовпці (frozenN): left задається інлайн (frozenStyle) */
.tg-table td.tg-frozen,
.tg-table th.tg-frozen { position: sticky; z-index: 2; }
.tg-table thead th.tg-frozen { z-index: 6; }        /* перетин шапки й закріпленого стовпця — найвище */
.tg-table .tg-frozen-last { border-right: 2px solid var(--border-color, #c2c7cf); }

/* #17385 віртуалізація (opt-in prop virtualrows): два порожні рядки-розпірки тримають висоту
   за невідмальовані рядки. Гасимо padding/рамку — інакше розпірка домальовує зайву лінію.
   Тло не задаємо: правило .tg-table td вище вже фарбує клітинку тим самим #fff, а власна
   змінна зробила б розпірки єдиними клітинками тіла, що ходять за темою — тобто видимим швом. */
.tg-table .tg-vpad td { padding: 0; border: 0; }

/* #17385 липкий підсумок (opt-in prop totalrow): tfoot прилипає до низу того ж скролера, до верху
   якого прилипає шапка. Ярус той самий, що й у тіла (база + 2 на перетин із закріпленою колонкою):
   тіло 0/2, підсумок 3/5, шапка 4/6, тулбар 8. Перетнутись по вертикалі шапка з підсумком можуть
   лише у вироджено низькому контейнері, і то в межах ОДНІЄЇ колонки — а там шапка 6 > підсумок 5.
   По одній клітинці на колонку, без colspan: яруси не можуть розійтися по ширині. */
.tg-table tfoot td {
	position: sticky;
	bottom: 0;
	z-index: 3;
	background: var(--table-header-bg, #f3f4f6);
	font-weight: 600;
	border-top: 1px solid var(--border-color, #d0d3d9);
}
.tg-table tfoot td.tg-frozen { z-index: 5; }

/* перша (деревна) колонка */
.tg-table .tg-indent { display: inline-flex; align-items: center; max-width: 100%; }
.tg-table .tg-caret {
	display: inline-block;
	width: 1.1rem;
	flex: 0 0 1.1rem;
	cursor: pointer;
	color: var(--text-muted, #6b7280);
	text-align: center;
	user-select: none;
}
.tg-table .tg-caret:hover { color: var(--text-color, #1f2937); }
.tg-table .tg-caret-leaf { cursor: default; }

/* іконки рядків (iconprop): платформенний шрифт ico-*; папка — жовта, як у провіднику */
.tg-table .tg-ico { flex: 0 0 auto; margin-right: 0.35rem; color: var(--text-muted, #6b7280); }
.tg-table .tg-ico.ico-folder { color: #f0b429; }
.tg-table .tg-ico.ico-gear { color: #5b7a9d; }
.tg-table .tg-ico.ico-user { color: #2e8b57; }
.tg-table .tg-ico.ico-wrench { color: #b0611a; }
.tg-table .tg-ico.ico-package { color: #8a6d3b; }

/* групи / листи / курсор */
.tg-table tr.tg-group td { background: #f7f8fa; font-weight: 600; }
.tg-table tr.tg-leaf:hover td { background: #f6f8fb; }
.tg-table tr.tg-selected td { background: #e8f0fe; }
.tg-table tr.tg-group.tg-selected td { background: #dde9fc; }

/* клітинки даних */
.tg-table .tg-num { text-align: right; }
.tg-table .tg-al-center { text-align: center; }
.tg-table .tg-cell.tg-edit { cursor: cell; }
.tg-table .tg-cell.tg-active { outline: 2px solid var(--accent-color, #2563eb); outline-offset: -2px; padding: 0; }

.tg-input {
	width: 100%;
	height: 100%;
	border: none;
	outline: none;
	font: inherit;
	padding: 2px 6px;
	box-sizing: border-box;
	background: #fff;
}
.tg-input-num { text-align: right; }

.tg-empty td {
	text-align: center;
	color: var(--text-muted, #6b7280);
	padding: 1.5rem;
	font-style: italic;
}

.tg-locked .tg-cell.tg-edit { cursor: default; }

/* --- нові типи колонок: select / checkbox / status / action --- */
/* select: клітинка-посилання (клік → діалог у TS); порожня — приглушено */
.tg-table .tg-selcell { cursor: pointer; color: var(--accent-color, #2563eb); }
.tg-table .tg-selcell:hover { text-decoration: underline; }
.tg-table .tg-selcell.tg-selcell-empty { color: var(--text-muted, #9aa3af); }
.tg-locked .tg-selcell { cursor: default; text-decoration: none; }

/* #17325 link: клітинка-розшифровка. Обгортка НЕ фарбується — колір лишається на самому <a>, щоб
   клітинка без payload (link() віддав null) читалась як звичайне число. Правило .tg-locked, яке
   гасить .tg-selcell вище, сюди свідомо НЕ поширюється: locked = «не редагується», а розшифровка
   є й на read-only формі (перший читач — вкладка картки проєкту, вона locked цілком). */
.tg-table .tg-link { cursor: pointer; color: var(--accent-color, #2563eb); text-decoration: none; }
.tg-table .tg-link:hover { text-decoration: underline; }

.tg-table .tg-check { cursor: pointer; }

/* status: чіп звірки — переиспользуємо платформенний .tag-label.success/.danger (без власних класів) */

/* #16760 sub: друга, дрібна лінія під значенням клітинки (відсоток виконання).
   display:block — щоб у числовій колонці вона стала ПІД числом, а не поруч. */
.tg-table .tg-sub {
	display: block;
	font-size: 0.75rem;
	font-style: normal;
	line-height: 1.2;
	color: var(--text-muted, #6b7280);
}

/* #16760 bar: складена смуга прогресу + легенда під нею. Сегменти — flex-діти доріжки, ширина у %
   приходить з col.segments(row). Префікс саме tg-prg, а НЕ tg-bar: `.tg-root .tg-bar` вище — це
   липкий тулбар дерева, і збіг імені протікав би в доріжку своїм padding/border/sticky. */
.tg-table .tg-prg-cell { display: block; }
.tg-table .tg-prg {
	display: flex;
	height: 0.65rem;
	border-radius: 0.35rem;
	overflow: hidden;
	background: var(--bg-muted, #eef1f5);
}
.tg-table .tg-prg-seg { height: 100%; }
.tg-table .tg-prg-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 0.1rem 0.75rem;
	margin-top: 0.2rem;
	font-size: 0.72rem;
	line-height: 1.3;
	color: var(--text-muted, #6b7280);
}
.tg-table .tg-prg-tag { white-space: nowrap; }
.tg-table .tg-prg-dot {
	display: inline-block;
	width: 0.55rem;
	height: 0.55rem;
	margin-right: 0.25rem;
	border-radius: 0.15rem;
	/* обвідка: найсвітліший сегмент («залишок») інакше зливається з білим тлом легенди */
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.14);
}
/* Три НЕЙТРАЛЬНІ тони (як `status` віддає загальні success/danger, а не доменні слова): main —
   акцент теми, soft — його світліший відтінок, rest — залишок. Домен («заактовано» / «виконано,
   не заактовано» / «залишок») лишається у споживача, у підписах сегментів. */
.tg-table .tg-prg-main { background: var(--accent-color, #2563eb); }
.tg-table .tg-prg-soft { background: var(--accent-color-soft, #93c5fd); }
.tg-table .tg-prg-rest { background: var(--border-color, #dfe3e8); }

/* action: іконки-дії (+підрядок / видалити) */
.tg-table .tg-actions { display: inline-flex; gap: 0.4rem; align-items: center; }
.tg-table .tg-act { cursor: pointer; color: var(--text-muted, #6b7280); }
.tg-table .tg-act:hover { color: var(--accent-color, #2563eb); }
.tg-locked .tg-act { cursor: default; color: var(--text-muted, #9aa3af); }

/* #17393 контекстне меню рядка (rowmenu) і чип статусу, що його відкриває (status-колонка з menu).
   position: fixed — меню не обрізають overflow-контейнери гріда й сторінки; координати — клік у вікні. */
.tg-tag-menu { cursor: pointer; }
.tg-menu {
	position: fixed; z-index: 2000; min-width: 12rem; padding: 0.25rem 0;
	background: #fff; border: 1px solid var(--border-color, #d1d5db); border-radius: 4px;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
}
.tg-menu .tg-menu-item { display: block; padding: 0.35rem 0.9rem; color: inherit; text-decoration: none; white-space: nowrap; }
.tg-menu .tg-menu-item:hover { background: #e8f0fe; }

/* #17396 друк. Липкі тулбар / шапка / підсумок / закріплені колонки на папері стоять зі зсувом або поверх
   рядків, а overflow обрізає друк до видимої області. Рамку сторінки (@page, .page-content, чром) задає
   сторінка-споживач; віртуалізацію на час друку знімає tree-grid.js. */
@media print {
	.tg-root .tg-bar,
	.tg-table .tg-resizer { display: none !important; }
	.tg-root,
	.tg-scroll {
		overflow: visible !important;
		height: auto !important;
		max-height: none !important;
	}
	.tg-table th,
	.tg-table td { position: static !important; }
	/* ширини колонок лишаються екранними (table-layout: fixed), тож заголовок на папері переноситься,
	   а не обрізається трикрапкою: «Сальдо на поча…» не прочитати, а навести курсор нема на що */
	.tg-table thead th,
	.tg-table thead th .tg-h-text {
		white-space: normal;
		overflow: visible;
		text-overflow: clip;
		height: auto;
	}
	/* шапка повторюється на кожній сторінці штатно; підсумок — один раз у кінці */
	.tg-table tfoot { display: table-row-group; }
	.tg-table tr { break-inside: avoid; }
	.tg-table .tg-caret { visibility: hidden; }
	.tg-menu { display: none !important; }
}
