/* Общий UI-базис FORTO OS + FORTO FC. Палитра задаётся проектом. */
:root {
  --col-id: 8ch;
  --col-project: 8ch;
  --col-period: 11ch;
  --col-date: 12ch;
  --col-datetime: 17ch;
  --col-money: 14ch;
  --col-status: 12rem;
  --col-actions: 8rem;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-6: 24px;
  --z-content: 0;
  /* Залипающая шапка таблицы стоит НИЖЕ главного меню: на узком экране меню
     становится горизонтальной полосой с --z-sticky, и шапка не должна его
     перекрывать (Р-61). */
  --z-table-head: 9;
  --z-sticky: 10;
  --z-dropdown: 100;
  --z-modal: 1000;
  --z-toast: 2000;
  /* Отступ залипающей шапки от верха окна. 0 на широком экране (меню — левая
     колонка); на узком экране высоту горизонтального меню подставляет
     base.html. */
  --table-head-top: 0px;
}

* { box-sizing: border-box; }
.content, .main, .page { min-width: 0; }
.nowrap { white-space: nowrap; }
/* Текст только для чтения с экрана. Раньше он выносился из потока
   `position: absolute` — и в шапке таблицы это давало горизонтальную
   прокрутку ВСЕЙ страницы: ячейка шапки залипающая, то есть
   позиционированная, и Chrome считал вклад скрытого слова в ширину не по
   тому месту, где оно нарисовано. Страдали «Заявки на оплату»,
   «Объекты» и «Уведомления» — везде, где есть безымянный столбец
   действий. Теперь слово остаётся в потоке размером 1×1 px и обрезается
   `clip-path`: из потока оно не выходит и вылезти ниоткуда не может. */
.sr-only { width: 1px; height: 1px; padding: 0; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; display: inline-block; }
.wrap-words { overflow-wrap: normal; word-break: normal; }
.wrap-anywhere { overflow-wrap: break-word; word-break: normal; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Залипающая шапка таблицы — ЕДИНОЕ правило (Р-61), объявлено здесь и только
   здесь. Работает лишь при трёх условиях одновременно, каждое из которых легко
   потерять при правке стилей:
     1) у .table НЕТ overflow (иначе таблица сама становится окном прокрутки и
        шапка липнет к своей же границе — то есть никуда);
     2) у .table-wrap горизонтальная прокрутка включена ТОЛЬКО когда таблица
        реально шире контейнера (класс ставит base.html): прокрутка по любой
        оси лишает вторую ось сквозного поведения;
     3) правило не перекрыто повторным объявлением .table thead th в палитре
        программы.
   Проверяется regression_table_display.py. */
.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Класс записан ДВАЖДЫ намеренно. Палитра программы подключается после этого
   файла и объявляет `.table-wrap` со своей прокруткой; при равной силе
   селектора побеждало бы её правило, и залипание молча выключалось бы —
   именно так и произошло 09.08.2026. Двойной класс сильнее и не зависит от
   порядка подключения файлов. Не упрощать до одного класса. */
.table-wrap.table-wrap--fits { overflow: visible; }
.table-wrap:focus-visible { outline: 2px solid var(--accent, #2f5bd4); outline-offset: 2px; }
.table-wrap > .table { margin: 0; }
.table { width: 100%; max-width: 100%; border-collapse: collapse; background: var(--panel, #fff); border: 1px solid var(--line, #e3e8ef); border-radius: 12px; margin: 10px 0; }
.table.narrow { width: auto; min-width: 420px; }
.table th, .table td { padding: 8px 10px; vertical-align: top; line-height: 1.35; word-break: normal; overflow-wrap: normal; border-bottom: 1px solid var(--line, #e3e8ef); }
.table thead th { text-align: left; font-weight: 600; white-space: normal; overflow-wrap: break-word; background: var(--surface-2, #f8fafc); position: sticky; top: var(--table-head-top, 0px); z-index: var(--z-table-head, 9); box-shadow: inset 0 -1px 0 var(--line, #e3e8ef); }
.table thead th + th { border-left: 1px solid var(--line, #e3e8ef); box-shadow: inset 1px 0 0 var(--line, #e3e8ef), inset 0 -1px 0 var(--line, #e3e8ef); }
/* Скругление углов раньше делал overflow:hidden у .table; он же ломал залипание.
   Углы скругляются угловыми ячейками — вид прежний, залипание работает. */
.table > thead > tr:first-child > th:first-child { border-top-left-radius: 12px; }
.table > thead > tr:first-child > th:last-child { border-top-right-radius: 12px; }
.table:not(:has(tfoot)) > tbody > tr:last-child > td:first-child { border-bottom-left-radius: 12px; }
.table:not(:has(tfoot)) > tbody > tr:last-child > td:last-child { border-bottom-right-radius: 12px; }
.table > tfoot > tr:last-child > td:first-child { border-bottom-left-radius: 12px; }
.table > tfoot > tr:last-child > td:last-child { border-bottom-right-radius: 12px; }
.table tbody tr:last-child td { border-bottom: none; }
.table tfoot td { background: var(--surface-2, #faf8f4); border-top: 2px solid var(--line, #e3e8ef); font-weight: 600; }
.table .num, .cell-money { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cell-id { min-width: var(--col-id); }
.cell-project, .cell-object { min-width: var(--col-project); }
.cell-period { min-width: var(--col-period); }
.cell-date { min-width: var(--col-date); }
.cell-datetime { min-width: var(--col-datetime); }
.cell-money, .table .num { min-width: var(--col-money); }
.cell-status { min-width: var(--col-status); }
.cell-actions { min-width: var(--col-actions); white-space: nowrap; }
.cell-text, .cell-comment, .cell-title { overflow-wrap: normal; word-break: normal; min-width: 0; }
.table.kv td:first-child { color: var(--muted, #667085); width: 190px; }
.table.kv td:last-child { overflow-wrap: break-word; word-break: normal; }

/* Форма кнопки. Перечень обязан включать КАЖДЫЙ объявленный вид: вид, которого
   здесь нет, задаёт только цвет и берёт форму у браузера. Проверяет selfcheck. */
.btn, .btn-accent, .btn-ghost, .btn-danger, .btn-muted, .btn-muted-danger { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 38px; padding: 8px 14px; border: 1px solid transparent; border-radius: 10px; font: inherit; font-weight: 600; line-height: 1.2; white-space: nowrap; cursor: pointer; text-decoration: none; }
.btn { background: var(--ink, #1f2733); color: #fff; }
.btn-accent { background: var(--accent, #2f5bd4); color: #fff; }
.btn-ghost { background: transparent; color: var(--ink, #1f2733); border-color: var(--line, #e3e8ef); }
.btn-danger { background: var(--err, #c0392b); color: #fff; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.btn:focus-visible, .btn-ghost:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent, #2f5bd4); outline-offset: 2px; }

/* --- АКТИВНОЕ ПОЛЕ (решение Р-77) -----------------------------------------
   Поле, с которым человек работает прямо сейчас, обводится контуром. Правило
   одно на обе программы и на все поля ввода и выбора: клавиатурой или мышью
   — вид одинаковый. До этого контур показывался только при переходе с
   клавиатуры (`:focus-visible`), поэтому щелчок мышью по выпадающему списку
   в половине случаев не выделял его вовсе.
   Эталон — `FORTO-FC/app/static/forto-base.css`; точная копия —
   `FORTO-OS/app/static/css/forto-base.css`. Совпадение проверяет сторож
   `regression_active_field.py`.                                             */
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) { border-color: var(--ink-3, #7a8698); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent, #2f5bd4);
  box-shadow: 0 0 0 3px rgba(47, 91, 212, .20);
}
input:disabled, select:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
.row-actions, .filter-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.field label { display: block; margin-bottom: 4px; }
.field input, .field select, .field textarea { display: block; width: 100%; min-height: 38px; padding: 8px 10px; border: 1px solid var(--line, #e3e8ef); border-radius: 8px; font: inherit; }
.field textarea { resize: vertical; min-height: 92px; }
/* `.badge` снят: его работу — подпись состояния капсулой — делает эталон
   `.tag` ниже, и двух имён у одного элемента быть не должно (Р-12). */

/* --- ЕДИНЫЙ СТИЛЬ: смысловые цвета, маркер, чекбокс, сортировка (Р-81) ------
   Блок объявлен ЗДЕСЬ и только здесь, одинаково в обеих программах. Эталон —
   `FORTO-FC/app/static/forto-base.css`; точная копия —
   `FORTO-OS/app/static/css/forto-base.css`. Совпадение проверяет сторож
   `regression_ui_standard.py`.
   Правила приняты при разборе макета Экономики и действуют во ВСЕЙ программе,
   а не в одном разделе: раздел был поводом их записать, а не областью.        */

/* Смысловые цвета приглушены намеренно. Цвет обозначает состояние, а не
   привлекает внимание: на экране, где половина строк цветная, цвет перестаёт
   что-либо значить. Тёмная тема получает осветлённые пары — те же смыслы при
   другой подложке. */
:root {
  --ok: #4E7C66;
  --warn: #96793F;
  --crit: #95594C;
  --info: #5A7C90;
  --ok-bg: #EDF3EF;
  --warn-bg: #F5F0E4;
  --crit-bg: #F6EBE8;
  --info-bg: #EAF0F4;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ok: #8AB29D;
    --warn: #C0A578;
    --crit: #C4948A;
    --info: #93AEBD;
    --ok-bg: #1E2924;
    --warn-bg: #2A2519;
    --crit-bg: #2A1F1C;
    --info-bg: #1D242A;
  }
}

/* Маркер — точка того же смыслового цвета перед числом. Нужен затем, чтобы
   значение читалось без цвета самого числа: окрашенные цифры в столбце сумм
   мешают их сравнивать. */
.mk { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 7px; vertical-align: middle; flex: 0 0 auto; }
.mk-ok { background: var(--ok); }
.mk-warn { background: var(--warn); }
.mk-crit { background: var(--crit); }
.mk-info { background: var(--info); }
.mk-mute { background: var(--muted, #667085); opacity: .45; }

/* --- ОТМЕТКА: ОДНО ПРАВИЛО НА ВСЮ ПРОГРАММУ -------------------------------
   Квадрат 16 px, отступ до подписи 10 px, подпись кликабельна целиком.
   Переключатель одиночного выбора (`radio`) — та же отметка: отличается он
   формой кружка, которую рисует браузер, а не размером и поведением подписи.

   ПОЧЕМУ ПО ТИПУ ПОЛЯ, А НЕ ПО КЛАССУ. Правило `.cb` работало только там, где
   класс проставлен, а вокруг стояли сплошные правила палитры — `input{...}`,
   `.stack input{width:100%}`, `label{flex-direction:column}`. Они били по
   отметкам, о которых не знали: квадрат растягивался на всю строку и вставал
   над подписью. Так было в форме заявки, в выборе срока оплаты, в карточке
   пользователя — и правка по одному классу каждый раз оставляла следующий.
   Теперь правило накрывает КАЖДУЮ отметку программы независимо от разметки, а
   класс `.cb` остаётся именем для тех мест, где отметку называют явно.

   ПОЧЕМУ СЕЛЕКТОР УДВОЕН. `input[type="checkbox"]` весит столько же, сколько
   `.stack input`, и при равном весе побеждает файл, подключённый позже, — то
   есть палитра. Удвоение признака делает правило сильнее любого такого
   сплошного правила и не зависит от порядка подключения файлов. Тот же приём
   и по той же причине применён к `.table-wrap` выше. Не упрощать.

   ИСКЛЮЧЕНИЯ. Там, где отметка скрыта намеренно (фишка-переключатель `.pick`,
   тумблер `.switch`, выбор людей `.member-picker`), палитра перекрывает это
   правило селектором такого же веса — и, будучи подключённой позже, побеждает.
   Других исключений быть не должно. */
input[type="checkbox"][type="checkbox"], input[type="radio"][type="radio"] {
  width: 16px; height: 16px; min-width: 0; min-height: 0; max-width: none;
  flex: 0 0 auto; margin: 0; padding: 0;
  accent-color: var(--accent, #2f5bd4); cursor: pointer;
}
/* Любая подпись, внутри которой лежит отметка, — строка, а не столбец. Вес
   селектора выше сплошных `label{...}` палитры, поэтому класс для этого не
   нужен: правильно выглядит и `<label class="cb">`, и `<label class="row">`,
   и `<label>` вовсе без класса. */
label:has(> input[type="checkbox"]), label:has(> input[type="radio"]) {
  display: inline-flex; flex-direction: row; align-items: center; gap: 10px;
  cursor: pointer; min-width: 0; line-height: 1.35;
  font-size: inherit; color: inherit; font-weight: inherit;
}
label:has(> input[type="checkbox"]:disabled),
label:has(> input[type="radio"]:disabled) { cursor: not-allowed; opacity: .55; }

/* Длинная подпись обрезается многоточием, а полностью показывается подсказкой
   — иначе она рвёт строку таблицы. Это поведение включает класс `.cb`: в
   форме подпись переносить можно, в строке таблицы нельзя. */
.cb > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-wrap > span { white-space: normal; overflow: visible; }
/* Отметка с многострочной подписью: квадрат прижат к первой строке. */
.cb-top { align-items: flex-start; }
.cb-top > input[type="checkbox"], .cb-top > input[type="radio"] { margin-top: 2px; }

/* СОРТИРОВКА. Стрелка показывается ТОЛЬКО у колонки, по которой отсортировано,
   и красится акцентом. Второго вида стрелок в программе нет: серые «неактивные»
   стрелки у каждой колонки превращают шапку в частокол и не сообщают ничего.
   Нумерации строк в таблицах нет — порядок задаёт сортировка, а не номер. */
.sort-link { display: inline-flex; align-items: center; gap: 5px; color: inherit; text-decoration: none; }
.sort-link:hover { color: var(--ink, #1f2733); text-decoration: none; }
.sort-link.active { color: var(--accent, #2f5bd4); }
.sort-mark { display: inline-block; min-width: 10px; font-size: 12px; color: var(--accent, #2f5bd4); font-variant-numeric: normal; }

/* ДЛИННОЕ НАЗВАНИЕ. Колонка с названием не тянет таблицу вширь и не рвёт
   строку: две строки, дальше многоточие, полное значение — подсказкой. */
.cell-wide { min-width: 240px; }
.cell-wide .two-line { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ПЛИТКА. Заголовок, значение и подпись выровнены по одной линии во всём ряду
   независимо от длины текста: разнобой по вертикали читается как ошибка. */
.tiles { display: grid; gap: 12px; align-items: stretch; grid-template-columns: repeat(auto-fill, minmax(214px, 1fr)); }
.tile { display: grid; grid-template-rows: auto auto 1fr; gap: 4px; min-width: 0; }
.tile .tile-k { font-size: 12.5px; color: var(--muted, #667085); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile .tile-v { font-size: clamp(19px, 2vw, 24px); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; overflow-wrap: anywhere; }
.tile .tile-n { font-size: 12px; color: var(--muted, #667085); align-self: end; overflow-wrap: anywhere; }
.tile-ok .tile-v { color: var(--ok); }
.tile-warn .tile-v { color: var(--warn); }
.tile-crit .tile-v { color: var(--crit); }
/* Значок в плитке — необязательная часть эталона, а не отдельный вид плитки.
   Он занимает свою колонку справа во всю высоту, поэтому заголовок, значение и
   подпись остаются на общей линии ряда. Обтеканием значок ставить нельзя:
   плитка — сетка, и обтекание в ней не работает. */
.tile:has(> .tile-ico) { grid-template-columns: minmax(0, 1fr) auto; }
.tile > .tile-k, .tile > .tile-v, .tile > .tile-n { grid-column: 1; }
.tile-ico { grid-column: 2; grid-row: 1 / span 3; align-self: start; width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; background: var(--info-bg); color: var(--info); }
/* Плитка-ссылка. Цвет и подчёркивание ссылки внутри плитки сбиваются: значение
   в ней должно читаться как значение, а не как ссылка. Подсветку рамки при
   наведении задаёт палитра — фирменный цвет у программ разный. */
.card-link { text-decoration: none; color: inherit; }
.card-link:hover { text-decoration: none; }

/* МЕТКА СОСТОЯНИЯ. Капсула с подписью — там, где состояние названо словом:
   статус заявки, статус задачи, вид пользователя. Отличается от маркера `.mk`
   назначением: маркер стоит перед числом и не красит его, метка сама и есть
   надпись. Пять видов и только пять; шестого смысла у состояния не бывает.

   До этого правила одно и то же рисовали четырьмя способами: `.status.st-*` и
   `.mark.mark--*` в FORTO FC, `.badge.green|amber|red|blue|gray` и `.pill` в
   FORTO OS. Имена цветов в разметке («красный», «янтарный») — отдельная беда:
   по ним не видно, что метка означает, и при смене палитры они начинают врать.
   Здесь имена смысловые. */
.tag { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 600; line-height: 1.35; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; background: var(--surface-2, #f8fafc); color: var(--muted, #667085); }
.tag-ok { background: var(--ok-bg); color: var(--ok); }
.tag-warn { background: var(--warn-bg); color: var(--warn); }
.tag-crit { background: var(--crit-bg); color: var(--crit); }
.tag-info { background: var(--info-bg); color: var(--info); }
.tag-mute { background: var(--surface-2, #f8fafc); color: var(--muted, #667085); }
.tag > .dotc { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

/* СИСТЕМНОЕ СООБЩЕНИЕ. Четыре вида, отличаются только смысловым цветом левой
   черты и подложкой. Пятого вида не заводить. */
.note { border-left: 3px solid var(--line, #e3e8ef); background: var(--surface-2, #f8fafc); padding: 10px 14px; border-radius: 8px; font-size: 13.5px; }
.note-ok { border-left-color: var(--ok); background: var(--ok-bg); }
.note-warn { border-left-color: var(--warn); background: var(--warn-bg); }
.note-crit { border-left-color: var(--crit); background: var(--crit-bg); }
.note-info { border-left-color: var(--info); background: var(--info-bg); }

/* ПОЛОСА ПРОКРУТКИ. Правило одно на любую прокручиваемую область: боковое
   меню, обёртку таблицы, список выбора, тело модального окна. Дорожка
   прозрачная, ползунок — полупрозрачный тон подложки. Пока правила не было,
   браузер рисовал светлую системную полосу; на тёмном меню она читалась как
   заплата. Ширина 10 px: тоньше не попадает под курсор, толще отъедает
   колонку у таблицы. Ползунок сжат внутренней рамкой, чтобы не касаться
   края. */
:root {
  --scroll-thumb: rgba(31, 39, 51, .26);
  --scroll-thumb-hover: rgba(31, 39, 51, .44);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --scroll-thumb: rgba(255, 255, 255, .22);
    --scroll-thumb-hover: rgba(255, 255, 255, .38);
  }
}
.scroll-area, .table-wrap, .choice-list, .modal-body { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
.scroll-area::-webkit-scrollbar, .table-wrap::-webkit-scrollbar, .choice-list::-webkit-scrollbar, .modal-body::-webkit-scrollbar { width: 10px; height: 10px; }
.scroll-area::-webkit-scrollbar-track, .table-wrap::-webkit-scrollbar-track, .choice-list::-webkit-scrollbar-track, .modal-body::-webkit-scrollbar-track { background: transparent; }
.scroll-area::-webkit-scrollbar-thumb, .table-wrap::-webkit-scrollbar-thumb, .choice-list::-webkit-scrollbar-thumb, .modal-body::-webkit-scrollbar-thumb { background: var(--scroll-thumb); background-clip: content-box; border: 3px solid transparent; border-radius: 999px; }
.scroll-area::-webkit-scrollbar-thumb:hover, .table-wrap::-webkit-scrollbar-thumb:hover, .choice-list::-webkit-scrollbar-thumb:hover, .modal-body::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: content-box; }
.scroll-area::-webkit-scrollbar-corner, .table-wrap::-webkit-scrollbar-corner { background: transparent; }
/* Тёмная подложка — своя пара тонов: на ней светлый ползунок, а не тёмный.
   Класс ставится на прокручиваемую часть бокового меню в обеих программах. */
.scroll-dark { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .22) transparent; }
.scroll-dark::-webkit-scrollbar { width: 10px; }
.scroll-dark::-webkit-scrollbar-track { background: transparent; }
.scroll-dark::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .22); background-clip: content-box; border: 3px solid transparent; border-radius: 999px; }
.scroll-dark::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .38); background-clip: content-box; }

/* РЯД ДЕЙСТВИЙ. Кнопка растягивается на всю ширину РОВНО в одном случае: ряд
   сложился в столбец на телефоне. Частных правил «width:100%» по разделам не
   заводить — их было шесть на две программы, и каждая новая форма заводила
   седьмое, каждый раз на своей ширине. Перелом один и взят из шкалы ниже. */
@media (max-width: 620px) {
  .row-actions, .filter-actions { flex-direction: column; align-items: stretch; }
  .row-actions > *, .filter-actions > * { width: 100%; text-align: center; }
}

/* ПОЛЕ ФОРМЫ. Подпись сверху, звёздочка обязательности после подписи,
   пояснение под полем, ошибка под пояснением тем же смысловым цветом, что и
   остальная тревога в программе. Второго вида подписи не заводить: поле,
   подписанное иначе, читается как поле другого рода. */
.field { min-width: 0; }
.field-req { color: var(--crit); margin-left: 3px; font-weight: 600; }
.field-hint { display: block; margin-top: 4px; font-size: 12px; color: var(--muted, #667085); }
.field-err { display: block; margin-top: 4px; font-size: 12px; color: var(--crit); }
.field:has(.field-err) input, .field:has(.field-err) select, .field:has(.field-err) textarea { border-color: var(--crit); }

/* РАСКРЫВАЮЩИЙСЯ БЛОК. Шеврон слева от заголовка поворачивается при
   раскрытии; собственного маркера у `summary` нет. Один вид на обе программы:
   раскрывающийся блок встречается в заявке, в пользователях, в поступлениях,
   и раньше в каждом месте выглядел по-своему. */
.sect { border: 1px solid var(--line, #e3e8ef); border-radius: 12px; background: var(--panel, #fff); margin: 10px 0; }
.sect > summary { display: flex; align-items: center; gap: 8px; padding: 11px 14px; cursor: pointer; font-weight: 600; list-style: none; }
.sect > summary::-webkit-details-marker { display: none; }
.sect > summary::before { content: "▸"; color: var(--muted, #667085); transition: transform .15s ease; flex: 0 0 auto; }
.sect[open] > summary::before { transform: rotate(90deg); }
.sect > summary .sect-hint { margin-left: auto; font-weight: 400; font-size: 12.5px; color: var(--muted, #667085); }
.sect-body { padding: 0 14px 14px; }

/* СЕГМЕНТИРОВАННЫЙ ПЕРЕКЛЮЧАТЕЛЬ ВИДА. Не кнопки и не вкладки: выбор одного
   из нескольких видов одних и тех же данных. Выбранный вид залит подложкой,
   остальные — нет. */
.seg { display: inline-flex; border: 1px solid var(--line, #e3e8ef); border-radius: 9px; overflow: hidden; background: var(--panel, #fff); }
.seg > * { padding: 6px 14px; font: inherit; font-size: 13px; color: var(--muted, #667085); background: transparent; border: 0; cursor: pointer; text-decoration: none; white-space: nowrap; }
.seg > * + * { border-left: 1px solid var(--line, #e3e8ef); }
.seg > *:hover { color: var(--ink, #1f2733); }
.seg > .active, .seg > [aria-pressed="true"] { background: var(--surface-2, #f8fafc); color: var(--ink, #1f2733); font-weight: 600; }

/* ЛЕГЕНДА. Обязательна везде, где цвет несёт смысл: под графиком и над
   таблицей с полосой состава. Цвет без подписи ничего не сообщает. */
.legend { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; font-size: 12.5px; color: var(--muted, #667085); margin: 6px 0; }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.legend .sw { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; }
/* Свотчи легенды повторяют цвета долей полосы: одно и то же слово и один и тот
   же цвет в двух местах не должны задаваться по-разному. `sw-rest` — фон
   полосы в рамке: незакрашенный хвост тоже доля («свободно», «остаток»). */
.legend .sw-ok { background: var(--ok); }
.legend .sw-warn { background: var(--warn); }
.legend .sw-crit { background: var(--crit); }
.legend .sw-info { background: var(--info); }
.legend .sw-mute { background: var(--muted, #667085); opacity: .45; }

/* ПОЛОСА СОСТАВА. Показывает, из чего складывается величина, — доли идут
   слева направо в том же порядке, что в легенде. Число рядом обязательно:
   полоса поясняет его, а не заменяет. Однодольная полоса — частный случай
   этой же, второго вида не заводить. */
.bar { display: flex; height: 7px; border-radius: 999px; overflow: hidden; background: var(--surface-2, #f8fafc); border: 1px solid var(--line, #e3e8ef); min-width: 84px; }
.bar > i { display: block; height: 100%; }
.bar-ok > i:first-child { background: var(--ok); }
.bar-warn > i:first-child { background: var(--warn); }
.bar-crit > i:first-child { background: var(--crit); }
.bar-info > i:first-child { background: var(--info); }
/* Многодольная полоса. Цвет ставится ДОЛЕ, а не полосе: долей несколько, и
   каждая означает своё. Модификатор полосы выше красит только первую долю и
   остаётся для однодольного случая. Незакрашенный хвост — это фон полосы, и
   он тоже доля: «остаток», «свободно». В легенде он показывается рамкой. */
.bar > i.share-ok { background: var(--ok); }
.bar > i.share-warn { background: var(--warn); }
.bar > i.share-crit { background: var(--crit); }
.bar > i.share-info { background: var(--info); }
.bar > i.share-mute { background: var(--muted, #667085); opacity: .45; }
.legend .sw-rest { background: var(--surface-2, #f8fafc); border: 1px solid var(--line, #e3e8ef); }

/* ПУСТОЕ СОСТОЯНИЕ. Одна строка на всю ширину таблицы, приглушённая. Раньше
   её писали руками в каждом шаблоне, и половина таблиц не писала вовсе —
   пустая таблица выглядела как сломанная. */
.empty { color: var(--muted, #667085); font-size: 13.5px; padding: 14px 10px; text-align: left; }

/* СОКРАЩЁННАЯ СУММА. Крупные суммы показываются коротко — «18,5 млн ₽», —
   а полная величина до копейки приходит подсказкой. Иначе колонка сумм
   распирает таблицу и вынуждает горизонтальную прокрутку. Сокращение считает
   сервер: разное сокращение на сервере и на экране означало бы два разных
   ответа на один вопрос. */
.sum-short { border-bottom: 1px dotted var(--line, #e3e8ef); cursor: help; }

/* ШКАЛА ТОЧЕК ПЕРЕЛОМА. Разрешённых значений ПЯТЬ и только пять:
     1180  — узкий рабочий стол: боковое меню и содержимое ещё рядом;
     1024  — планшет-альбом: многоколоночные сетки складываются вдвое;
     768   — планшет-портрет: меню становится горизонтальной полосой;
     620   — крупный телефон: сетки в одну колонку, ряды действий в столбец;
     400   — телефон: убираются второстепенные колонки таблиц.
   Своей ширины перелома раздел не заводит. До этого правила в FORTO FC было
   восемнадцать разных значений, в FORTO OS — одиннадцать, общих четыре: один
   и тот же экран перестраивался в двух программах на разной ширине.
   Соблюдение проверяет regression_ui_standard.py. */

/* --- КОНЕЦ ЕДИНОГО СТИЛЯ --- */
