/* Портал клиентов Систайл — оформление.
   Без сборки и внешних ресурсов: один CSS-файл. Фирменный стиль sistyle.ru
   (docs/design/design-spec.md §10): Montserrat — только заголовки, кнопки,
   вкладки и шапка (--font-brand), основной текст и таблицы — системный шрифт
   (--font). Шрифт self-hosted в /fonts/ (CSP font-src 'self'), кэш на год
   ставит server.js — новая версия шрифта = новое имя файла.

   Адаптивность — desktop-first, три порога (значения дублируются числами:
   в @media нельзя подставить кастомное свойство; см. docs/plans/responsive.md §2.1):

     ≥ 1200         десктоп: контейнер 980px, таблицы — таблицами;
     ≤ 1199         планшет: контейнер во всю ширину, отступы 24px;
     ≤  767         телефон: одна колонка, таблицы → карточки, липкое поле ответа;
     ≤  400         только уменьшение боковых отступов до 12px;
     hover:none + pointer:coarse — тач: минимальная цель 44px, независимо от ширины.

   Разметка волн В-адапт-2/3 (data-label у ячеек, .filters-toggle/.filters-body,
   role-атрибуты) появляется позже — файл рассчитан на её отсутствие:
   подписи рисуются только у td[data-label], тоггл фильтров скрыт, если его нет. */

/* Montserrat variable (ось wght), подмножества Google Fonts v31. Лицензия —
   /fonts/OFL.txt. Кириллица и латиница отдельными файлами: русская страница
   качает оба (цифры и знаки — из латиницы), вместе 56 КБ. */
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/montserrat-cyrillic-v31.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/montserrat-latin-v31.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- палитра --- */
  --bg: #f4f6f9;
  --surface: #ffffff;
  --border: #dde3ec;
  --text: #1b2430;
  --muted: #667488;
  /* Акцент — затемнённый фирменный бирюзовый (H 196°): #00a0dc на белом даёт
     2.97:1 и для текста, фокуса и белой надписи на кнопке не годится.
     --accent на белом 5.47:1, белый на нём 5.47:1 (§10.3). */
  --accent: #00719c;
  --accent-hover: #005f82;
  /* Фирменный цвет sistyle.ru: заливки, знак, акценты на тёмном (6.35:1 к #111).
     НЕ для текста на белом. */
  --brand: #00a0dc;
  --danger-bg: #fdecec;
  --danger-border: #f2c2c2;
  --danger-text: #9b1c1c;
  --info-bg: #eaf2fb;
  --info-border: #c3d9f0;
  --info-text: #1a4d85;
  --radius: 10px;
  --shadow: 0 1px 2px rgba(27, 36, 48, .06), 0 6px 20px rgba(27, 36, 48, .05);

  /* --- поверхности и текст (те же значения, что были литералами) --- */
  --surface-alt: #f7f9fc;      /* подсветка строки таблицы */
  --surface-sunken: #eef1f6;   /* hover .btn.ghost, фон нейтрального бейджа */
  --muted-strong: #5c6a7d;     /* серый текст НА сером фоне --bg: 5.0:1 против 4.33:1 у --muted */
  --border-strong: #c7d0dd;

  --radius-sm: 7px;
  --radius-pill: 999px;
  --shadow-card: 0 1px 2px rgba(27, 36, 48, .06);
  --shadow-raised: 0 2px 4px rgba(27, 36, 48, .10), 0 8px 24px rgba(27, 36, 48, .08);
  --focus-ring: 0 0 0 3px rgba(0, 113, 156, .35);
  --focus-ring-soft: 0 0 0 3px rgba(0, 113, 156, .18);   /* поля ввода */

  /* --- тёмная шапка (как у sistyle.ru) --- */
  --header-bg: #111111;
  --header-fg: #ffffff;        /* 18.9:1 */
  --header-muted: #b8c2cf;     /* 10.5:1 — строка пользователя */
  --header-line: #434b57;      /* разделитель логотипа, декор */
  --header-btn-bd: #6b7684;    /* рамка «Выйти» на тёмном, 4.09:1 */
  --header-h: 64px;            /* 56px на телефоне */

  /* --- отступы, шаг 4 --- */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px;
  --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px;
  /* синонимы из docs/design/design-spec.md (--sp-*); значения те же, чтобы
     board.css и макеты не зависели от того, какое имя выбрано в плане */
  --sp-1: var(--s-1); --sp-2: var(--s-2); --sp-3: var(--s-3);
  --sp-4: var(--s-4); --sp-5: var(--s-5); --sp-6: var(--s-6); --sp-7: var(--s-7);

  /* --- типографика --- */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "Consolas", "Courier New", monospace;
  /* Фирменный шрифт — только короткие строки: заголовки, кнопки, вкладки,
     шапка. В таблицах и тексте он на 12–23 % шире системного (§10.2). */
  --font-brand: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                Arial, sans-serif;
  /* Верхняя граница clamp() = сегодняшний десктопный размер: по критерию
     приёмки 8 (responsive.md §5.3) вид на 1366 не меняется, уменьшение
     работает только вниз, на узких экранах. */
  --fs-h1: clamp(20px, 1.15rem + 0.5vw, 22px);
  --fs-h2: clamp(17px, 1.05rem + 0.3vw, 19px);
  --fs-h3: 15px;
  --fs-body: 15px;
  --fs-small: 13px;
  --fs-micro: 12px;
  --fs-input: 16px;            /* меньше 16px — iOS Safari зумит страницу на фокусе */
  --lh-tight: 1.3;
  --lh-body: 1.5;
  /* синонимы из responsive.md §2.2 */
  --fs-xs: var(--fs-micro); --fs-sm: var(--fs-small); --fs-base: var(--fs-body);
  --fs-md: 16px; --fs-lg: var(--fs-h2); --fs-xl: var(--fs-h1);

  /* --- тач --- */
  --tap: 44px;                 /* минимальная сторона интерактивного элемента */

  /* --- контейнер и безопасные зоны --- */
  --container: 980px;
  --pad-x: 20px;               /* переопределяется в медиазапросах */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);

  /* --- статусы заявок (значения = прежние литералы .badge.s-*) --- */
  --st-new-bg:    #e7f0fb; --st-new-fg:    #17497f; --st-new-bd:    #c3d9f0;
  --st-work-bg:   #fff3da; --st-work-fg:   #8a5a00; --st-work-bd:   #f2ddb0;
  --st-wait-bg:   #f1ecfb; --st-wait-fg:   #573c9b; --st-wait-bd:   #ddd2f3;
  --st-done-bg:   #e6f5ec; --st-done-fg:   #1c6b3c; --st-done-bd:   #c3e4d1;
  --st-closed-bg: #eef1f6; --st-closed-fg: #55627a; --st-closed-bd: #dde3ec;

  /* --- приоритеты --- */
  --pri-crit-bg: #fdecec; --pri-crit-fg: #9b1c1c; --pri-crit-bd: #f2c2c2;
  --pri-high-bg: #fff3da; --pri-high-fg: #8a5a00; --pri-high-bd: #f2ddb0;
  --pri-norm-bg: #eef1f6; --pri-norm-fg: #55627a; --pri-norm-bd: #dde3ec;
  --pri-low-bg: transparent; --pri-low-fg: #5c6a7d; --pri-low-bd: #dde3ec;

  /* --- флаги на сообщениях и карточках --- */
  --flag-pending-bg: #fff3da; --flag-pending-fg: #8a5a00; --flag-pending-bd: #f2ddb0;
  --flag-client-bg:  #eaf2fb; --flag-client-fg:  #1a4d85; --flag-client-bd:  #c3d9f0;
  --flag-stale-bg:   #fdecec; --flag-stale-fg:   #9b1c1c; --flag-stale-bd:   #f2c2c2;
}

* { box-sizing: border-box; }

/* Атрибут hidden браузер выключает правилом [hidden]{display:none} из
   своей таблицы стилей — с наименьшим приоритетом. Любой наш селектор
   с display (например .view.centered ниже) его перебивает, и скрытый
   экран остаётся на странице. Поэтому фиксируем hidden явно. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--fs-body)/var(--lh-body) var(--font);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-brand); }
h1 { font-size: var(--fs-h1); margin: 0 0 4px; }
h2 { font-size: var(--fs-h2); margin: 0; }
h3 { font-size: var(--fs-h3); margin: 0 0 8px; }

a { color: var(--accent); }

.view.centered {
  min-height: 100vh;
  min-height: 100dvh;   /* фолбэк выше: старые Safari не знают dvh и берут vh */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-5) var(--s-4);
}

/* На сером фоне страницы (--bg) цвет --muted даёт 4.39:1 — ниже порога AA,
   поэтому там берём --muted-strong (5.09:1). Это осознанное видимое
   изменение оттенка серого ради контраста. Внутри белых карточек
   (--surface) у --muted 4.75:1, там прежний оттенок сохраняется. */
.muted { color: var(--muted-strong); }
.card .muted, .empty .muted,
.table-wrap .muted, ol.history .muted, dl.meta .muted { color: var(--muted); }
.small { font-size: var(--fs-small); }
.block { display: block; }
.req { color: var(--danger-text); }

/* Текст только для скринридеров (подпись поля ответа на телефоне и т.п.). */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Карточки и формы ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--s-5);
}

.auth-card {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
}

.auth-card h2 { font-size: 24px; font-weight: 700; line-height: 1.25; margin: 0 0 4px; }
.auth-card > .muted:first-of-type { margin: 0 0 20px; }

/* ---------- Экраны без сессии: фирменная плашка + форма (§10.4) ----------

   Плашка <aside class="auth-brand"> одна на все экраны входа (вход, код,
   установка пароля) и показывается без JS: когда виден любой .view.centered,
   кроме «Загрузка…». Всё оформление входа — под этим же условием: браузер
   без :has() выбросит правила целиком и покажет прежнюю карточку по центру. */
.auth-brand { display: none; }

body:has(> .view.centered:not([hidden]):not(#boot)) {
  display: grid;
  grid-template-columns: 5fr 6fr;
  height: auto;
  min-height: 100vh;
  min-height: 100dvh;
}
body:has(> .view.centered:not([hidden]):not(#boot)) .auth-brand {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--header-bg);
  color: var(--header-fg);
  padding: 72px 64px 48px max(64px, var(--safe-l));
}
body:has(> .view.centered:not([hidden]):not(#boot)) > .view.centered { min-width: 0; background: var(--surface); padding: var(--s-6); }
body:has(> .view.centered:not([hidden]):not(#boot)) .auth-card { border: 0; box-shadow: none; background: transparent; padding: 0; }

.auth-logo { display: block; height: 88px; width: auto; align-self: flex-start; }
.auth-title {
  font-family: var(--font-brand);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.2;
  margin: var(--s-7) 0 var(--s-3);
}
.auth-lead { font-size: var(--fs-md); color: var(--header-muted); margin: 0; max-width: 420px; }
.auth-pattern {
  display: block;
  margin-top: auto;
  padding-top: var(--s-6);
  width: 100%;
  max-width: 440px;
  height: auto;
  opacity: .9;
}
.auth-site { margin: var(--s-4) 0 0; font-size: var(--fs-small); color: var(--header-muted); }
.auth-site a { color: var(--header-fg); }

label {
  display: block;
  font-size: var(--fs-small);
  font-weight: 600;
  margin: 14px 0 5px;
}

input, select, textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: inherit;
  font: inherit;
  /* 16px обязателен: при меньшем размере iOS Safari зумит страницу на фокусе
     и обратно масштаб не возвращает. */
  font-size: var(--fs-input);
}

textarea { resize: vertical; }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--focus-ring-soft);
}

.row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.form-card { max-width: 720px; margin-top: 14px; }

.actions {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 20px;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font: inherit;
  font-family: var(--font-brand);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}

/* Главное действие экрана — пилюля заглавными, как на sistyle.ru. Заглавные
   только через text-transform: в DOM обычный регистр, скринридер читает
   слово, а не буквы. Белый на --accent — 5.47:1. */
.btn.primary {
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: 13px;
  padding: 11px 24px;
  min-height: var(--tap);
}
.btn.primary:hover { background: var(--accent-hover); }
.btn.primary:active { background: var(--accent-hover); }

.btn.ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text);
}
.btn.ghost:hover { background: var(--surface-sunken); }
.btn.ghost:active { background: var(--surface-sunken); }

.btn[disabled] { opacity: .6; cursor: default; }

.auth-card .btn { margin-top: 20px; }

/* Кнопка «Выйти» в тёмной шапке. */
.btn.on-dark {
  background: transparent;
  border-color: var(--header-btn-bd);
  color: var(--header-fg);
}
.btn.on-dark:hover, .btn.on-dark:active { background: #1f242b; }

/* Видимый фокус с клавиатуры: строки таблицы получают tabIndex в JS, но до
   сих пор не показывали, что выбраны. */
.btn:focus-visible,
.tab:focus-visible,
a:focus-visible,
summary:focus-visible,
tr[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.btn.primary:focus-visible { border-radius: var(--radius-pill); }
/* На тёмном --accent почти не виден (2.6:1 к #111) — там фирменный. */
.topbar :focus-visible,
.auth-brand :focus-visible { outline-color: var(--brand); }

/* Поле для кода из письма: цифры крупно и вразрядку, чтобы их было
   удобно сверять с письмом и вводить с телефона. */
.code-field {
  font-size: 24px;
  letter-spacing: 8px;
  text-align: center;
  font-family: var(--font-mono);
}

.code-actions {
  justify-content: space-between;
  flex-wrap: wrap;
}
.code-actions .link-back { margin-top: 0; }

.link-back {
  display: inline-block;
  margin-top: var(--s-4);
  font-size: var(--fs-small);
  text-decoration: none;
}
.link-back:hover { text-decoration: underline; }

/* ---------- Сообщения ---------- */

.alert {
  margin-top: var(--s-4);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid;
  font-size: 14px;
  scroll-margin-top: 64px;
}
.alert.error { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-text); }
.alert.info  { background: var(--info-bg);  border-color: var(--info-border);  color: var(--info-text); }

/* Старт кабинета и панели (#boot): «Загрузка…», причина повтора и кнопка
   «Повторить», когда проверка сессии не прошла по сети / 429 / 5xx. */
.boot-box { display: flex; flex-direction: column; align-items: center; gap: var(--s-3); max-width: 28rem; text-align: center; }
.boot-box > p { margin: 0; }

/* ---------- Шапка приложения (тёмная, §10.4) ---------- */

.topbar {
  background: var(--header-bg);
  color: var(--header-fg);
}

.topbar-inner {
  max-width: var(--container);
  min-height: var(--header-h);
  margin: 0 auto;
  padding-top: var(--s-2);
  padding-bottom: var(--s-2);
  padding-left: max(var(--pad-x), var(--safe-l));
  padding-right: max(var(--pad-x), var(--safe-r));
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

/* Логотип ведёт на главную портала; рядом текст, поэтому у img alt="",
   а имя ссылки — в aria-label. */
.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  flex: none;
  color: inherit;
  text-decoration: none;
}
.brand-logo { display: block; height: 32px; width: auto; flex: none; }
.brand-sep { flex: none; width: 1px; height: 24px; background: var(--header-line); }
.brand-name {
  font-family: var(--font-brand);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
}

/* Компания и пользователь: справа, обрезка многоточием — длинное название
   не выталкивает «Выйти». */
.topbar-who {
  margin-left: auto;
  min-width: 0;
  text-align: right;
  line-height: 1.3;
}
.topbar-who strong,
.topbar-who .topbar-sub {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topbar-who strong { font-size: 14px; }
.topbar-who .topbar-sub { font-size: var(--fs-micro); color: var(--header-muted); }
.topbar-inner > .btn { flex: none; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-top: var(--s-5);
  padding-bottom: calc(var(--s-6) + var(--safe-b));
  padding-left: max(var(--pad-x), var(--safe-l));
  padding-right: max(var(--pad-x), var(--safe-r));
  width: 100%;
  /* #view-app — флекс-колонка: контейнер забирает свободную высоту, и подвал
     стоит у нижнего края окна даже на пустом экране. */
  flex: 1 0 auto;
}

/* Приложение (кабинет и панель) — колонка «шапка · содержимое · подвал». */
#view-app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---------- Подвал «Собственная разработка ГК Систайл» (§10.9) ---------- */

/* Слева по сетке контейнера — тот же левый край, что у заголовка экрана.
   Фон --bg, поэтому --muted-strong (5.09:1), а не --muted (4.39:1). */
.foot {
  max-width: var(--container);
  width: 100%;
  margin: 0 auto;
  padding: var(--s-4) max(var(--pad-x), var(--safe-r)) calc(var(--s-5) + var(--safe-b)) max(var(--pad-x), var(--safe-l));
  font-size: var(--fs-micro);
  line-height: 1.4;
  color: var(--muted-strong);
}
/* На экранах входа подписей две: в тёмной плашке (десктоп) и под формой
   (телефон); одна всегда display:none — скринридер читает подпись раз. */
.foot--dark { max-width: none; margin: var(--s-3) 0 0; padding: 0; color: var(--header-muted); }
.foot--form { display: none; }

.pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: 18px;
}

/* ---------- Вкладки админ-панели ---------- */

.tabs {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.tabs-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: max(var(--pad-x), var(--safe-l));
  padding-right: max(var(--pad-x), var(--safe-r));
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--pad-x);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;          /* полоса прокрутки съедает высоту вкладок */
}
.tabs-inner::-webkit-scrollbar { display: none; }

.tab {
  padding: 11px 14px 10px;
  font-family: var(--font-brand);
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  /* Индикатор 3px --accent, не --brand: у --brand на белом 2.97:1 < 3:1. */
  border-bottom: 3px solid transparent;
  white-space: nowrap;
  scroll-snap-align: start;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.note { margin: 0 0 var(--s-4); }

.head-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}
.head-actions p { margin: 0; }

.col-actions { text-align: right; white-space: nowrap; }

/* Кнопки в строках таблиц — системным шрифтом: Montserrat шире и в плотных
   строках отъедает место (§10.4). */
.small-btn { padding: 5px 10px; font-family: var(--font); font-size: var(--fs-small); }

/* ---------- Фильтры списка ---------- */

.filters {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-bottom: 14px;
  padding: 14px var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Обёртка полей (появляется в волнах В-адапт-2/3) на широких экранах
   прозрачна для раскладки: .filter остаются прямыми флекс-детьми .filters.
   Порядок важен: правило на ≤767 с display:flex имеет ту же специфичность
   и обязано идти ниже этого. */
.filters-body { display: contents; }
.filters-toggle { display: none; }

.filter { display: flex; flex-direction: column; min-width: 0; }
.filter label { margin: 0 0 5px; }
.filter select, .filter input { width: auto; min-width: 150px; }
.filter-actions { justify-content: flex-end; }

.filter-count {
  margin: 0 0 2px auto;
  align-self: flex-end;
  white-space: nowrap;
}

/* ---------- Список заявок ---------- */

.table-wrap {
  /* Опора для .sr-only в шапке таблицы: без неё скрытая подпись (position:
     absolute) вылезает из прокручиваемой обёртки и расширяет страницу. */
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow-x: auto;
}

table.tickets {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

table.tickets th {
  text-align: left;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--muted);
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

table.tickets td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

table.tickets tbody tr:last-child td { border-bottom: none; }
table.tickets tbody tr { cursor: pointer; }
table.tickets tbody tr:hover { background: var(--surface-alt); }
/* На тач-экранах :hover не срабатывает — нажатие подсвечиваем через :active. */
table.tickets tbody tr:active { background: var(--surface-alt); }

.col-id { width: 56px; }
.col-cat, .col-pri, .col-status, .col-date { white-space: nowrap; }
.subject-cell { font-weight: 600; overflow-wrap: anywhere; }
/* «Инициатор»: перенос только по словам и после дефиса (<wbr> в app.js);
   anywhere сжимал колонку до буквы, min-width выталкивал таблицу за карточку. */
.col-init { overflow-wrap: normal; word-break: normal; }
/* Список кабинета: дата и время в две строки, длинный статус переносится —
   восемь колонок на ≥1024 помещаются в карточку без прокрутки. */
#list-table-wrap td.col-date .dt-time { display: block; }
@media (min-width: 768px) {
  #list-table-wrap td.col-status .badge { white-space: normal; }
  #list-table-wrap td.col-cat { white-space: normal; }
  #list-table-wrap th, #list-table-wrap td { padding-left: 10px; padding-right: 10px; }
}

.empty {
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 40px var(--s-5);
  text-align: center;
}
.empty p { margin: 0 0 6px; }

/* ---------- Бейджи статусов ---------- */

.badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-micro);
  font-weight: 600;
  white-space: nowrap;
  background: var(--surface-sunken);
  color: #4a5768;
  border: 1px solid var(--border);
}
.badge.s-new      { background: var(--st-new-bg);    color: var(--st-new-fg);    border-color: var(--st-new-bd); }
.badge.s-work     { background: var(--st-work-bg);   color: var(--st-work-fg);   border-color: var(--st-work-bd); }
.badge.s-wait     { background: var(--st-wait-bg);   color: var(--st-wait-fg);   border-color: var(--st-wait-bd); }
.badge.s-done     { background: var(--st-done-bg);   color: var(--st-done-fg);   border-color: var(--st-done-bd); }
.badge.s-closed   { background: var(--st-closed-bg); color: var(--st-closed-fg); border-color: var(--st-closed-bd); }

.pri-high { color: var(--pri-crit-fg); font-weight: 600; }

/* ---------- Карточка заявки ---------- */

.detail-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin: 14px 0 var(--s-4);
}
.detail-head h2 { overflow-wrap: anywhere; }

dl.meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-3) 20px;
  margin: 0 0 20px;
  padding: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
dl.meta dt { font-size: var(--fs-micro); color: var(--muted); margin-bottom: 2px; }
dl.meta dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }

/* Длинная строка без пробелов (URL, токен в отчёте обмена) не должна
   растягивать карточку и давать горизонтальную прокрутку страницы. */
.pre { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0; }

.history-title { margin: var(--s-5) 0 10px; font-size: var(--fs-h3); }

ol.history { list-style: none; margin: 0; padding: 0; }

ol.history li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s-3) 14px;
  margin-bottom: 10px;
}

/* Ответы клиента визуально отделены от ответов поддержки, чтобы ленту
   можно было читать по диагонали. */
ol.history li.from-client {
  background: var(--info-bg);
  border-color: var(--info-border);
  margin-left: var(--s-6);
}

.event-head {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-bottom: 4px;
  font-size: var(--fs-small);
}
.event-author { font-weight: 600; overflow-wrap: anywhere; }
.event-time { color: var(--muted); white-space: nowrap; margin-left: auto; }

.event-pending {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 600;
  background: var(--flag-pending-bg);
  color: var(--flag-pending-fg);
  border: 1px solid var(--flag-pending-bd);
}

.reply-card { margin-top: 18px; }
.reply-card label { margin-top: 0; }
.reply-card .actions { margin-top: 14px; }

/* ---------- Файлы (волна F1): приложенные в форме и вложения в ленте ---------- */
.attach { margin-top: var(--s-3); }
.attach-input { display: none; }
.attach-row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.attach-hint { line-height: 1.4; }
.attach-list { list-style: none; margin: var(--s-2) 0 0; padding: 0; display: grid; gap: 6px; }
.attach-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 6px 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  font-size: var(--fs-small);
}
.attach-item--busy { color: var(--muted-strong); }
.attach-item--error { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-text); grid-template-columns: minmax(0, 1fr) auto; }
.attach-item--error .attach-meta { grid-column: 1 / 2; grid-row: 2; white-space: normal; }
.attach-item--error .attach-remove { grid-row: 1 / span 2; grid-column: 2; }
.attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.attach-meta { color: inherit; opacity: .85; white-space: nowrap; }
.attach-remove {
  width: 32px; height: 32px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.attach-remove:hover { background: var(--surface-sunken); }
.attach-remove:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.attach-remove:disabled { opacity: .4; cursor: default; }
.attach-offer {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3);
  padding: 8px 10px;
  border: 1px solid var(--info-border);
  border-radius: var(--radius-sm);
  background: var(--info-bg);
  color: var(--info-text);
  font-size: var(--fs-small);
}

.event-files { list-style: none; margin: var(--s-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
ol.history li .event-files li { background: none; border: 0; padding: 0; margin: 0; }
.event-file { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--s-2); font-size: var(--fs-small); }
.file-thumb { display: block; flex-basis: 100%; line-height: 0; }
.file-thumb img {
  max-width: min(100%, 320px);
  max-height: 220px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  object-fit: contain;
}
.file-link { font-weight: 600; color: var(--accent); overflow-wrap: anywhere; }
.file-link:hover { color: var(--accent-hover); }
.file-name { font-weight: 600; overflow-wrap: anywhere; }
.file-note { color: var(--muted-strong); }
.event-file--unavailable .file-name, .event-file--deleted .file-name { color: var(--muted-strong); text-decoration: line-through; }
.event-file--unavailable .file-note { color: var(--danger-text); }

/* ============================================================
   Планшет и ниже: ≤ 1199
   ============================================================ */
@media (max-width: 1199px) {
  :root { --pad-x: 24px; }

  .topbar-inner, .tabs-inner, .container { max-width: none; }

  /* Плашка входа уже: 5/11 от 768 — это 349px. */
  body:has(> .view.centered:not([hidden]):not(#boot)) .auth-brand { padding: var(--s-7) var(--s-6) var(--s-6) max(var(--s-6), var(--safe-l)); }
  .auth-title { font-size: 28px; margin-top: var(--s-6); }

  /* Восемь колонок на 1024 в портрете не помещаются в 980px: разрешаем
     переносы вместо горизонтальной прокрутки внутри карточки. */
  table.tickets th { white-space: normal; }
  table.tickets td.col-date, table.tickets td.col-cat { white-space: normal; }
}

/* ============================================================
   Телефон: ≤ 767
   ============================================================ */
@media (max-width: 767px) {
  :root { --pad-x: 16px; --header-h: 56px; }

  .card { padding: var(--s-4); }

  /* ---- шапка: компания и пользователь — второй строкой на белом ---- */
  .topbar-inner { flex-wrap: wrap; row-gap: 0; min-height: 0; padding-top: 0; padding-bottom: 0; }
  .brand { min-height: var(--header-h); }
  .brand-logo { height: 28px; }
  .brand-name { font-size: 14px; }
  .topbar-inner > .btn { margin-left: auto; min-height: var(--tap); padding: 8px 14px; }
  .topbar-who {
    order: 3;
    flex: 0 0 calc(100% + max(var(--pad-x), var(--safe-l)) + max(var(--pad-x), var(--safe-r)));
    margin: 0 calc(-1 * max(var(--pad-x), var(--safe-r))) 0 calc(-1 * max(var(--pad-x), var(--safe-l)));
    padding: var(--s-2) max(var(--pad-x), var(--safe-r)) var(--s-2) max(var(--pad-x), var(--safe-l));
    background: var(--surface);
    color: var(--text);
    border-bottom: 1px solid var(--border);
    text-align: left;
  }
  .topbar-who .topbar-sub { color: var(--muted); }

  /* ---- вход: плашка сверху, форма ниже, подпись внизу колонки формы ---- */
  body:has(> .view.centered:not([hidden]):not(#boot)) { display: flex; flex-direction: column; }
  body:has(> .view.centered:not([hidden]):not(#boot)) .auth-brand {
    padding: calc(28px + var(--safe-t)) max(var(--pad-x), var(--safe-r)) var(--s-5) max(var(--pad-x), var(--safe-l));
  }
  .auth-logo { height: 52px; }
  .auth-title { font-size: 22px; margin: 20px 0 4px; }
  .auth-lead { font-size: var(--fs-base); }
  .auth-pattern, .auth-brand .foot--dark { display: none; }
  /* Ссылка на сайт остаётся и на телефоне — строкой под описанием (§16 п.6). */
  .auth-site { margin-top: var(--s-2); }
  body:has(> .view.centered:not([hidden]):not(#boot)) > .view.centered {
    flex: 1 0 auto;
    min-height: 0;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding: var(--s-5) max(var(--pad-x), var(--safe-r)) 0 max(var(--pad-x), var(--safe-l));
  }
  .auth-card h2 { font-size: 20px; }
  body:has(> .view.centered:not([hidden]):not(#boot)) .foot--form {
    display: block;
    max-width: 380px;
    margin-top: auto;
    padding: var(--s-6) 0 calc(var(--s-1) + var(--safe-b));
    color: var(--muted);
  }
  .row { grid-template-columns: 1fr; }

  .view.centered {
    /* Карточка входа не «прыгает» при появлении клавиатуры. */
    align-items: flex-start;
    padding-top: 12vh;
  }

  .pane-head { flex-direction: column; align-items: stretch; gap: var(--s-2); }
  .pane-head .btn { width: 100%; }

  .head-actions { flex-direction: column; align-items: stretch; gap: var(--s-2); }
  .head-actions .btn { width: 100%; }

  .actions { flex-direction: column-reverse; align-items: stretch; }
  .actions .btn { width: 100%; }
  /* У экрана с кодом обратный порядок не нужен: «Выслать заново» сверху,
     ссылка возврата — под ней. */
  .code-actions { flex-direction: column; }
  .code-actions .link-back { text-align: center; }

  /* Вкладки панели под рукой при длинном списке. */
  .tabs { position: sticky; top: 0; z-index: 5; }

  /* ---- фильтры сворачиваются ---- */
  .filters { flex-direction: column; align-items: stretch; }
  .filters-toggle {
    display: inline-flex;
    justify-content: space-between;
    width: 100%;
    min-height: var(--tap);
  }
  .filters-body {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-3);
    width: 100%;
  }
  .filters.is-collapsed .filters-body { display: none; }
  .filter { width: 100%; }
  .filter select, .filter input { width: 100%; min-width: 0; }
  .filter input[type="date"] { width: 100%; }
  .filter-actions { margin-left: 0; }
  .filter-actions .btn { width: 100%; }
  .filter-count { margin: 0; width: 100%; }

  /* ---- таблицы превращаются в карточки ---- */
  .table-wrap { background: none; border: 0; box-shadow: none; overflow: visible; }
  table.tickets, table.tickets tbody { display: block; }
  /* Заголовки убираются с глаз, но остаются для скринридеров. */
  table.tickets thead {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  table.tickets tbody tr {
    display: grid;
    /* Две равные колонки, а не «1fr auto»: колонка по содержимому
       раздувается от длинного email и сжимает соседнюю до переноса по букве. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s-1) var(--s-3);
    padding: var(--s-3) 14px;
    margin-bottom: var(--s-3);
    min-height: var(--tap);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
  }
  table.tickets tbody tr:last-child { margin-bottom: 0; }

  table.tickets td {
    display: block;
    padding: 0;
    border: 0;
    min-width: 0;
    white-space: normal;
    overflow-wrap: break-word;
  }
  /* Подпись рисуется только там, где JS проставил data-label; без разметки
     волн В-адапт-2/3 ячейки просто идут одна под другой. */
  table.tickets td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: var(--fs-micro);
    line-height: 1.35;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .03em;
  }

  /* Тема (а в таблице клиентов — компания) работает заголовком карточки. */
  table.tickets td.subject-cell,
  table.tickets tbody td:first-child:not(.col-id) {
    grid-column: 1 / -1;
    order: -2;
    font-size: var(--fs-md);
    font-weight: 600;
    overflow-wrap: anywhere;
  }
  table.tickets td.subject-cell::before,
  table.tickets tbody td:first-child:not(.col-id)::before { display: none; }

  /* Номер — приписка к теме, подпись в строку. */
  table.tickets td.col-id {
    order: -1;
    width: auto;
    font-size: var(--fs-micro);
    color: var(--muted);
  }
  table.tickets td.col-id[data-label]::before { display: inline; content: attr(data-label) " "; }

  /* Статус — в правом верхнем углу карточки, рядом с номером. */
  table.tickets td.col-id ~ td.col-status { order: -1; justify-self: end; align-self: start; }
  table.tickets td.col-id ~ td.col-status::before { display: none; }
  /* Вторая «статусная» ячейка (в панели это «Сделка») — обычная строка с подписью. */
  table.tickets td.col-status ~ td.col-status { order: 0; justify-self: start; }
  table.tickets td.col-status ~ td.col-status[data-label]::before { display: block; }

  table.tickets td.col-actions {
    grid-column: 1 / -1;
    text-align: left;
    white-space: normal;
    padding-top: var(--s-2);
  }
  table.tickets td.col-actions::before { display: none; }
  table.tickets td.col-actions:empty { display: none; }
  table.tickets td.col-actions .btn { width: 100%; }
  /* «Инициатор» — во всю ширину карточки: в половине двойная фамилия
     рвалась внутри слова, и дефис уезжал в начало следующей строки. */
  table.tickets td.col-init { grid-column: 1 / -1; }
  /* Карточка заявки на телефоне: дата и время в одну строку. */
  #list-table-wrap td.col-date .dt-time { display: inline; }

  /* ---- карточка заявки и лента ---- */
  dl.meta { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); padding: var(--s-3); }
  ol.history li.from-client { margin-left: var(--s-3); }
  /* Новое сообщение прокручивается к себе (app.js) — оставляем место,
     чтобы оно не оказалось под липкой формой ответа. */
  ol.history, ol.history li { scroll-margin-bottom: 160px; }
  #s-last-result { overflow-x: auto; max-height: 60vh; }

  /* ---- липкое поле ответа ---- */
  .reply-card {
    position: sticky;
    bottom: 0;
    z-index: 4;
    margin: var(--s-4) calc(-1 * max(var(--pad-x), var(--safe-r))) 0
            calc(-1 * max(var(--pad-x), var(--safe-l)));
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 0;
    box-shadow: 0 -6px 20px rgba(27, 36, 48, .10);
    padding: var(--s-3) var(--s-4) calc(var(--s-3) + var(--safe-b));
  }
  /* Подпись уводится к скринридерам — её роль играет placeholder.
     Значения те же, что у .sr-only выше, поэтому селектор общий. */
  .sr-only, .reply-card label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .reply-card textarea { height: 44px; min-height: 0; }
  .reply-card:focus-within textarea { height: 120px; }
  .reply-card .actions { margin-top: var(--s-2); }
  /* Липкая форма не должна расти на весь экран из-за списка файлов. */
  .reply-card .attach-list { max-height: 30vh; overflow-y: auto; }
  .attach-row .btn { width: 100%; }
  /* Клавиатура открыта (класс ставит app.js по visualViewport): форма встаёт
     в поток, иначе на iOS липкий блок уезжает под клавиатуру. */
  body.kb-open .reply-card { position: static; }
}

/* Ландшафт телефона: экран низкий, липкая форма съедает почти весь. */
@media (max-width: 767px) and (max-height: 450px) {
  .reply-card { position: static; }
  .view.centered { padding-top: var(--s-4); }
}

/* ============================================================
   Узкий телефон: ≤ 400
   ============================================================ */
@media (max-width: 400px) {
  :root { --pad-x: 12px; }
  .code-field { font-size: 22px; letter-spacing: 6px; }
}

/* ============================================================
   Тач: цель не меньше 44px независимо от ширины экрана
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  .btn, .tab, .small-btn, .filters-toggle,
  input, select, textarea, .filter select, .filter input {
    min-height: var(--tap);
  }
  .small-btn { padding: 8px 12px; }
  .link-back { display: inline-flex; align-items: center; min-height: var(--tap); }
}

/* Строка таблицы как тач-цель — только там, где таблица осталась таблицей:
   на телефоне ячейки живут в сетке карточки и своего вертикального
   отступа не имеют. */
@media (hover: none) and (pointer: coarse) and (min-width: 768px) {
  table.tickets td { padding-top: 14px; padding-bottom: 14px; }
}

/* ============================================================
   Меньше движения — меньше движения
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   Второй фактор (docs/design/design-spec.md §9, план mfa-passkey-totp §9.2)
   Вход без пароля, выбор способа, онбординг, «Безопасность», step-up.
   Только новые классы .mfa-* (и модификатор .auth-card--wide): styles.css
   подключён и в панели, существующие правила здесь не трогаются. Экраны
   рисует public/mfa-ui.js — классы общие для кабинета и панели (волна 4B).
   ============================================================ */
:root {
  --mfa-icon: 40px;            /* круг значка способа */
  --mfa-factor-min-h: 64px;    /* карточка способа: ≥ --tap и две строки */
  --mfa-passkey-min-h: 56px;   /* крупная кнопка входа без пароля */
  --mfa-qr: 184px;             /* сторона QR-кода */
  --mfa-ok-bg: var(--st-done-bg); --mfa-ok-fg: var(--st-done-fg); --mfa-ok-bd: var(--st-done-bd);
  --mfa-warn-bg: var(--st-work-bg); --mfa-warn-fg: var(--st-work-fg); --mfa-warn-bd: var(--st-work-bd);
}

.mfa-ico { width: 20px; height: 20px; flex: none; }

/* Карточка экранов входа пошире — пояснения на карточках способов не
   ломаются в три строки. */
.auth-card.auth-card--wide { max-width: 440px; }

/* Экран внутри карточки входа: колонка, как сама .auth-card. */
.mfa-screen, .mfa-form { display: flex; flex-direction: column; min-width: 0; }
.mfa-screen > h2 + .muted,
.mfa-form > h2 + .muted,
.mfa-screen > .alert + .muted { margin: 0 0 20px; }
[data-mfa-screen] h2[tabindex="-1"]:focus { outline: none; }

/* ---- Э1: вход без пароля ---- */
.btn.primary.mfa-passkey-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-3);
  width: 100%;
  min-height: var(--mfa-passkey-min-h);
  margin-top: 0;
  padding: 10px 16px;
  border-radius: var(--radius);
  text-align: left;
  text-transform: none;
  letter-spacing: 0;
  font-size: 15px;
  white-space: normal;
}
.btn.primary.mfa-passkey-btn:focus-visible { border-radius: var(--radius); }
.mfa-passkey-btn .mfa-ico { width: 28px; height: 28px; }
.mfa-passkey-btn__text { display: flex; flex-direction: column; line-height: 1.25; }
.mfa-passkey-btn__text small { font-weight: 400; font-size: var(--fs-small); opacity: .9; }
.mfa-passkey-btn.is-busy .mfa-passkey-btn__text { flex-direction: row; align-items: center; gap: var(--s-3); }
.mfa-or {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: var(--s-5) 0 0;
  font-size: var(--fs-small);
  color: var(--muted);
}
.mfa-or::before, .mfa-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---- Э2 / Э6: карточки способов ---- */
.mfa-factor-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.mfa-factor {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  min-height: var(--mfa-factor-min-h);
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.mfa-factor:hover { border-color: var(--accent); background: var(--surface-alt); }
.mfa-factor:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mfa-factor[disabled], .mfa-factor[aria-busy="true"] { opacity: .7; cursor: default; }
.mfa-factor__icon {
  flex: none;
  width: var(--mfa-icon);
  height: var(--mfa-icon);
  border-radius: 50%;
  background: var(--info-bg);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mfa-factor__body { flex: 1; min-width: 0; }
.mfa-factor__title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-weight: 600; line-height: 1.3; }
.mfa-factor__desc { display: block; font-size: var(--fs-small); color: var(--muted); margin-top: 2px; line-height: 1.35; overflow-wrap: anywhere; }
.mfa-factor__chev { flex: none; color: var(--muted); font-size: 18px; }
.mfa-factor--unavailable, .mfa-factor[aria-disabled="true"] { background: var(--surface-alt); border-style: dashed; }
.mfa-factor[aria-disabled="true"] { cursor: default; }
.mfa-factor[aria-disabled="true"]:hover { border-color: var(--border); }
.mfa-factor--unavailable .mfa-factor__icon { background: var(--surface-sunken); color: var(--muted); }
.mfa-factor--unavailable .mfa-factor__title { color: var(--muted-strong); }

.mfa-badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--info-border);
  background: var(--info-bg);
  color: var(--info-text);
  font-size: var(--fs-micro);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.mfa-badge--ok { background: var(--mfa-ok-bg); color: var(--mfa-ok-fg); border-color: var(--mfa-ok-bd); }
.mfa-badge--warn { background: var(--mfa-warn-bg); color: var(--mfa-warn-fg); border-color: var(--mfa-warn-bd); }
.mfa-badge--neutral { background: var(--surface-sunken); color: var(--muted-strong); border-color: var(--border); }

.mfa-links { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-2) var(--s-4); margin-top: var(--s-4); }
.mfa-links .link-back { margin-top: 0; }

/* ---- Э3: ожидание окна устройства ---- */
.mfa-waiting {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4);
  border: 1px solid var(--info-border);
  border-radius: var(--radius);
  background: var(--info-bg);
  color: var(--info-text);
  font-size: 14px;
}
.mfa-spinner {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 3px solid rgba(0, 113, 156, .2);
  border-top-color: var(--accent);
  animation: mfa-spin 1s linear infinite;
}
.mfa-passkey-btn .mfa-spinner { border-color: rgba(255, 255, 255, .35); border-top-color: #fff; }
@keyframes mfa-spin { to { transform: rotate(360deg); } }

/* ---- Э6: шаги онбординга ---- */
.mfa-steps { list-style: none; margin: 0 0 var(--s-5); padding: 0; display: flex; gap: var(--s-2); }
.mfa-steps li { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-micro); color: var(--muted); }
.mfa-steps li::before { content: ""; height: 4px; border-radius: 2px; background: var(--surface-sunken); }
.mfa-steps li.is-done { color: var(--mfa-ok-fg); }
.mfa-steps li.is-done::before { background: var(--mfa-ok-fg); }
.mfa-steps li.is-current { color: var(--text); font-weight: 600; }
.mfa-steps li.is-current::before { background: var(--accent); }

/* ---- Э9: объяснение, успех, совет ---- */
.mfa-hero {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--info-bg);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 0 var(--s-3);
}
.mfa-hero .mfa-ico { width: 34px; height: 34px; }
.mfa-hero--ok { background: var(--mfa-ok-bg); color: var(--mfa-ok-fg); }
.mfa-explain { list-style: none; margin: 0 0 var(--s-2); padding: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.mfa-explain li { display: flex; gap: var(--s-3); font-size: 14px; line-height: 1.4; }
.mfa-explain li .mfa-ico { color: var(--accent); margin-top: 1px; }
.mfa-tip {
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-alt);
  font-size: 14px;
}
.mfa-tip strong { display: block; margin-bottom: 2px; }

/* ---- Э10: подключение приложения ---- */
.mfa-apps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: var(--s-2); }
.mfa-app { display: flex; gap: var(--s-3); min-width: 0; padding: var(--s-3); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.mfa-app__logo {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 9px;
  border: 1px solid var(--border);
  background: var(--surface-sunken);
  color: var(--muted-strong);
  font-weight: 700;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mfa-app__body { min-width: 0; }
.mfa-app__name { font-weight: 600; font-size: 14px; line-height: 1.3; }
.mfa-store { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 3px; font-size: var(--fs-micro); }
.mfa-store a { display: inline-flex; align-items: center; min-height: 28px; text-decoration: none; white-space: nowrap; }
.mfa-store a:hover { text-decoration: underline; }
.mfa-setup { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: var(--s-5); margin-top: var(--s-4); }
.mfa-setup--stack { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
.mfa-setup-step { min-width: 0; }
.mfa-setup-step h3 { display: flex; gap: var(--s-2); align-items: center; }
.mfa-num {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.mfa-qr {
  width: var(--mfa-qr);
  height: var(--mfa-qr);
  padding: 10px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.mfa-qr img { display: block; width: 100%; height: 100%; }
.btn.mfa-otpauth { display: none; }
.mfa-secret { margin-top: var(--s-3); font-size: 14px; }
.mfa-secret summary { cursor: pointer; color: var(--accent); font-size: var(--fs-small); min-height: 32px; display: flex; align-items: center; }
.mfa-secret__value { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-top: var(--s-2); }
.mfa-secret__code {
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 1px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  overflow-wrap: anywhere;
}
.mfa-secret__value .btn { margin-top: 0; }
.mfa-secret dl { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; margin: var(--s-2) 0 0; font-size: var(--fs-small); color: var(--muted); }
.mfa-secret dd { margin: 0; color: var(--text); }
.mfa-setup .mfa-code { max-width: 240px; }
.mfa-setup .actions .btn { margin-top: 0; }

/* ---- Э7: «Безопасность» ---- */
.mfa-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--s-5); align-items: start; }
.mfa-section { padding: 0; overflow: hidden; margin-bottom: var(--s-4); }
.mfa-section__head { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-4); border-bottom: 1px solid var(--border); }
.mfa-section__head:last-child { border-bottom: 0; }
.mfa-section__text { flex: 1; min-width: 0; }
.mfa-section__head h3 { margin: 0; }
.mfa-section__head p { margin: 2px 0 0; font-size: var(--fs-small); color: var(--muted); overflow-wrap: anywhere; }
.mfa-section__head .btn { margin-left: auto; flex: none; }
.mfa-rows { list-style: none; margin: 0; padding: 0; }
.mfa-row-wrap { list-style: none; }
.mfa-row { display: flex; align-items: center; gap: var(--s-3); min-height: var(--tap); padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--border); }
.mfa-rows > li:last-child, .mfa-rows > li:last-child .mfa-row { border-bottom: 0; }
.mfa-row__main { flex: 1; min-width: 0; }
.mfa-row__name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-weight: 600; }
.mfa-row__title { overflow-wrap: anywhere; }
.mfa-row__meta { font-size: var(--fs-small); color: var(--muted); }
.mfa-row__actions { display: flex; flex: none; gap: var(--s-2); }
.mfa-row__actions .btn { padding: 6px 12px; }
.mfa-row input[type=text] { max-width: 320px; }
.mfa-empty { margin: 0; padding: var(--s-4); font-size: 14px; color: var(--muted); }
.mfa-inset { margin: 0 var(--s-4) var(--s-4); }
.btn.mfa-danger { background: transparent; color: var(--danger-text); border-color: var(--danger-border); }
.btn.mfa-danger:hover { background: var(--danger-bg); }
.btn.mfa-danger[aria-disabled="true"] { opacity: .6; cursor: default; }
.btn.mfa-danger-solid { background: var(--danger-text); color: #fff; }
.btn.mfa-danger-solid:hover { background: #7f1616; }
.mfa-warn {
  margin-top: var(--s-3);
  padding: 10px 12px;
  border: 1px solid var(--mfa-warn-bd);
  border-radius: var(--radius-sm);
  background: var(--mfa-warn-bg);
  color: var(--mfa-warn-fg);
  font-size: 14px;
}
.mfa-aside h3 { margin-bottom: var(--s-2); }
.mfa-aside ul { margin: 0; padding-left: 18px; font-size: 14px; }
.mfa-aside li + li { margin-top: 4px; }
/* Подключение ключа или приложения из «Безопасности». */
.mfa-flow { display: flex; flex-direction: column; margin-top: var(--s-3); }
.mfa-flow:not(:has(.mfa-setup)) { max-width: 560px; }
.mfa-flow > .btn, .mfa-flow .mfa-form > .btn { align-self: flex-start; margin-top: var(--s-4); }

/* Смена пароля (волна 8): блок «Пароль» в «Безопасности»/«Способах входа». */
.mfa-section__head:has(+ .mfa-pw[hidden]) { border-bottom: 0; }
.mfa-pw { padding: 0 var(--s-4) var(--s-4); }
.mfa-pw-form { max-width: 420px; }
.mfa-pw-hint { margin: 4px 0 0; font-size: var(--fs-small); color: var(--muted); }
.mfa-pw-show { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-2); }
/* Подпись — тач-цель флажка целиком (44px), а не 18px квадратик. */
.mfa-pw-show label { display: flex; align-items: center; min-height: var(--tap); margin: 0; font-weight: 400; font-size: 14px; cursor: pointer; }
.mfa-pw-show input[type=checkbox] { width: 18px; height: 18px; margin: 0; padding: 0; flex: none; accent-color: var(--accent); cursor: pointer; }
.mfa-pw-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-4); }

/* Ссылка «Безопасность» в тёмной шапке. */
.btn.mfa-sec-link { gap: 6px; }
.mfa-sec-link .mfa-ico { width: 18px; height: 18px; }
.btn.mfa-sec-link[aria-current="page"] { border-color: var(--brand); background: #1f242b; }

/* ---- Письма по заявкам (волна N1): блок под «Безопасностью» ----
   Ширина — как у левой колонки .mfa-grid (справа колонка 300px и зазор). */
@media (min-width: 768px) { .mail-prefs { max-width: calc(100% - 300px - var(--s-5)); } }
/* Телефон: колонка справа («Если потеряли телефон») встаёт над блоком — нужен зазор. */
@media (max-width: 767px) { .mail-prefs { margin-top: var(--s-4); } }
.mail-prefs__body { padding: var(--s-3) var(--s-4) var(--s-4); }
.mail-prefs__switch { display: inline-flex; align-items: center; gap: var(--s-3); min-height: var(--tap); margin: 0; font-weight: 600; cursor: pointer; position: relative; }
.mail-prefs__switch input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.mail-prefs__track { position: relative; flex: none; width: 44px; height: 26px; border-radius: 13px; background: var(--border); transition: background .15s; }
.mail-prefs__track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .15s; }
.mail-prefs__switch input:checked + .mail-prefs__track { background: var(--accent); }
.mail-prefs__switch input:checked + .mail-prefs__track::after { transform: translateX(18px); }
.mail-prefs__switch input:focus-visible + .mail-prefs__track { outline: 2px solid var(--accent); outline-offset: 2px; }
.mail-prefs__switch input:disabled + .mail-prefs__track { opacity: .6; }
.mail-prefs__state { margin: 4px 0 0; font-size: var(--fs-small); color: var(--muted); }
.mail-prefs .alert { margin-top: var(--s-3); }

/* ---- Э8: модалка подтверждения паролем и удаления ---- */
.mfa-dialog {
  width: calc(100% - 32px);
  max-width: 420px;
  padding: var(--s-5);
  border: 0;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-raised);
}
.mfa-dialog::backdrop { background: rgba(27, 36, 48, .42); }
.mfa-dialog h2 { margin-bottom: var(--s-2); }
.mfa-dialog p { margin: 0 0 var(--s-2); font-size: 14px; }
.mfa-dialog__actions { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-5); }

/* ---- Телефон ---- */
@media (max-width: 767px) {
  .mfa-links { flex-direction: column; align-items: stretch; }
  .mfa-setup { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .mfa-setup .mfa-code { max-width: none; }
  .mfa-setup .actions .btn { width: 100%; }
  .btn.mfa-otpauth { display: flex; width: 100%; margin-bottom: var(--s-3); }
  .mfa-grid { grid-template-columns: minmax(0, 1fr); }
  .mfa-section__head { flex-wrap: wrap; }
  .mfa-section__head .btn { width: 100%; margin-left: 0; }
  .mfa-row { flex-wrap: wrap; }
  .mfa-row__actions { width: 100%; }
  .mfa-row__actions .btn { flex: 1; }
  .mfa-row input[type=text] { max-width: none; }
  .mfa-flow > .btn, .mfa-flow .mfa-form > .btn { align-self: stretch; }
  .mfa-pw-form { max-width: none; }
  .mfa-pw-actions { flex-direction: column; }
  .mfa-pw-actions .btn { width: 100%; }
  .mfa-dialog { width: 100%; max-width: none; margin: auto 0 0; border-radius: var(--radius) var(--radius) 0 0; padding-bottom: calc(var(--s-5) + var(--safe-b)); }
  .mfa-dialog__actions { flex-direction: column-reverse; }
  .mfa-dialog__actions .btn { width: 100%; }
  /* Две кнопки в шапке: замок и «Выйти»; прижимает вправо только первая. */
  .mfa-sec-link__text { display: none; }
  .topbar-inner > .mfa-sec-link + .btn { margin-left: 0; }
}

@media (hover: none) and (pointer: coarse) {
  .mfa-store a, .mfa-secret summary { min-height: var(--tap); }
}

/* Файлы (волна F1) на тач-экране: «убрать» и ссылки на вложения — цели 44px. */
@media (hover: none) and (pointer: coarse) {
  .attach-remove { width: var(--tap); height: var(--tap); }
  .file-link { display: inline-flex; align-items: center; min-height: var(--tap); }
  .event-file { align-items: center; row-gap: 0; }
}

/* ============================================================
   Языки кабинета (RU / EN / 中文), решение заказчика 18.10.2026.
   Кнопки рисует /i18n/i18n.js (switcher): шапка кабинета и плашка экранов
   входа. Китайский — системные шрифты (CSP: внешних шрифтов нет).
   ============================================================ */
html:lang(zh-CN) {
  --font: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
          "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC",
          "Segoe UI", Roboto, Arial, sans-serif;
  /* Montserrat без иероглифов: латиница и цифры — им, иероглифы — системным. */
  --font-brand: "Montserrat", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
                "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC", -apple-system,
                BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

.lang-switch {
  display: inline-flex;
  flex: none;
  align-items: stretch;
  border: 1px solid var(--header-line);
  border-radius: 999px;
  overflow: hidden;
}
.lang-switch:empty { display: none; }
.lang-btn {
  appearance: none;
  margin: 0;
  border: 0;
  background: transparent;
  color: var(--header-muted);
  font: 600 12px/1 var(--font-brand);
  letter-spacing: .02em;
  padding: 7px 10px;
  min-height: 30px;
  cursor: pointer;
}
.lang-btn + .lang-btn { border-left: 1px solid var(--header-line); }
.lang-btn:hover { color: var(--header-fg); }
/* Выбранный язык: фирменный бирюзовый под тёмным текстом — 6.35:1. */
.lang-btn.is-active { background: var(--brand); color: #111; }
.lang-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

/* Плашка входа: переключатель в правом верхнем углу. На экране второго
   фактора скрыт: его карточку рисует mfa-ui.js, и смена языка посреди
   церемонии ключа оставила бы её на прежнем языке. */
.auth-brand { position: relative; }
.lang-switch--auth { position: absolute; top: 20px; right: 24px; }
body:has(#view-mfa:not([hidden])) .lang-switch--auth { display: none; }

@media (max-width: 767px) {
  .lang-switch--auth { top: calc(12px + var(--safe-t)); right: max(var(--pad-x), var(--safe-r)); }
  /* Шапка кабинета: в первой строке места нет (логотип, замок, «Выйти») —
     переключатель встаёт во вторую, белую строку справа от компании. */
  .topbar-who { flex: 1 1 55%; margin-right: 0; padding-right: var(--s-3); }
  .lang-switch--app {
    order: 3;
    align-self: stretch;
    margin: 0 calc(-1 * max(var(--pad-x), var(--safe-r))) 0 calc(-1 * var(--s-4));
    padding: var(--s-2) max(var(--pad-x), var(--safe-r)) var(--s-2) var(--s-2);
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface);
    align-items: center;
    gap: 0;
  }
  .lang-switch--app .lang-btn {
    color: var(--muted);
    border: 1px solid var(--border);
    min-height: 32px;
  }
  .lang-switch--app .lang-btn + .lang-btn { border-left: 0; }
  .lang-switch--app .lang-btn:first-child { border-radius: 999px 0 0 999px; }
  .lang-switch--app .lang-btn:last-child { border-radius: 0 999px 999px 0; }
  .lang-switch--app .lang-btn.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
}

@media (hover: none) and (pointer: coarse) {
  .lang-btn { min-height: var(--tap); min-width: var(--tap); }
  .lang-switch--app .lang-btn { min-height: var(--tap); }
}

/* Китайский: короткие метки (категория, приоритет, статус) не ломаются по
   одному иероглифу в столбик — переносы между иероглифами запрещены. */
html:lang(zh-CN) #list-table-wrap td.col-cat,
html:lang(zh-CN) #list-table-wrap td.col-pri,
html:lang(zh-CN) #list-table-wrap td.col-status .badge,
html:lang(zh-CN) .badge,
html:lang(zh-CN) .vis-status,
html:lang(zh-CN) .vis-unit,
html:lang(zh-CN) .mfa-badge,
html:lang(zh-CN) table.tickets th {
  word-break: keep-all;
  white-space: nowrap;
}
