/* ============================================================
   Дизайн «Рабочая документация» — поверх Bootstrap 5.
   Токены и решения согласованы по макету (артефакт design-orchestrator):
   бетон/графит + сигнальный жёлтый, DIN-типографика (Bahnschrift),
   острые углы, штампы статусов, дрейфующая чертёжная сетка.
   ============================================================ */

:root {
  --paper: #ECEDE9;          /* бетон: фон страницы */
  --sheet: #FBFBF9;          /* лист: карточки, таблицы */
  --ink: #22252A;            /* графит: текст, шапка, рамки */
  --ink-2: #5C6167;          /* разметка: подписи */
  --line: #C9CBC3;           /* линии */
  --hair: #E0E1DB;           /* волосяные линии */
  --accent: #F2B705;         /* сигнальный: главное действие */
  --accent-press: #D9A504;
  --blue: #2E68AC;           /* чертёжный: ссылки, «Новая», графики */
  --work: #B87A00;           /* в работе */
  --ok: #2E7D4F;             /* выполнено */
  --danger: #BF3B2B;
  --grid-line: rgba(34, 37, 42, 0.045);

  --f-display: 'Bahnschrift', 'Arial Narrow', 'Roboto Condensed', sans-serif;
  --f-body: 'Segoe UI', system-ui, sans-serif;
  --f-mono: 'Cascadia Mono', 'Consolas', monospace;

  --bs-body-font-family: var(--f-body);
  --bs-body-color: var(--ink);
  --bs-link-color: var(--blue);
  --bs-link-hover-color: #234f83;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
}
/* Без z-index: он создавал слой, и модальные окна внутри main
   оказывались ПОД затемняющей подложкой Bootstrap (её она вешает на
   body, z-index 1050). Окно было видно сквозь затемнение, но все
   нажатия ловила подложка — страница «зависала». Фоновые слои
   уведены на z-index: -1, поэтому шапка и контент и без того выше. */
main { flex: 1; position: relative; }
nav, footer { position: relative; }

/* Резиновая вёрстка: шапка и контент занимают всю доступную ширину
   экрана (вместо узкого .container ~1140–1320px), поля адаптивные.
   На сверхшироких мониторах — разумный предел, чтобы строки текста
   и таблицы не растягивались бесконечно. */
.app-container {
  width: 100%;
  max-width: 2100px;
  margin-inline: auto;
  padding-inline: clamp(12px, 2.4vw, 48px);
}

/* Живой фон: чертёжная сетка медленно дрейфует по диагонали.
   Слой на transform (GPU); отключается настройкой «уменьшить движение». */
body::before {
  content: '';
  position: fixed; inset: -28px 0 0 -28px;
  pointer-events: none; z-index: -1;
  background:
    linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 100% 28px,
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 28px 100%;
  animation: grid-drift 9s linear infinite;
}
@keyframes grid-drift {
  from { transform: translate(0, 0); }
  to   { transform: translate(28px, 28px); }
}
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
}

/* ---------- Типографика ---------- */
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, .display-6 {
  font-family: var(--f-display);
  font-weight: 700;
}
.form-label, th, .btn, .badge, .navbar { font-family: var(--f-display); }

/* ---------- Навбар: графит + марка ОЗ + жёлтая линия активного ---------- */
.navbar-dark.bg-dark { background-color: var(--ink) !important; }
.navbar-brand {
  font: 700 clamp(15px, .5vw + 10px, 18px)/1.2 var(--f-display);
  letter-spacing: .02em;
}
.brand-mark {
  display: inline-grid; place-items: center;
  width: 26px; height: 26px; margin-right: 8px;
  background: var(--accent); color: #22252A;
  font: 800 12px/1 var(--f-display);
  vertical-align: -7px;
}
/* Размер пунктов считается от ширины окна: на 1024 px полоса
   переносилась на вторую строку, на 1920 px подписи терялись. Нижняя
   граница — 13 px: мельче название раздела уже не прочитать с рабочего
   расстояния; верхняя — 15.5 px, дальше меню начинает спорить с
   заголовком страницы. */
.navbar-nav .nav-link {
  font: 600 clamp(13px, .55vw + 7.5px, 15.5px)/1.4 var(--f-display);
  letter-spacing: .015em;
  white-space: nowrap;
  box-shadow: inset 0 -2px 0 transparent;
}
/* Селектор из трёх классов намеренно: у Bootstrap отступы пунктов
   заданы так же (.navbar-expand-lg .navbar-nav .nav-link), и правило
   попроще он перебивает. */
.navbar-expand-lg .navbar-nav .nav-link {
  padding-left: clamp(6px, .62vw, 14px);
  padding-right: clamp(6px, .62vw, 14px);
}
.navbar-nav .nav-link.active {
  color: #fff;
  box-shadow: inset 0 -2px 0 var(--accent);
}
/* Выпадающие разделы меню. Пункты свёрнуты по смыслу — ежедневная
   работа, объекты, компания, справочники, настройки системы, — поэтому
   рядом с названием пункта уместно короткое пояснение: раздел
   открывают редко и по названию не всегда помнят, что внутри. */
.navbar-nav .dropdown-menu {
  border-radius: 0;
  border: 1px solid rgba(255, 255, 255, .14);
  background: var(--ink);
  padding: 6px 0;
  min-width: clamp(240px, 21vw, 330px);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .35);
}
.navbar-nav .dropdown-item {
  font: 600 clamp(13px, .45vw + 8px, 15px)/1.4 var(--f-display);
  padding: 7px 14px;
  white-space: normal;
  border-left: 2px solid transparent;
}
.navbar-nav .dropdown-item:hover,
.navbar-nav .dropdown-item:focus {
  background: rgba(255, 255, 255, .07);
  border-left-color: var(--accent);
}
.navbar-nav .dropdown-item.active {
  background: rgba(255, 255, 255, .1);
  border-left-color: var(--accent);
  color: #fff;
}
.nav-hint {
  display: block;
  font: 400 clamp(11px, .3vw + 7.5px, 12.5px)/1.35 var(--f-body);
  color: rgba(255, 255, 255, .55);
  margin-top: 2px;
}
.dropdown-item.active .nav-hint,
.dropdown-item:hover .nav-hint { color: rgba(255, 255, 255, .72); }
/* Стрелка выпадающего списка не должна спорить с названием раздела. */
.navbar-nav .dropdown-toggle::after { opacity: .5; margin-left: .4em; }

.navbar .btn-outline-light {
  border-radius: 0;
  font: 600 clamp(12px, .3vw + 8.5px, 13.5px)/1.5 var(--f-display);
}
/* Подпись с должностью и компанией — самая длинная часть полосы:
   у одних это «Администратор», у других «Рябков Николай Борисович
   (Руководитель компании, ООО СтройМакс)». Ограничиваем её долей
   ширины окна, полный текст остаётся во всплывающей подсказке. */
.navbar-text { font-family: var(--f-body); }
/* Пункт учётной записи: длинное ФИО не должно вытеснять разделы —
   обрезаем по доле ширины окна, полное имя есть в подсказке и в самом
   списке. */
.navbar-nav .nav-user {
  max-width: clamp(110px, 18vw, 340px);
  overflow: hidden;
  text-overflow: ellipsis;
}
.navbar-nav .dropdown-item-text {
  color: #fff;
  font: 600 clamp(13px, .45vw + 8px, 15px)/1.4 var(--f-display);
  padding: 6px 14px 8px;
}

/* Узкое окно: полоса свёрнута в список, ширина уже не жмёт — здесь
   важнее читаемость и то, чтобы в пункт попадали пальцем. */
@media (max-width: 991.98px) {
  .navbar-nav .nav-link {
    font-size: 15.5px;
    /* 11 px сверху и снизу дают пункт высотой 44 px — в такой попадают
       пальцем с первого раза. */
    padding-top: 11px;
    padding-bottom: 11px;
    padding-left: 2px;
    padding-right: 2px;
  }
  .navbar-nav .dropdown-menu { min-width: 100%; }
  .navbar-nav .dropdown-item { font-size: 15px; padding: 10px 14px; }
  .nav-hint { font-size: 12.5px; }
  .navbar-text { max-width: 100%; font-size: 13px; }
}

/* Окно отклонения задания (собственное, не модалка Bootstrap). */
.reject-overlay {
  position: fixed;
  inset: 0;
  z-index: 1080;
  background: rgba(34, 37, 42, 0.55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 8vh 16px 16px;
}
.reject-overlay[hidden] { display: none; }
.reject-panel {
  width: 100%;
  max-width: 480px;
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  box-shadow: var(--shadow);
}
.reject-panel-head,
.reject-panel-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
}
.reject-panel-head {
  justify-content: space-between;
  border-bottom: 1px solid var(--hair);
  font-family: var(--f-display);
}
.reject-panel-body { padding: 14px 16px; }
.reject-panel-foot {
  justify-content: flex-end;
  border-top: 1px solid var(--hair);
}

/* Верхний горизонтальный бегунок широкой таблицы (очередь):
   тонкая полоса прокрутки над таблицей, синхронная с нижней. */
.table-scroll-top {
  overflow-x: auto;
  overflow-y: hidden;
  border-bottom: 1px solid var(--hair);
}
.table-scroll-top > div { height: 1px; }

/* Выделенный блок загрузки файла-образца на форме нового задания:
   акцентная рамка и лёгкая подложка, чтобы поле было заметным. */
.sample-upload {
  border: 1.5px dashed var(--accent-press);
  background: color-mix(in srgb, var(--accent) 9%, var(--sheet));
  border-radius: 0;
  padding: 14px 16px;
}
.sample-upload-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.sample-badge {
  display: inline-block;
  padding: 3px 10px 2px;
  background: var(--accent);
  color: #22252A;
  font: 700 11px/1.5 var(--f-display);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.sample-title {
  font: 700 15px/1.2 var(--f-display);
  color: var(--ink);
}
.sample-upload .form-control { background: var(--sheet); }

/* Индикатор новых задач на пункте «Очередь» */
.queue-badge {
  display: inline-grid; place-items: center;
  min-width: 19px; height: 19px; padding: 0 5px;
  margin-left: 4px;
  background: var(--accent); color: #22252A;
  font: 800 11px/1 var(--f-display);
  font-variant-numeric: tabular-nums;
  border-radius: 10px;
  vertical-align: 1px;
}
/* Индикатор сообщений/ответов — отличается цветом от «новых задач»,
   чтобы переписка не путалась с поступившей работой. */
.msg-badge { background: var(--blue); color: #fff; }
.msg-badge::before { content: '✉ '; }
/* Метка сообщения в строке очереди описана ниже, в блоке статусов:
   там задан общий вид бейджей-«штампов», который её перекрывает. */

/* ---------- Карточки: листы с острыми углами ---------- */
.card {
  border-radius: 0;
  border: 1px solid var(--line);
  background: var(--sheet);
}
.card.shadow-sm {
  box-shadow: 0 1px 0 rgba(34,37,42,.08), 0 6px 18px rgba(34,37,42,.06) !important;
}
.card-header.bg-white { background: var(--sheet) !important; border-bottom-color: var(--hair); }
.list-group-item { background: var(--sheet); border-color: var(--hair); border-radius: 0 !important; }

/* ---------- Кнопки: жёлтое действие, графитовый контур ---------- */
.btn { border-radius: 0; font-weight: 600; letter-spacing: .03em; }
.btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.btn-primary, .btn-success, .btn-outline-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #22252A;
}
.btn-primary:hover, .btn-primary:active, .btn-primary:focus,
.btn-success:hover, .btn-success:active, .btn-success:focus,
.btn-outline-primary:hover, .btn-outline-primary:active {
  background: var(--accent-press) !important;
  border-color: var(--accent-press) !important;
  color: #22252A !important;
}

.btn-outline-secondary, .btn-outline-success {
  color: var(--ink);
  border-color: var(--ink);
  background: transparent;
}
.btn-outline-secondary:hover, .btn-outline-success:hover {
  background: rgba(34, 37, 42, 0.08);
  border-color: var(--ink);
  color: var(--ink);
}
.btn-outline-danger { color: var(--danger); border-color: var(--danger); }

/* ---------- Статусы: контурные штампы, как на чертеже ---------- */
.badge {
  border-radius: 2px;
  border: 1.5px solid currentColor;
  background: transparent !important;
  font: 700 10.5px/1.5 var(--f-display);
  letter-spacing: .09em;
  text-transform: uppercase;
  padding: 3px 9px 2px;
}
.badge.text-bg-primary   { color: var(--blue) !important; }
.badge.text-bg-warning   { color: var(--work) !important; }
.badge.text-bg-success   { color: var(--ok) !important; }
.badge.text-bg-secondary { color: #9BA0A6 !important; }   /* серые метки */
/* Отклонено — залитый красный: важный негативный статус, заметен на любом фоне. */
.badge.text-bg-danger {
  color: #fff !important;
  background: var(--danger) !important;
  border-color: var(--danger);
}
/* Новое сообщение инициатора — залитый синий: метка требует внимания,
   поэтому не контурная, а заливкой (контурная сливалась с фоном строки). */
.badge.badge-msg {
  color: #fff !important;
  background: var(--blue) !important;
  border-color: var(--blue);
}
/* Метки-кнопки в очереди: открывают переписку по клику. */
.badge.js-thread { cursor: pointer; }
.badge.js-thread:hover { filter: brightness(1.12); }
/* Значок переписки без непрочитанного — спокойный, но кликабельный. */
.btn-thread {
  border: 1px solid var(--hair); background: transparent;
  color: var(--ink-2); cursor: pointer;
  border-radius: 999px; line-height: 1;
  padding: 2px 8px 3px; font-size: 12px;
  transition: color .15s ease, border-color .15s ease;
}
.btn-thread:hover { color: var(--blue); border-color: var(--blue); }

/* ---------- Таблицы: ведомость ---------- */
.table { --bs-table-bg: var(--sheet); }
.table thead th, .table > :not(caption) > * > th {
  font: 600 10.5px/1.4 var(--f-display);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-2);
  border-bottom: 1.5px solid var(--ink);
  white-space: nowrap;
}
.table td { border-color: var(--hair); }
.table-hover { --bs-table-hover-bg: #FAF2D8; }
.table-light, .table-light th { background: var(--sheet) !important; }

/* номера задач и даты — моноширинные, столбцом */
.table td.fw-semibold a, td.text-nowrap {
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}
.table td.fw-semibold a { color: var(--blue); text-decoration: none; }
.table td.fw-semibold a:hover { text-decoration: underline; }

/* ---------- Формы ---------- */
.form-control, .form-select {
  border-radius: 0;
  border-color: var(--line);
  background-color: var(--sheet);
  color: var(--ink);
}
.form-control:focus, .form-select:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(242, 183, 5, 0.35);
}
.form-control:disabled { background-color: var(--paper); color: var(--ink-2); }
.form-label { font-size: 13px; font-weight: 600; letter-spacing: .04em; }
.form-text { color: var(--ink-2); }
.form-check-input { border-radius: 0; border-color: var(--line); }
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }
.form-check-input:focus { box-shadow: 0 0 0 3px rgba(242, 183, 5, 0.35); }

/* ---------- Оповещения ---------- */
.alert { border-radius: 0; }
.alert-secondary { background: var(--sheet); border-color: var(--line); color: var(--ink-2); }

/* ---------- Дашборд: плитки метрик ---------- */
.metric-tiles .card-body { padding: 12px 14px 13px; }
.metric-tiles .text-muted.small:first-child {
  font: 600 10px/1.4 var(--f-display);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.metric-tiles .h4 {
  font: 700 30px/1.1 var(--f-display);
  font-variant-numeric: tabular-nums;
}
.metric-tiles .tile-hero { border-top: 3px solid var(--accent); }

/* ---------- Вход: сцена с 3D-каркасом ---------- */
.login-canvas {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: -1; pointer-events: none;
}
.login-card-wrap { position: relative; }
.login-brand { display: flex; align-items: center; gap: 12px; }
.login-brand .brand-mark { width: 34px; height: 34px; font-size: 15px; vertical-align: 0; }
.login-brand .t { font: 700 17px/1.2 var(--f-display); }
.login-brand .s { font-size: 11.5px; color: var(--ink-2); }

/* ---------- Библиотека промптов: сводка ---------- */
.lib-summary { border-left: 3px solid var(--accent); }
.lib-stat { display: flex; flex-direction: column; line-height: 1.05; }
.lib-stat-num {
  font: 700 26px/1 var(--f-display);
  font-variant-numeric: tabular-nums;
}
.lib-stat-cap {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-2);
}
:target { scroll-margin-top: 84px; }  /* якоря не прячутся под навбар */

/* ---------- Дашборд: переключатель стиля + оживление ---------- */
.dash-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.dash-toolbar .theme-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-2);
}
.theme-swatch {
  --sw: transparent;
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid var(--hair); cursor: pointer; padding: 0;
  background:
    conic-gradient(from 210deg, var(--sw), var(--sw2, var(--sw)) 55%, var(--sw3, var(--sw)));
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
  position: relative;
}
.theme-swatch:hover { transform: translateY(-2px) scale(1.06); }
.theme-swatch.active {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(34,37,42,.12);
}
.theme-swatch.active::after {
  content: '✓'; position: absolute; inset: 0;
  display: grid; place-items: center;
  color: #fff; font-size: 13px; font-weight: 700;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
/* Плитки метрик оживают: лёгкое проявление снизу + счётчик чисел. */
.metric-tiles .card {
  animation: tile-rise .5s cubic-bezier(.2,.7,.3,1) backwards;
  transition: transform .18s ease, box-shadow .18s ease;
}
.metric-tiles .col-6:nth-child(1) .card { animation-delay: .02s; }
.metric-tiles .col-6:nth-child(2) .card { animation-delay: .07s; }
.metric-tiles .col-6:nth-child(3) .card { animation-delay: .12s; }
.metric-tiles .col-6:nth-child(4) .card { animation-delay: .17s; }
.metric-tiles .col-6:nth-child(5) .card { animation-delay: .22s; }
.metric-tiles .col-6:nth-child(6) .card { animation-delay: .27s; }
.metric-tiles .card:hover {
  transform: translateY(-3px);
  box-shadow: 0 .5rem 1.4rem rgba(34,37,42,.14) !important;
}
.metric-tiles .card::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--tile-accent, var(--accent));
  transform: scaleX(0); transform-origin: left;
  transition: transform .4s ease .2s;
}
.metric-tiles .card { position: relative; overflow: hidden; }
.metric-tiles .card.lit::after { transform: scaleX(1); }
@keyframes tile-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Фиксированная высота полотна — стабильный контейнер для Chart.js
   (иначе h-100 + responsive зацикливают пересчёт и график не рисуется). */
.chart-box { position: relative; height: 300px; }
.chart-box-sm { height: 220px; }
.chart-card canvas { animation: fade-in .6s ease backwards .15s; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .metric-tiles .card, .chart-card canvas { animation: none; }
  .metric-tiles .card::after { transition: none; }
}

/* ---------- Новое задание: анимация стройки за формой ---------- */
.site-canvas {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: -1; pointer-events: none;
}
/* Контент над канвасом; карточка полупрозрачна — сквозь неё видно
   анимацию, но текст и поля остаются читаемыми (размытие фона). */
.newtask-bg { position: relative; }
.newtask-bg .card {
  background: rgba(251, 251, 249, 0.70);
  backdrop-filter: blur(2.5px);
  -webkit-backdrop-filter: blur(2.5px);
}
.newtask-bg .card-header {
  background: rgba(251, 251, 249, 0.55) !important;
}
.newtask-bg .form-control,
.newtask-bg .form-select {
  background-color: rgba(255, 255, 255, 0.74);
}
.newtask-bg .form-control:focus,
.newtask-bg .form-select:focus {
  background-color: #fff;   /* при вводе поле полностью непрозрачно */
}
.newtask-bg .sample-upload {
  background: color-mix(in srgb, var(--accent) 12%, rgba(251, 251, 249, 0.55));
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

/* ---------- Лента переписки и изменений по задаче ---------- */
.task-thread { display: flex; flex-direction: column; gap: 8px; }
.task-thread .thread-item {
  border: 1px solid var(--hair);
  border-left: 3px solid var(--line);
  border-radius: 0;
  padding: 8px 12px;
  background: var(--sheet);
}
.task-thread .thread-initiator { border-left-color: var(--blue); }
.task-thread .thread-admin { border-left-color: var(--accent); }
.task-thread .thread-system { border-left-color: var(--line); background: transparent; }
.thread-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
  font-size: 12px;
}
.thread-author { font-weight: 600; }
.thread-kind {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-2);
  border: 1px solid var(--hair); border-radius: 999px; padding: 0 7px;
}
.thread-time { margin-left: auto; }
.thread-text { margin-top: 4px; white-space: pre-wrap; }

/* Комментарий администратора в «Мои задания»: компактно, полный текст —
   прокруткой внутри блока (≈3 строки видно). */
.comment-scroll {
  white-space: pre-wrap;
  max-height: 4.2em;
  overflow-y: auto;
  margin-top: 2px;
  padding: 4px 8px;
  border: 1px solid var(--hair);
  background: var(--sheet);
  border-radius: 0;
}

/* ---------- Отчёт: цепочка преемственности функций ---------- */
.continuity-step {
  display: grid; grid-template-columns: 38px 1fr; gap: 12px;
  padding-bottom: 16px; position: relative;
}
.continuity-step:not(:last-child)::before {
  content: ''; position: absolute; left: 18px; top: 40px; bottom: 0;
  width: 2px; background: var(--hair);
}
.continuity-num {
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink-2); color: #fff;
  font: 700 15px/1 var(--f-display); z-index: 1;
}
.continuity-step.done .continuity-num { background: var(--ok); }
.continuity-role {
  display: inline-block; margin-left: 6px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-2); border: 1px solid var(--hair);
  border-radius: 999px; padding: 1px 8px; vertical-align: middle;
}
.continuity-metric { margin-top: 3px; font-size: 13px; }
.continuity-metric strong { font-variant-numeric: tabular-nums; }

/* ---------- Кнопка «показать пароль» ---------- */
.pw-wrap { position: relative; display: block; }
.pw-wrap > .form-control { padding-right: 40px; }
.pw-wrap > .form-control-sm { padding-right: 32px; }
.pw-toggle {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 38px; display: grid; place-items: center;
  padding: 0; border: 0; background: transparent;
  color: var(--ink-2); cursor: pointer;
  transition: color .15s ease;
}
.pw-wrap > .form-control-sm ~ .pw-toggle { width: 30px; }
.pw-toggle:hover { color: var(--ink); }
.pw-toggle.on { color: var(--accent-press); }
.pw-toggle:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.pw-toggle svg { display: block; }

/* Акцентная подпись поля: ключевое требование к заполнению формы. */
.label-accent {
  display: block;
  font: 700 17px/1.25 var(--f-display);
  letter-spacing: .01em;
  color: var(--danger);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-left: 4px solid var(--accent-press);
  padding: 7px 10px;
  margin-bottom: 8px;
}

/* ---------- Подсказки агента-наставника ----------
   Кнопка стоит слева от чата: два плавающих круга не должны налезать
   друг на друга, а подсказка нужна реже переписки — поэтому она
   вторая по счёту, а не первая. */
.hint-launcher {
  position: fixed; right: 90px; bottom: 22px; z-index: 1040;
  width: 44px; height: 44px; border-radius: 50%;
  border: 2px solid var(--ink); background: var(--sheet); color: var(--ink);
  font: 700 20px/1 var(--f-display); cursor: pointer;
  box-shadow: 0 6px 18px rgba(34, 37, 42, .22);
  transition: transform .15s ease;
}
.hint-launcher:hover { transform: translateY(-2px); }
.hint-launcher.active { background: var(--ink); color: var(--accent); }

.hint-panel {
  position: fixed; right: 22px; bottom: 78px; z-index: 1041;
  width: min(420px, calc(100vw - 32px));
  max-height: min(520px, calc(100vh - 140px));
  display: flex; flex-direction: column;
  background: var(--sheet); border: 1px solid var(--ink);
  box-shadow: 0 14px 40px rgba(34, 37, 42, .3);
}
.hint-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; background: var(--ink); color: #fff;
}
.hint-title { font: 700 13px/1.2 var(--f-display); flex: 1; }
.hint-close {
  border: 0; background: transparent; color: #fff;
  font-size: 22px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.hint-body { padding: 12px 14px; overflow-y: auto; font-size: 14px; }
.hint-body ul { margin: 0; padding-left: 18px; }
.hint-body li { margin-bottom: 8px; }
.hint-empty { margin: 0; color: var(--ink-2); }
.hint-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 8px; padding: 8px 12px; border-top: 1px solid var(--hair);
  font-size: 11.5px; color: var(--ink-2); background: var(--paper);
}
@media print { .hint-launcher, .hint-panel { display: none !important; } }

/* Текст инструкции: разметку собирает фильтр md. */
.guide-body h3, .guide-body h4 {
  font-size: 15px; font-weight: 700; margin: 16px 0 6px;
}
.guide-body h3:first-child, .guide-body h4:first-child { margin-top: 0; }
.guide-body ul { margin-bottom: 12px; }
.guide-body li { margin-bottom: 5px; }
.guide-body p { margin-bottom: 10px; }

/* ---------- Внутренний чат компании ---------- */
.chat-launcher {
  /* Ниже модальных окон Bootstrap (подложка 1050, окно 1055): кнопка
     чата не должна висеть поверх открытого диалога. */
  position: fixed; right: 22px; bottom: 22px; z-index: 1040;
  width: 56px; height: 56px; border-radius: 50%;
  border: 2px solid var(--ink); background: var(--accent); color: var(--ink);
  display: grid; place-items: center; cursor: pointer;
  box-shadow: 0 6px 18px rgba(34, 37, 42, .28);
  transition: transform .15s ease, box-shadow .15s ease;
}
.chat-launcher:hover { transform: translateY(-2px); box-shadow: 0 9px 22px rgba(34,37,42,.34); }
.chat-launcher.active { background: var(--ink); color: var(--accent); }
.chat-launcher-icon { font-size: 23px; line-height: 1; }
.chat-launcher-badge {
  position: absolute; top: -4px; right: -4px;
  min-width: 21px; height: 21px; padding: 0 5px;
  display: grid; place-items: center; border-radius: 11px;
  background: var(--danger); color: #fff;
  font: 700 11px/1 var(--f-display); font-variant-numeric: tabular-nums;
  border: 2px solid var(--sheet);
}
.chat-launcher.has-unread { animation: chat-pulse 1.8s ease-in-out infinite; }
@keyframes chat-pulse {
  0%, 100% { box-shadow: 0 6px 18px rgba(34,37,42,.28); }
  50% { box-shadow: 0 6px 18px rgba(34,37,42,.28), 0 0 0 8px rgba(242,183,5,.22); }
}

.chat-panel {
  position: fixed; right: 22px; bottom: 90px; z-index: 1040;
  width: min(680px, calc(100vw - 32px));
  height: min(540px, calc(100vh - 140px));
  /* Пределы растягивания: уже — список разговоров и переписка уже не
     помещаются рядом, ниже — не видно ни одного сообщения. */
  min-width: 320px; min-height: 280px;
  display: flex; flex-direction: column;
  background: var(--sheet); border: 1px solid var(--ink);
  box-shadow: 0 14px 40px rgba(34, 37, 42, .3);
}

/* Уголок изменения размера. Панель прижата к правому нижнему углу,
   поэтому тянут её за левый верхний: окно растёт вверх и влево, а
   кнопка чата остаётся на месте. Размер запоминается между сеансами. */
.chat-resize {
  position: absolute; left: 0; top: 0; width: 20px; height: 20px;
  cursor: nwse-resize; z-index: 2;
  background:
    linear-gradient(135deg,
      color-mix(in srgb, #fff 85%, transparent) 0 42%,
      transparent 42%);
  border: 0; padding: 0;
}
.chat-resize::before {
  content: ''; position: absolute; left: 4px; top: 4px;
  width: 9px; height: 9px;
  border-left: 2px solid rgba(255, 255, 255, .85);
  border-top: 2px solid rgba(255, 255, 255, .85);
}
.chat-resize:hover::before { border-color: var(--accent); }
/* Пока тянут — не выделяем текст под курсором. */
body.chat-resizing { user-select: none; cursor: nwse-resize; }
.chat-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; background: var(--ink); color: #fff;
}
.chat-title { font: 700 13px/1.2 var(--f-display); flex: 1; }
.chat-back {
  border: 0; background: transparent; color: #fff;
  font-size: 20px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.chat-main { flex: 1; display: flex; min-height: 0; }

/* Список разговоров: общий чат компании + личные переписки */
.chat-side {
  width: 226px; flex: 0 0 226px; min-height: 0;
  display: flex; flex-direction: column;
  border-right: 1px solid var(--hair); background: var(--sheet);
}
.chat-rooms { margin: 8px; width: calc(100% - 16px); }
.chat-list { flex: 1; overflow-y: auto; }
.chat-item {
  display: grid; grid-template-columns: 1fr auto; gap: 0 6px;
  width: 100%; text-align: left; cursor: pointer;
  border: 0; border-bottom: 1px solid var(--hair);
  background: transparent; padding: 8px 10px;
}
.chat-item:hover { background: var(--paper); }
/* Ответственный по компании — к нему идут вопросы по данным. */
.chat-item.is-steward { border-left: 3px solid var(--accent); }
.chat-item.active { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.chat-item-name { font: 600 12.5px/1.25 var(--f-body); color: var(--ink); }
.chat-item-sub {
  grid-column: 1 / -1;
  font-size: 10.5px; color: var(--ink-2); margin-top: 1px;
}
.chat-item-badge {
  min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center; border-radius: 9px;
  background: var(--danger); color: #fff;
  font: 700 10.5px/1 var(--f-display); font-variant-numeric: tabular-nums;
}
.chat-conv { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-body {
  flex: 1; overflow-y: auto; padding: 12px;
  display: flex; flex-direction: column; gap: 8px;
  background: var(--paper);
}
/* Узкий экран: список и переписка показываются по очереди */
@media (max-width: 560px) {
  /* Панель и так во всю ширину — тянуть нечего. */
  .chat-resize { display: none; }
  .chat-side { width: 100%; flex: 1 1 auto; border-right: 0; }
  .chat-conv { display: none; }
  .chat-panel.show-conv .chat-side { display: none; }
  .chat-panel.show-conv .chat-conv { display: flex; }
}
.chat-empty { margin: auto; text-align: center; color: var(--ink-2); font-size: 13px; }
.chat-msg {
  border: 1px solid var(--hair); border-left: 3px solid var(--blue);
  background: var(--sheet); padding: 6px 9px; max-width: 92%;
}
.chat-msg.mine { align-self: flex-end; border-left-color: var(--accent-press); }
/* Личное сообщение: пунктирная рамка — видно, что переписка приватная. */
.chat-msg.private { border-style: dashed; border-left-style: solid; }
/* Заголовок группы в таблице (пользователи по компаниям): отделяет
   один блок от другого, не превращаясь в отдельную таблицу. */
.table-group td {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-top: 2px solid var(--accent-press);
  padding-top: 8px;
  padding-bottom: 8px;
}

/* ---------- Наблюдения агентов на дашборде ----------
   Уровень виден полосой слева: срочное нельзя пролистать мимо. */
.watch-list .list-group-item { border-left: 4px solid transparent; }
.watch-critical {
  border-left-color: var(--danger) !important;
  background: color-mix(in srgb, var(--danger) 7%, transparent);
}
.watch-warning { border-left-color: var(--accent-press) !important; }
.watch-info { border-left-color: var(--line) !important; }

/* ---------- Карточка компании ---------- */
.company-logo {
  max-width: 96px;
  max-height: 64px;
  object-fit: contain;
  background: #fff;
  border: 1px solid var(--line);
  padding: 4px;
}
.company-logo-lg { max-width: 200px; max-height: 120px; }

/* Карта: фиксированная высота, чтобы блок не «прыгал» при загрузке. */
.company-map {
  width: 100%;
  height: 320px;
  border: 0;
  display: block;
}

/* Контакты и реквизиты: подпись слева, значение справа; на узком
   экране — в столбик, иначе длинные адреса ломают сетку. */
.contact-list { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; }
.contact-list dt {
  font-weight: 600;
  color: var(--ink-2);
  font-size: 13px;
  white-space: nowrap;
}
.contact-list dd { margin: 0; }
@media (max-width: 480px) {
  .contact-list { grid-template-columns: 1fr; gap: 2px; }
  .contact-list dd { margin-bottom: 8px; }
}

/* ---------- Перетаскивание файлов ----------
   Область вокруг штатного поля выбора: принимает перетащенные файлы
   и показывает, что именно приложено. */
.dropzone {
  border: 1px dashed var(--line);
  border-radius: 4px;
  padding: 8px;
  background: var(--paper);
  transition: border-color .12s, background-color .12s;
}
.dropzone.is-over {
  border-color: var(--accent-press);
  border-style: solid;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.dropzone-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink-2);
}
.dropzone.is-over .dropzone-hint { color: var(--ink); font-weight: 600; }
.dropzone-icon { font-size: 14px; }
.dropzone-list { margin-top: 6px; }
.dropzone-file {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 6px;
  border-left: 3px solid var(--accent);
  background: var(--bg);
  font-size: 13px;
}
.dropzone-file + .dropzone-file { margin-top: 3px; }
.dropzone-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropzone-size { color: var(--ink-2); font-size: 12px; white-space: nowrap; }
.dropzone-remove {
  border: 0;
  background: transparent;
  color: var(--ink-2);
  font-size: 18px;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}
.dropzone-remove:hover { color: var(--danger); }
.dropzone-warn {
  margin-top: 5px;
  font-size: 12px;
  color: var(--danger);
  font-weight: 600;
}
/* Список выбранного заменяет собой подсказку — она уже не нужна. */
.dropzone.has-files .dropzone-hint { display: none; }

/* Разбор задания методологом на странице инициатора: длинный текст,
   поэтому ограничиваем высоту и даём прокрутку — форма правки должна
   оставаться в пределах экрана. */
.md-note {
  max-height: 340px;
  overflow-y: auto;
  padding: 10px 12px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 14px;
  line-height: 1.5;
}

/* Отчёт о доставке под своим сообщением */
.chat-receipt {
  margin-top: 4px; text-align: right;
  font-size: 10.5px; color: var(--ink-2);
}
.chat-receipt.is-read { color: var(--blue); font-weight: 600; }
.chat-receipt-mark { letter-spacing: -2px; margin-right: 3px; }
.chat-msg-head {
  display: flex; align-items: baseline; gap: 6px;
  font: 600 11.5px/1.3 var(--f-body); color: var(--ink);
}
.chat-msg-role {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-2);
}
.chat-msg-time { margin-left: auto; font-size: 10.5px; color: var(--ink-2); }
.chat-msg-text { margin-top: 2px; font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }
.chat-form {
  display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--hair);
  background: var(--sheet);
}
.chat-input { resize: none; font-size: 13.5px; }

/* ---------- Вложения в переписке ---------- */
.chat-attach-btn {
  flex: 0 0 auto; align-self: stretch;
  border: 1px solid var(--line); background: var(--sheet);
  font-size: 16px; line-height: 1; padding: 0 9px; cursor: pointer;
  border-radius: var(--bs-border-radius, 4px);
}
.chat-attach-btn:hover {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
}
/* Выбранные файлы — над строкой ввода: видно, что уйдёт с сообщением. */
.chat-files {
  display: flex; flex-wrap: wrap; gap: 4px;
  padding: 6px 8px 0; background: var(--sheet);
}
.chat-file-chip {
  display: inline-flex; align-items: center; gap: 4px;
  border: 1px solid var(--line); background: var(--paper);
  padding: 2px 4px 2px 7px; font-size: 11.5px; max-width: 100%;
}
.chat-file-chip button {
  border: 0; background: transparent; cursor: pointer;
  font-size: 14px; line-height: 1; padding: 0 2px; color: var(--ink-2);
}
.chat-file-chip button:hover { color: var(--danger); }
.chat-file-size { color: var(--ink-2); }

.chat-msg-files {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px;
}
.chat-file {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--hair); background: var(--paper);
  padding: 3px 8px; font-size: 12px; text-decoration: none;
  color: var(--ink);
}
.chat-file:hover { border-color: var(--accent); }
/* Картинку показываем сразу: снимок с площадки читается взглядом. */
.chat-img img {
  max-width: 190px; max-height: 150px; display: block;
  border: 1px solid var(--hair);
}
/* Пока файл тянут в окно — видно, куда его отпустить. */
.chat-panel.chat-dragover { outline: 3px dashed var(--accent); }
.chat-send { flex: 0 0 auto; align-self: stretch; padding-inline: 12px; }

/* ---------- Смайлики в строке сообщения ---------- */
.chat-emoji-btn {
  flex: 0 0 auto; align-self: stretch;
  border: 1px solid var(--line); background: var(--sheet);
  font-size: 17px; line-height: 1; padding: 0 9px; cursor: pointer;
  border-radius: var(--bs-border-radius, 4px);
}
.chat-emoji-btn:hover, .chat-emoji-btn.active {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
}
/* Набор открывается прямо над строкой ввода: панель чата стоит у
   нижнего края экрана, и снизу места нет. Отсчёт идёт от самой формы,
   а не от всей переписки, иначе набор уезжает за верх панели. */
.chat-form { position: relative; }
.chat-emoji-box {
  position: absolute; left: 8px; right: 8px; bottom: 100%;
  margin-bottom: 4px; z-index: 3;
  max-height: 232px; overflow-y: auto;
  background: var(--sheet); border: 1px solid var(--ink);
  box-shadow: 0 -8px 24px rgba(34, 37, 42, .22);
  padding: 6px 8px 8px;
}
.chat-emoji-group {
  font: 600 10.5px/1 var(--f-display); text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-2);
  margin: 8px 0 4px; position: sticky; top: -6px;
  background: var(--sheet); padding: 4px 0 2px;
}
.chat-emoji-group:first-child { margin-top: 2px; }
.chat-emoji-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(32px, 1fr));
  gap: 2px;
}
.chat-emoji-grid button {
  border: 0; background: transparent; cursor: pointer;
  font-size: 19px; line-height: 1; padding: 4px 0; border-radius: 4px;
}
.chat-emoji-grid button:hover {
  background: color-mix(in srgb, var(--accent) 24%, transparent);
}
@media print { .chat-launcher, .chat-panel { display: none !important; } }

/* ---------- Индикатор работы ИИ-агента ---------- */
.ai-waiting {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px; margin-bottom: 14px;
  border: 1px solid var(--accent-press);
  border-left-width: 4px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.ai-spinner {
  flex: 0 0 auto;
  width: 20px; height: 20px; border-radius: 50%;
  border: 3px solid color-mix(in srgb, var(--ink) 18%, transparent);
  border-top-color: var(--accent-press);
  animation: ai-spin .9s linear infinite;
}
.ai-spinner-sm { width: 11px; height: 11px; border-width: 2px; }
@keyframes ai-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .ai-spinner { animation-duration: 3s; }
}
/* Метка работы ИИ в строке очереди */
.badge.ai-badge {
  display: inline-flex; align-items: center; gap: 5px;
  color: #fff !important;
  background: var(--accent-press) !important;
  border-color: var(--accent-press);
}

/* Атрибут hidden должен скрывать элемент всегда: у Bootstrap классы
   раскладки (.d-flex и подобные) объявлены с !important и иначе
   перебивают его — элемент остаётся на экране. */
[hidden] { display: none !important; }

/* Иконка «нейромозг»: силуэт мозга с нейронными узлами и связями.
   Цвет — чертёжный голубой, он контрастен на жёлтой кнопке. */
.icon-neuro { flex: 0 0 auto; }
.icon-neuro .neuro-outline {
  fill: none; stroke: var(--blue);
  stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round;
}
.icon-neuro .neuro-links {
  fill: none; stroke: var(--blue);
  stroke-width: 1.1; stroke-linecap: round; opacity: .7;
}
.icon-neuro .neuro-nodes { fill: var(--blue); }

/* ---------- Подсказка методолога в форме нового задания ---------- */
.assist-box {
  border: 1px solid var(--blue);
  border-left-width: 4px;
  background: color-mix(in srgb, var(--blue) 7%, var(--sheet));
}
.assist-head {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px; border-bottom: 1px solid var(--hair);
}
.assist-head strong { flex: 1; font-size: 13px; }
.assist-body { padding: 10px 12px 12px; }
.assist-wording {
  white-space: pre-wrap;
  background: var(--sheet); border: 1px solid var(--hair);
  padding: 9px 11px; max-height: 220px; overflow-y: auto;
}
.assist-questions {
  margin: 0; padding-left: 20px;
  font-size: 13px; line-height: 1.5;
}
.assist-questions li { margin-bottom: 3px; }

/* ---------- Футер ---------- */
footer { background: transparent; }

/* ---------- Печать отчёта: документ без интерфейса ---------- */
@media print {
  nav, footer, .d-print-none { display: none !important; }
  body { background: #fff !important; }
  body::before { display: none !important; }
  .card { box-shadow: none !important; border: 1px solid #ccc; break-inside: avoid; }

  /* Раздел без отметки не печатается: для совещания нужны метрики и
     карта, для инвестора — состав системы и результаты. */
  .не-печатать { display: none !important; }

  /* Разрыв между разделами. Прежде разрыв был только внутри карточек,
     и раздел начинался в трёх сантиметрах от конца предыдущего. */
  .разрыв-страниц .отчёт-раздел { break-before: page; page-break-before: always; }
  .разрыв-страниц .отчёт-раздел:first-of-type {
    break-before: auto;
    page-break-before: auto;
  }
}

/* На экране снятый раздел остаётся видимым — приглушённым, чтобы было
   понятно, что в печать и выгрузку он не пойдёт. */
.не-печатать { opacity: .55; }

/* Цифра со ссылкой на источник. Синий подчёркнутый текст посреди
   крупных чисел отчёта читается как ошибка вёрстки, поэтому цифра
   остаётся цифрой — на связь указывает точечное подчёркивание. */
.отчёт-источник {
  color: inherit;
  text-decoration: underline dotted rgba(0, 0, 0, .35);
  text-underline-offset: .2em;
}
.отчёт-источник:hover { color: var(--bs-primary, #b47f00); }
@media print {
  .отчёт-источник { color: inherit; text-decoration: none; }
}

/* --- Очередь задач: таблица по ширине страницы -----------------------
   Колонок было десять, и очередь не помещалась на экран — работать
   приходилось с горизонтальной прокруткой. Служебные сведения собраны
   в одну колонку, а ширины заданы долями: колонки делят страницу, а не
   растягивают её под самое длинное имя файла. */
.queue-table {
  table-layout: fixed;
  width: 100%;
}
.queue-table th,
.queue-table td { overflow-wrap: anywhere; }


.queue-table .col-num     { width: 3.5%; }
.queue-table .col-task    { width: 26%; }
.queue-table .col-who     { width: 14%; }
.queue-table .col-files   { width: 17%; }
.queue-table .col-status  { width: 12%; }
.queue-table .col-review  { width: 11%; }
.queue-table .col-actions { width: 16.5%; }

/* Длинное имя файла или описание обрезается многоточием: полностью
   они видны в подсказке и в самой задаче. */
.queue-table .cell-clip {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* Кнопки действий переносятся на вторую строку вместо того, чтобы
   растягивать таблицу. Прижаты вправо — как и была колонка.
   Ячейка остаётся ячейкой таблицы: display:flex на td выводит её из
   табличной раскладки, и заданная ширина колонки перестаёт
   действовать — колонка схлопывается, а кнопки из неё вываливаются. */
.queue-table .col-actions {
  text-align: right;
  white-space: normal;
}
.queue-table .col-actions .btn {
  white-space: nowrap;
  margin: 0 0 .25rem .25rem;
}

/* Отзыв инициатора: длинный комментарий прокручивается внутри ячейки,
   а не раздвигает колонку. */
.queue-table .comment-scroll {
  max-height: 4.5rem;
  overflow-y: auto;
}

/* На планшете семь колонок не поместятся — там таблица прокручивается,
   и это честнее сломанной вёрстки. Раскладка остаётся жёсткой: со
   свободной («auto») ширину диктовало самое длинное имя файла, и на
   128 заданиях таблица разъезжалась до 15 294 точек — в окно попадало
   пять процентов строки. Жёсткая держит доли колонок, а перенос слов
   уводит длинное имя на вторую строку вместо растягивания. */
@media (max-width: 992px) {
  .queue-table { min-width: 56rem; }
  .queue-table .col-actions { display: table-cell; text-align: right; }
}

/* --- Очередь на телефоне: задание карточкой, а не строкой ------------
   Прокрутка вбок, приемлемая на планшете, на телефоне превращается в
   издевательство: при 128 заданиях свободная раскладка растягивала
   таблицу до 15 000 точек — на экране помещалось два процента строки,
   и до колонки «Действия» надо было листать вбок полтора десятка
   экранов. Поэтому ниже 768 точек таблица перестаёт быть таблицей:
   каждое задание — отдельная карточка со своими подписями. */
@media (max-width: 767.98px) {
  .queue-table,
  .queue-table tbody,
  .queue-table tbody tr,
  .queue-table tbody td {
    display: block;
    width: auto;
  }
  /* Долевые ширины колонок заданы селектором из двух классов и по
     старшинству перебивают «width: auto» выше: ячейки схлопывались до
     38–83 точек, и текст сыпался в узкий столбик. Здесь их снимаем
     тем же старшинством, но ниже по файлу. */
  .queue-table .col-num,
  .queue-table .col-task,
  .queue-table .col-who,
  .queue-table .col-files,
  .queue-table .col-status,
  .queue-table .col-review,
  .queue-table .col-actions { width: auto; }
  /* Шапку заменяют подписи в самих ячейках (data-label). */
  .queue-table thead { display: none; }
  .queue-table { min-width: 0; table-layout: auto; }

  .queue-table tbody tr {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .75rem .875rem;
    margin-bottom: .75rem;
    background: var(--bs-body-bg, #fff);
  }
  .queue-table tbody td {
    border: 0;
    padding: .3rem 0;
  }
  .queue-table tbody td:empty { display: none; }

  .queue-table tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .7rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: .15rem;
  }

  /* Номер задания — над названием, как в шапке карточки. */
  .queue-table tbody td.col-num { padding-bottom: 0; }
  .queue-table tbody td.col-num a::before { content: "№ "; }

  /* Описание задания на узкой карточке читают, а не опознают: одной
     строки с многоточием мало. Даём три строки — дальше открывают само
     задание. Снимать обрезку совсем нельзя: длинные постановки
     раздували карточку до 1045 точек, по экрану на задание. */
  .queue-table .col-task .cell-clip {
    white-space: normal;
    text-overflow: clip;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
  }
  /* Имена файлов и служебные сведения остаются в одну строку: их
     опознают по началу, а полное имя есть в подсказке. */
  /* Кнопки действий во всю ширину: на телефоне в них попадают пальцем,
     а не курсором. */
  .queue-table tbody td.col-actions { text-align: left; }
  .queue-table tbody td.col-actions .btn { margin: .25rem .25rem 0 0; }

}

/* --- «Мои задания»: таблица по ширине страницы ------------------------
   Колонка оповещений стоит последней, а ширину таблицы задавало
   содержимое: название объекта в метке не переносится, и одно длинное
   («Жилой комплекс в границах переулка Базовый — полосы отвода ж/д
   путей — Кольцовского тракта…») растягивало таблицу до 2137 точек при
   окне 1280. Девятьсот точек уезжали за край вместе с оповещениями:
   инициатор не видел, что ему ответил администратор.

   Лечение то же, что в очереди задач: жёсткая раскладка и доли вместо
   содержимого. Колонки делят страницу, а длинное содержимое
   переносится или обрезается многоточием. */
.mine-table {
  table-layout: fixed;
  width: 100%;
}
.mine-table th,
.mine-table td { overflow-wrap: anywhere; }

.mine-table .col-num    { width: 4%; }
.mine-table .col-doc    { width: 30%; }
.mine-table .col-when   { width: 11%; }
.mine-table .col-state  { width: 10%; }
.mine-table .col-result { width: 32%; }
.mine-table .col-msg    { width: 13%; }

/* Кнопки оповещений прижаты вправо и переносятся на вторую строку,
   вместо того чтобы растягивать колонку. */
.mine-table .col-msg {
  text-align: right;
  white-space: normal;
}
.mine-table .col-msg .btn {
  white-space: nowrap;
  margin: 0 0 .25rem .25rem;
}

/* На узком экране шесть колонок не поместятся: там таблица становится
   карточками — по заданию на карточку, как в очереди. */
@media (max-width: 767.98px) {
  .mine-table,
  .mine-table tbody,
  .mine-table tbody tr,
  .mine-table tbody td {
    display: block;
    width: auto;
  }
  .mine-table thead { display: none; }
  .mine-table { table-layout: auto; }
  .mine-table .col-num,
  .mine-table .col-doc,
  .mine-table .col-when,
  .mine-table .col-state,
  .mine-table .col-result,
  .mine-table .col-msg { width: auto; }

  .mine-table tbody tr {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .75rem .875rem;
    margin-bottom: .75rem;
    background: var(--bs-body-bg, #fff);
  }
  .mine-table tbody td { border: 0; padding: .3rem 0; }
  .mine-table tbody td:empty { display: none; }
  .mine-table tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .7rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: .15rem;
  }
  .mine-table tbody td.col-num a::before { content: "№ "; }
  .mine-table tbody td.col-msg { text-align: left; }
  .mine-table tbody td.col-msg .btn { margin: .25rem .25rem 0 0; }
}


/* --- Метки в таблицах: переносить, а не вылезать ----------------------
   Метка по умолчанию не переносится, а ширину колонки держит раскладка
   таблицы. Длинное название объекта — «Жилой комплекс в границах
   переулка Базовый — полосы отвода ж/д путей — Кольцовского тракта —
   русла реки Исети…» — вылезало из ячейки на 660 точек и ложилось
   поверх соседней колонки: графу «Кто и когда» было не прочитать.

   Правило общее для всех таблиц намеренно. Названия объектов стоят в
   метках на нескольких страницах, и частные правила расходятся:
   поправишь очередь — останется тот же изъян в заданиях компании. */
.table td .badge,
.table th .badge {
  white-space: normal;
  text-align: left;
}

/* ---------- Учётные записи на узком экране ---------- */
/* Шесть граф — логин, имя, роль, компания, отдел, действия — на 375
   точках не помещаются: таблица уезжала за край, и список работников
   приходилось возить вбок. Раскладываем строку карточкой, тем же
   приёмом, что у очереди заданий: подпись графы переезжает в саму
   ячейку. */
@media (max-width: 767.98px) {
  .users-table,
  .users-table tbody,
  .users-table tbody tr,
  .users-table tbody td {
    display: block;
    width: auto;
  }
  .users-table thead { display: none; }
  .users-table { min-width: 0; table-layout: auto; }

  .users-table tbody tr {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .7rem .85rem;
    margin-bottom: .75rem;
    background: var(--bs-body-bg, #fff);
  }
  /* Заголовок компании остаётся заголовком, а строка с формой правки
     — служебная: она раскрывается кнопкой «Профиль» и в свёрнутом
     виде рисовалась пустой рамкой между карточками. */
  .users-table tbody tr.table-group {
    border: 0;
    background: transparent;
    padding: 0;
    margin: 1rem 0 .35rem;
  }
  .users-table tbody tr.edit-row {
    border: 0;
    background: transparent;
    padding: 0;
    margin: 0;
  }
  .users-table tbody td { border: 0; padding: .28rem 0; }
  .users-table tbody td:empty { display: none; }

  .users-table tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .7rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: .1rem;
  }
  /* Логин — шапка карточки: подпись ему не нужна. */
  .users-table tbody td[data-label="Логин"]::before { content: none; }
  .users-table tbody td[data-label="Логин"] { font-size: 1rem; }

  /* Кнопки действий выстраиваются в ряд и берут высоту под палец. */
  .users-table tbody td[data-label="Действия"] {
    text-align: left !important;
    white-space: normal !important;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    padding-top: .5rem;
  }
  .users-table tbody td[data-label="Действия"] .btn { min-height: 36px; }
  .users-table tbody td[data-label="Действия"] form { display: inline-flex; }
}

/* ---------- Библиотека промптов на узком экране ---------- */
/* Шапка карточки держала обе половины в одной строке: слева название
   с меткой вида документа, справа метки, дата и кнопка. На 375 точках
   правая половина распирала карточку, и вбок ехала вся страница. */
@media (max-width: 767.98px) {
  .prompt-head > span { max-width: 100% !important; }
  .prompt-head .text-nowrap {
    white-space: normal !important;
    flex-wrap: wrap;
  }
  .prompt-head .badge { white-space: normal; text-align: left; }
}

/* ---------- Карточка компании на узком экране ---------- */
/* Поле названия объявлено шириной 260 точек: вместе с кнопкой
   «Переименовать» это 422 при экране в 375, и вбок ехала вся
   страница. На телефоне поле занимает строку целиком. */
@media (max-width: 767.98px) {
  .company-rename input[name="name"] {
    min-width: 0 !important;
    width: 100%;
  }
  .company-rename > div { min-width: 12rem; }
}

/* ---------- Реестр и отчёт на узком экране ---------- */
/* Реестр — четырнадцать граф и 1724 точки ширины: почти впятеро шире
   телефона, возить такую таблицу вбок невозможно. В отчёте таблицы
   уже, но и там строку не прочесть целиком. Раскладываем карточками —
   тем же приёмом, что у очереди заданий: подпись графы переезжает в
   саму ячейку. */
@media (max-width: 767.98px) {
  .registry-table,
  .registry-table tbody,
  .registry-table tbody tr,
  .registry-table tbody td,
  .report-table,
  .report-table tbody,
  .report-table tbody tr,
  .report-table tbody td {
    display: block;
    width: auto;
  }
  .registry-table thead,
  .report-table thead { display: none; }
  .registry-table,
  .report-table { min-width: 0; table-layout: auto; }

  .registry-table tbody tr,
  .report-table tbody tr {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    padding: .7rem .85rem;
    margin-bottom: .75rem;
    background: var(--bs-body-bg, #fff);
  }
  .registry-table tbody td,
  .report-table tbody td {
    border: 0;
    padding: .26rem 0;
    text-align: left !important;
    /* Обрезка по ширине графы на карточке ни к чему: место есть. */
    max-width: none !important;
    white-space: normal !important;
    overflow: visible;
    text-overflow: clip;
  }
  .registry-table tbody td:empty,
  .report-table tbody td:empty { display: none; }

  .registry-table tbody td[data-label]::before,
  .report-table tbody td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .7rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: .1rem;
  }
  /* Номер задания и название показателя — шапка карточки: подпись им
     не нужна, а размер нужен. */
  .registry-table tbody td[data-label="Задание"]::before { content: none; }
  .registry-table tbody td[data-label="Задание"] { font-size: 1.05rem; }
  .report-table tbody td:first-child { font-size: 1rem; font-weight: 600; }
  .report-table tbody td[data-label="Агент"]::before,
  .report-table tbody td[data-label="Тип документа"]::before { content: none; }

  /* Ссылка на файл результата занимает строку целиком. */
  .registry-table tbody td[data-label="Результат"] a { max-width: none !important; }
}

/* Карточка задания в реестре занимала целый экран: четырнадцать граф
   столбиком. Короткие ставим по две-три в ряд — читается так же, а
   пролистывать вчетверо меньше. */
@media (max-width: 767.98px) {
  .registry-table tbody tr,
  .report-table tbody tr {
    display: flex;
    flex-wrap: wrap;
    gap: 0 .9rem;
  }
  .registry-table tbody td,
  .report-table tbody td { flex: 1 1 100%; }

  /* Отдел встаёт в пару с объектом, иначе остаётся один в строке. */
  .registry-table tbody td[data-label="Объект"] { flex: 1 1 52%; }
  .registry-table tbody td[data-label="Отдел"],
  .registry-table tbody td[data-label="Статус"],
  .registry-table tbody td[data-label="Создана"],
  .registry-table tbody td[data-label="Завершена"],
  .registry-table tbody td[data-label="Сложность"] { flex: 1 1 40%; }

  .registry-table tbody td[data-label="Факт., мин"],
  .registry-table tbody td[data-label="Норматив, мин"],
  .registry-table tbody td[data-label="Экономия, мин"] { flex: 1 1 25%; }

  .report-table tbody td[data-label="Текущий период"],
  .report-table tbody td[data-label="Предыдущий"],
  .report-table tbody td[data-label="Изменение"],
  .report-table tbody td[data-label="Задач"],
  .report-table tbody td[data-label="Ср. факт. время, мин"],
  .report-table tbody td[data-label="Экономия, мин"],
  .report-table tbody td[data-label="«Полезно», %"] { flex: 1 1 28%; }
}
