/* Компоненты дизайн-системы Reflux в CSS — по карточкам состояний и README
   макетов (Claude Design). Значения — только из токенов; жёлтый — акцент,
   никогда не текст на белом. */

/* --- Кнопки ---------------------------------------------------------------- */

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:var(--control-h-md);padding:0 16px;border:1px solid transparent;border-radius:var(--radius-sm);font-size:var(--text-body-sm-size);font-weight:700;cursor:pointer;text-decoration:none;transition:var(--transition-control);white-space:nowrap}
.btn:disabled{opacity:.55;cursor:not-allowed}
.btn-primary{background:var(--accent);color:var(--text-on-brand)}
.btn-primary:hover{background:var(--accent-hover)}
.btn-primary:active{background:var(--accent-active)}
.btn-secondary{background:var(--surface-card);border-color:var(--border-default);color:var(--text-primary)}
.btn-secondary:hover{border-color:var(--border-strong);background:var(--surface-hover)}
.btn-ghost{background:transparent;color:var(--text-primary)}
.btn-ghost:hover{background:var(--surface-hover)}
.btn-lg{height:var(--control-h-lg);padding:0 20px;font-size:var(--text-body-size)}
.btn-full{width:100%}

.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--text-secondary);cursor:pointer;transition:var(--transition-control)}
.icon-btn:hover{background:var(--surface-hover);color:var(--text-primary)}
.icon-btn-sm{width:28px;height:28px}
.icon-btn-secondary{background:var(--surface-card);border-color:var(--border-default);color:var(--text-primary)}

/* --- Поля ------------------------------------------------------------------ */

.field{display:flex;flex-direction:column;gap:6px}
.field-label{font-size:var(--text-body-sm-size);font-weight:700}
.input-wrap{position:relative;display:flex;align-items:center}
.input-wrap>svg{position:absolute;left:10px;color:var(--text-muted);pointer-events:none}
.input{width:100%;height:var(--control-h-md);padding:0 12px;border:1px solid var(--border-default);border-radius:var(--radius-sm);background:var(--surface-card);font-size:var(--text-body-sm-size);transition:var(--transition-control)}
.input-wrap>svg+.input{padding-left:34px}
.input:hover{border-color:var(--border-strong)}
.input:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--focus-ring)}
.input.invalid{border-color:var(--status-danger-dot)}
.input::placeholder{color:var(--text-muted)}
.input-sm{height:var(--control-h-sm)}

.checkbox{display:inline-flex;align-items:center;gap:8px;font-size:var(--text-body-sm-size);cursor:pointer;user-select:none}
.checkbox input{appearance:none;width:16px;height:16px;margin:0;border:1px solid var(--border-strong);border-radius:var(--radius-xs);background:var(--surface-card);cursor:pointer;transition:var(--transition-control);display:grid;place-content:center}
.checkbox input:checked{background:var(--accent);border-color:var(--accent)}
.checkbox input:checked::before{content:"";width:9px;height:9px;background:var(--text-on-brand);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%)}

.select{height:var(--control-h-sm);padding:0 28px 0 10px;border:1px solid var(--border-default);border-radius:var(--radius-sm);background:var(--surface-card) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236D6F71' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;font-size:var(--text-body-sm-size);color:var(--text-primary);cursor:pointer}

/* --- Бейджи и теги ---------------------------------------------------------- */

.badge{display:inline-flex;align-items:center;height:18px;padding:0 7px;border-radius:var(--radius-pill);font-size:var(--text-caption-size);font-weight:700;white-space:nowrap}
.badge-brand{background:var(--yellow-100);color:var(--grey-900)}
.badge-info{background:var(--status-info-bg);color:var(--status-info-fg);--badge-dot:var(--status-info-dot)}
.badge-neutral{background:var(--status-neutral-bg);color:var(--status-neutral-fg);--badge-dot:var(--status-neutral-dot)}
.badge-warning{background:var(--status-warning-bg);color:var(--status-warning-fg);--badge-dot:var(--status-warning-dot)}

/* Точка перед словом — свойство `dot` компонента Badge (макет ChatScreen 5a-5d).
   Ею отмечено то, о чём сообщает механика, а не модель: «Без обращения к
   архиву», «Ответ остановлен», «Файла больше нет». Цвет точки насыщеннее
   текста — на бледной подложке бейджа её иначе не видно. */
.badge-dot::before{content:"";flex:0 0 auto;width:6px;height:6px;margin-right:5px;border-radius:50%;background:var(--badge-dot,currentColor)}

.tag{display:inline-flex;align-items:center;height:26px;padding:0 10px;border:1px solid var(--border-default);border-radius:var(--radius-pill);background:var(--surface-card);font-size:var(--text-body-sm-size);color:var(--text-secondary);cursor:pointer;transition:var(--transition-control);user-select:none}
.tag:hover{border-color:var(--border-strong);color:var(--text-primary)}
.tag.active{background:var(--surface-selected);border-color:var(--border-brand);color:var(--text-primary)}
.tag .num{margin-left:6px;color:var(--text-muted)}

/* --- Табы ------------------------------------------------------------------- */

.tabs{display:flex;gap:20px;border-bottom:1px solid var(--border-default)}
.tab{display:inline-flex;align-items:center;gap:6px;padding:6px 2px 10px;border:none;border-bottom:2px solid transparent;margin-bottom:-1px;background:none;font-size:var(--text-body-sm-size);font-weight:700;color:var(--text-secondary);cursor:pointer;transition:var(--transition-control)}
.tab:hover{color:var(--text-primary)}
.tab.active{color:var(--text-primary);border-bottom-color:var(--yellow-400)}
.tab .num{font-weight:400;color:var(--text-muted)}

/* --- Сайдбар ---------------------------------------------------------------- */

.sidebar-item{display:flex;align-items:center;gap:10px;height:38px;padding:0 14px;border:none;border-left:2px solid transparent;background:none;border-radius:0 var(--radius-sm) var(--radius-sm) 0;font-size:var(--text-body-sm-size);color:var(--text-secondary);text-decoration:none;cursor:pointer;transition:var(--transition-control);white-space:nowrap;overflow:hidden}
.sidebar-item svg{flex:0 0 auto}
.sidebar-item:hover{background:var(--surface-hover);color:var(--text-primary)}
.sidebar-item.active{background:var(--yellow-50);border-left-color:var(--yellow-400);color:var(--text-primary);font-weight:700}
.sidebar-item.static{cursor:default}
.sidebar-item.static:hover{background:none;color:var(--text-secondary)}
.sidebar-item.active.static:hover{background:var(--yellow-50);color:var(--text-primary)}

.avatar{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;flex:0 0 auto;border-radius:50%;background:var(--yellow-400);color:var(--text-on-brand);font-size:var(--text-caption-size);font-weight:700}

/* --- Плашка иконки сервиса --------------------------------------------------- */

.app-icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;flex:0 0 auto;border-radius:var(--radius-sm);background:var(--yellow-50);border:1px solid var(--yellow-200);color:var(--grey-900)}
.app-icon-lg{width:40px;height:40px;border-radius:var(--radius-md)}
.app-icon.muted{background:var(--grey-50);border-color:var(--border-default);color:var(--grey-600)}

/* --- Таблица данных ---------------------------------------------------------
   Переехала из photometry-chat.css (предложение 0034): те же строки с
   координатой рисует и сводная за год. Липкая шапка и сортировка кликом
   остались у чата — они про ленту, а не про таблицу. */

.table-scroll { overflow-x: auto; }
.table-scroll .data-table { min-width: 640px; }

.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-body-sm-size); }

.data-table th {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  color: var(--text-muted);
  font-weight: var(--weight-regular);
  border-bottom: var(--border-width) solid var(--border-default);
  /* Шапка переносится, значения — нет, и это не противоречие (приёмка
     02.09.2026). У значений перенос делал строки разной высоты: «ДНаЗ Ag
     600/400» складывался надвое, и таблицу нельзя было читать глазами по
     горизонтали. У шапки высота общая на всю таблицу, и лишняя строка в ней
     стоит дешевле прокрутки вбок.

     Замер, ради которого правило и появилось: набор колонок, названный
     владельцем (наработка, поток, доля, ФАР, цветопередача, дата, источник),
     с запретом переноса растягивал таблицу до 999 px в колонке чтения 880 —
     и «Источник» уезжал за край. С переносом — ровно 880, прокрутки нет.
     Сводной это не меняет: там все заголовки в одно слово. */
  white-space: normal;
}

.data-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-width) solid var(--border-subtle);
  /* Значение не переносится по словам. Приёмка 25.08: когда таблица деградации
     получила десятую колонку, «ДНаЗ Ag 600/400» сложился в две строки и
     ВСЯ таблица стала вдвое выше — при том, что вбок она и так прокручивается.
     Лучше прокрутка, чем строки разной высоты: глазами их не сопоставить. */
  white-space: nowrap;
}

.data-table tbody tr:hover { background: var(--surface-hover); }
.data-table .num { font-variant-numeric: var(--numeric-features); }
.data-table .col-source { text-align: right; white-space: nowrap; }
.data-table .col-right { text-align: right; }

/* --- Столбики ---------------------------------------------------------------- */

/* Столбики сводной рисуются разметкой, а не uPlot: по оси x названия
   («входной контроль», «ДНаЗ»), а не числа. */
.block-bars { display: flex; flex-direction: column; gap: var(--space-2); }
.bar-row { display: grid; grid-template-columns: minmax(120px, 1.2fr) 3fr auto; gap: var(--space-3); align-items: center; }
.bar-label { font-size: var(--text-body-sm-size); color: var(--text-secondary); }
.bar-track { height: 10px; border-radius: var(--radius-pill); background: var(--surface-sunken); overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--grey-700); }
.bar-value { font-size: var(--text-body-sm-size); font-variant-numeric: var(--numeric-features); color: var(--text-primary); }

/* Меню действий — всплывающая полка пунктов у кнопки (три точки в списке
   диалогов, приёмка 27.08.2026).

   Компонента Menu в дизайн-системе НЕТ: он собран здесь на токенах системы по
   образцу Claude и ChatGPT, которые владелец показал референсами. Значит
   система и репозиторий в этом месте разошлись — карточка компонента должна
   приехать отдельным заказом в Claude Design, иначе следующий экран нарисует
   своё меню заново и по-другому.

   position: fixed — не украшение: меню рисуется в body, потому что панель
   диалогов прокручивается и обрезала бы его собственным краем. Координаты
   ставит menu.js. */
.menu{position:fixed;z-index:60;min-width:200px;padding:var(--space-2);border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg);background:var(--surface-card);box-shadow:var(--shadow-lg)}
.menu-item{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-sm);background:none;font:inherit;font-size:var(--text-body-sm-size);color:var(--text-primary);text-align:left;white-space:nowrap;cursor:pointer;transition:var(--transition-control)}
.menu-item:hover{background:var(--surface-hover)}
.menu-item svg{flex:0 0 auto;color:var(--text-muted)}
.menu-item:hover svg{color:var(--text-primary)}
/* Опасное действие — красным текстом, а не красной кнопкой: в меню это один
   пункт из нескольких, и заливка сделала бы его главным действием экрана.
   Пунктов класса danger сегодня нет ни одного — «Удалить» появится отдельной
   работой (заявка 29), и стиль для него уже готов, чтобы он не появился
   выглядящим как все остальные. */
.menu-item.danger,.menu-item.danger svg{color:var(--status-danger-fg)}
.menu-item.danger:hover{background:var(--status-danger-bg)}
/* Разделители — по группам действий, а не между всеми пунктами подряд. */
.menu-sep{height:0;margin:var(--space-2) 0;border:none;border-top:var(--border-width) solid var(--border-subtle)}

/* Всплывашка о сделанном — Toast (приёмка 27.08.2026).

   В дизайн-системе компонент Toast описан, но в репозиторий не переносился —
   этот первый, и потому живёт здесь, среди компонентов, а не в стилях одного
   экрана: следующему экрану он понадобится таким же.

   СВЕРХУ ПО ЦЕНТРУ, а не в правом нижнем углу, как было в первой редакции.
   Владелец: «вообще почти его не видно». Причина не в размере: человек нажал
   пункт меню в панели слева и смотрит туда, а подтверждение появлялось в
   противоположном углу экрана — дальше всего от взгляда. Сверху по центру
   оно попадает в поле зрения при любом положении курсора.

   Отсчёт от НИЗА топбара (--layout-topbar-h), а не от верха окна: иначе
   всплывашка легла на поиск по сервисам и кнопки топбара — проверено снимком.
   Перекрывает крошки и заголовок страницы — намеренно и ненадолго: 6 секунд
   заголовок «Нейрочат» никому не нужен, а подтверждение нужно. */
.toast-host{position:fixed;top:calc(var(--layout-topbar-h) + var(--space-4));left:50%;transform:translateX(-50%);z-index:70;display:flex;flex-direction:column;gap:var(--space-2);align-items:center;pointer-events:none}
.toast{display:flex;align-items:center;gap:var(--space-4);padding:var(--space-3) var(--space-3) var(--space-3) var(--space-5);border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg);background:var(--surface-card);box-shadow:var(--shadow-overlay);font-size:var(--text-body-size);color:var(--text-primary);pointer-events:auto;animation:toast-in 180ms linear}
/* Иконка называет действие раньше, чем прочитан текст: «убрал» и «вернул»
   различаются на скорости по значку, а не по чтению строки. */
.toast-icon{flex:0 0 auto;color:var(--text-secondary)}
.toast-text{white-space:nowrap}
/* «Вернуть» — кнопка, а не ссылка: во всплывашке сверху по центру это
   единственное действие, и оно обязано выглядеть нажимаемым с расстояния. */
.toast-undo{height:var(--control-h-sm);padding:0 var(--space-4)}
/* Крестик мельче кольца и не касается его: круг, вплотную обнимающий косой
   крест, читается как знак «запрещено» ⊗ — а это не отказ, а таймер.
   Поймано снимком крупным планом 27.08.2026. */
/* Крестик внутри кольца подсветку фоном НЕ получает: скруглённый квадрат
   заливки внутри круга выглядит мусором (приёмка 27.08.2026). Наведение
   показывается цветом самого глифа — этого хватает, кольцо и так очерчивает
   область нажатия. */
.toast-close{width:28px;height:28px;color:var(--text-muted)}
.toast-close svg{width:14px;height:14px}
.toast-close:hover{background:none;color:var(--text-primary)}

/* Кольцо обратного отсчёта вокруг крестика — видно, сколько всплывашке
   осталось (просьба владельца 27.08.2026).

   ОТСТУПЛЕНИЕ ОТ ШКАЛЫ ДВИЖЕНИЯ дизайн-системы, и намеренное: там
   80/120/180/260 мс, «крутится только спиннер». Здесь шесть секунд — но это
   не переход и не вращение, а показ оставшегося времени; такой роли в шкале
   просто нет. Линейность правило сохраняет: никаких пружин.

   Длительность приходит переменной --toast-life из chat.js: число живёт в
   одном месте, иначе кольцо однажды дотикает после исчезновения.

   Серое, а не жёлтое: жёлтый в системе — акцент главного действия, а отсчёт
   ничего не требует и обязан быть ненавязчивым (о чём владелец и просил). */
.toast-timer{position:relative;display:grid;place-items:center;width:38px;height:38px;flex:0 0 auto}
/* ПРЯМОЙ потомок, а не любой вложенный: крестик тоже лежит внутри
   .toast-timer, и правило `.toast-timer svg` растягивало его до 38px и
   разворачивало на -90° вместе с кольцом. Крест во всю ширину кольца — это
   и был тот самый знак «запрещено», который видно на снимке крупным планом
   27.08.2026. Селектор с потомками в контейнере, где SVG больше одного, —
   ловушка, а не стиль. */
/* pointer-events:none — не украшение, а починка: кольцо позиционировано
   абсолютно и потому рисуется ПОВЕРХ крестика, перехватывая нажатие на
   него. Крестик выглядел рабочим и не работал (приёмка 27.08.2026). */
.toast-timer > svg{position:absolute;inset:0;width:38px;height:38px;transform:rotate(-90deg);pointer-events:none}
.toast-timer > svg circle{fill:none;stroke-width:2}
.toast-ring-track{stroke:var(--border-subtle)}
/* Кольцо УБЫВАЕТ: наполнение читается как «идёт работа», убывание — как
   «время уходит». forwards — чтобы после конца оно осталось пустым, а не
   прыгнуло обратно в полное на последнем кадре. */
.toast-ring-run{stroke:var(--text-muted);stroke-linecap:round;stroke-dasharray:100.53;stroke-dashoffset:0;animation:toast-drain var(--toast-life,6000ms) linear forwards}
/* Наведение останавливает отсчёт — см. mouseenter в chat.js. */
.toast.paused .toast-ring-run{animation-play-state:paused}
@keyframes toast-drain{to{stroke-dashoffset:100.53}}
@keyframes toast-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* --- Экран без мыши (план 0061, сессия mobile-shell) ---------------------------
   Пальцу нужна цель не меньше 44px, а полю — шрифт не меньше 16px: Safari
   увеличивает страницу при фокусе на поле мельче. Токены не трогаются:
   правила действуют только там, где наведения нет и указатель грубый, —
   настольный вид остаётся по макетам 1440. Кнопки чата (микрофон, оценка,
   три точки) — сессия mobile-chat. */
@media (hover:none) and (pointer:coarse){
  .btn{height:var(--control-h-lg)}
  .icon-btn{width:44px;height:44px}
  /* Малая кнопка живёт внутри поля 36px (показ пароля) — выше поля ей нельзя. */
  .icon-btn-sm{width:36px;height:36px}
  .input{height:var(--control-h-lg);font-size:16px}
  .input-sm{height:40px}
  .select{height:40px;font-size:16px}
  .checkbox input{width:20px;height:20px}
  .tag{height:32px}
  .tab{padding:10px 2px 12px}
  .sidebar-item{height:44px}
  .sidebar-fold{height:44px;width:36px}
}

/* --- Лаборатория: экран протокола и карточка замера (#168, #169) -------------
   Вариант Б по итогу созвона 14.10.2026 (#234), вид — по макету к созвону:
   шапка протокола, строки ламп с числами внесённых замеров, строка
   раскрывается на месте; в ней карточка замера: плашки файлов, «Вычислить
   данные», числа группами 2×2, условия замера. Экран узкий (как макет): строки
   читаются глазом, а не растягиваются на всю ширину. */
.lab-page{display:flex;flex-direction:column;gap:16px}
.page-header + .lab-page{margin-top:20px}
.lab-title{display:flex;align-items:baseline;gap:8px 12px;flex-wrap:wrap;margin-top:8px}
.lab-title h1{margin:0}
.lab-title-sub{color:var(--text-secondary);font-size:var(--text-body-size)}
.lab-card{background:var(--surface-card);border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg);padding:20px 24px}
.lab-card-title{margin:0 0 12px;font-size:16px;font-weight:700}
.lab-card > .lab-muted{margin:12px 0 0}
.lab-muted{color:var(--text-muted);font-size:var(--text-body-sm-size)}
.lab-hint{flex-basis:100%;margin:0}
.lab-error{margin:0;padding:12px 16px;border-radius:var(--radius-md);background:var(--status-danger-bg);color:var(--status-danger-fg);font-size:var(--text-body-sm-size)}
.badge-success{background:var(--status-success-bg);color:var(--status-success-fg);--badge-dot:var(--status-success-dot)}
.lab-list a{font-weight:700}

/* шапка протокола */
.lab-head{display:flex;flex-wrap:wrap;align-items:center;gap:12px 24px}
.lab-proto{display:flex;flex-wrap:wrap;gap:12px 32px;margin:0;font-size:var(--text-body-sm-size)}
.lab-proto dt{color:var(--text-muted);font-size:12px}
.lab-proto dd{margin:2px 0 0;font-weight:700}
.lab-head-actions{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}
.lab-head > form{flex-basis:100%}

/* формы в строку: поля узкие по смыслу */
.lab-inline-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px 16px}
.lab-inline-form[hidden]{display:none}
.lab-inline-form .field{display:flex;flex-direction:column;gap:4px}
.lab-inline-form .select,.lab-mfields .select{height:var(--control-h-md)}
.lab-w-s{width:130px}
.lab-number{display:flex;align-items:center;gap:6px}
.lab-number .input{width:80px}
.lab-number-suffix{color:var(--text-secondary);font-size:var(--text-body-sm-size)}
.lab-w-m{width:220px}
.lab-w-wide{flex:1 1 280px;min-width:0}
.lab-inline-actions{display:flex;gap:12px;align-items:center}

/* прогресс и строки ламп */
.lab-progress{display:flex;align-items:center;gap:12px;flex-wrap:wrap;font-size:var(--text-body-sm-size)}
.lab-bar{width:260px;max-width:40%;height:6px;border-radius:var(--radius-pill);background:var(--surface-sunken);overflow:hidden}
.lab-bar i{display:block;height:100%;background:var(--status-success-dot)}
.lab-rows{background:var(--surface-card);border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg)}
/* Без overflow:hidden: он резал выпадающий список дефектов у нижних ламп (#279).
   Скругление держат углы крайних строк — фон у summary есть только под курсором
   и у раскрытой строки. */
.lab-row:last-child:not([open]) > summary{border-radius:0 0 calc(var(--radius-lg) - var(--border-width)) calc(var(--radius-lg) - var(--border-width))}
.lab-rows-head,.lab-row-head{display:grid;grid-template-columns:150px repeat(var(--lab-cols,1),minmax(0,1fr)) 20px;gap:12px;align-items:center;padding:10px 12px}
.lab-rows-head{color:var(--text-muted);font-size:12px;border-bottom:var(--border-width) solid var(--border-default)}
.lab-row + .lab-row{border-top:var(--border-width) solid var(--border-subtle)}
.lab-row > summary{list-style:none;cursor:pointer;font-size:var(--text-body-sm-size)}
.lab-row > summary::-webkit-details-marker{display:none}
.lab-row > summary:hover{background:var(--surface-hover)}
.lab-row[open] > summary{background:var(--surface-selected)}
.lab-row-lamp{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lab-cell{display:inline-flex;align-items:center;gap:6px;min-width:0}
.lab-cell-done svg{flex:none;color:var(--status-success-fg)}
.lab-cell-label{display:none;color:var(--text-muted)}
.lab-chev{width:7px;height:7px;border-right:2px solid var(--text-secondary);border-bottom:2px solid var(--text-secondary);transform:rotate(45deg);transition:transform .12s linear;justify-self:center}
.lab-row[open] > summary .lab-chev{transform:rotate(225deg)}
.lab-row-body{display:flex;flex-direction:column;gap:12px;padding:12px 12px 16px;border-top:var(--border-width) solid var(--border-default)}
.lab-row-what{margin:0;color:var(--text-secondary);font-size:var(--text-body-sm-size)}
.lab-row-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.lab-row-actions[hidden]{display:none}
.lab-measurements{max-width:760px}
.lab-m-actions{white-space:nowrap;text-align:right}
.lab-delete{margin:0}
.lab-add{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
.lab-add > form{align-self:stretch}
/* Испытание с точками наработки (#388): полоса точек, «Новая точка» справа от неё */
.lab-strip{display:flex;align-items:flex-end;justify-content:space-between;gap:16px}
.lab-tabs{flex:1;min-width:0;overflow-x:auto;overflow-y:hidden}
.lab-tabs .tab{flex:none;white-space:nowrap;text-decoration:none;padding-bottom:12px}
.lab-strip > .btn{flex:none;margin-bottom:6px}
.lab-cell-out{flex-wrap:wrap}
.lab-cell-late{flex-wrap:wrap} /* значок «после формирования» уходит под числа, а не сжимает их */
.lab-cell-defects{display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-width:0}
.lab-row-out{display:flex;align-items:center;gap:8px;margin:0;font-size:var(--text-body-sm-size)}
.lab-measurements .lab-m-other{color:var(--text-muted)}
.lab-points{display:flex;flex-wrap:wrap;gap:6px}
.lab-list .lab-point-chip{display:inline-flex;align-items:center;height:24px;padding:0 10px;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-pill);background:var(--surface-sunken);color:var(--text-secondary);font-size:12px;font-weight:400;white-space:nowrap;text-decoration:none}
.lab-list .lab-point-chip:hover{background:var(--surface-hover);color:var(--text-primary)}

/* карточка замера */
/* Автоподкрутка браузера держала бы на месте поля под карточкой и уводила
   кнопку «Вычислить данные» вверх; положение держит keepInPlace (lab-protocol.js). */
html:has(.lab-rows),.content:has(.lab-rows){overflow-anchor:none}
.lab-mcard{display:flex;flex-direction:column;gap:16px;padding:16px;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg);background:var(--surface-card)}
.lab-mcard [hidden]{display:none}
.lab-mcard.lab-drop-over{border-color:var(--border-focus);background:var(--surface-hover)}
.lab-mcard-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.lab-mcard-title{margin:0;font-size:16px;font-weight:700}
.lab-plates{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.lab-plate{display:grid;grid-template-columns:32px minmax(0,1fr) auto auto;gap:4px 10px;align-items:start;padding:12px;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-md);min-height:86px}
.lab-plate-empty{border-style:dashed;background:var(--surface-page)}
.lab-plate-icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:var(--radius-md);background:var(--surface-sunken);color:var(--text-secondary)}
.lab-plate-text{display:flex;flex-direction:column;gap:2px;min-width:0;font-size:var(--text-body-sm-size)}
.lab-plate-title{color:var(--text-muted);font-size:12px}
.lab-plate-name{font-weight:700;overflow-wrap:anywhere}
.lab-plate-empty .lab-plate-name{font-weight:400;color:var(--text-muted)}
.lab-plate-meta{color:var(--text-secondary);font-size:12px}
.lab-plate-ok{color:var(--status-success-fg);padding-top:6px}
.lab-plate-ok[hidden],.lab-plate-remove[hidden]{display:none}
.lab-plate-remove:hover{color:var(--status-danger-fg)}
/* Плашка сама принимает файл (макет 13.10): подпись-label растворена в сетке
   плашки, щелчок по значку или тексту открывает выбор файла этого вида. */
.lab-plate{position:relative}
.lab-plate-pick{display:contents;cursor:pointer}
.lab-plate:has(.lab-file-input:not(:disabled)){cursor:pointer}
.lab-plate:has(.lab-file-input:not(:disabled)):hover{border-color:var(--border-strong);background:var(--surface-hover)}
.lab-plate:focus-within{box-shadow:0 0 0 3px rgba(255,217,0,.55)}
.lab-plate-empty .lab-plate-name{color:var(--text-secondary)}
/* Поле выбора файла не прячется атрибутом hidden: так оно выпадает из порядка
   клавиши Tab. Невидимо, но фокусируется; кольцо фокуса — у плашки. */
.lab-file-input{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden}
.lab-pick{margin:0}
.lab-pick[hidden]{display:none}
.lab-series{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--text-body-sm-size)}
.lab-series[hidden]{display:none}
.lab-compute{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.lab-stale{color:var(--status-warning-fg);font-size:var(--text-body-sm-size);font-weight:700}
.lab-stale[hidden]{display:none}
.lab-warnings{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:12px 16px;border-radius:var(--radius-md);background:var(--status-warning-bg);color:var(--status-warning-fg)}
.lab-warnings[hidden]{display:none}
.lab-warnings-title{font-weight:700}
.lab-warnings-list{margin:0;padding-left:20px}
.lab-status{font-size:var(--text-body-sm-size);color:var(--text-secondary)}
.lab-status-bad{color:var(--status-danger-fg)}
.lab-numbers{display:flex;flex-direction:column;gap:12px}
.lab-numbers[hidden]{display:none}
.lab-numbers-stale .lab-groups{opacity:.45}
.lab-numbers-head{display:flex;align-items:center;gap:8px 12px;flex-wrap:wrap}
.lab-numbers-head > .lab-muted{margin-right:auto}
.lab-groups{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.lab-group{padding:12px;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-md)}
.lab-group-title{margin:0 0 4px;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-secondary)}
.lab-group-table{width:100%;border-collapse:collapse;font-size:var(--text-body-sm-size)}
.lab-group-table td{padding:6px 4px;border-bottom:var(--border-width) solid var(--border-subtle)}
.lab-group-table tr:last-child td{border-bottom:none}
.lab-num-row{cursor:pointer}
.lab-num-row:hover{background:var(--surface-hover)}
.lab-num-row td:nth-child(2){font-weight:700;white-space:nowrap}
.lab-where-row td{color:var(--text-muted);font-size:12px;padding-top:0}
.lab-where-row[hidden]{display:none}
.lab-how{display:inline-flex;gap:4px;flex-wrap:wrap;justify-content:flex-end}
.lab-method{display:inline-block;padding:2px 8px;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-pill);font-size:12px;white-space:nowrap}
.lab-method-calc{background:var(--status-info-bg);border-color:var(--status-info-bg);color:var(--status-info-fg)}
.lab-method-typed{background:var(--yellow-100);border-color:var(--yellow-100)}
.lab-flag{display:inline-block;padding:2px 8px;border-radius:var(--radius-pill);background:var(--status-warning-bg);color:var(--status-warning-fg);font-size:12px;white-space:nowrap}
.lab-note{display:block;color:var(--status-warning-fg)}
.lab-shown{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;font-size:var(--text-body-sm-size)}
.lab-shown:empty{display:none}
.lab-shown li{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.lab-shown-head{color:var(--text-muted);font-size:12px;text-transform:uppercase;letter-spacing:.06em}
.lab-shown .lab-where{color:var(--text-muted)}
/* Условия замера — как в макете: одна колонка, подпись слева, поле по длине значения. */
.lab-mfields{display:grid;grid-template-columns:200px minmax(0,1fr);gap:10px 16px;align-items:center;padding-top:12px;border-top:var(--border-width) solid var(--border-subtle);font-size:var(--text-body-sm-size)}
.lab-mfields-title{grid-column:1/-1;margin:0 0 4px;font-size:var(--text-body-size);font-weight:700}
.lab-f{display:contents}
.lab-f-label{font-weight:700}
.lab-mfields .lab-f-ctl > .select{width:220px;max-width:100%}
.lab-f-label small{display:block;font-weight:400;color:var(--text-muted);font-size:12px;line-height:16px}
.lab-f-ctl{display:flex;flex-direction:column;gap:4px;min-width:0}
.lab-line{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.lab-f-error{color:var(--status-danger-fg);font-size:12px}
.lab-f-error[hidden]{display:none}
.lab-mfields .input-error{border-color:var(--status-danger-fg)}
/* дефекты замера (#12): поле с метками и список по группам */
.lab-defects{position:relative;display:block;width:100%;max-width:520px}
.lab-dbox{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:var(--control-h-md);padding:4px 6px;border:1px solid var(--border-default);border-radius:var(--radius-sm);background:var(--surface-card);cursor:text;transition:var(--transition-control)}
.lab-dbox:focus-within{border-color:var(--border-focus);box-shadow:var(--focus-ring)}
.lab-dbox-off{background:var(--surface-sunken);cursor:default}
.lab-dinput{flex:1 1 120px;min-width:120px;height:26px;padding:0 4px;border:none;outline:none;background:transparent;font-size:var(--text-body-sm-size);color:var(--text-primary)}
.lab-dinput:disabled{color:var(--text-muted)}
.lab-dinput:focus,.lab-dinput:focus-visible{outline:none;box-shadow:none;border:none}
.lab-dtag{display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 8px;border-radius:var(--radius-pill);font-size:12px;white-space:nowrap}
.lab-dtag-own{background:var(--yellow-100);color:var(--grey-900);font-weight:700}
.lab-dtag-old{background:var(--surface-sunken);color:var(--text-secondary);border:1px dashed var(--border-strong)}
.lab-dbox .lab-dtag-old{height:auto;min-height:24px;max-width:100%;padding:2px 8px;white-space:normal}
td .lab-dtag + .lab-dtag{margin-left:4px}
.lab-dtag-x{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;border-radius:50%;background:transparent;color:inherit;font-size:14px;line-height:1;cursor:pointer}
.lab-dtag-x:hover{background:var(--yellow-200)}
/* «Тип ПРА» — поле с подсказками (свой текст можно), но стрелка — как у списков рядом:
   родная стрелка datalist другого вида (встреча 16.10, #250 п. 12). */
.lab-mfields .input[list]{padding-right:28px;background:var(--surface-card) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236D6F71' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center}
.lab-mfields .input[list]::-webkit-calendar-picker-indicator{display:none !important}
.lab-dlist{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:20;max-height:260px;overflow-y:auto;margin:0;padding:6px 0;list-style:none;border:var(--border-width) solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-card);box-shadow:var(--shadow-md)}
.lab-dlist[hidden]{display:none}
.lab-dgroup{padding:6px 12px 2px;font-size:12px;font-weight:700;color:var(--text-muted)}
.lab-doption{padding:6px 12px 6px 22px;font-size:var(--text-body-sm-size);cursor:pointer}
.lab-doption:hover,.lab-doption-active{background:var(--surface-selected)}
.lab-dempty{padding:6px 12px;font-size:12px;color:var(--text-muted)}
.lab-dnone{display:inline-flex;align-items:center;gap:8px;font-size:var(--text-body-sm-size);color:var(--text-secondary);cursor:pointer}
.lab-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap}

/* окна подтверждения */
.lab-dialog{width:min(480px,calc(100vw - 32px));border:var(--border-width) solid var(--border-default);border-radius:var(--radius-lg);padding:24px;color:var(--text-primary);background:var(--surface-card)}
.lab-dialog::backdrop{background:rgb(0 0 0 / 35%)}
.lab-dialog-title{margin:0;font-size:var(--text-h3-size);font-weight:var(--text-h3-weight)}
.lab-dialog-text{margin:8px 0 16px;font-size:var(--text-body-sm-size);color:var(--text-secondary)}
.lab-dialog-files{display:grid;grid-template-columns:auto 1fr;gap:6px 16px;margin:0;font-size:var(--text-body-sm-size)}
.lab-dialog-files dt{color:var(--text-muted)}
.lab-dialog-files dd{margin:0;font-weight:700;overflow-wrap:anywhere}
.lab-dialog-actions{display:flex;justify-content:flex-end;gap:12px;flex-wrap:wrap;margin-top:24px}

@media (max-width:760px){
  .lab-card{padding:16px}
  .lab-head-actions{margin-left:0}
  .lab-rows-head{display:none}
  .lab-rows-head + .lab-row > summary{border-radius:calc(var(--radius-lg) - var(--border-width)) calc(var(--radius-lg) - var(--border-width)) 0 0}
  .lab-rows-head + .lab-row:last-child:not([open]) > summary{border-radius:calc(var(--radius-lg) - var(--border-width))}
  .lab-row-head{grid-template-columns:minmax(0,1fr) 20px;row-gap:4px}
  .lab-row-lamp{grid-column:1}
  .lab-cell{grid-column:1}
  .lab-cell-label{display:inline}
  .lab-cell-empty{display:none}
  .lab-cell-defects{grid-column:1}
  .lab-cell-defects:not(:has(.lab-dtag)){display:none}
  .lab-strip{flex-direction:column;align-items:flex-start}
  .lab-strip .lab-tabs{width:100%}
  .lab-chev{grid-column:2;grid-row:1}
  .lab-plates,.lab-groups{grid-template-columns:1fr}
  .lab-mfields{grid-template-columns:1fr;gap:4px 0}
  .lab-f-label{margin-top:8px}
  .lab-w-s,.lab-w-m{width:calc(50% - 8px)}
}
/* Палец: поля 40 px, как у .input и .select выше. */
@media (hover:none) and (pointer:coarse){.lab-inline-form .select,.lab-mfields .select{height:40px}}
