/* zxlab — компактное рабочее пространство. Спокойные поверхности и цветовые
   состояния отделяют навигацию, данные и действия во всех рабочих модулях.

   Общий слой: здесь лежат рецепты, одинаковые для всех областей — шапка раздела,
   полоса «сейчас», плотность таблиц (строка 52 px, шапка 34 px), размер
   подсказки, малый капс, значок основной кнопки. Файлы областей (orders.css,
   order-card.css, intake.css, money.css, admin.css) эти рецепты не повторяют и
   задают поверх только то, что у экрана своё по смыслу.

   Порог второй колонки — 80rem для всех экранов, где широкая раскладка делится
   надвое: карточка наряда, настройки «Лаборатория», «С чего начать», зарплата.
   Медиазапрос не читает переменные, поэтому значение записано числом в каждом
   файле; менять его — во всех четырёх местах сразу. */

/* Шрифты лежат внутри программы, а не тянутся из сети. Лаборатория работает без
   интернета — это условие продукта, — и шрифт по ссылке означал бы, что программа
   выглядит по-разному в зависимости от того, дошёл ли запрос до Гугла. Оба начертания
   переменные, поэтому на все веса хватает одного файла на подмножество: вместе с
   кириллицей и латиницей это 77 КБ на всё. */
@font-face {
  font-family: "Onest"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("fonts/onest-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Onest"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("fonts/onest-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/mono-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("fonts/mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122, U+2191, U+2193, U+2212, U+2215;
}

/* Токены (цвета, шрифты, отступы, радиусы, тени) лежат в theme.css: он подключается
   раньше этого файла, и новая палитра правится в одном месте. */

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); background-attachment: fixed; color: var(--ink);
  font: var(--fw-400) var(--fs-13)/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
}
.loading { padding: 3rem; color: var(--muted); }
.num, .subline.nowrap, .rate { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ вход --- */
/* Макет «Вход»: две колонки 1.1fr / 1fr. Слева фиолетовая панель с радиусом 26 и
   фигурами на CSS, справа форма до 400 px с полями 44 px. ≤800 — панель
   сжимается до плашки 200 px с логотипом и заголовком. */

/* В макетах у body нет line-height (normal); на экранах группы «Каркас» —
   вход, меню, шапка, «С чего начать», «Отчёты», «Настройки» — так же. */
.gate, .shell > nav, .workspace-top,
main:is([data-view="setup"], [data-view="reports"], [data-view="settings"]) { line-height: normal; }
.gate {
  min-height: 100vh; display: grid; grid-template-columns: 1.1fr 1fr; gap: var(--sp-5);
  padding: var(--sp-5); background: var(--surface);
}
.gate-story {
  position: relative; overflow: hidden; display: flex; flex-direction: column; gap: var(--sp-5);
  min-height: calc(100vh - 40px); padding: 36px; border-radius: 26px;
  background: var(--gate-bg); color: var(--ink-inverse);
}
.gate-story > * { position: relative; z-index: 1; }
.brand { display: flex; align-items: center; gap: var(--sp-2-5); }
.brand-mark {
  width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 9px;
  font: var(--fw-700) var(--fs-12)/1 var(--mono);
}
.brand-word { font-size: var(--fs-17); font-weight: var(--fw-600); line-height: 1.2; }
.gate-story .brand-mark { background: var(--lime); color: var(--gate-bg); }
.gate-story h2 {
  margin: 0; max-width: 520px; font-size: 56px; line-height: 1.05; font-weight: var(--fw-600); letter-spacing: -.02em;
}
.gate-story h2 em { color: var(--lime); font-style: normal; }
.gate-story > p { margin: 0; max-width: 400px; font-size: 15px; line-height: 1.5; color: var(--lilac); }
.gate-art { position: relative; flex: 1; min-height: 220px; z-index: 0; }
.gate-art span { position: absolute; display: block; }
.gate-art-circle { left: 8%; bottom: 34%; width: 120px; height: 120px; border-radius: var(--radius-pill); background: var(--coral); }
.gate-art-drop {
  left: 34%; bottom: 22%; width: 190px; height: 220px; background: var(--lilac);
  border-radius: 46% 46% 38% 38% / 40% 40% 60% 60%;
}
.gate-art-diamond { left: 72%; bottom: 52%; width: 64px; height: 64px; border-radius: 10px; background: var(--lime); transform: rotate(45deg); }
.gate-art-floor { left: 28%; right: 18%; bottom: 14%; height: 14px; border-radius: var(--radius-pill); background: var(--gate-deep); }
.gate-caption { font-size: var(--fs-11); font-weight: var(--fw-600); letter-spacing: .12em; text-transform: uppercase; color: var(--lilac); }

.gate-side { display: flex; flex-direction: column; justify-content: center; align-items: center; min-width: 0; padding: var(--sp-6); }
.gate-form { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 14px; }
.gate-head { display: flex; flex-direction: column; gap: var(--sp-1); }
.gate-eyebrow { font-size: var(--fs-11); font-weight: var(--fw-600); letter-spacing: .1em; text-transform: uppercase; color: var(--gate-bg); }
.gate h1 { margin: 0; font-size: var(--fs-26); line-height: normal; font-weight: var(--fw-600); letter-spacing: -.01em; }
.gate-lead { margin: 0; color: var(--muted); line-height: 1.45; }
.gate label.field { gap: var(--sp-1); font-size: var(--fs-12-5); font-weight: var(--fw-500); color: var(--ink); }
.gate input { height: 44px; padding: 0 var(--sp-3); border-radius: var(--radius-card); font-size: var(--fs-14); }
.gate input[aria-invalid="true"] { border-color: var(--danger); }
.gate input:disabled { background: var(--fill-soft); }
.gate-secret { position: relative; display: flex; }
.gate-secret input { flex: 1; padding-right: 84px; }
.gate-reveal {
  position: absolute; right: 6px; top: 6px; height: 32px; padding: 0 var(--sp-2-5); border: 0;
  border-radius: var(--radius); background: var(--chip-bg); color: var(--ink);
  font: inherit; font-size: var(--fs-12); font-weight: var(--fw-400); cursor: pointer;
}
.gate-pw-hint { font-size: var(--fs-12); font-weight: var(--fw-400); color: var(--muted); }
.gate-pw-hint.is-ok { color: var(--ok); }
.gate-error {
  display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2-5) var(--sp-3);
  border-radius: var(--radius-card); background: var(--danger-soft); color: var(--danger); line-height: 1.45;
}
.gate-retry {
  align-self: flex-start; height: 32px; padding: 0 var(--sp-3); border: 1px solid var(--danger-line);
  border-radius: var(--radius); background: var(--surface); color: var(--danger);
  font: inherit; font-weight: var(--fw-500); cursor: pointer;
}
.gate button.gate-submit { height: 46px; border-radius: var(--radius-card); font-size: var(--fs-14); font-weight: var(--fw-600); }
.gate-forgot { margin: 0; font-size: var(--fs-12-5); color: var(--muted); line-height: 1.45; }
/* В макете подпись цвета --decor; здесь --muted: светлый серый не годится для
   текста (3,6:1 на белом, см. theme.css). */
.gate-footer { margin: var(--sp-2) 0 0; font-size: var(--fs-12); color: var(--muted); }

/* --------------------------------------------------------------- каркас --- */
/* Каркас по макету zx-shell: меню 232 px на --sidebar-bg; бренд — чёрная плитка
   «zx» с лаймом; группы — малый капс 10,5; пункты 30 px со значком 18 px; у
   каждой группы свой цвет (--group-hue) — им окрашены значок активного пункта и
   плитка в шапке. Активный пункт — белая плашка с кольцом 1 px и тенью. Пункты
   остаются <button> с прежними подписями. */
.shell { display: grid; grid-template-columns: 232px minmax(0,1fr); min-height: 100vh; }
.shell > nav {
  background: var(--sidebar-bg); border-right: 1px solid var(--sidebar-border);
  padding: var(--sp-4) var(--sp-3); display: flex; flex-direction: column; gap: 18px;
  position: sticky; top: 0; height: 100vh; min-height: 0; overflow: auto; z-index: 30;
}
nav button.nav-brand {
  display: flex; align-items: center; gap: var(--sp-2-5); padding: 0 var(--sp-1-5); min-height: 0;
  color: var(--ink); background: none; border-radius: 0; font-weight: var(--fw-400);
}
nav button.nav-brand:hover { background: none; color: var(--ink); }
/* Как в макете: подпись «зуботехническая лаборатория» переносится в две строки,
   а части меню не сжимаются, когда меню выше окна (прокручивается целиком). */
.shell > nav > * { flex-shrink: 0; }
nav button.nav-brand > span.brand-mark { flex: none; }
nav button.nav-brand > span.brand-text { display: flex; flex-direction: column; gap: 1px; flex: 0 1 auto; min-width: 0; }
nav .brand-word { font-size: var(--fs-14); font-weight: var(--fw-700); letter-spacing: 0; line-height: normal; }
nav .brand-mark { width: 30px; height: 30px; border-radius: var(--radius); background: var(--brand-ink); color: var(--brand-lime); }
.brand-caption { display: block; color: var(--muted); font-size: var(--fs-11); letter-spacing: 0; font-weight: var(--fw-400); line-height: normal; }
.nav-links { display: flex; flex-direction: column; gap: 18px; }
.nav-group { display: flex; flex-direction: column; gap: 2px; }
.nav-group[data-group="work"], .page-tile[data-group="work"] { --group-hue: var(--hue-work); --group-hue-soft: var(--hue-work-soft); }
.nav-group[data-group="ledger"], .page-tile[data-group="ledger"] { --group-hue: var(--hue-ledger); --group-hue-soft: var(--hue-ledger-soft); }
.nav-group[data-group="dirs"], .page-tile[data-group="dirs"] { --group-hue: var(--hue-dirs); --group-hue-soft: var(--hue-dirs-soft); }
.nav-group-title { font-size: var(--fs-10-5); font-weight: var(--fw-600); color: var(--muted); text-transform: uppercase; letter-spacing: .06em; padding: 0 var(--sp-2); margin: 0 0 var(--sp-1); line-height: normal; }
nav button {
  appearance: none; background: none; border: 0; text-align: left; width: 100%;
  display: flex; align-items: center; gap: var(--sp-2-5);
  padding: 0 var(--sp-2); min-height: 30px; border-radius: var(--radius); cursor: pointer;
  font: var(--fw-400) var(--fs-13)/normal var(--font); color: var(--ink-2); margin: 0;
}
nav button > span:not(.badge) { flex: 1; min-width: 0; }
.ui-icon { width: 19px; height: 19px; flex: none; }
nav .ui-icon { width: 18px; height: 18px; }
nav button:hover { background: var(--sidebar-hover); color: var(--ink); }
nav button[aria-current="page"] { background: var(--sidebar-active-bg); color: var(--ink); font-weight: var(--fw-600); box-shadow: var(--shadow-active); }
nav button[aria-current="page"] .ui-icon { color: var(--group-hue, var(--ink)); }
/* Внизу — аватар, ФИО, роль и «Выйти» маленькой кнопкой с рамкой. */
nav .who { margin-top: auto; border-top: 1px solid var(--sidebar-border); padding: var(--sp-2-5) var(--sp-2); display: flex; align-items: center; gap: var(--sp-2-5); }
.avatar { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; font-size: var(--fs-12); font-weight: var(--fw-600); color: var(--hue-work); background: var(--hue-work-soft); flex: none; }
.who-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.who-info b, .who-info span { display: block; overflow-wrap: anywhere; }
.who-info b { font-size: var(--fs-13); font-weight: var(--fw-500); line-height: normal; }
.who-info span { font-size: var(--fs-12); color: var(--muted); line-height: normal; }
nav .who button {
  width: auto; flex: none; min-height: 28px; height: 28px; padding: 0 var(--sp-2); font-size: var(--fs-12); color: var(--ink);
  background: var(--surface); border: 1px solid var(--button-border);
}
nav .who button:hover { background: var(--surface); }
.workspace { min-width: 0; }
/* Шапка 56 px: значок страницы в цвете группы, путь «группа / раздел», дата. */
.workspace-top { height: var(--header-h); padding: 0 28px; display: flex; align-items: center; gap: var(--sp-3); background: var(--surface); border-bottom: 1px solid var(--rule); position: sticky; top: 0; z-index: 30; }
.page-tile { width: 28px; height: 28px; border-radius: var(--radius); display: grid; place-items: center; flex: none; background: var(--group-hue-soft, var(--chip-bg)); color: var(--group-hue, var(--ink-2)); }
.page-tile .ui-icon { width: 16px; height: 16px; }
.breadcrumb { display: flex; gap: var(--sp-1-5); align-items: center; font-size: var(--fs-13); color: var(--muted); min-width: 0; white-space: nowrap; }
.breadcrumb b { font-weight: var(--fw-500); color: var(--ink); overflow: hidden; text-overflow: ellipsis; }
.breadcrumb i { color: var(--decor); font-style: normal; }
.breadcrumb.has-tail > b:not(.crumb-tail) { font-weight: var(--fw-400); color: var(--muted); }
.breadcrumb [hidden] { display: none; }
.workspace-date { margin-left: auto; color: var(--muted); font-size: var(--fs-13); white-space: nowrap; }
/* Колокольчик уведомлений (каркас zx-shell.js этапа 3, ADR-0047): кнопка 36 × 36,
   счётчик — красная пилюля, панель 380 px под кнопкой; на телефоне — во всю ширину. */
.bell { position: relative; display: inline-flex; flex: none; }
.bell-button {
  position: relative; display: grid; place-items: center; width: 36px; height: 36px; padding: 0;
  border: 1px solid var(--button-border); border-radius: var(--radius); background: var(--surface); color: var(--ink); cursor: pointer;
}
.bell-button[aria-expanded="true"] { border-color: var(--ink); }
.bell-button > svg { width: 18px; height: 18px; }
.bell-count {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill);
  background: var(--danger); color: var(--ink-inverse); font: var(--fw-600) var(--fs-11)/18px var(--mono); text-align: center;
  box-shadow: 0 0 0 2px var(--surface);
}
.bell-count[hidden] { display: none; }
.bell-panel {
  position: absolute; top: 44px; right: 0; z-index: 60; width: 380px; max-width: calc(100vw - 24px); overflow: hidden;
  border-radius: 12px; background: var(--surface); box-shadow: var(--shadow-popover); font-size: var(--fs-13);
}
.bell-panel[hidden] { display: none; }
.bell-head { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) 14px; border-bottom: 1px solid var(--rule); }
.bell-head > b { flex: 1; font-size: var(--fs-14); font-weight: var(--fw-600); }
.bell-all {
  height: 28px; padding: 0 6px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: var(--fs-12-5);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.bell-all:disabled { color: var(--decor); text-decoration: none; cursor: default; }
.bell-all[hidden] { display: none; }
.bell-list { max-height: min(480px, calc(100vh - 140px)); overflow-y: auto; }
.bell-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: var(--sp-3) 14px; border: 0; border-top: 1px solid var(--divider);
  background: var(--surface); color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.bell-item:first-child { border-top: 0; }
.bell-item:hover { background: var(--hover-bg); }
.bell-item.is-unread { background: var(--gray-25); }
.bell-dot { flex: none; width: 8px; height: 8px; margin-top: 6px; border-radius: var(--radius-pill); background: var(--gray-300); }
.bell-item.is-unread .bell-dot { background: var(--indigo-700); }
.bell-text { min-width: 0; }
.bell-title { display: block; line-height: 1.4; }
.bell-item.is-unread .bell-title { font-weight: var(--fw-600); }
.bell-at { display: block; margin-top: 2px; font-size: var(--fs-12); color: var(--muted); }
.bell-tag { display: inline-block; margin-top: var(--sp-1); padding: 1px var(--sp-2); border-radius: var(--radius-pill); background: var(--warn-soft); color: var(--warn); font-size: var(--fs-12); font-weight: var(--fw-500); }
.bell-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 28px var(--sp-4); text-align: center; color: var(--ink-2); }
.bell-empty > strong { font-size: var(--fs-14); font-weight: var(--fw-600); color: var(--ink); }
.bell-empty.is-error > strong { color: var(--danger); }
.bell-retry { height: 32px; padding: 0 14px; }
.menu-toggle, .menu-scrim { display: none; }
.menu-toggle .ui-icon { width: 18px; height: 18px; }
.skip-link { position: fixed; top: .7rem; left: 16rem; z-index: 100; padding: .7rem 1rem; background: var(--ink); color: var(--ink-inverse); border-radius: var(--radius); transform: translateY(-200%); }
.skip-link:focus { transform: none; }
/* Отступ страницы 28 / 20 (≤800) / 16 (≤600), сверху 24 — как во всех макетах. */
main { padding: var(--sp-6) 28px 48px; min-width: 0; max-width: 1800px; margin: auto; }
/* Шапка раздела — один рецепт на все экраны: название и «?» одной строкой,
   подзаголовок — своей строкой под ними, как на макетах. h1 блочный, и без
   inline-block кнопка справки уезжала на отдельную строку между заголовком и
   подзаголовком; там, где подзаголовок лежит прямо в шапке-флексе, его на свою
   строку переводит flex-basis. Области эти правила больше не повторяют. */
header.page { display: flex; align-items: baseline; gap: .65rem; flex-wrap: wrap; margin-bottom: var(--sp-4); }
/* Заголовок экрана — 26 px, 600, −.01em на любой ширине, как во всех макетах. */
header.page h1 {
  display: inline-block; vertical-align: middle; margin: 0;
  font-size: var(--fs-26); line-height: normal; font-weight: var(--fw-600); letter-spacing: -.01em;
}
header.page .help-dot { margin-left: var(--sp-1); vertical-align: middle; }
/* Подзаголовок, лежащий прямо в шапке-флексе (производство, ресурсы, мой лист),
   занимает свою строку. Перенос решает гипотетический размер элемента, поэтому
   нужен и flex-basis 100 %, и снятый max-width: мера в 80ch иначе укладывает
   подзаголовок обратно в строку заголовка. */
header.page > .section-sub { flex: 0 0 100%; max-width: none; }
header.page .about { color: var(--muted); font-size: .88rem; }
header.page .ro { font-size: var(--fs-12); color: var(--muted); background: var(--chip-bg); padding: .1875rem .4375rem; border-radius: var(--radius-sm); }

@media (max-width: 50rem) {
  .shell { grid-template-columns: minmax(0,1fr); }
  /* Меню прячется после того, как уехало (.2 с), а показывается сразу: иначе в
     первый кадр перехода оно ещё visibility:hidden и фокус на логотип не встаёт. */
  .shell > nav { position: fixed; left: 0; top: 0; width: 232px; z-index: 50; transform: translateX(-100%); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s; }
  .shell[data-menu-open="true"] > nav { transform: none; visibility: visible; box-shadow: var(--shadow-panel); transition: transform .2s ease, visibility 0s; }
  .menu-toggle { display: grid; place-items: center; flex: none; width: 36px; height: 36px; margin-left: -6px; padding: 0; border: 1px solid var(--button-border); border-radius: var(--radius); background: var(--surface); color: var(--ink); cursor: pointer; }
  .shell[data-menu-open="true"] .menu-scrim { display: block; position: fixed; inset: 0; background: var(--menu-scrim); z-index: 45; }
  body.menu-is-open { overflow: hidden; }
  .workspace-top { padding: 0 var(--sp-5); }
  main { padding: var(--sp-6) var(--sp-5) 48px; }
  .skip-link { left: 1rem; }
  .gate { grid-template-columns: minmax(0, 1fr); padding: var(--sp-3); }
  .gate-story { min-height: 200px; padding: var(--sp-5); }
  .gate-story h2 { font-size: 34px; }
  .gate-story > p, .gate-art, .gate-caption { display: none; }
  .gate-side { padding: var(--sp-3) var(--sp-2) 32px; }
}
/* Телефон: в шапке остаётся только название экрана. */
@media (max-width: 37.5rem) {
  .workspace-top { padding: 0 var(--sp-4); }
  .breadcrumb > span, .breadcrumb > i, .workspace-date { display: none; }
  .breadcrumb.has-tail > b:not(.crumb-tail) { display: none; }
  .bell { margin-left: auto; }
  .bell-panel { position: fixed; top: var(--header-h); left: 0; right: 0; width: auto; max-width: none; border-radius: 0 0 14px 14px; }
  main { padding: var(--sp-6) var(--sp-4) 48px; }
}

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

.bar { display: flex; gap: 0.55rem; flex-wrap: wrap; align-items: center; margin-bottom: 1rem; }
.bar input[type="search"] { flex: 1 1 16rem; }
/* Подпись флажка не должна переноситься и не должна отрываться от самого флажка:
   иначе на узком экране «Показывать устаревшие» встаёт в две строки вплотную к
   кнопке, и по нему промахиваются. */
.bar label {
  display: flex; align-items: center; gap: 0.45rem; flex: none;
  white-space: nowrap; color: var(--ink-2); font-size: 0.88rem; cursor: pointer;
}
.bar label input { width: auto; flex: none; }

/* Поле формы — 38 px, текст 13 px, рамка 1 px. Высота задана через :where, чтобы
   любое контекстное правило (строка фильтров, таблица) перекрывало её без борьбы
   за специфичность. Флажки и переключатели в высоту не растягиваются. */
input, select, textarea {
  font: inherit; font-size: var(--fs-13); color: var(--ink); background: var(--surface);
  border: 1px solid var(--field-border); border-radius: var(--radius);
  padding: 0 .75rem; width: 100%; box-shadow: none;
}
input:where(:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="hidden"])), select {
  height: var(--control-h-lg);
}
input[type="file"] { padding: .375rem .5rem; }
textarea { padding: .5625rem .75rem; line-height: 1.45; }
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--focus-ring); outline-offset: 2px;
}
/* Поле в фокусе, как в макете: чёрная кромка 1 px поверх рамки и мягкий ореол. */
input:where(:not([type="checkbox"], [type="radio"])):focus-visible, select:focus-visible, textarea:focus-visible {
  outline-width: 1px; outline-offset: -1px; box-shadow: var(--shadow-focus);
}
label.field { display: grid; gap: var(--sp-1-5); font-size: var(--fs-12-5); font-weight: var(--fw-500); color: var(--ink-2); }
label.field input, label.field select, label.field textarea { font-weight: var(--fw-400); color: var(--ink); }
/* Подсказка — один размер во всех областях: 12,5 px, как ячейка таблицы.
   Собственные размеры областей сняты; свою шкалу сохраняет только экран входа. */
.hint { color: var(--muted); font-size: var(--fs-12-5); line-height: 1.5; }
.hint[role="alert"] { color: var(--danger); }
/* Явный display перебивает атрибут hidden, и спрятанное поле остаётся на экране.
   Правило общее: то же самое ждёт любой .bar, .row или .field, который когда-нибудь
   попробуют скрыть. */
[hidden] { display: none !important; }
/* Текст только для экранного диктора: в раскладке не виден, в дереве доступности
   остаётся (например, полный список этапов строки нарядов). */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
label.check { display: flex; align-items: center; gap: 0.5rem; }
label.check input { width: auto; }

/* Кнопки — 32 px: основная чёрная, значок в ней лаймовый; вторичная (ghost) белая
   с рамкой 1 px. Малая кнопка тоже 32 px: в строке фильтров и в окнах пробы требуют
   controls не ниже 31,5 px, поэтому 28-пиксельной кнопки макета здесь нет. */
button.action {
  font: inherit; font-size: var(--fs-12-5); font-weight: var(--fw-600); cursor: pointer;
  padding: 0 var(--sp-3); height: var(--control-h);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1-5);
  border-radius: var(--radius); border: 0; white-space: nowrap;
  background: var(--button-primary-bg); color: var(--button-primary-ink); box-shadow: var(--shadow-button);
  transition: background-color .12s ease, transform .12s ease;
}
/* Значок основной кнопки — лаймовый: и нарисованный (svg), и знаковый («+»).
   .plus-mark — тот же текстовый узел подписи, textContent кнопки не меняется. */
button.action svg { color: var(--button-primary-icon); }
button.action .plus-mark { color: var(--button-primary-icon); font-weight: var(--fw-600); }
button.action:hover:not(:disabled) { background: var(--primary-light); }
button.action:active:not(:disabled) { transform: translateY(1px); }
button.ghost {
  font: inherit; font-size: var(--fs-12-5); font-weight: var(--fw-500); cursor: pointer;
  padding: 0 var(--sp-3); height: var(--control-h);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1-5);
  border-radius: var(--radius); white-space: nowrap;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--button-border); box-shadow: var(--shadow-sm);
  transition: background-color .12s ease, color .12s ease;
}
button.ghost:hover:not(:disabled) { background: var(--hover-bg); color: var(--ink); }
button.tiny { height: var(--control-h); padding: 0 var(--sp-2-5); font-size: var(--fs-12); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

/* --------------------------------------------------------------- таблица --- */

.table-wrap, .orders-table {
  overflow-x: auto; background: var(--surface);
  border: 1px solid var(--card-border); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 0.7rem 0.9rem; border-bottom: 1px solid var(--row-rule); }
/* Шапка таблицы — тон бокового меню и линия 1 px, 12 px без капса. */
th {
  font-size: var(--fs-12); letter-spacing: 0; text-transform: none;
  color: var(--muted); font-weight: var(--fw-500); padding-block: .5rem;
  background: var(--table-head-bg); border-bottom-color: var(--rule);
}
td { font-size: var(--fs-13); }
/* Плотность одна во всех областях: строка 52 px, шапка 34 px. Наряды,
   справочники, склад, деньги, зарплата и отчёты больше не задают её сами. */
.table-wrap th { height: 34px; padding-block: 0; white-space: nowrap; }
.table-wrap td { height: 52px; padding-block: var(--sp-1-5); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr { cursor: pointer; transition: background-color .1s ease; }
tbody tr:hover { background: var(--hover-bg); }
td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
tr.off td { color: var(--muted); }
tr.off td:first-child::after { content: " · устарел"; font-size: 0.78rem; }

/* --------------------------------------------------------------- наряды --- */

.orders-bar select { flex: 0 1 12rem; }
.order-number { white-space: nowrap; font-variant-numeric: tabular-nums; }
.subline { display: block; color: var(--muted); font-size: 0.82rem; margin-top: 0.08rem; }
.due { white-space: nowrap; }
.due.overdue, .fact.danger b { color: var(--danger); }
.due.overdue::before { content: "Просрочен · "; font-size: 0.75rem; font-weight: 650; }

.status {
  display: inline-flex; align-items: center; width: max-content; white-space: nowrap;
  gap: 5px; height: 22px; padding: 0 7px; border-radius: var(--radius-sm);
  background: var(--chip-bg); color: var(--ink-2);
  font-size: var(--fs-12); font-weight: var(--fw-500); line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* Точка перед подписью — цвет состояния; подпись остаётся текстом. */
.status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
/* Цвет статуса берётся из той же палитры, что и всё остальное: приёмщик считывает
   состояние наряда цветом, а не читает слово, и цвета обязаны значить одно и то же
   на всех экранах. */
.status-created, .status-pending { background: var(--stage-pending-soft); color: var(--stage-pending); }
.status-sent, .status-fitting { background: var(--violet-soft); color: var(--violet); }
.status-in_work { background: var(--stage-working-soft); color: var(--stage-working); }
.status-ready, .status-completed { background: var(--stage-ready-soft); color: var(--stage-ready); }
.status-done { background: var(--stage-done-soft); color: var(--stage-done); }
.status-cancelled { background: var(--danger-soft); color: var(--danger); }
.status.compact { height: 20px; padding: 0 6px; font-size: var(--fs-11); }

button.back { margin-bottom: 1rem; }
.order-head { justify-content: space-between; align-items: center; }
.order-head > div { min-width: 0; }
.order-head h1 { overflow-wrap: anywhere; }
/* Малый капс — один рецепт на надзаголовки и подписи групп: 11 px, 600, +.08em.
   Свои 11,5 px и +.04em области больше не заводят. */
.eyebrow {
  display: block; color: var(--muted); font-size: var(--fs-11); font-weight: var(--fw-600);
  letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 0.15rem;
}
.facts {
  display: flex; flex-wrap: wrap; gap: 1px;
  border: 1px solid var(--rule); border-radius: var(--radius-card); overflow: hidden;
  background: var(--divider); box-shadow: var(--shadow-card); margin-bottom: 0.75rem;
}
.fact {
  flex: 1 1 10rem; min-width: 0; padding: 0.75rem 0.95rem;
  background: var(--surface); backdrop-filter: var(--glass-blur);
}
.fact span { display: block; color: var(--muted); font-size: 0.76rem; margin-bottom: 0.15rem; }
.fact b { display: block; overflow-wrap: anywhere; font-weight: 600; }
.fact.money b { font-variant-numeric: tabular-nums; }
/* Заметки, ошибки и уведомления — мягкая заливка без полосы слева. */
.note {
  margin-top: 1rem; padding: .6875rem .75rem; border: 0; border-radius: var(--radius-card);
  background: var(--fill-soft); color: var(--ink-2); line-height: 1.5;
}
.note p { margin: 0; white-space: pre-wrap; }
.card-lines { margin-top: 1.4rem; }
.card-lines > h2, .trips .op-title, .op-title {
  font-size: var(--fs-11); font-weight: var(--fw-600); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 0.5rem; display: block;
}
.work-card {
  background: var(--surface); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rule); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 1rem 1.1rem; margin-bottom: 0.7rem;
}
.work-card > header { display: flex; justify-content: space-between; gap: 1rem; align-items: start; }
.work-card h3 { margin: 0; font-size: 1rem; }
.line-amount { white-space: nowrap; font-variant-numeric: tabular-nums; }
.price-note { color: var(--muted); font-size: 0.8rem; margin-top: 0.35rem; }
.card-formula { margin-top: 0.85rem; }
.card-formula > .operations-title { display: block; margin-top: 0; }
.tooth-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.tooth-chip {
  display: inline-flex; align-items: center; gap: 0.35rem; min-width: 3rem;
  padding: 0.3rem 0.45rem; border-radius: var(--radius); color: var(--ink-inverse);
  font-weight: 700; font-variant-numeric: tabular-nums;
}
.tooth-chip small { font-size: 0.68rem; font-weight: 500; opacity: 0.9; }
.tooth-unit { background: var(--tooth-unit); }
.tooth-abutment { background: var(--tooth-abutment); }
.tooth-pontic { background: var(--tooth-pontic); }
.operations-title {
  color: var(--muted); font-size: var(--fs-11); font-weight: var(--fw-600); letter-spacing: 0.08em;
  text-transform: uppercase; margin: 1rem 0 0.35rem;
}
.operations { border-top: 1px solid var(--rule); }
.operation {
  display: grid; grid-template-columns: minmax(12rem, 1fr) auto auto; align-items: center;
  gap: 0.7rem; padding: 0.55rem 0; border-bottom: 1px solid var(--rule);
}
.operation:last-child { border-bottom: 0; padding-bottom: 0; }
.operation small { display: block; color: var(--muted); }
.operation .rate { color: var(--ink-2); font-size: 0.84rem; font-variant-numeric: tabular-nums; }

.empty {
  padding: 2rem 1.5rem; text-align: center; color: var(--muted); font-size: var(--fs-13); line-height: 1.6;
  background: var(--fill-soft); border: 0; border-radius: var(--radius-panel);
}
/* Внутри уже готовой поверхности вторая рамка не нужна. */
.production .empty, .table-wrap .empty { border: 0; border-radius: 0; box-shadow: none; background: none; }

/* ----------------------------------------------------------------- форма --- */

/* Длинная форма обязана прокручиваться внутри себя, а кнопка «Сохранить» — всегда
   быть видной. Карточка заказчика — это девять полей плюс реквизиты; на мониторе в
   цехе она не помещается, и без этого человек упирается в форму, которую заполнил, но
   не может отправить. */
dialog {
  border: 0; border-radius: var(--radius-dialog); padding: 0;
  background: var(--surface); color: var(--ink); width: min(34rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem); overflow: hidden; box-shadow: var(--shadow-dialog);
}
dialog::backdrop { background: var(--overlay); }
/* Отступ окна один на поля и липкий футер: футер выходит в край ровно на него. */
dialog form {
  --dialog-pad: var(--sp-5);
  display: grid; gap: 0.9rem; padding: var(--dialog-pad);
  max-height: calc(100vh - 2rem); overflow-y: auto;
}
dialog h2 { margin: 0; font-size: var(--fs-17); font-weight: var(--fw-600); letter-spacing: -0.01em; }
dialog .row {
  display: flex; gap: var(--sp-2); justify-content: flex-end;
  position: sticky; bottom: calc(-1 * var(--dialog-pad, var(--sp-5)));
  margin: 0.4rem calc(-1 * var(--dialog-pad, var(--sp-5))) calc(-1 * var(--dialog-pad, var(--sp-5)));
  padding: var(--sp-3) var(--dialog-pad, var(--sp-5)); background: var(--dialog-footer-bg); border-top: 1px solid var(--rule);
}

dialog.order-dialog { width: min(52rem, calc(100vw - 2rem)); }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem; }
.form-grid .field:last-child { grid-column: 1 / -1; }
.section-title, .order-line {
  display: grid; grid-template-columns: minmax(12rem, 1fr) 6rem 9rem 2.4rem;
  gap: 0.6rem; align-items: center;
}
.section-title { margin-top: 0.35rem; color: var(--muted); font-size: 0.72rem; }
.section-title h3 { margin: 0; color: var(--ink); font-size: 0.95rem; }
.order-lines { display: grid; gap: 0.85rem; }
.order-line-wrap {
  display: grid; gap: 0.45rem; padding-bottom: 0.85rem; border-bottom: 1px solid var(--rule);
}
.order-line-wrap:last-child { padding-bottom: 0; border-bottom: 0; }
.order-line input { text-align: right; font-variant-numeric: tabular-nums; }
.line-price { text-align: right; color: var(--ink-2); font-size: 0.86rem; font-variant-numeric: tabular-nums; }
.icon-button {
  width: var(--control-h-lg); height: var(--control-h-lg); border: 1px solid var(--button-border); border-radius: var(--radius);
  background: none; color: var(--muted); font: 1.25rem/1 system-ui; cursor: pointer;
}
.icon-button:hover:not(:disabled) { color: var(--danger); border-color: var(--danger); }
button.add-line { justify-self: start; }
.order-total { text-align: right; font-weight: 650; font-variant-numeric: tabular-nums; }

.formula { display: grid; gap: 0.45rem; }
button.formula-toggle {
  justify-self: start; padding: 0.28rem 0.55rem; border-color: transparent;
  color: var(--accent); font-size: 0.82rem;
}
button.formula-toggle.has-teeth { border-color: var(--rule); color: var(--ink-2); }
.formula-editor {
  min-width: 0; padding: 0.75rem; border-radius: var(--radius);
  border: 1px solid var(--rule); background: var(--bg);
}
.formula-toolbar { display: grid; grid-template-columns: 1fr 1fr; gap: 0.65rem; }
.formula-hint { color: var(--muted); font-size: 0.76rem; margin: 0.55rem 0; }
.tooth-grid { overflow-x: auto; padding: 0.15rem 0 0.3rem; }
.tooth-row { display: flex; gap: 0.25rem; min-width: 32rem; margin-bottom: 0.25rem; }
.tooth-row:last-child { margin-bottom: 0; }
.tooth-midline { flex: 0 0 0.55rem; border-left: 1px solid var(--muted); margin-left: 0.3rem; }
button.tooth {
  flex: 1 1 0; min-width: 1.85rem; height: 2rem; padding: 0;
  border: 1px solid var(--rule); border-radius: 999px; background: var(--surface);
  color: var(--ink-2); font: 600 0.76rem/1 system-ui; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
button.tooth:hover { border-color: var(--accent); }
button.tooth-unit { background: var(--tooth-unit); }
button.tooth-abutment { background: var(--tooth-abutment); }
button.tooth-pontic { background: var(--tooth-pontic); }
button.tooth-unit, button.tooth-abutment, button.tooth-pontic { color: var(--ink-inverse); border-color: transparent; }
.tooth-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.55rem; }
.tooth-legend span { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--muted); font-size: 0.72rem; }
.tooth-legend i { width: 0.7rem; height: 0.7rem; border-radius: 50%; }
.legend-unit { background: var(--tooth-unit); }
.legend-abutment { background: var(--tooth-abutment); }
.legend-pontic { background: var(--tooth-pontic); }

@media (max-width: 42rem) {
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .field:last-child { grid-column: auto; }
  .section-title { display: none; }
  .order-line { grid-template-columns: minmax(8rem, 1fr) 4.5rem 2.4rem; }
  .order-line .line-price { grid-column: 1 / 3; grid-row: 2; text-align: left; }
  .order-line .icon-button { grid-column: 3; grid-row: 1; }
  .formula-toolbar { grid-template-columns: 1fr; }
  .tooth-chip small { display: none; }
  .operation { grid-template-columns: minmax(8rem, 1fr) auto; }
  .operation .rate { grid-column: 1 / -1; }
}

.error {
  background: var(--danger-soft); color: var(--danger); border: 0;
  padding: .6875rem .75rem; border-radius: var(--radius-card); line-height: 1.5;
}
/* Слой уведомлений: столбик внизу экрана. Он попадает в верхний слой браузера
   (popover), иначе сообщение из открытого диалога остаётся под ним. Указатель слой
   не перехватывает — под ним всё так же нажимается. Правила ниже перекрывают
   стиль браузера для popover, в том числе скрытие закрытого слоя: без верхнего
   слоя уведомления показываются на прежнем месте. */
.toast-host {
  position: fixed; inset: auto 0 24px; margin: 0 auto; width: max-content;
  max-width: calc(100vw - 32px); display: flex; flex-direction: column; align-items: center;
  gap: var(--sp-2); padding: 0; border: 0; background: none; color: inherit; overflow: visible;
  pointer-events: none;
}
/* Тост — как во всех макетах этапа 2: тёмная плашка, белый текст, лаймовая точка
   8 px слева (её кладёт toast() отдельным элементом, а не ::before — у экранов,
   строящих тост сами, точка своя). С действием «Вернуть» — отступ справа 10 и
   кнопка 28 px лаймом (общий приём 7). Ошибка выглядит так же: в макетах нет
   отдельного вида тоста-ошибки. */
.toast {
  display: flex; align-items: center; gap: var(--sp-2-5); max-width: 100%;
  background: var(--ink); color: var(--ink-inverse); border: 0; font-weight: var(--fw-400);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-card); box-shadow: var(--shadow-toast);
}
.toast-dot { width: 8px; height: 8px; flex: none; border-radius: var(--radius-pill); background: var(--brand-lime); }
.toast.toast-action { gap: var(--sp-3); padding: var(--sp-2-5) var(--sp-2-5) var(--sp-2-5) var(--sp-4); pointer-events: auto; }
.toast-undo {
  flex: none; height: 28px; min-height: 28px; padding: 0 var(--sp-2-5); border: 1px solid var(--ink-2); border-radius: var(--radius-sm);
  background: transparent; color: var(--brand-lime); font: inherit; font-weight: var(--fw-500); box-shadow: none; cursor: pointer;
}
.toast-undo:hover:not(:disabled) { background: transparent; color: var(--brand-lime); }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ------------------------------------------------ производство наряда --- */

/* Операции всего наряда одной таблицей (вариант Б планировки): при пяти работах
   вложенные списки не дают увидеть цех целиком и прячут то, что часть операций не
   назначена никому. Полная ширина — единственная, где помещаются исполнитель,
   работа, статус и оплата разом. */
.production {
  border: 1px solid var(--rule); border-radius: var(--radius-card); overflow-x: auto;
  background: var(--surface); backdrop-filter: var(--glass-blur); box-shadow: var(--shadow-card);
}
.prod-row {
  display: grid;
  grid-template-columns: 2rem minmax(11rem, 1fr) 12rem 9rem auto 6.5rem auto;
  gap: 0.7rem; align-items: center; padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--rule);
}
.prod-row:last-child { border-bottom: 0; }
.prod-row.head {
  background: var(--table-head-bg); color: var(--muted);
  font-size: var(--fs-12); font-weight: var(--fw-500); letter-spacing: 0; text-transform: none;
}
.prod-row select { height: var(--control-h); padding: 0 0.5rem; }
.prod-row .rate { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.prod-row .subline { margin-top: 0; }

/* Нераспределённая операция — законное состояние, но она не должна теряться: это
   работа, которую никто не взял. Оттенка в пару процентов на экране цеха не видно,
   поэтому метка идёт по самому полю исполнителя — там, где её и надо исправлять. */
.prod-row.unassigned { background: var(--danger-soft); }
.prod-row.unassigned select { border-color: var(--danger); color: var(--danger); }
.danger-text { color: var(--danger); }

.seq {
  width: 1.6rem; height: 1.6rem; border-radius: var(--radius-pill); display: inline-flex;
  align-items: center; justify-content: center; font-size: 0.78rem; font-weight: 700;
  background: var(--surface-2); color: var(--muted);
}
.moves { display: flex; gap: 0.4rem; }
.moves.operation-status-controls { flex-direction: column; align-items: flex-start; min-width: 0; }
.operation-status-controls > button { white-space: normal; height: auto; min-height: var(--control-h); }
.operation-time { max-width: 14rem; font-size: .75rem; }
.operation-time input { width: 100%; min-width: 0; }
.operation-time summary { cursor: pointer; }
.operation-status-controls .subline:empty { display: none; }
.payroll-output { min-width: 14rem; }

/* Все семь колонок остаются доступны на узком экране внутри своей поверхности. */
.prod-row { min-width: 940px; }

/* ---------------------------------------------- движение по наряду --- */

.ledger-row {
  display: grid; grid-template-columns: 11rem minmax(9rem, 1fr) 14rem 8rem 7rem;
  gap: 0.7rem; align-items: center; padding: 0.5rem 0.9rem;
  border-bottom: 1px solid var(--rule);
}
.ledger-row:last-child { border-bottom: 0; }
.ledger-row.head {
  background: var(--table-head-bg); color: var(--muted);
  font-size: var(--fs-12); font-weight: var(--fw-500); letter-spacing: 0; text-transform: none;
}
/* Сторно видно, но приглушено: это не событие цеха, а исправление записи о нём. */
.ledger-row.reversal { color: var(--muted); font-style: italic; }
.ledger-row.total { background: var(--surface-2); font-weight: 650; }

.head-actions { display: flex; gap: 0.6rem; align-items: center; }
.ledger-row.event { grid-template-columns: 9rem 11rem 12rem 1fr; }
.ledger-row .reason { color: var(--ink-2); }
/* Закрытый наряд читается как документ, а не как рабочий экран. */
.order-closed .production select, .order-closed button.tiny { display: none; }

/* Колонка срока — первое, что читает приёмщик, и читает он её цветом. Пороги считает
   сервер (due_state), здесь только раскраска. Цвет никогда не единственный признак:
   рядом всегда слово, иначе экран бесполезен при дальтонизме и на выцветшем мониторе
   в цехе. */
.due-soon { color: var(--warn); font-weight: 650; }
.due-soon::before { content: "Скоро · "; font-size: 0.75rem; }
.due-overdue { color: var(--danger); font-weight: 650; }
.due-overdue::before { content: "Просрочен · "; font-size: 0.75rem; font-weight: 650; }
.due-done { color: var(--ok); font-weight: 650; }
.due-done::before { content: "Готов · "; font-size: 0.75rem; }
/* Остановленные часы — не просрочка: ход за заказчиком, и цвет здесь жёлтый, а не
   красный. Приёмщик, глядя на список, должен видеть разницу между «мы задержали» и
   «ждём заказчика», не открывая наряд. */
.due-held { color: var(--warn); font-weight: 650; }
.due-held::before { content: "Часы стоят · "; font-size: 0.75rem; }
/* Наряд, который лаборатория ещё не взяла, не красится вовсе: обещать нечего. */
.due-none { color: var(--muted); }
.due .subline { display: block; font-weight: 400; }

/* Вторая строка фильтров: даты и списки не должны растягиваться на всю ширину. */
.orders-bar input[type="date"] { flex: 0 0 9.5rem; }
.orders-bar select { flex: 0 1 12rem; }

.settings-card { max-width: 34rem; }
.settings-card.wide-card { max-width: 56rem; }
.settings-card .hint { color: var(--muted); }

.print-pick { width: auto; min-width: 11rem; }
.req-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.8rem; margin-bottom: 1rem; }
@media (max-width: 40rem) { .req-grid { grid-template-columns: 1fr; } }

/* Дефицит виден строкой, а не только словом справа: этот экран открывают ровно затем,
   чтобы увидеть, чего не хватает. */
tr.short td { background: color-mix(in srgb, var(--danger) 8%, var(--surface)); }
tr.short td:first-child { font-weight: 650; }

/* Строка разнесения шире события наряда: в ней ещё поле суммы и кнопка. Раскладка
   считается по числу колонок, и лишний элемент иначе уезжает на вторую строку. */
.ledger-row.alloc { grid-template-columns: 7.5rem 4.5rem 7rem 1fr auto; gap: 0.6rem; }
.ledger-row.alloc .nowrap { white-space: nowrap; }
dialog.wide { width: min(46rem, calc(100vw - 2rem)); }
.alloc-sum { width: 6.5rem; text-align: right; font-variant-numeric: tabular-nums; }
dialog .production { max-height: 40vh; overflow-y: auto; margin-bottom: 0.5rem; }

/* Срок наряда.

   Это не поле «дата», а состояние спора: чей сейчас ход. Поэтому у панели три вида, и
   различаются они цветом левой полосы — на неё смотрят издалека, между делом.
   Серая — обязательства ещё нет. Обычная — работа идёт. Жёлтая — часы стоят, и это не
   авария: простой защищает лабораторию. Красная — просрочка, и она уже её. */
.deadline {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.9rem 1.2rem;
  margin: 0 0 1rem; padding: 0.9rem 1rem 0.9rem 1.2rem;
  background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-card);
}
.deadline-main { flex: 1 1 20rem; min-width: 0; }
.deadline-main b { display: block; font-size: 1.35rem; font-weight: 650; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums; margin: 0.1rem 0 0.35rem; }
.deadline-main p { margin: 0 0 0.25rem; }
.deadline-main p.hint { margin-bottom: 0; }
.deadline-act { flex: 0 0 auto; align-self: center; }
.deadline-history { flex: 1 1 100%; }
.deadline-holds { margin-top: 0.4rem; }
/* У простоя свои столбцы: дата узкая, причина широкая, длительность выключена
   вправо. Сетка «событий наряда» здесь ломает причину на две строки рядом с
   пустым местом. */
.ledger-row.hold { grid-template-columns: 5rem minmax(9rem, 1fr) 6rem 1.6fr; }
.deadline-history .op-title { display: block; margin-bottom: 0.35rem; }
.deadline.idle b { color: var(--muted); font-size: 1.1rem; }
.deadline.held { border-color: transparent; background: var(--warn-soft); }
.deadline.held .deadline-main b { color: var(--warn); }
.deadline.late { border-color: transparent; background: var(--danger-soft); }
.deadline.late .deadline-main b { color: var(--danger); }

/* Заявки — раздел, собранный как раздел СРМ клиники: шапка, полоса «сейчас»,
   фильтры и доска дорожек.

   Доска, а не список, потому что у заявки три исхода и приёмщик держит в голове все
   три: что ждёт ответа, что взято и что мы отклонили. Список показывает только первое,
   а спрашивают чаще как раз о третьем — «почему вы нам тогда отказали». */

.section-head { align-items: flex-end; justify-content: space-between; }
.section-head h1 { line-height: 1.15; }
.section-sub {
  display: block; margin: var(--sp-1) 0 0; max-width: 80ch;
  font-size: var(--fs-12-5); font-weight: var(--fw-400); line-height: 1.5; color: var(--muted);
}

.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-bottom: 0.6rem; }
.chip {
  display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  border: 1px solid var(--button-border); border-radius: var(--radius); padding: 0.34rem 0.7rem;
  background: var(--surface); color: var(--ink-2);
  font: inherit; font-size: var(--fs-12); font-weight: var(--fw-500);
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.chip:hover { background: var(--hover-bg); color: var(--ink); }
.chip b { font-variant-numeric: tabular-nums; font-weight: 700; }
.chip.on.chip-info { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.chip.on.chip-danger { border-color: var(--danger); background: var(--danger-soft); color: var(--danger); }
.chip.on.chip-warn { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }
.chip.on.chip-plain { border-color: var(--rule-strong); background: var(--surface-2); color: var(--ink); }
.chip-ok {
  border-color: transparent; background: var(--ok-soft); color: var(--ok); cursor: default;
}
.chip-link {
  background: none; border: 0; cursor: pointer; font: inherit;
  font-size: 0.76rem; font-weight: 600; color: var(--faint); padding: 0 0.3rem;
}
.chip-link:hover { color: var(--ink); }
.chip-select { width: auto; min-width: 9rem; max-width: 13rem; height: var(--control-h); padding: 0 0.6rem; font-size: var(--fs-12-5); }
/* Даты не растягиваются: поле выбора даты и так шире своего содержимого, а рядом с
   ним в строке фильтров стоят ещё пять контролов. */
.chip-date { width: auto; flex: 0 0 8.6rem; height: var(--control-h); padding: 0 0.5rem; font-size: var(--fs-12-5); }
/* Строка фильтров прижата к полосе «сейчас»: это два яруса одного управления, а не
   два отдельных блока. */
.now-strip { margin-bottom: 0.5rem; }
/* Заголовок блока внутри раздела: тише названия раздела, но громче строки таблицы. */
h2.sect { font-size: 0.95rem; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 0.55rem; }
h2.sect-next { margin-top: 1.4rem; }
.filter-strip > label:not(.search-field) {
  display: flex; align-items: center; gap: 0.4rem; white-space: nowrap;
  color: var(--muted); font-size: 0.8rem; font-weight: 500; cursor: pointer;
}
.filter-strip > label:not(.search-field) input { width: auto; }
.filter-strip { margin-bottom: 0.9rem; }
.search-field { flex: 0 1 17rem; }
.search-field input { height: var(--control-h); font-size: var(--fs-12-5); padding: 0 0.7rem; }

/* Дорожек всего три, но на узком экране они всё равно не помещаются рядом: лента
   прокручивается вбок, как доска воронки в клинике. */
.board { display: flex; flex-wrap: nowrap; gap: 0.75rem; overflow-x: auto; padding-bottom: 0.4rem; align-items: flex-start; }
.lane {
  display: flex; flex-direction: column; gap: 0.45rem;
  flex: 1 1 18rem; min-width: 17rem; min-height: 12rem;
  border: 1px solid var(--rule); border-radius: 16px; padding: 0.7rem;
  background: var(--surface-2);
}
.lane-head { display: flex; align-items: center; gap: 0.45rem; padding: 0 0.15rem 0.15rem; }
.lane-dot { width: 9px; height: 9px; border-radius: 3px; flex: none; background: var(--faint); }
.lane-wait .lane-dot { background: var(--accent); }
.lane-taken .lane-dot { background: var(--ok); }
.lane-refused .lane-dot { background: var(--danger); }
.lane-name { font-size: 0.82rem; font-weight: 700; }
.lane-count {
  border-radius: 6px; background: var(--surface-solid); padding: 0.12rem 0.4rem;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 600; color: var(--muted);
}
/* Молчим, когда гореть нечему: пустой красный счётчик — ложная тревога. */
.lane-hot {
  margin-left: auto; border-radius: 6px; background: var(--danger-soft);
  padding: 0.12rem 0.4rem; font-size: 0.66rem; font-weight: 700; color: var(--danger);
}
.lane-empty, .lane-more {
  margin: 0; border-radius: 12px; padding: 1.1rem 0.75rem; text-align: center;
  font-size: 0.72rem; color: var(--faint); background: color-mix(in srgb, var(--surface-solid) 55%, transparent);
}
.lane-more { padding: 0.5rem; }

.req-card {
  display: flex; flex-direction: column; gap: 0.2rem;
  background: var(--surface-solid); border: 1px solid var(--rule);
  border-radius: 12px; padding: 0.6rem 0.7rem; box-shadow: var(--shadow-sm);
}
.req-card.decided { opacity: 0.82; }
.req-top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.req-no { font-family: var(--mono); font-size: 0.68rem; font-weight: 600; color: var(--faint); }
.req-when { font-size: 0.68rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.req-clinic { font-size: 0.92rem; font-weight: 700; letter-spacing: -0.01em; }
.req-who { font-size: 0.76rem; color: var(--muted); }
.req-what { font-size: 0.82rem; font-weight: 600; margin-top: 0.15rem; }
.req-marks { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.25rem; }
.req-due, .req-hot {
  border-radius: 999px; padding: 0.08rem 0.45rem; font-size: 0.7rem; font-weight: 600;
  background: var(--surface-2); color: var(--ink-2); white-space: nowrap;
}
.req-hot { background: var(--danger-soft); color: var(--danger); }
.req-note { margin: 0.3rem 0 0; font-size: 0.76rem; color: var(--ink-2); }
.req-answer { margin: 0.3rem 0 0; font-size: 0.74rem; color: var(--danger); }
.req-acts { margin-top: 0.45rem; gap: 0.35rem; }

.ledger-row.request-item { grid-template-columns: 1fr minmax(14rem, 20rem); align-items: center; }

/* Метки: сколько ждёт и чем кончилось. */
.badge {
  display: inline-block; padding: 0.125rem 0.4375rem; border-radius: var(--radius-sm);
  font-size: var(--fs-12); font-weight: var(--fw-500); background: var(--chip-bg); color: var(--ink-2);
}
.badge.waiting { background: var(--warn-soft); color: var(--warn); }
.badge.accepted { background: var(--ok-soft); color: var(--ok); }
.badge.declined { background: var(--danger-soft); color: var(--danger); }
/* Счётчик пункта меню — только существующие (заявки, «С чего начать»): чёрная
   пилюля с белой цифрой, как в каркасе макета. */
nav button .badge {
  margin-left: auto; min-width: 20px; height: 18px; padding: 0 6px; border-radius: var(--radius-pill);
  background: var(--brand-ink); color: var(--ink-inverse); text-align: center;
  font: var(--fw-600) var(--fs-11)/18px var(--mono); font-variant-numeric: tabular-nums;
}

/* Перевозка коробки.

   Стоит вплотную под сроком намеренно: отметка «забрал» и есть то место, где срок
   начинается, и ставить её человек должен там же, где видит дату. */
.trips { margin: 0 0 1rem; }
.trips-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.trips-head .op-title { margin-right: auto; }
.trip {
  display: grid; grid-template-columns: minmax(12rem, 1fr) 12rem 7rem auto;
  gap: 0.6rem; align-items: center;
  padding: 0.55rem 0.8rem; background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--radius); margin-bottom: 0.35rem;
}
.trip .subline { display: block; color: var(--muted); font-size: 0.85rem; }
/* Дата и время — моноширинные: их читают столбиком и сравнивают. */
.trip-when { color: var(--muted); font: var(--fw-400) var(--fs-12)/1.35 var(--mono); white-space: nowrap; }
.trip-acts { justify-content: flex-end; gap: 0.4rem; }
.trip-delivered, .trip-cancelled { opacity: 0.65; }
.trips-note { margin-top: 0.3rem; }
.badge.planned { background: var(--surface-2); color: var(--ink-2); }
.badge.picked { background: var(--warn-soft); color: var(--warn); }
.badge.delivered { background: var(--surface-2); color: var(--ok); }
.badge.cancelled { background: var(--surface-2); color: var(--muted); }
@media (max-width: 900px) {
  .trip { grid-template-columns: 1fr; }
  .trip-acts { justify-content: flex-start; }
}

/* Зарплата.

   Период наверху с тремя числами, ради которых экран и открывают. Закрытый выглядит
   иначе не для красоты: под ним заперты начисления, и человек должен видеть это до
   того, как попробует что-то отметить. */
.period {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem;
  padding: 0.9rem 1rem 0.9rem 1.2rem; margin-bottom: 1rem;
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-card);
}
.period.closed { background: var(--fill-soft); }
.period-main { flex: 1 1 14rem; min-width: 0; }
.period-main b { display: block; font-size: 1.2rem; font-weight: 650; margin: 0.1rem 0 0.1rem; }
.period-main .subline { color: var(--muted); font-size: 0.88rem; }
.period-sums { display: flex; gap: 0.5rem; flex: 2 1 24rem; }
.period-sums .fact { border: 1px solid var(--rule); border-radius: var(--radius); }
.period-act { display: flex; gap: 0.5rem; flex: none; }
.period-note { flex: 1 1 100%; margin: 0; }
.period-pick { flex: 0 1 18rem; }
/* Долг технику подсвечен: это то, ради чего на экран пришли. */
td.num.owed { font-weight: 650; color: var(--danger); }
.row-acts { text-align: right; white-space: nowrap; }
.row-acts button { margin-left: 0.4rem; }
/* Действие внутри строки — тихая кнопка. На «Перевозке» подряд идут два десятка
   «Забрал»/«Довёз», на «Зарплате» — два десятка «Выдать»: чёрная заливка в каждой
   строке превращает колонку в сплошное пятно и перестаёт что-либо выделять.
   Чёрной остаётся кнопка страницы (шапка раздела) и главная кнопка окна. */
.row-acts button.action, .trip-acts button.action {
  background: var(--surface); color: var(--ink-2); font-weight: var(--fw-500);
  border: 1px solid var(--button-border); box-shadow: var(--shadow-sm);
}
.row-acts button.action svg, .trip-acts button.action svg { color: currentColor; }
.row-acts button.action:hover:not(:disabled), .trip-acts button.action:hover:not(:disabled) {
  background: var(--hover-bg); color: var(--ink);
}
.ledger-row.sheet { grid-template-columns: 5rem 1fr 4rem 7rem; }
.ledger-row.sheet.reversal .rate { color: var(--danger); }
/* Шаг · операция · как считать · сколько · убрать. Колонка количества остаётся на
   месте и когда поле спрятано («один раз на наряд»): иначе строки прыгают вбок при
   каждом переключении. */
.ledger-row.work-op { grid-template-columns: 4.5rem 1fr 11rem 5rem auto; align-items: center; }
.ledger-row.work-op .op-mode { width: 100%; min-width: 0; }
/* Поле количества занимает свою колонку целиком: с фиксированной шириной оно
   наезжало на кнопку «Убрать». */
.ledger-row.work-op .alloc-sum { width: 100%; min-width: 0; }
.ledger-row.backup { grid-template-columns: 11rem 1fr 6rem auto; align-items: center; }
.ledger-row.employee { grid-template-columns: 1fr 9rem 7rem auto; align-items: center; }
.ledger-row.employee.off { opacity: 0.6; }
.resource-page .bar { flex-wrap:wrap; }
.resource-page .bar [aria-pressed="true"] { background:var(--accent-soft); color:var(--accent); }
.resource-panel { display:grid; grid-template-columns:minmax(0,1fr); gap:1rem; min-width:0; }
.resource-panel .card-lines { margin:0; }
.resource-table td { vertical-align:top; white-space:normal; min-width:7rem; }
.resource-table td:first-child { min-width:12rem; }
.resource-dialog { width:min(42rem,94vw); max-height:90vh; padding:0; }
.resource-dialog form { padding:0; gap:0; display:grid; grid-template-rows:minmax(0,1fr) auto; max-height:88vh; overflow:hidden; }
.resource-form-body { overflow:auto; display:grid; gap:.9rem; padding:1.4rem; }
.resource-form-footer { display:flex; flex-wrap:wrap; gap:.7rem; justify-content:flex-end; padding:1rem 1.4rem; border-top:1px solid var(--rule); }
.resource-form-body label:has(input[type=checkbox]) { display:flex; align-items:center; gap:.65rem; }
.resource-form-body input[type=checkbox] { width:auto; min-height:auto; }
.resource-form-body label[hidden] { display:none; }
.resource-summary { white-space:pre-wrap; overflow-wrap:anywhere; font:inherit; }

/* Карточка настроек — та же поверхность, что у списков и нарядов: один вид у всего,
   что лежит «на столе» страницы. */
.card {
  background: var(--surface); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rule); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 1.2rem 1.3rem; margin-bottom: 1.1rem;
}
.card h2.sect {
  margin: 0 0 0.7rem; font-size: 1.02rem; font-weight: 700; letter-spacing: -0.015em;
}

/* -------------------------------------------------------- ставки техников --- */

/* Строка группы прайса. Операций у лаборатории под сотню, и без разделителей
   список превращается в ленту, по которой ищут прокруткой. */
.group-row td {
  padding: 0.7rem 0.6rem 0.3rem; font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--faint);
  background: none; border-bottom: 1px solid var(--divider);
}
/* Операция, которую техник не делает, приглушена: заполненных строк у человека
   обычно пять из восьмидесяти, и видно должно быть именно их. */
tr.dim td { color: var(--faint); }
tr.dim td b { font-weight: 500; color: var(--muted); }
.num-input {
  width: 7.5rem; height: var(--control-h); text-align: right;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.num-input::placeholder { font-family: var(--font); font-size: 0.78rem; color: var(--faint); }
.bar .ro { font-size: 0.8rem; color: var(--muted); }
td.faint { color: var(--faint); font-size: 0.82rem; }

/* Пустой справочник объясняет себя. Карточка, а не серая строка: это единственное,
   что на экране есть, и она обязана выглядеть как содержимое, а не как отсутствие
   содержимого. */
.blank {
  background: var(--surface); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rule); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 1.6rem 1.7rem; max-width: 46rem;
}
.blank b { display: block; font-size: 1.02rem; font-weight: 700; color: var(--ink); }
.blank p { margin: 0.5rem 0 0; font-size: 0.88rem; line-height: 1.55; color: var(--ink-2); max-width: 60ch; }
.blank-acts { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.1rem; }

/* ------------------------------------------------------ переписка по наряду --- */

/* Лента ограничена по высоте и прокручивается внутри себя: разговор по сложной
   работе идёт неделями, и полсотни реплик иначе уносят вниз всё, что под ними —
   журналы, движение, историю закрытий. */
.thread {
  display: grid; gap: 0.55rem; max-height: 30rem; overflow-y: auto;
  padding: 0.2rem 0.2rem 0.4rem; margin-top: 0.9rem;
}
.msg {
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--surface-solid); padding: 0.6rem 0.75rem; max-width: 46rem;
}
/* Своя реплика — бледная синяя заливка и сдвиг вправо: в ленте на десять реплик
   надо за долю секунды понимать, где кончается своё и начинается чужое. */
.msg.mine { background: var(--accent-soft); border-color: transparent; margin-left: auto; }
.msg.gone { background: var(--surface-2); border-style: dashed; }
.msg > header { display: flex; align-items: baseline; gap: 0.5rem; }
.msg > header b { font-size: 0.85rem; font-weight: 700; color: var(--ink); }
.msg > header .subline { display: inline; font-size: 0.76rem; }
.msg > header button { margin-left: auto; }
.msg-body { margin: 0.35rem 0 0; font-size: 0.88rem; line-height: 1.5; color: var(--ink); white-space: pre-wrap; }
.msg.gone .msg-body { color: var(--faint); text-decoration: line-through; }
.msg-gone { margin: 0.35rem 0 0; font-size: 0.76rem; font-weight: 600; color: var(--faint); }
.msg-files { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.file-with-versions { display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; max-width: 100%; }
dialog.file-version-history { padding: 1.4rem; overflow-y: auto; }
.file-version-entry { padding: 0.8rem 0; border-bottom: 1px solid var(--rule); overflow-wrap: anywhere; }
.file-version-entry p { margin: 0.3rem 0; }
dialog .file-version-upload { margin-top: 1rem; padding: 0; max-height: none; overflow: visible; }
/* Снимок показывается в ленте, а не ссылкой: за фото уступа сюда и приходят, и
   открывать его, чтобы понять, то ли оно, — лишний шаг на каждом сообщении. */
.msg-shot {
  display: block; width: 8.5rem; height: 8.5rem; border-radius: var(--radius);
  overflow: hidden; border: 1px solid var(--rule); background: var(--surface-2);
}
.msg-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

.thread-blank {
  border: 1px dashed var(--rule-strong); border-radius: var(--radius);
  padding: 0.9rem 1rem; font-size: 0.85rem; line-height: 1.5; color: var(--muted);
  max-width: 52ch;
}
.thread-box { display: grid; gap: 0.55rem; margin-top: 0.9rem; }
.thread-box textarea { min-height: 3.6rem; resize: vertical; }
.thread-acts { display: flex; gap: 0.55rem; align-items: center; }
.thread-acts .action { margin-left: auto; }
.thread-picked { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.thread-chip {
  display: inline-flex; align-items: baseline; gap: 0.4rem;
  border: 1px solid var(--rule); border-radius: 999px; padding: 0.24rem 0.7rem;
  font-size: 0.8rem; color: var(--ink-2); background: var(--surface-solid);
  text-decoration: none; max-width: 22rem;
}
a.thread-chip:hover { border-color: var(--accent); color: var(--accent); }
.thread-chip i { font-style: normal; font-size: 0.72rem; color: var(--faint); white-space: nowrap; }
.thread-chip.erased { border-style: dashed; color: var(--faint); text-decoration: line-through; }
.thread-chip.erased i { text-decoration: none; }
/* Отзыв — действие редкое и необратимое для файлов. Держать его на виду у каждой
   реплики значит предлагать его десять раз подряд; появляется по наведению и по
   клавиатурному фокусу, чтобы не пропасть для тех, кто мышью не пользуется. */
.msg > header button { opacity: 0; transition: opacity .12s ease; }
.msg:hover > header button, .msg:focus-within > header button { opacity: 1; }
@media (hover: none) { .msg > header button { opacity: 1; } }
/* Снимок и вложение — кнопки: файл забирается запросом с токеном, а не ссылкой. */
button.msg-shot { padding: 0; cursor: zoom-in; appearance: none; }
button.thread-chip { cursor: pointer; font: inherit; font-size: 0.8rem; }
button.thread-chip:hover { border-color: var(--accent); color: var(--accent); }
.msg-shot i { display: block; padding: 0.6rem; font-style: normal; font-size: 0.76rem; color: var(--faint); }

/* ------------------------------------------------------------- перевозка --- */

.trip-group { margin-bottom: 0.9rem; padding: 0.9rem 1rem; }
.trip-group-head {
  display: flex; align-items: baseline; gap: 0.6rem;
  padding-bottom: 0.5rem; border-bottom: 1px solid var(--divider); margin-bottom: 0.2rem;
}
.trip-group-head b { font-size: 0.98rem; font-weight: 700; color: var(--ink); }
.trip-group-head .subline { display: inline; font-size: 0.78rem; }
.trip-group-head button { margin-left: auto; }
/* На общем экране в строке на одну колонку больше, чем в карточке наряда: там
   номер наряда известен, а здесь его надо назвать — иначе непонятно, за чем едут. */
.trip-group .trip {
  grid-template-columns: minmax(11rem, 1fr) 9.5rem 11rem 6.5rem auto;
}
@media (max-width: 1100px) {
  .trip-group .trip { grid-template-columns: 1fr 1fr; }
  .trip-group .trip .trip-acts { grid-column: 1 / -1; justify-content: flex-start; }
}
/* Наряд в строке поездки — вход в карточку: приёмщик, который увидел странный
   адрес, идёт смотреть наряд, а не ищет его потом в списке по номеру. */
.trip-what { cursor: pointer; font-family: var(--mono); font-size: 0.82rem; }
.trip-what:hover { color: var(--accent); }
.trip-what .subline { font-family: var(--font); }
/* Отметка состояния — по содержимому, а не во всю колонку: растянутая пилюля
   читается как поле ввода, а не как метка. */
.trip .badge { justify-self: start; }

/* -------------------------------------------------------- связи с клиниками --- */

.link-row {
  display: grid; grid-template-columns: minmax(12rem, 1fr) auto auto;
  gap: 0.4rem 0.9rem; align-items: center;
  padding: 0.7rem 0.85rem; margin-bottom: 0.5rem;
  border: 1px solid var(--rule); border-radius: var(--radius); background: var(--surface-solid);
}
.link-row.off { opacity: 0.6; }
.link-main b { display: block; font-size: 0.92rem; font-weight: 700; color: var(--ink); }
.link-main .subline { font-family: var(--mono); font-size: 0.74rem; }
.link-state { display: grid; gap: 0.15rem; justify-items: end; text-align: right; }
.link-state .badge { justify-self: end; }
.link-state .subline { font-size: 0.76rem; }
/* Очередь, которая растёт, — это и есть неработающий провод. */
.link-state .subline.warn { color: var(--warn); font-weight: 600; }
.link-acts { display: flex; gap: 0.4rem; }
.link-error {
  grid-column: 1 / -1; margin: 0.2rem 0 0; padding: 0.4rem 0.6rem;
  border-radius: var(--radius); background: var(--danger-soft); color: var(--danger);
  font-size: 0.78rem; line-height: 1.4;
}
@media (max-width: 900px) {
  .link-row { grid-template-columns: 1fr; }
  .link-state { justify-items: start; text-align: left; }
  .link-state .badge { justify-self: start; }
}
/* Реплика из клиники. Отличается от реплики коллеги за соседним столом намеренно:
   на первую отвечают в программе, и через месяц спорят именно о ней. */
.msg.from-clinic { border-color: transparent; background: var(--violet-soft); }
.msg-side {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--violet); padding: 0.05rem 0.35rem; border-radius: 4px;
  background: var(--surface);
}
/* Голосовое проигрывается в ленте: техник записал двадцать секунд, приёмщик их
   слушает — скачивать ради этого файл значит не слушать вовсе. */
.msg-voice { display: block; width: 15rem; max-width: 100%; height: 2.2rem; }
.thread-acts button.recording { border-color: var(--danger); color: var(--danger); }
.thread-hint { font-size: 0.76rem; color: var(--muted); max-width: 30ch; line-height: 1.35; }
/* Переделка в карточке: видно сразу, что работа уже делалась и почему вернулась. */
.remake-note { background: var(--warn-soft); }
.remake-note .eyebrow { color: var(--warn); }
.remake-note button { margin-top: 0.5rem; }
/* Кнопка «зачем этот раздел». Рядом с заголовком и в его размере — она часть
   названия, а не действие: нажимают её один раз в жизни, и мешать она не должна. */
.help-dot {
  appearance: none; border: 1px solid var(--rule-strong); background: none;
  color: var(--muted); cursor: pointer; font: inherit; font-size: 0.7em;
  font-weight: 700; line-height: 1; width: 1.5em; height: 1.5em; border-radius: 999px;
  margin-left: 0.5em; vertical-align: middle; padding: 0;
}
.help-dot:hover { border-color: var(--accent); color: var(--accent); }
.help-line { margin: 0 0 0.7rem; font-size: 0.88rem; line-height: 1.55; color: var(--ink-2); max-width: 56ch; }
/* Production pages remain readable on a workstation and a narrow tablet. */
.production-board { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1rem; align-items:start; }
.production-column { min-width:0; background:var(--column-bg); padding:1rem; border-radius:var(--radius-panel); }
.production-column h2 { font-size:1.05rem; margin:0 0 1rem; }
.production-card { display:flex; flex-direction:column; gap:.5rem; background:var(--surface-solid); border:1px solid var(--rule); border-radius:8px; padding:1rem; margin-bottom:.75rem; overflow-wrap:anywhere; }
.production-card p { margin:0; }
.production-card select { width:100%; min-width:0; }
@media (max-width:1000px) { .production-board { grid-template-columns:1fr; } }
.payroll-adjustment-entry { border-top:1px solid var(--rule); padding:.8rem 0; overflow-wrap:anywhere; }
.payroll-adjustment-entry p { margin:.35rem 0; }
.stock-entry { border-top:1px solid var(--rule); padding:.8rem 0; overflow-wrap:anywhere; }
.stock-entry p { margin:.35rem 0; }
.order-edit-dialog { width:min(900px,95vw); max-width:95vw; }
.order-edit-dialog form { padding:0; gap:0; overflow:hidden; grid-template-rows:auto minmax(0,1fr) auto; }
.order-edit-dialog form > h2 { padding:1.2rem 1.4rem; }
.order-edit-body { display:grid; gap:.8rem; padding:0 1.4rem 1rem; overflow-y:auto; min-height:0; }
.order-edit-footer { display:flex; justify-content:flex-end; gap:.6rem; padding:.9rem 1.4rem; border-top:1px solid var(--rule); }
.order-edit-teeth-toolbar { display:grid; grid-template-columns:1fr 1fr auto; gap:.5rem; margin-bottom:.6rem; }
.order-edit-line .check { margin:.8rem 0; }
dialog.order-edit-history { padding:1.4rem; overflow-y:auto; }
.order-edit-line,.order-edit-entry { border-top:1px solid var(--rule); padding:1rem 0; overflow-wrap:anywhere; }
.order-edit-audit { display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem; }
@media (max-width:640px) { .order-edit-audit,.order-edit-teeth-toolbar { grid-template-columns:1fr; } }
.encrypted-backups { margin-top:1.5rem; padding-top:1rem; border-top:1px solid var(--rule); }
.encrypted-backups .error:empty { display:none; }
.pairing-dialog .error:empty { display:none; }
.pairing-dialog form { min-width:0; grid-template-columns:minmax(0,1fr); }
.pairing-dialog .row { flex-wrap:wrap; }
.pairing-dialog .hint, .pairing-dialog .error { overflow-wrap:anywhere; }
.backup-encrypted-row { overflow-wrap:anywhere; }

/* Общие поверхности и плотность рабочего пространства. */
::selection { background: var(--brand-lime); color: var(--ink); }
a { color: var(--accent); text-underline-offset: .2em; }
:where(a, [tabindex], summary):focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input, select, textarea { min-width: 0; box-shadow: none; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.bar { gap: .65rem; }
.section-head .row { flex-shrink: 0; }
tbody tr:focus-visible { outline-offset: -3px; background: var(--accent-soft); }
.table-wrap { max-width: 100%; }
.table-wrap > table { border: 0; box-shadow: none; }
dialog .row { z-index: 1; }
.toast-host { z-index: 90; }
.help-dot { font-size: 12px; width: var(--control-h); height: var(--control-h); border-color: transparent; }
/* Поиск, компактные счётчики и строки — единое рабочее представление. */
.orders-heading { padding: 0; gap: 1rem; }
.orders-heading > div:first-child { flex: 1 1 20rem; }
.head-actions { flex-wrap: wrap; min-width: 0; max-width: 100%; }
.head-actions > button { min-height: var(--control-h); height: auto; padding-block: var(--sp-1); white-space: normal; }
.print-pick { max-width: 100%; }
.orders-controls { background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-card); padding: .65rem; }
/* Полоса «сейчас» — один рецепт на «Наряды», «Заявки» и «Перевозку»: мягкая
   смысловая заливка, точка тона слева и моноширинное число. Области задают себе
   только смысл тона (что считать тревогой), но не вид полосы. */
.now-strip { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1-5); margin: var(--sp-2-5) 0 var(--sp-2); }
.now-strip .chip {
  display: inline-flex; align-items: center; justify-content: flex-start; gap: var(--sp-2);
  min-height: var(--control-h); padding: var(--sp-1) var(--sp-2-5);
  border: 1px solid transparent; border-radius: var(--radius);
  text-align: left; font-size: var(--fs-12-5); font-weight: var(--fw-500); line-height: 1.25;
}
.now-strip .chip::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.now-strip .chip b { font: var(--fw-600) var(--fs-12)/1 var(--mono); font-variant-numeric: tabular-nums; }
.now-strip .chip-danger { background: var(--danger-soft); color: var(--danger); }
.now-strip .chip-warn { background: var(--warn-soft); color: var(--warn); }
.now-strip .chip-info { background: var(--info-soft); color: var(--info); }
.now-strip .chip-ok { background: var(--ok-soft); color: var(--ok); }
.now-strip .chip-plain { background: var(--chip-bg); color: var(--ink-2); }
.now-strip .chip:hover:not(:disabled) { border-color: currentColor; }
.now-strip .chip.on { border-color: currentColor; box-shadow: inset 0 0 0 1px currentColor; }
.now-strip .chip.is-zero { opacity: 1; background: var(--chip-bg); color: var(--muted); }
.now-strip .chip.is-zero::before { background: var(--decor); }
/* «Сбросить» в полосе — тихая ссылка, а не счётчик: без точки и без заливки. */
.now-strip .chip-link {
  justify-self: start; min-height: var(--control-h); padding: 0 var(--sp-2);
  background: none; color: var(--ink-2); font-size: var(--fs-12-5); font-weight: var(--fw-500);
  text-decoration: underline; text-decoration-color: var(--rule-strong); text-underline-offset: .25em;
}
.now-strip .chip-link::before { content: none; }
.now-strip .chip-link:hover { color: var(--ink); text-decoration-color: currentColor; }
.filter-strip { gap: .65rem; padding: 0; margin-bottom: .65rem; align-items: end; }
.filter-strip .search-field { flex: 1 1 16rem; }
.filter-strip .search-field input { width: 100%; }
.filter-strip .chip-select, .filter-strip .chip-date, .search-field input { height: var(--control-h); }
.order-scanner { padding: .2rem 0; align-items: flex-end; margin: .3rem 0; }
.order-scanner .field { flex: 1 1 14rem; max-width: 26rem; font-size: .72rem; }
.order-scanner input { height: var(--control-h); font-size: var(--fs-12-5); }
.order-scanner .ghost { height: var(--control-h); }
.scanner-hint { color: var(--muted); margin: .35rem 0 1.1rem; }
.order-number { color: var(--muted); font: 500 .76rem var(--mono); }
.order-patient { color: var(--ink); font-weight: 600; }
.orders-table tbody tr:hover .order-number { color: var(--accent); }
.order-card > .back { margin-bottom: .75rem; padding-inline: 0; border-color: transparent; color: var(--muted); }
.order-card > .order-head { display: flex; align-items: center; margin-bottom: 1rem; }
.order-head > .order-title { display: flex; flex: 1 1 24rem; flex-wrap: wrap; align-items: center; gap: .45rem .75rem; }
.order-head .eyebrow { flex-basis: 100%; color: var(--muted); }
.order-head .head-actions { margin: 0; padding: 0; border: 0; flex: 0 1 auto; }
.order-head .head-actions:has(.order-actions[open]) { flex-basis: 100%; }
.order-card .facts { background: var(--surface); border-radius: var(--radius-card); gap: 0; }
.order-card .fact { padding: .7rem .9rem; border-right: 1px solid var(--rule); flex-basis: 9rem; }
.order-card .fact:last-child { border-right: 0; }
.order-card .fact b { font-size: .85rem; }
.order-card .fact.money { background: var(--surface); }
.order-card .fact.money b { font-size: .95rem; color: var(--ink); }
.content-workspace { min-width: 0; }
/* Вкладки — сегментный переключатель: серая подложка, выбранная вкладка белая с тенью
   1 px. Фокус рисуется внутри вкладки: подложка прокручивается и обрезала бы внешний. */
.workspace-tabs { display: flex; width: fit-content; max-width: 100%; gap: 2px; overflow-x: auto; padding: 2px; margin: .9rem 0 1.1rem; background: var(--chip-bg); border-radius: var(--radius); }
.workspace-tabs [role="tab"] { flex: 0 0 auto; min-height: 28px; border: 0; border-radius: var(--radius-sm); padding: 0 var(--sp-2-5); background: transparent; color: var(--muted); font: inherit; font-size: var(--fs-12-5); font-weight: var(--fw-500); cursor: pointer; white-space: nowrap; }
.workspace-tabs [role="tab"]:hover { color: var(--ink); }
.workspace-tabs [aria-selected="true"] { background: var(--surface); color: var(--ink); font-weight: var(--fw-600); box-shadow: var(--shadow-tab); }
.workspace-tabs [role="tab"]:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.workspace-panel:focus-visible, summary:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.workspace-panel { min-width: 0; }
.workspace-panel > .card-lines:first-child, .workspace-panel > .thread:first-child { margin-top: 0; }
.order-head .head-actions { align-items: flex-start; justify-content: flex-start; }
.order-actions { flex: 0 1 auto; min-width: 0; }
.order-actions summary, .orders-tools summary { width: fit-content; min-height: var(--control-h); padding: 6px var(--sp-3); border: 1px solid var(--button-border); border-radius: var(--radius); background: var(--surface); color: var(--ink-2); cursor: pointer; font-size: var(--fs-12-5); font-weight: var(--fw-500); box-shadow: var(--shadow-sm); }
.order-action-items { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; padding: .85rem 0 .2rem; }
.order-action-items > * { max-width: 100%; }
.order-action-items .hint { flex-basis: 100%; }
.orders-primary > .field { flex: 0 1 12rem; min-width: 0; }
.orders-primary > .search-field { flex: 1 1 20rem; }
.orders-primary > .field input, .orders-primary > .field select { width: 100%; }
.orders-primary > label:not(.field) { align-self: end; min-height: 2.4rem; }
.orders-primary > label.field { display: grid; font-size: .74rem; }
.orders-tools { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-start; }
.orders-filters[open] { flex-basis: 100%; }
.orders-filter-fields { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .8rem; padding: 1rem 0; }
.orders-filter-fields .field { min-width: 0; }
.orders-qr[open] { flex: 1 1 100%; }
.orders-list-meta { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem 1rem; flex-wrap: wrap; margin: .3rem 0 .2rem; }
.orders-found { font-size: .78rem; color: var(--muted); margin: 0; }
.orders-deadline-hint { font-size: .72rem; color: var(--muted); }
.workspace-search { max-width: 32rem; }
.workspace-search .field { font-size: .76rem; }
dialog.order-intake { width: min(72rem, calc(100vw - 2rem)); }
dialog.order-intake form { padding: 0; gap: 0; overflow: hidden; max-height: calc(100dvh - 2rem); grid-template-rows: auto minmax(0, 1fr) auto; }
.intake-head { padding: 1rem 1.4rem; border-bottom: 1px solid var(--rule); background: var(--surface); }
.intake-head .eyebrow { color: var(--muted); display: block; margin-bottom: .25rem; }
.intake-head .hint { margin: .25rem 0 0; }
.intake-body { overflow-y: auto; min-height: 0; display: grid; gap: 0; }
.intake-layout { display: grid; grid-template-columns: minmax(15rem, 18rem) minmax(0, 1fr); min-width: 0; }
.intake-sidebar { min-width: 0; display: grid; align-content: start; gap: 1.4rem; padding: 1.25rem; background: var(--fill-soft); border-right: 1px solid var(--rule); }
.intake-workspace { min-width: 0; padding: 1.25rem; }
.intake-body > .error, .intake-body > .intake-prerequisite { margin: 1rem; }
.intake-group { border: 0; padding: 0; margin: 0; min-width: 0; }
.intake-group legend { padding: 0 0 .75rem; font-size: .88rem; font-weight: 650; color: var(--ink); }
.intake-group .hint { margin: 0 0 .8rem; }
.intake-group .field { font-size: .77rem; }
.intake-group .form-grid { grid-template-columns: minmax(0, 1fr); gap: .75rem; }
.intake-group .form-grid .field:last-child { grid-column: auto; }
.intake-details { padding-top: 1.1rem; border-top: 1px solid var(--rule); }
.intake-details .form-grid { margin-bottom: .75rem; }
.intake-group .order-line-wrap { padding: .85rem; border: 1px solid var(--card-border); border-radius: var(--radius-card); background: var(--surface); }
.intake-group .order-line { grid-template-columns: minmax(10rem, 1fr) 5.5rem 7rem 2.4rem; align-items: end; }
.intake-group .order-line .field { min-width: 0; }
.intake-group .order-line .field > input, .intake-group .order-line .field > select { width: 100%; }
.line-price-field { display: grid; gap: .5rem; padding-bottom: .5rem; }
.line-label { color: var(--muted); font-size: .76rem; }
.intake-group .add-line { margin-top: .8rem; }
.intake-prerequisite { padding: 1rem; background: var(--warn-soft); border-radius: var(--radius-panel); color: var(--warn); }
.intake-prerequisite p { margin: 0 0 .6rem; }
.intake-footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .85rem 1.4rem; border-top: 1px solid var(--rule); background: var(--dialog-footer-bg); }
.intake-footer .order-total { text-align: left; font-size: 1rem; }
.intake-actions { display: flex; gap: .65rem; flex-shrink: 0; }
@media (max-width: 64rem) {
  .orders-filter-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .intake-layout { grid-template-columns: 15rem minmax(0, 1fr); }
  .intake-group .order-line { grid-template-columns: minmax(8rem, 1fr) 4.5rem 6.5rem 2.4rem; gap: .45rem; }
}
@media (max-width: 56rem) {
  .intake-layout { grid-template-columns: minmax(0, 1fr); }
  .intake-sidebar { border-right: 0; border-bottom: 1px solid var(--rule); grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .intake-details { border-top: 0; padding-top: 0; }
}
@media (max-width: 42rem) {
  .workspace-tabs { margin-top: 1rem; }
  .workspace-tabs [role="tab"] { min-height: 36px; padding: 0 .85rem; font-size: var(--fs-13); }
  .orders-primary > .field, .orders-primary > .search-field { flex-basis: 100%; }
  .orders-filter-fields { grid-template-columns: 1fr; }
  dialog.order-intake { width: calc(100vw - 1rem); max-height: calc(100dvh - 1rem); }
  dialog.order-intake form { max-height: calc(100dvh - 1rem); }
  .intake-head, .intake-sidebar, .intake-workspace { padding: 1rem; }
  .intake-sidebar { grid-template-columns: minmax(0, 1fr); }
  .intake-details { border-top: 1px solid var(--rule); padding-top: 1rem; }
  .intake-group .form-grid { grid-template-columns: 1fr; }
  .intake-group .order-line { grid-template-columns: minmax(0, 1fr) 2.4rem; }
  .intake-group .order-line > .field:first-child { grid-column: 1; }
  .intake-group .order-line > .field:nth-child(2) { grid-column: 1; grid-row: 2; }
  .intake-group .order-line > .icon-button { grid-column: 2; grid-row: 1; }
  .intake-group .line-price-field { grid-column: 1 / -1; grid-row: 3; grid-template-columns: 1fr 1fr; }
  .intake-group .line-price { grid-column: auto; grid-row: auto; text-align: right; }
  .intake-footer { padding: .9rem 1rem; flex-wrap: wrap; }
  .intake-actions { width: 100%; justify-content: space-between; }
  .order-card .facts { gap: 0; }
  .order-card .fact { padding: .8rem; }
}
.work-card { padding: 1rem 1.1rem; }
.card-formula { padding: .65rem .8rem; border-radius: var(--radius); background: var(--fill-soft); }
.card-formula > .operations-title { margin-top: 0; }
.tooth-chip { border-radius: 8px; }
.deadline { padding: 1rem; }
.deadline.idle { background: var(--fill-soft); }
.trips { padding: 1rem; background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-card); }
.production > .ledger-row { min-width: 900px; }
.production > .ledger-row.event { min-width: 760px; }
.production > .ledger-row.sheet, .production > .ledger-row.hold, .production > .ledger-row.alloc { min-width: 650px; }
.production > .ledger-row.work-op { min-width: 660px; }
.production > .ledger-row.employee, .production > .ledger-row.backup { min-width: 600px; }
.production .prod-row, .production .ledger-row { padding-block: .7rem; }
.production .head { background: var(--table-head-bg); }
main[data-view="production"] > .bar > select { flex: 0 1 18rem; }
.production-column { --stage-color: var(--stage-pending); --stage-soft: var(--stage-pending-soft); padding: .65rem; border-radius: var(--radius-panel); background: var(--column-bg); border: 1px solid var(--rule); border-top: 3px solid var(--stage-color); }
.production-column[data-stage="in_work"] { --stage-color: var(--stage-working); --stage-soft: var(--stage-working-soft); }
.production-column[data-stage="completed"] { --stage-color: var(--stage-ready); --stage-soft: var(--stage-ready-soft); }
.production-column h2 { display: flex; align-items: center; gap: .55rem; color: var(--stage-color); background: var(--stage-soft); border-radius: 4px; font-size: .83rem; padding: .55rem .6rem; margin-bottom: .65rem; }
.production-column h2::before { content: ""; width: 8px; height: 8px; border-radius: 3px; background: var(--stage-color); flex: none; }
.production-card { border-radius: var(--radius-card); border-color: var(--card-border); padding: .85rem; gap: .55rem; box-shadow: none; }
.production-card > b { font-size: .9rem; }
.production-card > p { font-size: .8rem; }
.production-card > button { max-width: 100%; white-space: normal; height: auto; min-height: var(--control-h); padding-block: var(--sp-1); }
.production-card > button:first-child { align-self: flex-start; justify-content: flex-start; padding: .2rem 0; border: 0; min-height: 2rem; color: var(--accent); font-size: .72rem; font-weight: 600; box-shadow: none; }
.production-card .danger-text:empty { display: none; }
.production-card select { height: var(--control-h); font-size: var(--fs-12-5); }
.production-card .production-deadline { font-size: .74rem; color: var(--muted); padding-block: .4rem; border-top: 1px solid var(--rule); }
.production-card .production-deadline.is-held { color: var(--warn); background: var(--warn-soft); padding: .45rem; border-radius: 4px; }
.production-assignment { display: flex; gap: .4rem; align-items: center; min-width: 0; }
.production-assignment select { flex: 1; width: 0; }
.production-assignment button { flex: none; }
.lane { border: 0; background: var(--column-bg); padding: .85rem; }
.lane-taken { background: var(--ok-soft); }
.lane-refused { background: var(--danger-soft); }
.req-card { padding: 1rem; border: 0; margin-top: .2rem; }
.req-card.decided { opacity: 1; }
.resource-page > .bar { padding: .3rem; background: var(--surface-2); border-radius: 7px; gap: .3rem; }
.resource-page > .bar > button { background: transparent; border-color: transparent; height: auto; min-height: 2.5rem; white-space: normal; }
.resource-page > .bar [aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.resource-panel > button { justify-self: start; }
.resource-panel > .hint { margin: 0; color: var(--muted); max-width: 90ch; }
.resource-panel .card-lines { min-width: 0; padding: 1rem; background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-card); }
.resource-row { border-top: 2px solid var(--rule-strong) !important; }
.resource-row h2 { font-size: 1.15rem; letter-spacing: -.025em; margin-top: 0; }
.resource-row > p { color: var(--muted); font-size: .83rem; }
.resource-panel h2 { font-size: 1.15rem; }
.resource-panel > p { margin-block: .3rem; }
.period { background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-card); padding: 1rem; }
.period-sums .fact { border: 1px solid var(--rule); border-radius: 6px; }
.period-sums .fact b { font-size: 1.1rem; letter-spacing: -.02em; }
.period-act { flex-wrap: wrap; }
.settings-card { max-width: 46rem; }
.settings-card > h2.sect { padding-bottom: .9rem; border-bottom: 1px solid var(--rule); }
.thread-box { background: var(--surface); padding: 1rem; border-radius: var(--radius-card); border: 1px solid var(--card-border); }
.thread-acts, .link-acts { flex-wrap: wrap; }
.msg.own { background: var(--accent-soft); }

/* Internal workflows share semantic field groups without remounting drafts. */
.form-group { min-width: 0; margin: 0; padding: .9rem; border: 1px solid var(--card-border); border-radius: var(--radius-card); display: grid; gap: .7rem; }
/* Заголовок группы — малый капс, как группы окна в макете; текст legend прежний. */
.form-group > legend { padding-inline: .3rem; font-size: var(--fs-11); font-weight: var(--fw-600); letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.form-group > .field { min-width: 0; margin: 0; }
.form-group input, .form-group select, .form-group textarea { min-width: 0; max-width: 100%; }
.form-group .production { min-width: 0; }
.dialog-actions { border-top: 1px solid var(--rule); padding-top: .8rem; justify-content: flex-end; flex-wrap: wrap; }
dialog.grouped-dialog { width: min(60rem, calc(100vw - 2rem)); }
.grouped-dialog form > h2 { overflow-wrap: anywhere; }
.grouped-dialog form > .hint { margin: 0; }
.grouped-dialog .field { font-size: .77rem; }
.dialog-groups { min-width: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem; align-items: start; }
.dialog-groups > .form-group-wide { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-group-wide > .production, .form-group-wide > .hint { grid-column: 1 / -1; }
.grouped-dialog .ledger-row.request-item { min-width: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.req-grid:has(> .form-group) { grid-template-columns: minmax(0, 1fr); }
.req-grid > .form-group { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-group.work-op { grid-template-columns: minmax(0, 2fr) minmax(0, 1.4fr) minmax(4rem, .7fr) auto; align-items: end; margin-top: .6rem; }
.work-op > button { align-self: end; }
.payout-history, .production-details { border-block: 1px solid var(--rule); padding-block: .6rem; }
.payout-history > summary, .production-details > summary { cursor: pointer; color: var(--accent); font-size: .85rem; font-weight: 600; }
.payout-history { min-width: 0; }
.payout-history > .production { margin-top: 1rem; min-width: 0; max-width: 100%; }
.production-details p { margin-block: .6rem 0; }
.production-stage-nav { display: none; }
.production-column h2 { scroll-margin-top: 1rem; }
.production-column h2:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
[data-workspace="money"] .workspace-panel > .hint { margin-block: .7rem; }
[data-workspace="settings"] .workspace-panel { min-width: 0; }
@media (max-width: 1000px) {
  .production-stage-nav { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
  .production-stage-nav > button { flex: 1 1 auto; }
}
@media (max-width: 42rem) {
  .form-group { padding: .85rem; }
  .dialog-groups, .dialog-groups > .form-group-wide { grid-template-columns: minmax(0, 1fr); }
  .form-group.work-op, .req-grid > .form-group { grid-template-columns: minmax(0, 1fr); }
  .form-group.work-op > button { justify-self: start; }
  .form-group .ledger-row.request-item { min-width: 0; grid-template-columns: minmax(0, 1fr); }
  .payout-history .production > .ledger-row.alloc { min-width: 0; grid-template-columns: minmax(0, 1fr) auto; }
  .payout-history .ledger-row.alloc > .reason { grid-column: 1 / -1; overflow-wrap: anywhere; }
  .payout-history .ledger-row.alloc > button { grid-column: 1 / -1; justify-self: start; }
}
@media (max-width: 42rem) {
  .table-wrap > table { min-width: 620px; }
  header.page { gap: .8rem; }
  dialog .row { flex-wrap: wrap; }
  .period-sums { flex-wrap: wrap; min-width: 0; }
  .period-sums .fact { flex-basis: 8rem; }
  .orders-heading { padding: 0; }
  .now-strip { gap: var(--sp-1-5); }
  .now-strip .chip { flex: 1 1 8rem; }
  .order-scanner .field { max-width: none; }
  .filter-strip > label:not(.search-field) { white-space: normal; }
  .filter-strip .chip-select { max-width: 100%; min-width: 0; flex: 1 1 8rem; }
  .head-actions { gap: .5rem; }
  .order-head .head-actions { align-items: stretch; }
  .order-head .head-actions > * { flex: 1 1 9rem; min-width: 0; }
  .production > .ledger-row.employee, .production > .ledger-row.backup { min-width: 0; grid-template-columns: minmax(0,1fr); padding: 1rem; }
  .ledger-row.employee > *, .ledger-row.backup > * { min-width: 0; overflow-wrap: anywhere; }
  .ledger-row.employee .row-acts, .ledger-row.backup .row-acts { display: flex; flex-wrap: wrap; white-space: normal; gap: .4rem; }
  .row-acts button { margin-left: 0; }
  .thread-acts > button { white-space: normal; height: auto; min-height: 2.5rem; }
  .trip-group .trip { grid-template-columns: minmax(0,1fr); }
  .resource-panel .card-lines { padding: 1rem; }
}
