/* Общий 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: 10;
  --z-dropdown: 100;
  --z-modal: 1000;
  --z-toast: 2000;
}

* { box-sizing: border-box; }
.content, .main, .page { min-width: 0; }
.nowrap { white-space: nowrap; }
.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; }

.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.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;
  overflow: hidden;
  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: 0;
  z-index: var(--z-sticky);
}
.table thead th + th { border-left: 1px solid var(--line, #e3e8ef); }
.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; }

.btn, .btn-ghost, .btn-danger, .btn-muted {
  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. */

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