:root{--nav:#07111f;--surface:#fff;--glass:rgba(255,255,255,.82);--bg:#f3f7fb;--cyan:#19c7e5;--violet:#7667f5;--green:#18a979;--amber:#e9a23b;--red:#e05263;--text:#172033;--muted:#617087;--line:#dce6ef;--radius:14px;--shadow:0 18px 50px rgba(39,72,108,.11);font-family:Inter,"Segoe UI",Arial,sans-serif;color:var(--text);background:var(--bg);font-synthesis:none}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:linear-gradient(145deg,#f8fbfd 0%,#eef5fb 60%,#f5f2ff 100%);font-size:15px}.ambient{position:fixed;border-radius:50%;filter:blur(80px);pointer-events:none;opacity:.25}.ambient-a{width:380px;height:380px;background:#46d8ff;top:-220px;right:9%}.ambient-b{width:360px;height:360px;background:#8b76ff;bottom:-250px;left:30%}.app-shell{position:relative;display:grid;grid-template-columns:248px 1fr;min-height:100vh}.sidebar{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;padding:24px 18px;background:linear-gradient(180deg,#07111f,#0b1728 68%,#111a32);color:#eef7ff;box-shadow:8px 0 36px rgba(8,20,37,.11)}.brand{display:flex;align-items:center;gap:12px;color:inherit;text-decoration:none;font-size:19px;font-weight:800;letter-spacing:-.02em}.brand small{display:block;margin-top:2px;color:#7589a3;font-size:9px;letter-spacing:.16em;text-transform:uppercase}.brand-mark{display:grid;place-items:center;width:38px;height:38px;border:1px solid #6de3ff88;border-radius:12px;background:linear-gradient(145deg,#18c9e9,#736cf7);box-shadow:inset 0 1px 0 #fff8,0 8px 22px #168fdc45;color:white}.nav{display:grid;gap:7px;margin-top:46px}.nav-item{display:flex;align-items:center;gap:12px;padding:12px 13px;border:1px solid transparent;border-radius:11px;color:#a8b6c8;text-decoration:none;transition:.15s ease}.nav-item>span{width:20px;color:#7f96af;font-size:18px}.nav-item small{margin-left:auto;color:#53667e;font-size:9px;text-transform:uppercase}.nav-item:hover,.nav-item.active{color:white;border-color:#ffffff12;background:linear-gradient(90deg,#1bbadf22,#7667f51c);box-shadow:inset 0 1px 0 #ffffff0f}.nav-item.active>span{color:#4bdbf5}.nav-item.disabled{cursor:default;opacity:.64}.sidebar-user{display:grid;grid-template-columns:36px 1fr auto;align-items:center;gap:10px;margin-top:auto;padding:15px 4px 0;border-top:1px solid #ffffff12}.sidebar-user strong,.sidebar-user small{display:block;max-width:116px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sidebar-user strong{font-size:12px}.sidebar-user small{margin-top:3px;color:#72859c;font-size:10px}.avatar{display:grid;place-items:center;width:34px;height:34px;border:1px solid #58d7ef55;border-radius:10px;background:#17314b;color:#7ce8fb;font-weight:800}.icon-button{border:0;background:transparent;color:#7387a0;cursor:pointer;font-size:18px}.main{padding:38px clamp(28px,5vw,70px) 60px;min-width:0}.page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;margin-bottom:28px}.page-header.compact{align-items:flex-start}.page-header h1{margin:7px 0 7px;font-size:clamp(32px,4vw,46px);line-height:1;letter-spacing:-.045em}.page-header p{margin:0;color:var(--muted);font-size:15px}.eyebrow{color:#4f7c94;font-size:10px;font-weight:800;letter-spacing:.16em;text-transform:uppercase}.button{display:inline-flex;align-items:center;justify-content:center;gap:14px;min-height:42px;padding:0 17px;border:1px solid transparent;border-radius:11px;font:inherit;font-size:13px;font-weight:750;text-decoration:none;cursor:pointer;transition:.15s ease}.button.primary{color:white;background:linear-gradient(110deg,#079ec7,#6e64ed);box-shadow:inset 0 1px 0 #ffffff66,0 10px 24px #447ce32f}.button.primary:hover{transform:translateY(-1px);box-shadow:inset 0 1px 0 #ffffff66,0 14px 30px #447ce342}.button.secondary{border-color:var(--line);background:#fff;color:#3d5267}.button.wide{width:100%}.button:disabled{opacity:.5;cursor:not-allowed}.glass{border:1px solid #fff;background:var(--glass);box-shadow:inset 0 1px 0 #fff,var(--shadow);backdrop-filter:blur(16px)}.metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:18px}.metric{position:relative;overflow:hidden;min-height:112px;padding:21px;border-radius:var(--radius)}.metric span{display:block;color:var(--muted);font-size:12px}.metric strong{display:block;margin-top:12px;font-size:32px;letter-spacing:-.04em}.metric i{position:absolute;width:7px;height:44px;right:17px;top:22px;border-radius:9px;background:#b8c4d1;box-shadow:0 0 18px #b8c4d177}.metric i.cyan{background:var(--cyan);box-shadow:0 0 20px #19c7e577}.metric i.violet{background:var(--violet);box-shadow:0 0 20px #7667f577}.metric i.green{background:var(--green);box-shadow:0 0 20px #18a97966}/* overflow-x:clip держит широкую таблицу внутри карточки. Без него она распирала всю страницу: на 375 px документ становился 812 px и прокручивался вбок целиком, вместе с меню. Именно clip, а не hidden: hidden создал бы контекст прокрутки и сломал position:sticky. */
.panel{border-radius:18px;padding:24px;overflow-x:clip}.toolbar{display:flex;gap:10px;margin-bottom:20px}.search{display:flex;align-items:center;gap:9px;flex:1;padding:0 13px;border:1px solid var(--line);border-radius:10px;background:#f9fbfd}.search span{color:#7d8da0;font-size:20px}.search input,.toolbar select{width:100%;border:0;outline:0;background:transparent;color:var(--text);font:inherit}.toolbar select{max-width:210px;padding:0 12px;border:1px solid var(--line);border-radius:10px;background:#f9fbfd}.table-wrap{overflow:auto;margin:0 -24px -24px}table{width:100%;border-collapse:collapse}th,td{padding:15px 20px;border-top:1px solid #e5ecf2;text-align:left;vertical-align:middle}th{color:#718094;background:#f7fafc;font-size:10px;letter-spacing:.1em;text-transform:uppercase}td{font-size:13px}td span,td small{display:block;margin-top:4px;color:var(--muted);font-size:11px}.ticket-link{display:block;min-width:180px;color:inherit;text-decoration:none}.ticket-link strong{color:#526df2;font-size:11px;letter-spacing:.03em}.ticket-link span{color:var(--text);font-size:13px}.row-arrow{display:grid;place-items:center;width:30px;height:30px;border-radius:8px;color:#6477e9;background:#eef0ff;text-decoration:none}.status-pill{display:inline-flex!important;width:max-content;align-items:center;margin:0!important;padding:6px 10px;border:1px solid #b6c8d8;border-radius:999px;color:#526377!important;background:#edf3f7;font-size:10px!important;font-weight:800;letter-spacing:.03em}.status-new{border-color:#6fd9ed;color:#087a93!important;background:#e6faff}.status-clarifying,.status-awaiting_approval{border-color:#efc778;color:#97630d!important;background:#fff6df}.status-estimating,.status-planning{border-color:#a9a1ff;color:#5d50c8!important;background:#efedff}.status-in_progress,.status-review{border-color:#67d6b1;color:#147859!important;background:#e8fbf4}.status-closed{border-color:#b8c8c1;color:#547067!important;background:#eff5f2}.status-cancelled{border-color:#e9a4ad;color:#a23d4c!important;background:#fff0f2}.empty-state{text-align:center;padding:64px 20px}.empty-state>span{display:grid;place-items:center;width:58px;height:58px;margin:0 auto 16px;border:1px solid #78d8ec;border-radius:18px;color:#09a6c8;background:#e9fbff;font-size:30px}.empty-state h2{margin:0 0 8px}.empty-state p{margin:0 0 22px;color:var(--muted)}.back-link{display:inline-block;margin-bottom:9px;color:#5f72db;text-decoration:none;font-size:12px}.title-line{display:flex;align-items:center;gap:14px}.title-line h1{margin-right:2px}.form-layout{display:grid;grid-template-columns:minmax(0,1fr) 290px;align-items:start;gap:18px}.form-card{display:grid;grid-template-columns:1fr 1fr;gap:18px}.section-heading{display:flex;grid-column:1/-1;align-items:center;gap:13px;margin-bottom:4px}.section-heading>span{display:grid;place-items:center;width:38px;height:38px;border:1px solid #80dff0;border-radius:11px;color:#1295b2;background:#e9fbff;font-size:12px;font-weight:900}.section-heading h2,.section-heading p{margin:0}.section-heading h2{font-size:17px}.section-heading p{margin-top:3px;color:var(--muted);font-size:11px}.field{display:grid;gap:7px;color:#4f6072;font-size:11px;font-weight:750}.field.full{grid-column:1/-1}.field input,.field select,.field textarea{width:100%;padding:12px 13px;border:1px solid var(--line);border-radius:10px;outline:0;background:#fbfdff;color:var(--text);font:inherit;font-size:13px}.field input:focus,.field select:focus,.field textarea:focus{border-color:#5ecde3;box-shadow:0 0 0 3px #19c7e51c}.field-error{color:var(--red)}.submit-card{position:sticky;top:30px}.submit-card h3{margin:10px 0 7px;font-size:26px}.submit-card p{margin:0 0 24px;color:var(--muted);font-size:12px;line-height:1.6}.detail-grid{display:grid;grid-template-columns:minmax(0,1fr) 310px;gap:18px}/* Дорожка грида по умолчанию не может стать уже своего содержимого (min-width:auto). Внутри карточек лежат таблицы с min-width:760px, и без этой строки колонка распирала страницу: на 375 px документ становился 778 px и прокручивался вбок целиком. */.detail-grid>*,.form-layout>*{min-width:0}.prose{padding:16px 0 8px;color:#33465a;line-height:1.7}.timeline{margin-top:28px;padding-top:22px;border-top:1px solid var(--line)}.timeline h3{font-size:13px}.timeline article{position:relative;display:flex;gap:12px;padding:10px 0}.timeline article i{width:9px;height:9px;margin-top:4px;border-radius:50%;background:var(--cyan);box-shadow:0 0 12px #19c7e577}.timeline article strong,.timeline article span{display:block}.timeline article strong{font-size:12px}.timeline article span{margin-top:3px;color:var(--muted);font-size:10px}.facts h2{margin-top:0;font-size:17px}.facts dl{margin:0}.facts dt{margin-top:18px;color:#7a899a;font-size:9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}.facts dd{margin:5px 0 0;font-size:13px;font-weight:700}.facts dd small{display:block;margin-top:4px;color:var(--muted);font-size:11px;font-weight:400}.muted{color:var(--muted)!important}.login-page{display:grid;place-items:center;min-height:100vh;padding:24px;background:linear-gradient(135deg,#07111f,#0d1c31 55%,#17173b);color:#eef7ff}.login-page .ambient{opacity:.32}.login-card{position:relative;width:min(460px,100%);padding:40px;border-color:#ffffff22;border-radius:26px;background:linear-gradient(145deg,#18263bcc,#0b1424e6);box-shadow:inset 0 1px 0 #ffffff22,0 32px 80px #0009}.login-brand{margin-bottom:34px}.status-line{display:flex;align-items:center;gap:9px;color:#83a5b9;font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase}.status-dot{width:7px;height:7px;border-radius:50%;background:#48f6bd;box-shadow:0 0 14px #48f6bd}.login-card h1{margin:18px 0 10px;font-size:38px;letter-spacing:-.045em}.login-card .lead{margin:0 0 28px;color:#8ca0b6;line-height:1.6}.stack{display:grid;gap:16px}.stack label{display:grid;gap:7px;color:#91a6bc;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}.stack input{width:100%;padding:13px;border:1px solid #ffffff20;border-radius:10px;outline:0;background:#06101fcc;color:white;font:inherit}.stack input:focus{border-color:#42d4ee;box-shadow:0 0 0 3px #19c7e51c}.login-card footer{margin-top:27px;padding-top:18px;border-top:1px solid #ffffff14;color:#60748b;font-size:9px;letter-spacing:.07em;text-align:center;text-transform:uppercase}.alert{margin:0 0 18px;padding:12px;border-radius:10px;font-size:12px}.alert.error{border:1px solid #e0526355;color:#ffacb7;background:#e0526318}@media(max-width:960px){.app-shell{grid-template-columns:82px 1fr}.sidebar{padding:22px 13px}.brand>span:last-child,.nav-item:not(.active)>small,.nav-item{font-size:0}.brand{justify-content:center}.nav-item{justify-content:center}.nav-item>span{font-size:18px}.sidebar-user{grid-template-columns:1fr}.sidebar-user>span:nth-child(2),.sidebar-user form{display:none}.avatar{margin:auto}.metric-grid{grid-template-columns:1fr 1fr}.form-layout,.detail-grid{grid-template-columns:1fr}.submit-card{position:static}}@media(max-width:640px){.app-shell{display:block}.sidebar{position:static;width:100%;height:auto;flex-direction:row;align-items:center;padding:12px 16px}.brand{justify-content:flex-start}.brand>span:last-child{display:block;font-size:16px}.nav{display:flex;margin:0 0 0 auto}.nav-item{display:none}.nav-item.active{display:flex}.sidebar-user{display:none}.main{padding:25px 16px 42px}.page-header{align-items:flex-start;flex-direction:column}.metric-grid{grid-template-columns:1fr 1fr}.metric{min-height:90px;padding:16px}.metric strong{font-size:26px}.toolbar{flex-wrap:wrap}.search{flex-basis:100%;height:42px}.toolbar select{height:42px;max-width:none;flex:1}.form-card{grid-template-columns:1fr}.field.full{grid-column:auto}.panel{padding:18px}.table-wrap{margin:0 -18px -18px}.table-wrap table{min-width:760px}.login-card{padding:28px 22px}.login-card h1{font-size:32px}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}
/* Внутренняя заметка видна глазом сразу: её читает только сервисная компания, и спутать её с сообщением заказчику нельзя. */
.timeline article.internal{border-left:3px solid var(--amber);padding-left:11px;background:#fffaf0}.internal-mark{color:#97630d;font-weight:800;text-transform:uppercase;letter-spacing:.04em}.checkline{display:flex;align-items:center;gap:8px;margin:8px 0;color:#4f6072;font-size:12px}.checkline input{width:auto}
/* Состояние офлайна на форме отчёта. Заметно, но не кричит: исполнитель читает его в подвале с телефона, часто одной рукой. */
.offline-status{margin:0 0 12px;padding:10px 12px;border-radius:10px;font-size:12px;line-height:1.5}.offline-status.ok{border:1px solid #67d6b1;color:#147859;background:#e8fbf4}.offline-status.warn{border:1px solid #efc778;color:#97630d;background:#fff6df}.offline-status.error{border:1px solid #e0526355;color:#a23d4c;background:#fff0f2}
/* Кнопка «показать пароль». Поле остаётся на всю ширину, кнопка лежит поверх него справа: так не съезжает вёрстка формы и не меняется порядок обхода. */
.password-field{position:relative;display:block}.password-field input{width:100%;padding-right:42px}.password-toggle{position:absolute;top:50%;right:6px;transform:translateY(-50%);display:grid;place-items:center;width:32px;height:32px;padding:0;border:0;border-radius:8px;background:transparent;color:#8ca0b6;font-size:17px;line-height:1;cursor:pointer}.password-toggle:hover{color:#cfe0f0;background:#ffffff14}.password-toggle:focus-visible{outline:2px solid #42d4ee;outline-offset:1px}
/* Н-2 (прогон 13.09.2026). Коммерческая таблица — состав работ в расчёте и в КП
   — превращается в карточки, когда ей тесно.

   Проблема была не в вёрстке вообще, а в самой нужной колонке: «Сумма» стоит
   последней и уезжала за край прокрутки. На телефоне — на 419 px, на экране
   1024 px в расчёте — на 300. Человек видел позицию и количество, а сколько
   стоит строка — нет. В КП это особенно неприятно: его согласовывают нажатием
   кнопки, и проверить, из чего сложился итог, было нельзя.

   Почему `@container`, а не `@media`. Окно бывает широким, а колонка узкой:
   состав работ лежит в сетке рядом с блоком «Итого», и ему остаётся 330–650 px
   независимо от размера экрана. Медиазапрос про окно об этом не знает —
   контейнерный запрос знает.

   Порядок в карточке — тот, в котором это читают: что сделали, сколько, почём,
   сколько вышло. Сумма крупнее прочего: она здесь главная. */
.quote-table{container-type:inline-size}
@container (max-width: 560px){
  .quote-table table,.quote-table tbody,.quote-table tr,.quote-table td{display:block;width:auto}
  .quote-table thead{display:none}
  .quote-table table{min-width:0}
  .quote-table tr{padding:14px 0;border-top:1px solid #e5ecf2}
  .quote-table tr:first-child{border-top:0}
  .quote-table td{padding:2px 0;border:0}
  /* Подпись берётся из разметки: без неё карточка — набор чисел без значения. */
  .quote-table td[data-label]::before{content:attr(data-label) " ";color:var(--muted);font-size:11px}
  .quote-table td.align-right{text-align:left}
  .quote-table td.price{margin-top:6px;font-size:17px;font-weight:800}
  .quote-table td.price::before{font-weight:400}
}
/* Поле назначения прямо в карточке фактов: без перехода на отдельный экран ради одной даты. */
.inline-set{display:grid;gap:8px;margin-top:8px}.inline-set input{width:100%;padding:9px 10px;border:1px solid var(--line);border-radius:9px;background:#fbfdff;font:inherit;font-size:13px}.inline-set .button{min-height:36px;font-size:12px}
/* ───────────────────────────── очередь диспетчера ──────────────────────────
   B1 и B2 из `todo/UI_PROPOSALS_2026-09-13_RU.md`.

   Очередь — главный экран координатора: он в ней весь день. Тем, кто разбирает
   десятки заявок, нужна плотность, а не воздух: обзор без прокрутки экономит
   больше времени, чем любые отступы. Но плотность без иерархии превращается в
   шум — когда каждая ячейка звучит одинаково громко, смотреть везде значит не
   смотреть никуда. Поэтому вместе с плотностью расставлен и приоритет. */

/* B2 — приоритет внутри строки.
   Главное — номер и тема; служебное (заказчик, ответственный, время) звучит
   тише. Разница в весе и цвете, а не в размере: одинаковая высота строк важна
   для беглого просмотра столбцом. */
.queue-table .ticket-link strong{font-size:12px}
.queue-table .ticket-link span{font-weight:650}
.queue-table td:nth-child(4),
.queue-table td:nth-child(5){color:var(--muted);font-size:12px}

/* Просрочка — полосой слева. Цветом плашки её не отметить: в таблице уже семь
   цветных состояний, и восьмой ни с чем не будет спорить только сбоку. */
.queue-table tr.row-overdue td:first-child{box-shadow:inset 3px 0 0 var(--red)}
.queue-table tr.row-overdue .ticket-link strong{color:var(--red)}

/* B1 — плотный режим: одна строка на заявку.
   Прячется всё, что можно узнать, открыв заявку; остаётся то, по чему её
   выбирают из сотни. */
/* Селектор начинается с `#queue`, потому что в `modules.css` уже есть
   `#queue td{padding:12px 20px}` — правило с идентификатором, которое класс не
   перебивает по специфичности. Поймано замером: тема послушно встала в строку,
   а отступы остались прежними, и плотный режим выглядел точно как просторный. */
#queue .queue-table.density-compact th,
#queue .queue-table.density-compact td{padding:7px 14px}
#queue .queue-table.density-compact .ticket-link span{display:inline;margin:0 0 0 8px;font-size:12px;font-weight:400;color:var(--muted)}
#queue .queue-table.density-compact td span,
#queue .queue-table.density-compact td small{display:inline;margin:0}
#queue .queue-table.density-compact td:nth-child(2) span{margin-left:8px;font-size:11px}
#queue .queue-table.density-compact .status-pill{padding:3px 8px;font-size:9px!important}
#queue .queue-table.density-compact .row-arrow{width:24px;height:24px}
.density-toggle{white-space:nowrap}
/* B3 — назначение из строки. Список выглядит текстом, пока его не трогают: рамка в каждой строке превратила бы таблицу в форму. */
#queue .coordinator-cell select{width:100%;max-width:170px;padding:4px 6px;border:1px solid transparent;border-radius:7px;background:transparent;color:inherit;font:inherit;font-size:12px;cursor:pointer}#queue .coordinator-cell select:hover{border-color:var(--line);background:#f9fbfd}#queue .coordinator-cell select:focus{border-color:#5ecde3;background:#fff;outline:0}#queue .coordinator-cell .field-error{display:block;margin-top:4px;font-size:11px}
/* C2 — документный режим. Меню убрано, содержимое по центру и не шире листа:
   длинная строка через весь монитор читается хуже узкой колонки, а документ
   читают, а не просматривают. Возврат к заявке остаётся на самой странице. */
.app-shell.document{grid-template-columns:1fr}
.app-shell.document .sidebar{display:none}
.app-shell.document .main{max-width:960px;margin:0 auto;padding:34px clamp(18px,4vw,44px) 60px}

/* W5-2 — плановое и фактическое количество в отчёте.
   Карточный режим на телефоне по тому же правилу, что и таблицы КП: четыре
   колонки на 400 px превращаются в нечитаемую кашу, а заполняют эту таблицу
   как раз с телефона на объекте. */
.report-lines { margin-top: 24px; }
.quantity-table { width: 100%; border-collapse: collapse; margin: 12px 0; }
.quantity-table th { text-align: left; font-weight: 600; font-size: 13px; color: var(--muted); padding: 6px 8px; }
.quantity-table td { padding: 8px; border-top: 1px solid var(--line); vertical-align: top; }
.quantity-table input { width: 100%; min-width: 80px; }
/* Расхождение — полосой слева, а не цветом всей строки: строка остаётся
   читаемой, а взгляд находит отличие сам. То же решение, что у просрочки
   в очереди. */
.quantity-table tr.row-differs td:first-child { box-shadow: inset 3px 0 0 var(--amber, #d98324); }
.report-lines .small { font-size: 12px; }

@container (max-width: 560px) {
  .quantity-table thead { display: none; }
  .quantity-table tr { display: block; border-top: 1px solid var(--line); padding: 10px 0; }
  .quantity-table td { display: flex; justify-content: space-between; gap: 12px; border: 0; padding: 4px 0; }
  .quantity-table td::before { content: attr(data-label); color: var(--muted); font-size: 12px; flex: 0 0 auto; }
  .quantity-table input { max-width: 55%; }
}
.report-lines { container-type: inline-size; }

/* W5-4 — решение представителя заказчика.
   Отказ отмечен полосой, а не заливкой: блок остаётся читаемым, а отличие
   видно с одного взгляда. То же решение, что у просрочки в очереди и у
   расхождения количеств. */
.representative-box { margin-top: 24px; padding: 16px; border: 1px solid var(--line); border-radius: 10px; }
.representative-box.refused { box-shadow: inset 3px 0 0 var(--red, #c0392b); }
.representative-box h3 { margin-top: 0; }
.representative-box .small { font-size: 12px; }
