/*
  Оболочка приложения и общие элементы. Компоненты Kendo переопределяются в kendo-theme.css.
  Литеральных цветов здесь нет — только токены из tokens.css.
*/

* { box-sizing: border-box; }

html, body {
    height: 100%;
}

body {
    margin: 0;
    font-family: var(--ts-font);
    font-size: var(--ts-text-base);
    line-height: 1.45;
    color: var(--ts-text);
    background: var(--ts-bg);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0 0 var(--ts-space-3); font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: var(--ts-text-xl); }
h2 { font-size: var(--ts-text-lg); }

a { color: var(--ts-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- Оболочка ------------------------------------------------------------- */

/* Каркас (меню, шапка, оболочка) живёт в shell.css — он один на обе области. */

.ts-page-head {
    display: flex;
    align-items: center;
    gap: var(--ts-space-3);
    margin-bottom: var(--ts-space-3);
}
.ts-page-head h1 { margin: 0; }

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

.ts-panel:not(.k-card) {
    background: var(--ts-surface);
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-lg);
    box-shadow: var(--ts-shadow-sm);
}

.ts-panel-head:not(.k-card-header) {
    display: flex;
    align-items: center;
    gap: var(--ts-space-2);
    padding: var(--ts-space-3) var(--ts-space-4);
    border-bottom: 1px solid var(--ts-border);
}

.ts-panel-body:not(.k-card-body) { padding: var(--ts-space-4); }

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

.ts-btn:not(.k-button) {
    display: inline-flex;
    align-items: center;
    gap: var(--ts-space-2);
    height: var(--ts-control-height);
    padding: 0 var(--ts-space-3);
    font: inherit;
    font-size: var(--ts-text-base);
    color: var(--ts-text);
    background: var(--ts-surface);
    border: 1px solid var(--ts-border-strong);
    border-radius: var(--ts-radius);
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s, border-color .12s;
}
.ts-btn:not(.k-button):hover { background: var(--ts-surface-hover); text-decoration: none; }
.ts-btn:not(.k-button):disabled { opacity: .5; cursor: not-allowed; }

.ts-btn-primary:not(.k-button) {
    color: var(--ts-text-inverse);
    background: var(--ts-accent);
    border-color: var(--ts-accent);
}
.ts-btn-primary:not(.k-button):hover { background: var(--ts-accent-hover); border-color: var(--ts-accent-hover); }

.ts-btn-danger:not(.k-button) { color: var(--ts-danger); border-color: var(--ts-border-strong); }

/* Иконка перед текстом кнопки (ts-icons.js). Цвет — от текста кнопки: у «Удалить» она
   красная, у основной — белая, без отдельных правил. */
.ts-btn-icon {
    display: inline-flex;
    flex: none;
    width: 16px;
    height: 16px;
    color: currentColor;
}
.ts-btn-icon svg { width: 100%; height: 100%; fill: currentColor; }
.ts-btn-icon .ts-sprite-icon { fill: none; stroke: currentColor; }
.ts-btn-sm .ts-btn-icon { width: 14px; height: 14px; }
.ts-btn-danger:not(.k-button):hover { background: var(--ts-danger-soft); border-color: var(--ts-danger); }

/* Круглая кнопка-подсказка «i» рядом с главной кнопкой страницы (иерархия: «Зарплата не
   посчитается»). Янтарная — это предупреждение, а не справка; цифра в углу — сколько записей
   внутри; нажатая (aria-expanded) заливается, чтобы было видно, что панель открыта. */
.ts-btn-info {
    position: relative;
    justify-content: center;
    width: var(--ts-control-height);
    padding: 0;
    border-radius: 50%;
    color: var(--ts-warning);
    background: var(--ts-warning-soft);
    border-color: color-mix(in srgb, var(--ts-warning) 45%, var(--ts-border));
}
.ts-btn-info .ts-btn-icon { width: 18px; height: 18px; }
.ts-btn-info:hover { background: color-mix(in srgb, var(--ts-warning) 18%, var(--ts-surface)); }
.ts-btn-info[aria-expanded="true"] {
    color: var(--ts-text-inverse);
    background: var(--ts-warning);
    border-color: var(--ts-warning);
}
.ts-btn-info[data-count]::after {
    content: attr(data-count);
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    box-sizing: border-box;
    border-radius: 8px;
    font-size: 10px;
    font-weight: 600;
    line-height: 16px;
    text-align: center;
    color: var(--ts-text-inverse);
    background: var(--ts-danger);
}

/* --- Состояния строки ------------------------------------------------------ */

/*
    Состояние строки — ФЛАЖКОМ, как в Timesheet8: серое древко и цветное полотнище.
    Колонка узкая и стоит первой, а цвет читается периферийным зрением, когда просматриваешь
    два десятка строк подряд. Название состояния — в подсказке при наведении.

    Полотнище — треугольник на границах (border), цвет берётся из currentColor: его задаёт
    инлайновый стиль по значению из справочника состояний. Классов с цветами здесь нет
    намеренно — иначе цвет жил бы в двух местах и разошёлся бы после первой правки справочника.
*/
.ts-flag {
    position: relative;
    display: inline-block;
    width: 13px;
    height: 14px;
    vertical-align: middle;
}

.ts-flag::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 2px;
    border-radius: 1px;
    background: var(--ts-text-faint);
}

.ts-flag::after {
    content: "";
    position: absolute;
    left: 2px;
    top: 1px;
    width: 0;
    height: 0;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 9px solid currentColor;
}

/* Строка в счёте — приглушена: её нельзя править, и это должно читаться до клика. */
.ts-row-locked td { color: var(--ts-text-muted); }

/* Пометка «обратить внимание» — полоской слева, а не заливкой строки: заливка спорит с
   выделением активной строки и делает грид пёстрым. */
.ts-row-marked td:first-child { box-shadow: inset 3px 0 0 var(--ts-warning); }

/* Фон строки по состоянию: цвет состояния, разбавленный до светлого оттенка. Смешение с
   прозрачным, а не с белым, — так оттенок читается и в тёмной теме. Селектор с .k-grid
   перебивает чередование и наведение Kendo. */
.k-grid tbody tr.ts-row-tinted > td {
    background-color: color-mix(in srgb, var(--ts-row-tint) 14%, transparent);
}
.k-grid tbody tr.ts-row-tinted:hover > td {
    background-color: color-mix(in srgb, var(--ts-row-tint) 24%, transparent);
}

/* Галочка флага в таблице: зелёная, нарисована границами — без шрифта и картинок, цвет от
   токена. Пустая ячейка = «нет». */
.ts-check {
    display: inline-block;
    width: 6px;
    height: 11px;
    margin-bottom: 3px;
    border: solid var(--ts-success);
    border-width: 0 2.5px 2.5px 0;
    transform: rotate(45deg);
}
.ts-center { text-align: center; }

/* Неактивные записи серым — соглашение перенесено из Timesheet8. */
.ts-inactive { color: var(--ts-text-faint); }
/* Класс стоит на строке (грид Kendo, таблица карточки), а цвет задан на ячейке — поэтому ячейки красим отдельно. */
tr.ts-inactive > td { color: var(--ts-text-faint); }
.k-grid tr.ts-muted > td { color: var(--ts-text-muted); }

/* Числа не переносятся никогда: «210 250,00» в две строки — это не число, а загадка. */
.ts-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ts-neg { color: var(--ts-danger); }

/* Маленький значок «?» рядом с подписью: пояснение прячется в подсказку (title), а не занимает строку. */
.ts-help {
    display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px; margin-left: var(--ts-space-1);
    border: 1px solid var(--ts-border); border-radius: 50%;
    color: var(--ts-text-muted); font-size: 11px; line-height: 1; cursor: help;
    user-select: none;
}
.ts-help:hover { color: var(--ts-accent); border-color: var(--ts-accent); }

/* Таблицы выбора заказов и расходов (создание счёта, «Сборка»): числа и их заголовки — по правому краю. */
.ts-pick-table th.ts-num,
.ts-pick-table td.ts-num { text-align: right; }

/* Колонка ПО СОДЕРЖИМОМУ: занимает ровно то, что нужно, и ни пикселем больше.
   width:1% в таблице с автораскладкой означает «дай минимум» — браузер расширит ячейку
   до содержимого (мешает этому только перенос, поэтому nowrap), а весь остаток отдаст
   колонкам без ширины. Так текстовая колонка забирает свободное место, а дата, часы и
   сумма не растягиваются на пол-экрана.

   Раньше на этих местах стояли фиксированные rem: их приходилось подбирать под самое
   длинное значение, и при первом же имени подлиннее колонка либо резала текст, либо
   отъедала место у описания работ. */
.ts-tight { width: 1%; white-space: nowrap; }

/*
    Перенос внутри узкой колонки. «Узкая» (ts-tight) — это «дай минимум» плюс запрет
    переноса, и длинный текст в такой ячейке превращает минимум в свою полную длину: колонка
    расползается, а числовая уезжает за край экрана. Так пропадала сумма оплаты, под датой
    которой стояло примечание из 1С.
*/
.ts-wrap { white-space: normal; }

.ts-muted { color: var(--ts-text-muted); }
.ts-sm { font-size: var(--ts-text-sm); }
.ts-xs { font-size: var(--ts-text-xs); }

/* --- Формы ----------------------------------------------------------------- */

.ts-field { margin-bottom: var(--ts-space-3); }

.ts-label {
    display: block;
    margin-bottom: var(--ts-space-1);
    font-size: var(--ts-text-sm);
    font-weight: 500;
    color: var(--ts-text-muted);
}

.ts-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--ts-space-3); }
.ts-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 var(--ts-space-3); }

.ts-form-foot {
    display: flex;
    align-items: center;
    gap: var(--ts-space-2);
    padding-top: var(--ts-space-3);
    margin-top: var(--ts-space-2);
    border-top: 1px solid var(--ts-border);
}
/* «Удалить» — справа, отдельно от «Сохранить»: соседние кнопки разного смысла ловят
   случайный клик. Соглашение из Timesheet8. */
.ts-form-foot .ts-push { margin-left: auto; }

.ts-error {
    padding: var(--ts-space-2) var(--ts-space-3);
    margin-bottom: var(--ts-space-3);
    font-size: var(--ts-text-sm);
    color: var(--ts-danger);
    background: var(--ts-danger-soft);
    border: 1px solid var(--ts-danger);
    border-radius: var(--ts-radius);
}

.ts-hint {
    padding: var(--ts-space-2) var(--ts-space-3);
    margin-bottom: var(--ts-space-3);
    font-size: var(--ts-text-sm);
    color: var(--ts-warning);
    background: var(--ts-warning-soft);
    border: 1px solid var(--ts-warning);
    border-radius: var(--ts-radius);
}

/* Подсказка ВНУТРИ строки таблицы — пояснение рядом с подписью, а не плашка на всю
   ширину. Вертикальный padding у строчного элемента высоту строки не раздвигает, а
   выходит за её пределы: с плотными строками такая подсказка наезжает на соседние. */
.ts-table .ts-hint {
    display: inline-block;
    padding: 0 var(--ts-space-2);
    margin: 0 0 0 var(--ts-space-2);
    vertical-align: middle;
}

/* --- Вход ------------------------------------------------------------------ */

.ts-auth { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; padding: var(--ts-space-4); }
.ts-auth-card { width: 100%; max-width: 360px; padding: var(--ts-space-5); background: var(--ts-surface); border: 1px solid var(--ts-border); border-radius: var(--ts-radius-lg); box-shadow: var(--ts-shadow); }
.ts-auth-logo { display: block; max-width: 220px; max-height: 64px; margin: 0 auto var(--ts-space-4); object-fit: contain; }
.ts-auth-remember { display: flex; align-items: center; gap: var(--ts-space-2); font-size: var(--ts-text-sm); cursor: pointer; }
.ts-auth-remember input { margin: 0; width: 16px; height: 16px; accent-color: var(--ts-primary, #0e7566); }
.ts-auth-title { margin: 0 0 var(--ts-space-1); font-size: var(--ts-text-xl); text-align: center; }
.ts-auth-sub { text-align: center; margin: 0 0 var(--ts-space-4); color: var(--ts-text-muted); font-size: var(--ts-text-sm); }

/* --- Мой профиль ------------------------------------------------------------ */

.ts-profile { display: grid; grid-template-columns: 20rem minmax(0, 1fr); gap: var(--ts-space-4); align-items: start; }
.ts-profile-main { display: grid; gap: var(--ts-space-4); }
.ts-profile-card .ts-panel-body { display: flex; flex-direction: column; align-items: center; text-align: center; }
.ts-profile-photo { width: 128px; height: 128px; margin-bottom: var(--ts-space-3); border-radius: 50%; overflow: hidden; background: var(--ts-accent-soft); display: flex; align-items: center; justify-content: center; }
.ts-profile-photo img { width: 100%; height: 100%; object-fit: cover; }
.ts-profile-initials { font-size: 2.5rem; font-weight: 600; color: var(--ts-accent); }
.ts-profile-name { margin: 0 0 var(--ts-space-1); font-size: var(--ts-text-xl); }
.ts-profile-facts { width: 100%; margin: var(--ts-space-4) 0; display: grid; grid-template-columns: auto 1fr; gap: var(--ts-space-2) var(--ts-space-3); text-align: left; font-size: var(--ts-text-sm); }
.ts-profile-facts dt { color: var(--ts-text-muted); }
.ts-profile-facts dd { margin: 0; }
.ts-profile-chip { display: inline-block; margin: 0 var(--ts-space-1) var(--ts-space-1) 0; padding: 1px var(--ts-space-2); border: 1px solid var(--ts-border); border-radius: 999px; background: var(--ts-surface-hover); font-size: var(--ts-text-xs); }
.ts-profile-actions { display: flex; gap: var(--ts-space-2); flex-wrap: wrap; justify-content: center; }
.ts-profile-perms { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--ts-space-4); }
.ts-profile-perms h3 { margin: 0 0 var(--ts-space-2); font-size: var(--ts-text-sm); color: var(--ts-text-muted); font-weight: 600; }
.ts-profile-perms ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--ts-space-1); font-size: var(--ts-text-sm); }
.ts-profile-perms li { display: flex; align-items: baseline; gap: var(--ts-space-2); }
.ts-profile-perms li .ts-check { flex: none; }
@media (max-width: 900px) { .ts-profile { grid-template-columns: 1fr; } }

/* --- Таблица (админка; тайм-шиты рисует Kendo Grid) ------------------------ */

/* Вертикальный отступ 4px, а не 8: приложение 2 месячного счёта — это полторы сотни
   строк, и каждые лишние четыре пикселя в строке это пол-экрана прокрутки. Строки
   разделяет граница, а не воздух между ними. По горизонтали отступ прежний — там он
   отделяет колонки друг от друга, и сжимать его нельзя. */

.ts-table { width: 100%; border-collapse: collapse; font-size: var(--ts-text-base); }
.ts-table th {
    padding: var(--ts-space-1) var(--ts-space-3);
    text-align: left;
    font-weight: 500;
    font-size: var(--ts-text-sm);
    color: var(--ts-text-muted);
    background: var(--ts-surface-muted);
    border-bottom: 1px solid var(--ts-border);
}
.ts-table td { padding: var(--ts-space-1) var(--ts-space-3); border-bottom: 1px solid var(--ts-border); }
.ts-table tbody tr:hover { background: var(--ts-surface-hover); }

.ts-input:not(.k-input) {
    width: 100%;
    height: var(--ts-control-height);
    padding: 0 var(--ts-space-2);
    font: inherit;
    font-size: var(--ts-text-base);
    color: var(--ts-text);
    background: var(--ts-surface);
    border: 1px solid var(--ts-border-strong);
    border-radius: var(--ts-radius);
}
.ts-input:not(.k-input):focus { outline: 2px solid var(--ts-accent-border); outline-offset: -1px; border-color: var(--ts-accent); }

/* Поле, которое показывают, но не правят: высота та же, что у ts-input, — иначе соседние
   поля в сетке разъезжаются по вертикали, и форма выглядит сломанной, а не частично
   закрытой. Рамки нет: она обещала бы правку. */
.ts-static {
    display: flex;
    align-items: center;
    min-height: var(--ts-control-height);
    padding: 0 var(--ts-space-2);
    font-size: var(--ts-text-base);
    color: var(--ts-text-muted);
    background: var(--ts-surface-muted);
    border-radius: var(--ts-radius);
}

@media (max-width: 720px) {
    .ts-grid-2, .ts-grid-3 { grid-template-columns: 1fr; }
}

/* --- Экран справочников ------------------------------------------------------ */

.ts-dict-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--ts-space-2) var(--ts-space-3);
    border-bottom: 1px solid var(--ts-border);
    color: var(--ts-text);
    text-decoration: none;
}

.ts-dict-item:hover { background: var(--ts-surface-hover); }

.ts-dict-item.is-active {
    background: var(--ts-accent-soft);
    box-shadow: inset 3px 0 0 var(--ts-accent);
}

/* Кнопка в строке грида: полная высота там ломает компактный ряд. */
.ts-btn-sm:not(.k-button) {
    height: 26px;
    padding: 0 var(--ts-space-2);
    font-size: var(--ts-text-xs);
}

/* Кнопки AI-помощника («AI» — проверка текста, «EN» — перевод) видны всегда, как в Timesheet8. Не включён или не настроен —
   сервер отвечает текстом «AI-помощник не настроен…», он выводится дословно. Проверка при сохранении (tsAiReview) работает,
   только когда ai-tools.js поставил ts-ai-on на <html> (Ai/Status ответил «доступен»). */
.ts-ai-row { display: flex; align-items: center; justify-content: space-between; gap: var(--ts-space-2); margin-bottom: var(--ts-space-1); }
.ts-ai-row .ts-label { margin-bottom: 0; }
.ts-ai-tools { display: inline-flex; gap: 6px; }
.ts-busy { opacity: .55; cursor: progress; }

/* --- Карточка документа ------------------------------------------------------
   Счёт смотрят целиком: слева сам документ (реквизиты, суммы, оплаты), справа
   приложения к нему. Две колонки, а не одна длинная лента, потому что вопросы
   «на сколько выставлен» и «за что именно» задают одновременно, а приложение 2
   месячного счёта — это сотни строк, через которые иначе пришлось бы прокручивать
   до итога. */

.ts-cols {
    display: grid;
    grid-template-columns: minmax(22rem, 30rem) minmax(0, 1fr);
    gap: var(--ts-space-3);
    align-items: start;
}

/* Панели внутри колонки идут стопкой с тем же шагом, что и между колонками. */
.ts-col { display: flex; flex-direction: column; gap: var(--ts-space-3); min-width: 0; }

/* На узком экране колонки складываются: приложения уходят под документ, а не
   сжимаются до нечитаемой ширины. */
@media (max-width: 1200px) {
    .ts-cols { grid-template-columns: 1fr; }
}

/* Строка «метка — значение». Метка фиксированной ширины: значения тогда выстраиваются
   в столбец, и карточка читается сверху вниз, а не зигзагом. */
.ts-info-row {
    display: flex;
    gap: var(--ts-space-3);
    padding: var(--ts-space-2) 0;
    border-bottom: 1px solid var(--ts-border);
}
.ts-info-row:last-child { border-bottom: none; }

.ts-info-label {
    flex: 0 0 7rem;
    font-size: var(--ts-text-sm);
    color: var(--ts-text-muted);
}

.ts-info-value { flex: 1; min-width: 0; font-size: var(--ts-text-base); }

/* Итоговая строка таблицы. Жирная и без нижней границы: под ней ничего нет. */
.ts-total-row td {
    font-weight: 600;
    background: var(--ts-surface-muted);
    border-bottom: none;
}

/* Метка рядом с состоянием: «провизорный», «скрыт», «инфляционный». */
.ts-badge {
    display: inline-flex;
    align-items: center;
    padding: 1px var(--ts-space-2);
    font-size: var(--ts-text-xs);
    color: var(--ts-text-muted);
    background: var(--ts-surface-muted);
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-sm);
    text-decoration: none;
}

.ts-badge-warn {
    color: var(--ts-warning);
    background: var(--ts-warning-soft);
    border-color: var(--ts-warning);
}

/* Полоса оплаты. Отвечает на вопрос «сколько уже пришло» до чтения цифр — у
   частично оплаченного счёта это первое, что хотят увидеть. */
.ts-pay-bar {
    height: 6px;
    background: var(--ts-surface-hover);
    border-radius: 3px;
    overflow: hidden;
}

.ts-pay-bar-fill { height: 100%; background: var(--ts-success); border-radius: 3px; }

/* Текст, который правится кликом. Пунктир снизу — обещание, что здесь что-то
   произойдёт: без него человек не отличит эту ячейку от соседней. */
.ts-editable { cursor: text; border-bottom: 1px dashed var(--ts-border-strong) !important; }
.ts-editable:hover { background: var(--ts-accent-soft); }

/* Сворачиваемая панель на <details>: состояние держит браузер, и сорока строк
   своего JS ради «спрятать приложение» не нужно. */
.ts-fold > summary {
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.ts-fold > summary::-webkit-details-marker { display: none; }

/* При теме Telerik заголовок получает k-card-header, и общее правило .ts-panel-head:not(.k-card-header)
   не действует: без flex треугольник (::before с нулевым размером) рисуется чёрной полосой, а счётчик
   строк не уходит вправо. Раскладку строки держим здесь, независимо от темы. */
.ts-fold > summary {
    display: flex;
    align-items: center;
    gap: var(--ts-space-2);
}

/* Треугольник рисуем сами и поворачиваем при раскрытии: у нативного маркера нет
   способа встать в конец строки рядом со счётчиком строк. */
.ts-fold > summary::before {
    content: "";
    flex: none;
    width: 0;
    height: 0;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 6px solid var(--ts-text-faint);
    transition: transform .12s ease;
}

.ts-fold[open] > summary::before { transform: rotate(90deg); }

/* Закрытая панель остаётся одной строкой — граница под заголовком тогда лишняя. */
.ts-fold:not([open]) > summary { border-bottom: none; }

/* Заголовок группы внутри таблицы: заказ в приложении 1. Строкой, а не ячейкой слева —
   описание заказа длинное, и в узкой колонке оно рассыпается по одному слову. */
.ts-group-row td {
    font-weight: 600;
    background: var(--ts-surface-muted);
    border-bottom: 1px solid var(--ts-border);
}


/* --- Сверка платежей с 1С ------------------------------------------------------
   Плашки над таблицей — группы по тому, что со строкой делать. Цвет группы один и в
   плашке, и в метке статуса строки: глаз связывает их без подписи. */

.ts-recon-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ts-space-3) var(--ts-space-5);
    margin-bottom: var(--ts-space-3);
}

.ts-recon-period {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ts-space-2);
}

.ts-recon-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ts-space-2);
    margin-left: auto;
}

.ts-recon-tile {
    --tile: var(--ts-text-muted);
    display: grid;
    grid-template-columns: auto auto;
    align-items: baseline;
    column-gap: var(--ts-space-3);
    min-width: 9.5rem;
    padding: var(--ts-space-1) var(--ts-space-3);
    font: inherit;
    text-align: left;
    color: var(--ts-text);
    background: var(--ts-surface);
    border: 1px solid var(--ts-border);
    border-left: 3px solid var(--tile);
    border-radius: var(--ts-radius);
    cursor: pointer;
}

.ts-recon-tile:hover { background: var(--ts-surface-hover); }
.ts-recon-tile.is-active { border-color: var(--tile); box-shadow: 0 0 0 1px var(--tile) inset; }
.ts-recon-tile.is-empty { opacity: .55; }

.ts-recon-tile-title { grid-column: 1 / -1; font-size: var(--ts-text-xs); color: var(--ts-text-muted); }
.ts-recon-tile-count { font-size: var(--ts-text-lg); font-weight: 600; color: var(--tile); }
.ts-recon-tile-sum { font-variant-numeric: tabular-nums; font-size: var(--ts-text-xs); color: var(--ts-text-muted); text-align: right; }

.is-ok { --tile: var(--ts-success); }
.is-record { --tile: var(--ts-accent); }
.is-problem { --tile: var(--ts-danger); }
.is-other { --tile: var(--ts-text-faint); }

.ts-recon-status {
    display: inline-block;
    padding: 1px var(--ts-space-2);
    font-size: var(--ts-text-xs);
    white-space: nowrap;
    color: var(--tile);
    border: 1px solid var(--tile);
    border-radius: var(--ts-radius-sm);
}

/* Расхождение не должно теряться среди сошедшихся строк. Цвет — на ячейках: у строки
   грида Kendo фон задаёт на td. */
.ts-recon-row-problem > td { background: var(--ts-danger-soft); }

.ts-recon-diff { color: var(--ts-danger); font-weight: 600; }
.ts-recon-warn { color: var(--ts-warning); }

.ts-recon-comment {
    max-width: 18rem;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Оплата в списке счетов: недоплата и отрицательная курсовая разница — красным, переплата и
   положительная — зелёным. Как в Timesheet8: остаток виден без вычитания в уме. */
.ts-paid-less { color: var(--ts-danger); }
.ts-paid-more { color: var(--ts-success); }

/* Сумма долей разнесения, отличная от ста, — красным: сервер такую запись не примет,
   и видеть это лучше до нажатия «Сохранить». */
.ts-share-off { color: var(--ts-danger); font-weight: 600; }

/* --- Курсы валют ------------------------------------------------------------ */

/* Карточки графиков: столько в ряд, сколько влезает по 360px, растянуты на всю ширину
   (auto-fit, а не auto-fill: тот держал бы пустое место под несуществующую четвёртую
   валюту). Три валюты на широком
   экране встают в строку, на узком уходят одна под другую. */
.ts-rates-charts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: var(--ts-space-3);
}
/* Кнопка «Графики» в нажатом виде — графики показаны. */
#btnRatesCharts.is-active { background: var(--ts-accent-soft); border-color: var(--ts-accent-border); color: var(--ts-accent); }
.ts-rates-charts { margin-bottom: var(--ts-space-4); }
/* display:grid выше перебивает атрибут hidden браузера — без этого графики не прятались бы. */
.ts-rates-charts[hidden] { display: none; }
.ts-rate-card { padding: var(--ts-space-3); margin: 0; }
.ts-rate-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--ts-space-3); }
.ts-rate-code { font-size: var(--ts-text-lg); font-weight: 600; color: var(--ts-text); }
.ts-rate-stats { text-align: right; }
.ts-rate-last { font-size: var(--ts-text-xl); font-weight: 600; color: var(--ts-text); font-variant-numeric: tabular-nums; }

/* Стрелки таблицы: рост курса — тенге дешевеет — красным, как в Timesheet8. Направление
   несёт сама стрелка, цвет только вторит ей. Ширина фиксирована, чтобы числа стояли разряд
   в разряд и в строках без стрелки. */
.ts-rate-up, .ts-rate-down, .ts-rate-flat { display: inline-block; width: 12px; text-align: left; font-size: var(--ts-text-xs); }
.ts-rate-up { color: var(--ts-danger); }
.ts-rate-down { color: var(--ts-success); }

/* Вид корректировки: знак несёт текст («+ Доплата», «− Возврат»), цвет только вторит. */
.ts-adj-surcharge { color: var(--ts-success); }
.ts-adj-refund { color: var(--ts-danger); }

/* Поля будущих виджетов Kendo до их создания (см. ts-booting в _Layout): невидимы, но
   место держат — иначе форма сначала показывала бы голые <select> и <input>, а потом
   перерисовывалась. Обычные поля (ts-input), флажки и поиск видны сразу: их Kendo не
   трогает. <select multiple> ужат до одной строки — будущий MultiSelect тоже в одну, и
   без этого форма прыгала бы по высоте. */
.ts-booting .ts-content input:not([type=hidden]):not([type=checkbox]):not([type=radio]):not([type=search]):not(.ts-input):not(.k-input-inner),
.ts-booting .ts-content select:not(.ts-input),
.ts-booting .ts-content textarea:not(.ts-input) { visibility: hidden; }
.ts-booting .ts-content select[multiple]:not(.ts-input) { height: 30px; overflow: hidden; }

/* Кнопка, на которую надо нажать (перерасчёт при устаревших суммах): мягкая пульсация кольцом. */
.ts-pulse { animation: ts-pulse 1.6s ease-in-out infinite; }
@keyframes ts-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ts-accent) 55%, transparent); }
    50% { box-shadow: 0 0 0 6px transparent; }
}
@media (prefers-reduced-motion: reduce) { .ts-pulse { animation: none; } }

/* --- Файлы клиента (карточка) ------------------------------------------------ */
.ts-files-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--ts-space-3); padding: var(--ts-space-2) var(--ts-space-3); flex-wrap: wrap; }
.ts-files-crumbs { font-size: var(--ts-text-sm, 13px); }
.ts-files-crumbs a { color: var(--ts-accent, inherit); text-decoration: none; }
.ts-files-crumbs a:hover { text-decoration: underline; }
.ts-files-actions { display: flex; gap: var(--ts-space-2); }
.ts-files-icon { display: inline-block; width: 1.4em; text-align: center; }
.ts-files-open { text-decoration: none; }
#clientFiles.ts-files-drop { outline: 2px dashed var(--ts-accent, #2563eb); outline-offset: -2px; }

/*
    Переключатель из трёх состояний в строке таблицы (личные права: по ролям / выдать / запретить).
    Три радио в один ряд кнопок вместо столбика с переносами; выбранное видно цветом: «выдать» — зелёным,
    «запретить» — красным, «по ролям» — нейтральным. Радио остаются настоящими (форма шлёт их как раньше,
    клавиатура работает), прячется только кружок.
*/
.ts-seg { display: inline-flex; border: 1px solid var(--ts-border); border-radius: var(--ts-radius); overflow: hidden; white-space: nowrap; }
.ts-seg label { position: relative; margin: 0; padding: 4px 12px; cursor: pointer; font-size: 13px; color: var(--ts-text-muted); background: var(--ts-surface); user-select: none; }
.ts-seg label + label { border-left: 1px solid var(--ts-border); }
.ts-seg label:hover { background: var(--ts-surface-hover); }
.ts-seg input { position: absolute; opacity: 0; pointer-events: none; }
.ts-seg label:has(input:checked) { background: var(--ts-surface-hover); color: var(--ts-text); font-weight: 600; }
.ts-seg label.is-grant:has(input:checked) { background: color-mix(in srgb, var(--ts-success) 16%, var(--ts-surface)); color: var(--ts-success); }
.ts-seg label.is-deny:has(input:checked) { background: color-mix(in srgb, var(--ts-danger) 14%, var(--ts-surface)); color: var(--ts-danger); }
.ts-seg label:has(input:focus-visible) { outline: 2px solid var(--ts-accent); outline-offset: -2px; }

/* Многострочное поле растёт по тексту (Chrome/Edge: field-sizing). rows — высота «по умолчанию» там, где свойства нет;
   max-height не даёт очень длинному тексту растянуть форму — дальше поле прокручивается. */
textarea.ts-autosize { field-sizing: content; min-height: 4.5em; max-height: 40vh; resize: vertical; }

/* Публичные юридические страницы (политика, условия): читаемый текст в одну колонку. */
.ts-legal { max-width: 820px; margin: 0 auto; padding: 32px 16px 64px; line-height: 1.6; color: var(--ts-text); }
.ts-legal h1 { font-size: 1.8rem; margin: 0 0 4px; }
.ts-legal h2 { font-size: 1.2rem; margin: 28px 0 8px; }
.ts-legal p, .ts-legal ul { margin: 8px 0; }
.ts-legal ul { padding-left: 22px; }
.ts-legal .ts-legal-meta { color: var(--ts-text-muted, #667085); margin-bottom: 24px; }
.ts-legal .ts-legal-nav { display: flex; gap: 16px; margin-bottom: 24px; font-size: .9rem; }
.ts-legal .ts-legal-en { margin-top: 40px; padding-top: 8px; border-top: 1px solid var(--ts-border); }
