/* Lingverra — только своё (шапка/язык/инпут). Стили секций (sec-*, security-card)
   приходят из форкнутого custom.css Auditary 1:1, здесь их НЕ переопределяем. */

/* ── Шрифт документа: Source Serif 4 — ТОТ ЖЕ, что в PDF для печати
   (templates/translate_pdf.html). Без этого @font-face браузер не находил
   'Source Serif 4' и подставлял Times New Roman → просмотр и PDF различались.
   Пути относительны к static/css/ (шрифты в static/fonts/). */
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4/regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4/italic.woff2') format('woff2');
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4/semibold.woff2') format('woff2');
  font-weight: 600 700; font-style: normal; font-display: swap;
}

/* ── Шапка: site-header стилизован в theme.css Auditary (градиент). Здесь только actions. ── */
/* Раскладка header__inner (раньше держалась на inline-style; вынесена сюда с семантическим
   селектором .site-header .header__inner — специфичность выше generic-правил, перебивавших
   вынесенный класс при удалении inline; desktop-значения 1:1 с исходным inline). */
.site-header .header__inner {
  display: flex; align-items: center; justify-content: space-between; padding: 10px 24px;
}
.tf-header-actions { display: flex; align-items: center; gap: 8px; }
.logo { color: #fff !important; }  /* лого не как синяя ссылка */
/* Брендовый SVG-логотип в шапке (фон шапки тёмно-синий в обеих темах → dark-вариант) */
.tf-logo { display: inline-flex; align-items: center; }
.tf-logo img { height: 64px; width: auto; display: block; }
.tf-logo .tf-logo-light { display: none; }
.tf-logo-mini { display: none; }             /* вузький варіант — лише ≤480 */
@media (max-width: 760px) { .tf-logo img { height: 48px; } }

.tf-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 10px;
  border: 1.5px solid var(--border-2, var(--border));
  background: transparent; color: var(--fg); cursor: pointer;
  text-decoration: none; font-size: 1.05rem; transition: background .15s;
}
.tf-icon-btn:hover { background: rgba(127,127,127,.12); }

.tf-lang { position: relative; }
.tf-lang-btn {
  display: flex; align-items: center; gap: 6px;
  height: 38px; box-sizing: border-box;
  padding: 0 10px; border-radius: 10px;
  border: 1.5px solid var(--border-2, var(--border));
  background: transparent; color: var(--fg); cursor: pointer;
}
.tf-lang-code { font-size: .72rem; font-weight: 700; letter-spacing: .05em; }
.tf-flag { border-radius: 3px; display: block; }
/* position:FIXED (не absolute): выносим меню из stacking-контекста sticky-шапки
   на root-уровень, иначе плавающее окно оригинала (fixed) перекрывало его несмотря
   на z-index. Координаты ставит JS по кнопке при открытии. */
.tf-lang-menu {
  display: none; position: fixed; z-index: 100001;
  background: #1a1d27;               /* тёмная тема по умолчанию */
  border: 1.5px solid var(--border-2, var(--border));
  border-radius: 14px; padding: 8px; min-width: 150px;
  grid-template-columns: 1fr 1fr; gap: 4px;
  box-shadow: 0 12px 32px rgba(0,0,0,.25);
}
html[data-theme="light"] .tf-lang-menu { background: #ffffff; border-color: #d9dee8; }
.tf-lang-menu.open { display: grid; }
.tf-lang-item {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 9px; border-radius: 8px; text-decoration: none;
  color: var(--fg); font-size: .72rem; font-weight: 700;
}
.tf-lang-item:hover { background: rgba(127,127,127,.12); }
.tf-lang-item.active { border: 1px solid var(--brand); color: var(--brand); }

/* Кнопки/язык в шапке поверх тёмного градиента site-header — светлые */
.site-header .tf-icon-btn,
.site-header .tf-lang-btn {
  color: #fff; border-color: rgba(255,255,255,.25);
}
.site-header .tf-icon-btn:hover,
.site-header .tf-lang-btn:hover,
.site-header .tf-dash-btn:hover { background: rgba(255,255,255,.16); }
.site-header .tf-lang-code { color: #fff; }

/* ── Шапка: как у Auditary — светло-синяя в светлой теме, тёмно-синяя в тёмной.
   Светлый тон #5a6bff→#4b59e6 взят из палитры Auditary (custom.css:75). ── */
html[data-theme="light"] .site-header {
  background: linear-gradient(180deg, #5a6bff 0%, #4b59e6 100%) !important;
  border-bottom: 1px solid rgba(255,255,255,.12) !important;
}
html[data-theme="dark"] .site-header,
.site-header {
  background: linear-gradient(180deg, #243060 0%, #1a2448 100%) !important;
  border-bottom: 1px solid #2d3148 !important;
}
/* Текст/кнопки в шапке всегда светлые (фон тёмный в обеих темах) */
.site-header .logo,
.site-header .tf-icon-btn,
.site-header .tf-lang-btn,
.site-header .tf-lang-code { color: #fff !important; }
.site-header .tf-icon-btn,
.site-header .tf-lang-btn { border-color: rgba(255,255,255,.25) !important; }

.tf-lang-item { color: var(--fg) !important; }
/* пока открыт дропдаун языка — прячем плавающее окно оригинала, чтобы оно
   гарантированно не перекрывало меню (подстраховка к z-index stacking). */
body.tf-langmenu-open .tf-split-source { display: none !important; }

/* Поля ввода (в духе дизайн-системы) */
.tf-input {
  padding: 7px 12px; border-radius: 10px;
  border: 1.5px solid var(--border-2, var(--border));
  background: var(--bg, transparent); color: var(--fg);
  font-size: .9rem; width: 100%; box-sizing: border-box;
}
.tf-input:focus { outline: none; border-color: var(--brand); }

/* Тёмная тема для полей ввода (Auditary profil-input не имеет dark-варианта —
   её профиль read-only. Паттерн взят из её dark inputs: #1e2540). */
html[data-theme="dark"] .profil-input,
html[data-theme="dark"] textarea.profil-input,
html[data-theme="dark"] .tf-input {
  background: #1e2540;
  border-color: rgba(255,255,255,.12);
  color: #e2e8f0;
}
html[data-theme="dark"] .profil-input::placeholder,
html[data-theme="dark"] .tf-input::placeholder { color: #7b86a8; }
html[data-theme="dark"] .profil-input:focus,
html[data-theme="dark"] .tf-input:focus {
  border-color: #6d63ff;
  box-shadow: 0 0 0 1px rgba(109,99,255,.4);
  background: #1e2540;
}

/* ── ФИКС тёмной темы: custom.css задаёт светлый --ui-bg в :root без dark-override,
   и он перебивает theme.css. tf.css подключён последним — восстанавливаем dark-токены. */
html[data-theme="dark"] {
  /* custom.css задаёт ВСЕ эти токены светлыми в :root БЕЗ dark-override и перебивает
     theme.css → в dark карточки/фоны белые, текст тёмный. tf.css последний в каскаде —
     восстанавливаем полный тёмный набор разом. */
  --bg:        #0f1117;
  --card:      #1a1d27;
  --surface:   #1e2130;
  --surface-2: #252838;
  --border:    #2d3148;
  --border-2:  #323654;
  --ui-bg:      #0f1117;
  --ui-surface: #1a1d27;
  --ui-text:    #e2e8f0;
  --ui-muted:   #94a3b8;
  --ui-border:  rgba(255,255,255,.07);
  --fg:      #e2e8f0;
  --fg-2:    #f1f5f9;
  --muted:   #94a3b8;
  --muted-2: #cbd5e1;
}
html[data-theme="dark"] body { background: #0f1117; color: #e2e8f0; }

/* ── Тёмная тема: текст профиля. profil.css хардкодит светлые цвета текста
   (#0f172a/#4b5563), dark-варианта в theme.css нет → текст невидим на тёмной
   карточке. Восстанавливаем светлый текст в dark. */
html[data-theme="dark"] .profil-hero-title,
html[data-theme="dark"] .profil-title,
html[data-theme="dark"] .profil-dl-row dt,
html[data-theme="dark"] .profil-field-label { color: #e2e8f0 !important; }

html[data-theme="dark"] .profil-text,
html[data-theme="dark"] .profil-hero-sub,
html[data-theme="dark"] .profil-dl-row dd,
html[data-theme="dark"] .profil-field-value { color: #b4bdd0 !important; }

html[data-theme="dark"] .profil-eyebrow { color: #8b95b0 !important; }
html[data-theme="dark"] .profil-placeholder { color: #6b7488 !important; }

/* и form-label (мои <label class="profil-field-label"> в форме) */
html[data-theme="dark"] label.profil-field-label { color: #e2e8f0 !important; }

/* ── Стилизованный выбор файла (нативный input file спрятан) ──────────────── */
.tf-file { display: inline-block; }
.tf-file input[type="file"] {
  position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden;
}
.tf-file-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  border: 1.5px solid var(--border-2, var(--border));
  background: transparent; color: var(--fg);
  font-size: .85rem; font-weight: 600; transition: background .15s, border-color .15s;
}
.tf-file:hover .tf-file-btn { border-color: var(--brand); color: var(--brand); }
/* «Попробовать на образце» (core.samples): строкой под выбором файла */
.tf-sample-line { margin: 8px 0 4px; font-size: .9rem; color: var(--fg-muted); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.tf-sample-btn { background: none; border: 0; padding: 2px 0; color: var(--brand); font: inherit; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.tf-sample-btn:hover { text-decoration: underline; }
.tf-sample-modal .ds-modal-body { max-height: calc(100vh - 140px); overflow-y: auto; }
.tf-sample-note { margin: 0 0 12px; color: var(--fg-muted); font-size: .9rem; }
.tf-sample-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.tf-sample-card { display: flex; flex-direction: column; gap: 8px; align-items: stretch; padding: 8px; border: 1px solid var(--border, rgba(127,127,127,.3)); border-radius: 10px; background: var(--card, transparent); color: var(--fg); font: inherit; font-size: .85rem; text-align: left; cursor: pointer; }
.tf-sample-card:hover, .tf-sample-card:focus-visible { border-color: var(--brand); }
.tf-sample-card img { width: 100%; height: 180px; object-fit: cover; object-position: top; border-radius: 6px; background: #fff; }
.tf-file-name {
  display: inline-block; margin-left: 8px; font-size: .82rem;
  color: var(--muted, #94a3b8); vertical-align: middle;
}

/* ── Фикс бага Auditary: QR-svg (segno scale=4) без max-width вылезает за карточку.
   Ограничиваем размер QR. */
/* QR должен быть на БЕЛОМ фоне (сканируемость + не тонуть на тёмной плашке),
   отцентрирован, фиксированный размер. */
.twofa-qr-inner {
  background: #fff !important;
  border-radius: 14px;
  display: grid !important;
  place-items: center !important;
  width: 214px !important;
  height: 214px !important;
  padding: 0 !important;
  box-sizing: border-box;
}
.twofa-qr-inner svg {
  width: 190px !important;
  height: 190px !important;
  display: block;
}

/* ── Hero-заголовки во всех standalone-карточках: явный цвет (наследуемый бывает
   тусклым на hero). Светлая тема — тёмный текст, тёмная — светлый. */
.twofa-title, .sec-title, .profil-hero-title { color: var(--fg, #0f172a); }
.twofa-sub, .sec-subtitle, .profil-hero-sub { color: var(--muted, #64748b); }
html[data-theme="dark"] .twofa-title,
html[data-theme="dark"] .sec-title,
html[data-theme="dark"] .profil-hero-title { color: #f1f5f9 !important; }
html[data-theme="dark"] .twofa-sub,
html[data-theme="dark"] .sec-subtitle,
html[data-theme="dark"] .profil-hero-sub { color: #b4bdd0 !important; }

/* Поле пароля с глазом — стили берутся из security.css/custom.css (идентичны Auditara),
   свой дубль убран: .auth-pass/.input-wrap/.pass-eye + pw-eye.js работают как у Auditary. */

/* ── Кнопка «Дашборд» в шапке (pill, светлая на тёмном градиенте) ── */
.tf-dash-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; box-sizing: border-box;
  padding: 0 14px; border-radius: 999px;
  border: 1.5px solid rgba(255,255,255,.25);
  background: rgba(255,255,255,.06); color: #fff !important;
  text-decoration: none; font-size: .85rem; font-weight: 600;
  transition: background .15s;
}
.tf-dash-btn:hover { background: rgba(255,255,255,.16); }
.tf-dash-btn i { font-size: 1rem; }
/* Реєстрація закрита: кнопка присутня в шапці, але вимкнена (не клікабельна) */
.tf-dash-btn--disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }
.tf-dash-btn--disabled:hover { background: rgba(255,255,255,.06); }

/* ── Грид для разметки Auditary (row/col). У TF нет полного Bootstrap.
   Колонку центрируем и ограничиваем шириной — надёжнее флекс-justify. */
.row { display: block; }
.row.justify-content-center { text-align: center; }
.row.justify-content-center > [class*="col-"] { display: inline-block; text-align: left; width: 100%; }
.col-12 { width: 100%; }
.col-xl-7, .col-lg-9 { width: 100%; max-width: 720px; margin: 0 auto; }

/* ── Пакеты пополнения баланса (плитки, не .btn — избегаем наезда строк) ── */
.tf-pack-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 10px; }
.tf-pack { margin: 0; }
.tf-pack-btn {
  width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 16px 12px;
  border: 1.5px solid var(--border-2, var(--border));
  border-radius: 14px; background: var(--surface, transparent);
  cursor: pointer; transition: border-color .15s, background .15s;
}
.tf-pack-btn:hover { border-color: var(--brand); background: rgba(127,127,127,.06); }
.tf-pack-pages { font-size: 1.05rem; font-weight: 700; color: var(--fg); line-height: 1.2; }
.tf-pack-total { font-size: 1rem; font-weight: 700; color: var(--brand); line-height: 1.2; }
.tf-pack-per   { font-size: .72rem; color: var(--muted); line-height: 1.2; }
/* Гривнёвый эквивалент — только украинская версия (см. inject_billing_ctx).
   Намеренно мельче и бледнее цены в евро: это справка, а не второй прайс —
   продаём и выставляем счета в евро. */
.tf-pack-uah   { font-size: .66rem; color: var(--muted); opacity: .75; line-height: 1.2; }
.tf-uah-note   { font-size: .7rem; color: var(--muted); opacity: .8; margin-top: 8px; }

/* Две мини-карточки в карточке баланса: куплено / пробные */
.tf-bal-split { display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  margin: 4px 0 12px; }
.tf-bal-mini { border: 1px solid var(--border, rgba(127,127,127,.18));
  border-radius: 12px; padding: 14px 12px; text-align: center;
  background: rgba(127,127,127,.04);
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; }
.tf-bal-mini-num { font-size: 1.5rem; font-weight: 800; color: var(--fg);
  line-height: 1.1; }
/* Подсветка обновлённого баланса. Число меняется САМО, после зачисления с
   банка, и без пометки это выглядит как глюк — человек не заметит, что именно
   обновилось (static/js/balance_watch.js). Держится 2 с и гаснет.
   prefers-reduced-motion уважаем: анимацию убираем, цвет оставляем. */
.tf-bal-updated { animation: tfBalPulse 2s ease-out; }
@keyframes tfBalPulse {
  0%   { color: var(--ok, #34d399); transform: scale(1.12); }
  30%  { color: var(--ok, #34d399); transform: scale(1); }
  100% { color: var(--fg); }
}
@media (prefers-reduced-motion: reduce) {
  .tf-bal-updated { animation: none; color: var(--ok, #34d399); }
}
.tf-bal-mini-num .bi-gift { color: var(--brand); font-size: 1rem;
  vertical-align: baseline; }
.tf-bal-mini-label { font-size: .74rem; color: var(--muted); margin-top: 8px;
  text-transform: uppercase; letter-spacing: .03em; }
.tf-bal-mini-note { font-size: .72rem; color: var(--muted); margin-top: 4px; }
.tf-bal-mini-note.tf-trial-used { opacity: .75; }
.tf-trial-lots { margin-top: 6px; display: flex; flex-direction: column; gap: 2px;
  width: 100%; }
.tf-trial-lot { display: flex; justify-content: center; gap: 6px;
  font-size: .72rem; color: var(--muted); }
.tf-trial-lot-n { font-weight: 700; color: var(--fg); }
/* Лот, до истечения которого осталось меньше LOT_EXPIRE_WARN_DAYS. Подсветка
   тихая: это не ошибка и не потеря — страницы ещё можно потратить, а деньги
   за них вернутся на карту. Красный цвет обещал бы беду, которой нет. */
.tf-lot-soon .tf-trial-lot-exp { color: var(--warn, #b26a00); font-weight: 600; }

/* Поля формы ручной правки баланса (admin) — не обрезать текст */
.tf-adjust-delta { width: 70px; }
.tf-adjust-target { width: auto; min-width: 130px; }
.tf-adjust-reason { min-width: 160px; flex: 1 1 160px; }

/* Правка страниц в конкретном оплаченном лоте (admin) */
.tf-lot-head { margin-top: 1rem; }
.tf-lot-empty { opacity: .7; font-size: .9em; }

/* Картка лоту: кожен лот — окрема рамка, щоб правка й повернення одного лоту
   не читались як дії над сусіднім. Шапка — що за лот; нижче рядки дій. */
.tf-lot-cards { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }
.tf-lot-card { border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface, transparent); padding: 12px 14px; }
.tf-lot-card-head { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline;
  padding-bottom: 8px; margin-bottom: 8px; border-bottom: 1px solid var(--border-2, var(--border));
  font-size: .92rem; }
.tf-lot-card-head > span:first-child { font-weight: 600; }
.tf-lot-card .tf-lot-row { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center;
  padding: 6px 0; }
.tf-lot-card .tf-lot-row + .tf-lot-row,
.tf-lot-card form.tf-lot-row + .tf-lot-row { border-top: 1px dashed var(--border-2, var(--border)); }
.tf-lot-row-label { min-width: 110px; font-size: .85rem; color: var(--muted); }
.tf-lot-note { font-size: .85rem; color: var(--muted); }
.tf-partial-preview { font-size: .85rem; color: var(--muted); }
.tf-lot-card form.tf-partial-form { display: flex; flex-wrap: wrap; gap: 6px 10px;
  align-items: center; flex: 1 1 auto; }
@media (max-width: 600px) {
  .tf-lot-card { padding: 10px; }
  .tf-lot-row-label { min-width: 100%; }
}
.tf-lot-label { font-size: .82rem; opacity: .85; min-width: 210px; }

/* Разбивка баланса под метрикой в детали юзера */
.sec-metric-sub { display: block; font-size: .72rem; color: var(--muted);
  margin-top: 3px; }

/* Трек «есть долг» + форма возврата (superadmin) */
.tf-hold-badge { margin: 8px 0 4px; font-size: .8rem; color: #92400e;
  background: #fef3c7; border-radius: 8px; padding: 6px 10px; display: inline-block; }
.tf-refund-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 8px; }
.tf-refund-close { font-size: .78rem; color: var(--muted); display: inline-flex;
  align-items: center; gap: 4px; }

/* Раскладка возврата в админ-детали (superadmin) */
.tf-refund-box { margin: 10px 0; padding: 10px 12px;
  border: 1px solid var(--border, rgba(127,127,127,.18)); border-radius: 10px;
  background: rgba(127,127,127,.04); }
.tf-refund-title { font-size: .8rem; font-weight: 700; margin-bottom: 6px;
  color: var(--fg); }
.tf-refund-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
.tf-refund-table th { text-align: right; color: var(--muted); font-weight: 600;
  padding: 2px 6px; }
.tf-refund-table th:first-child { text-align: left; }
.tf-refund-table td { text-align: right; padding: 2px 6px; }
.tf-refund-table td:first-child { text-align: left; }
.tf-refund-table tfoot td { border-top: 1px solid var(--border, rgba(127,127,127,.25));
  padding-top: 5px; }
.tf-refund-uncovered td { color: var(--muted); opacity: .8; }

/* ── Результат перевода: двухпанельный вид + confidence-подсветка ── */
.tf-result-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 900px) { .tf-result-grid { grid-template-columns: 1fr; } }
.tf-translation { line-height: 1.9; font-size: .95rem; color: var(--fg); }
/* Сегменты текут INLINE внутри параграфа/поля — иначе каждый сегмент (слово,
   цифра, low-вставка) встаёт на свою строку и текст рассыпается столбиком. */
.tf-seg { display: inline; }
/* Пустая ячейка ДОБАВЛЕННОЙ строки: у пустого inline-элемента высоты нет
   вовсе, и строка выходила полоской в пару пикселей — курсору некуда было
   встать (замечание 22.09.2026). Пробел в текст подставлять нельзя: он уехал
   бы в сохранённые данные и в готовый PDF. Поэтому высоту держит оформление,
   и только пока сегмент пуст. */
.tf-seg[contenteditable]:empty {
  display: inline-block; min-height: 1.2em; min-width: 2px;
}
.tf-seg--low {
  display: inline; background: rgba(217,119,6,.18); border-bottom: 2px solid #d97706;
  border-radius: 3px; padding: 0 2px; cursor: pointer; transition: background .12s;
}
.tf-seg--low:hover, .tf-seg--low:focus { background: rgba(217,119,6,.32); outline: none; }
/* Рукопис, прочитаний упевнено ("hand"): пунктир (підказка редактору) + курсив, як у PDF.
   У режимі «пометкою» (tf-hand--label) поза таблицями — пометка замість курсиву. */
.tf-seg--hand { text-decoration: underline dotted; text-decoration-color: #64748b; text-underline-offset: 3px; font-style: italic; }
.tf-hand--label .tf-seg--hand { font-style: normal; }
.tf-hand--label .tf-blk-table .tf-seg--hand { font-style: italic; }
.tf-doubts { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.tf-doubt {
  border: 1px solid var(--border); border-left: 3px solid #d97706;
  border-radius: 10px; padding: 10px 12px; background: var(--surface, transparent);
}
.tf-doubt-tgt { font-weight: 600; color: var(--fg); }
.tf-doubt-reason { font-size: .8rem; color: #d97706; margin-top: 3px; }
.tf-doubt-src { font-size: .8rem; color: var(--muted); margin-top: 3px; }
.tf-doubt-src code { background: rgba(127,127,127,.15); padding: 1px 5px; border-radius: 4px; }
.tf-doubt-alt { font-size: .8rem; color: var(--muted-2, var(--muted)); margin-top: 3px; }

/* ═══ Итоговый документ перевода (формат образца BDÜ/ISO 18587) ═══ */
/* ПАНЕЛЬ ЗАКРІПЛЮЄТЬСЯ, КОЛИ З НЕЮ ПРАЦЮЮТЬ. «Позначки» гортають виділені
   фрагменти й прокручують сторінку до кожного — а сама панель лишалася
   вгорі, і щоб перейти до наступної правки, треба було щоразу вертатися в
   шапку (зауваження 22.09.2026).

   Закріплюємо НЕ завжди, а від кліку по панелі: постійно прибита смуга
   з'їдала б висоту екрана в усіх, хто позначками не користується. Клік
   повз панель або Esc відпускає її.

   top рахує код (--tf-toolbar-top): висота шапки не стала — вона інша на
   телефоні й змінюється від довжини меню. Фон непрозорий: крізь панель
   просвічував би документ, що повзе під нею. */
.tf-result-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 10px; background: var(--surface,transparent); border: 1px solid var(--border);
  border-radius: 10px; margin-bottom: 10px;
}
/* Група дій переноситься разом із панеллю: без цього на ширині до ~760 px
   «Зберегти/Завантажити/Друк/Word/…» йшли за край і обрізались
   (overflow:hidden у .tf-collapsible), 20.10.2026. */
.tf-result-toolbar > .s-5b2be1db { flex-wrap: wrap; min-width: 0; }
/* Подвійний клас, бо .tf-collapsible нижче оголошує position:relative з
   такою самою силою й перебивав закріплення (замір 22.09.2026: position
   лишався relative, панель їхала зі сторінкою). */
.tf-toolbar-pinned.tf-toolbar-pinned {
  position: fixed; left: 0; right: 0; z-index: 99997;
  top: var(--tf-toolbar-top, 0px);
  padding: 0 16px;
  margin-bottom: 0;
}
.tf-toolbar-pinned > .tf-result-toolbar {
  max-width: 1180px; margin: 0 auto 10px;
  background: var(--surface, #fff);
  box-shadow: 0 2px 10px rgba(2, 6, 23, .14);
}
/* Місце, яке панель звільнила, лишається за нею: без розпірки документ
   стрибнув би вгору рівно в мить закріплення. */
.tf-toolbar-spacer { display: block; }
/* Хрестик — лише в закріпленому стані: у шапці, на своєму місці, панель
   нікуди повертати. Клік повз неї працює й так, але здогадатися про це
   нізвідки. */
.tf-toolbar-unpin { display: none; }
/* Праворуч і абсолютно: кнопка лежить не у flex-смузі, а поруч із ручкою
   згортання, тому margin-left:auto її туди не посуває (замір 22.09.2026 —
   хрестик опинявся зліва). Місце праворуч у панелі вже зарезервовано:
   .tf-collapsible має padding-right під ручку. */
.tf-toolbar-pinned .tf-toolbar-unpin {
  display: inline-flex; align-items: center; justify-content: center;
  /* Праворуч у самій смузі. Спершу кнопка стояла в обгортці й позиціювалася
     абсолютно — але в закріпленому стані обгортка розтягнута на все вікно,
     а смуга 1180px по центру, тож хрестик опинявся за краєм видимої панелі
     (скріншот 22.09.2026). Ще раніше він перекривався ручкою згортання. */
  margin-left: auto; z-index: 5;
  width: 30px; height: 30px; flex: 0 0 30px; font-size: .9rem;
  width: 28px; height: 28px; padding: 0;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface, #fff); color: var(--fg-muted, #64748b);
  cursor: pointer;
}
.tf-toolbar-pinned .tf-toolbar-unpin:hover {
  background: rgba(127,127,127,.12); color: inherit;
}
/* Смуга вкладок прокручується: без цього на телефоні (360px) вона не
   вміщалася й тягнула вбік УСЮ сторінку, а не себе. Знайдено
   19.09.2026 на секції «Фінанси», перевірено заміром по всіх стрічках. */
.tf-mode-tabs { display: flex; gap: 4px; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
.tf-mode-tabs > * { flex: 0 0 auto; }
/* разделитель между группами «режимы | инструменты» */
.s-5b2be1db::before {
  content: ''; align-self: stretch; width: 1px; margin: 2px 4px 2px 0;
  background: var(--border);
}
.tf-mode-tab {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px; border-radius: 999px; border: 1.5px solid var(--border);
  background: transparent; color: var(--fg); cursor: pointer; font-size: .82rem; font-weight: 600;
}
/* компактнее кнопки-инструменты в тулбаре */
.tf-result-toolbar .btn-sm {
  padding: 5px 10px; font-size: .82rem;
}
.tf-mode-tab.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }
.tf-low-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  background: #d97706; color: #fff; border-radius: 999px; font-size: .72rem; font-weight: 700;
}

/* ── Поиск по переводу и обход мест «на проверку» ──────────────────────────
   Строка поиска свёрнута до иконки, пока ею не пользуются: тулбар и без того
   плотный. Раскрывается по Ctrl+F или по клику на поле. */
.tf-find {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1.5px solid var(--border); border-radius: 999px; padding: 2px 4px 2px 9px;
}
.tf-find-ico { font-size: .82rem; opacity: .65; }
.tf-find-input {
  width: 96px; border: 0; background: transparent; color: var(--fg);
  font-size: .82rem; padding: 3px 4px; outline: none;
  transition: width .15s ease;
}
.tf-find.is-open .tf-find-input { width: 190px; }
.tf-find-input::-webkit-search-cancel-button { display: none; }
.tf-find-count {
  font-size: .72rem; opacity: .7; min-width: 30px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.tf-find-count.tf-find-none { color: #dc2626; opacity: 1; }
.tf-find-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
  border: 0; border-radius: 50%; background: transparent;
  color: var(--fg); opacity: .7; cursor: pointer; font-size: .72rem;
}
.tf-find-btn:hover { opacity: 1; background: var(--border); }
.tf-markjump {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1.5px solid #d97706; border-radius: 999px; padding: 2px 4px 2px 9px;
}
.tf-markjump-lbl { font-size: .72rem; font-weight: 600; color: #d97706; }

/* Подсветка найденного. CSS Custom Highlight API красит ПОВЕРХ текста и не
   трогает DOM — важно, потому что сегменты contenteditable: вставленный <mark>
   попал бы в сохраняемый перевод. */
::highlight(tf-find) { background: #fde68a; color: #0f172a; }
::highlight(tf-find-one) { background: #f59e0b; color: #0f172a; }

/* Вспышка при прыжке к метке — чтобы глаз поймал, куда переместились. */
@keyframes tf-seg-flash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217,119,6,0); }
  30%      { box-shadow: 0 0 0 4px rgba(217,119,6,.55); }
}
.tf-seg-flash { animation: tf-seg-flash 1.1s ease-out; border-radius: 3px; }
@media (prefers-reduced-motion: reduce) {
  .tf-seg-flash { animation: none; box-shadow: 0 0 0 3px rgba(217,119,6,.55); }
}

/* Документ — лист A4 на белом, классический присяжный перевод, serif */
.tf-doc {
  background: #ffffff; color: #0f172a;
  border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,.10);
  padding: 0; overflow: hidden;
  font-family: 'Source Serif 4', 'Times New Roman', Times, serif;
  font-feature-settings: 'liga' 1, 'kern' 1;
}
html[data-theme="dark"] .tf-doc { background: #ffffff; color: #0f172a; }

.tf-doc-header {
  border-bottom: 1px solid #0f172a; padding: 18px 56px 12px;
  font-style: italic; font-size: 1.0rem; color: #1e293b; text-align: center;
  letter-spacing: .01em;
}
/* ТІЛО ДОКУМЕНТА = ДРУКОВАНИЙ АРКУШ, ЗБІЛЬШЕНИЙ ЦІЛКОМ.

   Перекладач тягне межу графи, дивлячись на екран, — і те, що він бачить,
   має надрукуватися. Доти екран показував таблицю на всю ширину вікна
   (до 1180px), а текстовий блок A4 — це 170мм ≈ 643px: та сама частка
   давала на екрані майже вдвічі більше місця. Підпис ставав у рядок «із
   запасом», а в PDF рубився, і врахувати це людина не могла — вона бачила
   запас, якого в друку немає (зауваження 22.09.2026).

   Тому аркуш на екрані має РЕАЛЬНУ геометрію A4 і збільшується ЦІЛКОМ,
   разом із полями та кеглем, як зум сторінки: пропорції лишаються
   друкованими, а читати не дрібніше, ніж раніше.

   794px = 210мм при 96dpi (вся A4), 76px = поля по 20мм з шаблону PDF.
   Всередині лишається 643px тексту — рівно стільки, скільки в друку.
   Множник рахує JS (applyZoom): CSS ширини вікна не знає. */
.tf-doc-body {
  width: 794px; padding: 28px 76px; margin: 0 auto;
  line-height: 1.6; font-size: 1.02rem;
  box-sizing: border-box;
  transform: scale(var(--tf-zoom, 1));
  transform-origin: top center;
}
/* Збільшений аркуш займає більше місця, ніж його «справжні» 794px, а scale
   потоку не змінює — висоту обгортці дораховує той самий JS, інакше внизу
   лишиться порожнеча, а сусідні блоки наїдуть. */
.tf-doc-body-wrap { overflow: hidden; }
/* Вузький екран: аркуш зменшено до ширини вікна (applyZoom). Його
   «справжня» ширина 794/1123px лишається в потоці — від лівого краю, без
   центрування, інакше після scale він зсувався б вправо. Обгортка не
   обрізає: якщо щось усе ж ширше, лист прокручується вбік. */
.tf-doc-body--fit { transform-origin: top left; margin: 0; }
.tf-doc-body-wrap:has(> .tf-doc-body--fit) { overflow-x: auto; overflow-y: hidden; }
/* Альбомний блок (у PDF — аркуш A4 landscape) і на екрані — на альбомній ширині
   листа: 1123px = A4 landscape у тих самих px, що 794 для портрета. Портретні
   блоки лишаються в колонці 642px (794 − поля), як у PDF; на вузькому екрані
   лист прокручується вбок (11.10.2026: 18 граф щеплень не влазили в 794). */
.tf-doc-body--landscape { width: 1123px; }
.tf-doc-body--landscape > :not(.tf-landscape):not(.tf-sec-full),
.tf-doc-body--landscape .tf-sec-full > :not(.tf-landscape) { max-width: 642px; margin-left: auto; margin-right: auto; }
.tf-doc-body-wrap:has(.tf-doc-body--landscape) { overflow-x: auto; overflow-y: hidden; }

/* Секции вёрстки: воспроизводят зонирование оригинала (рекомендация владельца —
   «зоны + колонки»). full-width идёт обычным потоком; columns = двухколоночный
   разворот книжечки/сертификата (левая страница | правая страница). */
.tf-sec-full { margin: 0; }
/* min-width колонки НЕ 0: иначе flex ужимает её в «ниточку» и текст ломается по
   ОДНОЙ БУКВЕ вертикальным столбиком. ~220px — читаемый минимум; если оба столбца
   не влезают, flex-wrap переносит их друг под друга (не режет буквы). */
.tf-sec-columns { display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-start; margin: 10px 0; }
.tf-sec-col { flex: 1 1 260px; min-width: 220px; }
.tf-sec-col + .tf-sec-col { border-left: 1px solid #e2e8f0; padding-left: 32px; }
/* В двухколоночном развороте колонка узкая: длинные значения полей (адрес ЗАГСа,
   полное наименование органа) при горизонтальной раскладке label|value ломались
   по одной БУКВЕ. В колонках кладём поле вертикально — label сверху, value снизу
   на всю ширину колонки. */
.tf-sec-col .tf-blk-field { flex-direction: column; align-items: stretch; gap: 2px; }
.tf-sec-col .tf-blk-field-label { min-width: 0; }
/* break-word (не anywhere): переносит по СЛОВАМ, а сверхдлинное слово рвёт лишь
   когда оно само шире строки — НЕ дробит каждое слово по буквам.
   flex: 0 0 auto — КРИТИЧНО: в колонке блок flex-direction:column, и базовый
   flex-grow:1 (для горизонтальной раскладки label|value) растягивал value по
   ВЫСОТЕ на всю высоту блока → огромные пустоты под коротким значением. В колонке
   value должен занимать высоту своего текста, не тянуться. */
.tf-sec-col .tf-blk-field-value {
  word-break: normal; overflow-wrap: break-word;
  flex: 0 0 auto;
}
/* на узком экране разворот складываем в одну колонку — иначе текст не читается */
@media (max-width: 760px) {
  .tf-sec-columns { display: block; }
  .tf-sec-col + .tf-sec-col { border-left: 0; padding-left: 0; margin-top: 10px; }
}

.tf-blk-heading { font-size: 1.15rem; font-weight: 700; margin: 16px 0 8px; color: #0f172a; }
.tf-blk-paragraph { margin: 6px 0; }
/* flex-wrap: при ОЧЕНЬ длинном многоязычном label (напр. «Paspoortnummer... /
   Passport no. / Numéro du passeport...») он занимает всю строку, а value
   переносится ПОД него на всю ширину — вместо того чтобы схлопнуться в 1px и
   ломаться по буквам вертикальным столбиком. */
.tf-blk-field {
  display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: baseline; margin: 4px 0;
}
.tf-blk-field-label {
  font-weight: 700; color: #0f172a;
  flex: 0 1 auto; max-width: 100%; overflow-wrap: break-word;
}
/* value держит читаемый минимум (≈220px); если и label, и value вместе не
   влезают в строку — flex-wrap уводит value на новую строку целиком. */
.tf-blk-field-value {
  flex: 1 1 220px; min-width: 200px;
  border-bottom: 1px solid #0f172a; padding-bottom: 1px;
  font-style: italic; overflow-wrap: break-word; word-break: normal;
}
/* Поле-форма с НЕСКОЛЬКИМИ подполями или длинной многоязычной меткой:
   НЕ раскладывать флексом в 2 колонки (в оригинале их нет — иначе слева зияет
   пустота). Метка сверху, подполя вертикальным списком в полную ширину. */
.tf-blk-field.tf-blk-field-block { display: block; }
.tf-blk-field-block .tf-blk-field-label { display: block; max-width: 100%; margin-bottom: 3px; }
.tf-blk-field-block .tf-blk-field-value { display: block; border-bottom: none; min-width: 0; }
.tf-blk-field-block .tf-subfield {
  display: block; border-bottom: 1px solid #0f172a; padding: 1px 0;
}

/* Обычная таблица — на всю ширину листа, table-layout:fixed вписывает колонки. */
.tf-blk-table {
  width: 100%; table-layout: fixed;
  border-collapse: collapse; margin: 10px 0; font-size: 12px;  /* = 9pt PDF: та сама колонка 642px — ті самі переноси */
}
.tf-blk-table td {
  border: 1px solid #0f172a; padding: 5px 7px; vertical-align: top;
  overflow-wrap: break-word; word-break: break-word;
}
.tf-blk-table tr:first-child td { font-weight: 600; background: #f8fafc; }
/* Бланк «мітка | значення» без друкованої шапки (header_rows: 0): перший рядок — дані. */
.tf-blk-table--nohead tr:first-child td { font-weight: inherit; background: none; }
.tf-split-note { color: #b45309; }

/* ── Широкая таблица (>6 колонок) = как в PDF (альбомная прививочная карта) ────
   Узкие «галочные» колонки (b.col_narrow) сужаем, их заголовки пишем ВЕРТИКАЛЬНО
   (writing-mode на экране браузер поддерживает — в отличие от WeasyPrint, где мы
   крутим transform'ом). Так все 16 колонок влезают в ширину листа и читаются,
   как в PDF. */
.tf-blk-table--wide { font-size: 11.33px; }  /* = 8.5pt альбому PDF */
/* УЗКАЯ КОЛОНКА — НЕ ТОЛЬКО В ШИРОКИХ ТАБЛИЦАХ. Правило стояло внутри
   .tf-blk-table--wide, то есть работало от семи колонок. В трудовой книжке
   после пересборки таблица шестиколоночная, класс не ставился, и день/месяц/
   год занимали ту же ширину, что графа со сведениями — при том, что col_narrow
   считался верно и в данные попадал (замер 15.09.2026). */
/* Узкая графа — ровно под ЧЕТЫРЁХЗНАЧНЫЙ год: при 34px «1999» ломалось на
   «199 / 9» (замечено юзером 15.09.2026). Ширина считана от содержимого, а не
   подобрана на глаз: 4 знака табличных цифр 15px ≈ 36px плюс отступы и рамка.
   white-space: nowrap — страховка, чтобы перенос был виден как выход за край,
   а не тихо разваливал строку на две. */
/* Узкая графа — под четырёхзначный год. БЕЗ nowrap: он тут стоял полчаса и
   выпускал длинный текст ЗА ячейку — если в узкую графу попало «Mitglied in
   80 Pos. leit. TschM 1993-1999» (а попадает: сетка иногда съезжает), запрет
   переноса рисовал его поверх соседних колонок (замер 15.09.2026).
   Год не ломается и без nowrap: 48px хватает на четыре знака, а перенос
   остаётся страховкой на случай, когда содержимое оказалось шире ожидаемого. */
.tf-blk-table td.tf-td-narrow {
  width: 48px; text-align: center; padding: 4px 3px;
  font-variant-numeric: tabular-nums;
}
/* Когда ширины заданы через <colgroup> (разметка модели или рука
   переводчика), фиксированные 48px их перебивают — снимаем. Выравнивание по
   центру и табличные цифры остаются: они про содержимое, не про ширину. */

.tf-blk-table--wide td.tf-td-narrow {
  width: 44px; text-align: center; padding: 4px 3px;
  font-variant-numeric: tabular-nums;
}
/* Ширины заданы через <colgroup> — фиксированные 48/44px их перебивают.
   Правило стоит ПОСЛЕ обоих и включает --wide в селектор: иначе то, что идёт
   ниже и той же силы, снова возьмёт верх (замер 15.09.2026: граница не
   тянулась, ширина держалась на 44px). */
.tf-blk-table--cols td.tf-td-narrow,
.tf-blk-table--wide.tf-blk-table--cols td.tf-td-narrow { width: auto; }
/* УЗКАЯ ГРАФА С ДЛИННОЙ ПОДПИСЬЮ: «Stundenzahl» над «120». По данным она
   узкая, но в 48px не влезает заголовок — раньше код разворачивал подпись
   вертикально, и поворот растягивал строку по высоте, утаскивая соседние
   ячейки (замечание 20.09.2026).

   ШИРИНА КОНКРЕТНАЯ, А НЕ width:1%. Таблица идёт с table-layout:fixed (см.
   .tf-blk-table выше), и «1%» там означает буквально один процент, а остаток
   браузер раздаёт поровну: графа получала 337px наравне с текстовыми
   (замер 20.09.2026). 96px — это «Stundenzahl» шрифтом .82rem плюс поля;
   подписи длиннее ужимает nowrap с overflow, а не растягивают таблицу.

   nowrap стоит на ВСЕЙ графе, а не только на шапке: выбрать строки шапки в
   CSS нечем (их число живёт в data-header-rows), а данные здесь заведомо
   короткие — переносить в них нечего. */
.tf-blk-table td.tf-td-narrow-cap {
  width: 96px; white-space: nowrap; overflow: hidden;
  text-align: center; padding: 4px 6px;
  font-variant-numeric: tabular-nums;
}
/* ПОВЁРНУТАЯ ПОДПИСЬ — ПО КЛАССУ, А НЕ ПО ШИРИНЕ ТАБЛИЦЫ. Раньше правило
   висело на .tf-blk-table--wide (от семи граф), и в шестиколоночной таблице
   «Datum» ломался на «Dat / um». Теперь класс ставит код там, где подпись
   не влезает в свою графу (см. _mark_vertical_heads). */
/* ВЫСОТА — ПО ДЛИНЕ ПОДПИСИ, А НЕ 190px НА ВСЕХ. Прежние 190px рассчитаны на
   прививочную карту («Менінгококова інфекція» в две строки). Для «Monat» и
   «Tag» нужно 28 и 17 пикселей, а строка раздувалась на все 190 — таблица
   уходила в пустые поля на пол-экрана (замечание юзера 15.09.2026).
   Высоту задаёт код через --vh (см. _mark_vertical_heads), 190px остаётся
   потолком для длинных подписей. */
/* ПОВОРОТ НА САМОЙ ЯЧЕЙКЕ — через writing-mode, а не transform на обёртке.
   Обёртка <span class="tf-vhead"> сидела ВОКРУГ редактируемого сегмента, и
   переводчик, стирая значение, стирал её вместе с текстом: правка вставала
   горизонтально и ломала вёрстку (замечание юзера 15.09.2026). writing-mode
   живёт на ячейке, ввод его не трогает.
   sideways-lr даёт чтение снизу вверх — как в бумажном бланке; браузеры без
   его поддержки берут vertical-rl из строки ниже. */
.tf-blk-table td.tf-td-vhead {
  padding: 4px 2px;
  --vh: 64px; height: var(--vh);
  /* Запасной вариант для браузеров без sideways-lr: vertical-rl читается
     сверху вниз (голову наклонять ВПРАВО). Без rotate — вместе они давали
     двойной поворот, и подпись вставала вверх ногами. */
  writing-mode: vertical-rl;
  text-align: left; vertical-align: bottom;
  font-weight: 600; font-size: .7rem; line-height: 1.1;
  white-space: nowrap; overflow: hidden;
}
/* Где поддерживается — читаем СНИЗУ ВВЕРХ, как в бумажном бланке
   (голову наклонять ВЛЕВО). */
@supports (writing-mode: sideways-lr) {
  .tf-blk-table td.tf-td-vhead { writing-mode: sideways-lr; text-align: right; }
}
/* Три ступени высоты: короткое слово («Tag», «Monat»), обычная подпись,
   подпись в две строки («Менінгококова інфекція»). Класс ставит код —
   inline-стили в шаблонах запрещены (строгий CSP). */
.tf-blk-table--vh-s td.tf-td-vhead { --vh: 52px; }
.tf-blk-table--vh-m td.tf-td-vhead { --vh: 104px; }
.tf-blk-table--vh-l td.tf-td-vhead { --vh: 190px; }
.tf-blk-table--vh-xl td.tf-td-vhead { --vh: 260px; }
.tf-blk-table--vh-xxl td.tf-td-vhead { --vh: 340px; }   /* 40+ знаків */
/* Прививочная карта шла отдельным путём — через обёртку с transform. Обёртки
   больше нет, поворот один на всех (.tf-td-vhead), графы ей размечает тот же
   код. Осталась только высота: её подписи длинные. */
.tf-blk-table--wide:not(.tf-blk-table--vh-xl):not(.tf-blk-table--vh-xxl) td.tf-td-vhead { --vh: 190px; }
/* Прежняя обёртка .tf-vhead с transform убрана: поворот теперь на самой
   ячейке (см. .tf-td-vhead выше), и правка текста его не ломает. Широкая
   прививочная карта идёт тем же путём — код помечает ей графы так же. */

.tf-blk-stamp {
  display: inline-block; max-width: 75%;
  border: 1.5px solid #1e3a8a; color: #1e3a8a;
  padding: 6px 12px; border-radius: 6px; margin: 8px 0; font-size: .92rem; background: #eef2ff;
}
.tf-blk-stamp i { margin-right: 6px; }
.tf-blk-stamp-text { margin: 8px 0; }
.tf-blk-signature { font-style: italic; color: #1e293b; margin: 4px 0; }
.tf-blk-note { font-size: .82rem; color: #475569; font-style: italic; margin: 6px 0; padding-left: 8px; border-left: 2px solid #cbd5e1; }

.tf-doc-footnotes {
  padding: 0 44px 12px; font-size: .78rem; color: #475569;
}
.tf-doc-footnotes hr { border: none; border-top: 1px solid #0f172a; margin: 12px 0 8px; width: 30%; }

.tf-doc-cert { padding: 22px 56px 36px; border-top: 1px solid #cbd5e1; margin-top: 20px; }
.tf-cert-formula { font-size: .98rem; color: #0f172a; margin: 0 0 8px; line-height: 1.55; }

/* Предпросмотр заверения на форме перевода: что будет написано под подписью
   и печатью. Свёрнут по умолчанию — форма не должна расти, — но доступен до
   запуска, когда ещё можно поправить текст в профиле. */
.tf-cert-preview { margin: 10px 0 0; padding: 0; border: 1px solid var(--border, #e2e8f0);
  border-radius: 8px; background: var(--surface, #f8fafc); }
.tf-cert-preview > summary { padding: 8px 12px; cursor: pointer; font-size: .82rem;
  font-weight: 600; color: var(--fg, #1e293b); list-style: revert; }
.tf-cert-preview[open] > summary { border-bottom: 1px solid var(--border, #e2e8f0); }
.tf-cert-preview-text { margin: 0; padding: 10px 12px 4px; font-size: .84rem;
  line-height: 1.5; color: var(--fg, #1e293b); white-space: pre-wrap; }
.tf-cert-preview-note { margin: 0; padding: 0 12px 10px; font-size: .74rem;
  color: var(--muted, #64748b); }
.tf-cert-preview-text:empty, .tf-cert-preview-note:empty { display: none; }
.tf-cert-date { font-size: .96rem; color: #0f172a; margin: 0 0 22px; }
.tf-cert-translator { display: flex; gap: 40px; align-items: flex-end; flex-wrap: wrap; }
/* Плейсхолдеры под ЖИВУЮ печать и ЖИВУЮ подпись — место, не картинка. */
.tf-cert-placeholders { display: flex; gap: 36px; align-items: flex-end; }
.tf-cert-ph {
  width: 150px; height: 110px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed #94a3b8; color: #94a3b8; font-size: .82rem; font-style: italic;
  border-radius: 6px; background: #fff;
}
.tf-cert-ph--stamp { width: 140px; height: 140px; border-radius: 50%; }
.tf-cert-ph--sig { width: 200px; height: 70px; border-radius: 4px; border-top: 1px solid #0f172a; border-left: none; border-right: none; border-bottom: none; }
.tf-cert-translator-info { font-size: .94rem; color: #0f172a; line-height: 1.45; }
.tf-cert-muted { color: #475569; font-size: .86rem; }

/* Редактируемые сегменты — еле заметный hover, чтобы было видно что можно править */
.tf-doc .tf-seg { outline: none; }
.tf-doc .tf-seg:focus { background: rgba(99,102,241,.10); border-radius: 3px; }
.tf-doc .tf-meta-edit[contenteditable]:focus { background: rgba(99,102,241,.10); border-radius: 3px; outline: none; }
.tf-doc .tf-seg--low {
  background: rgba(217,119,6,.18); border-bottom: 2px solid #d97706;
  border-radius: 3px; padding: 0 2px; cursor: context-menu;
}
.tf-doc .tf-seg--low:hover { background: rgba(217,119,6,.30); box-shadow: 0 0 0 1px #d97706; }
.tf-doc .tf-seg--low:focus { background: rgba(217,119,6,.32); }

/* Рукописное поле: не угадываем текст — метка «впишіть вручну».
   Когда пусто, показываем placeholder + (если есть) подсказку-оригинал. */
.tf-doc .tf-seg--hw {
  display: inline-block; min-width: 90px;
  border: 1px dashed #2563eb; border-radius: 4px;
  padding: 1px 8px; background: rgba(37,99,235,.07);
  color: #1e3a8a; font-style: italic;
}
.tf-doc .tf-seg--hw:empty::before {
  content: '✍ ' attr(data-placeholder);
  color: #2563eb; opacity: .8;
}
.tf-doc .tf-seg--hw[data-src]:empty::after {
  content: ' (' attr(data-src) ')';
  color: #64748b; font-size: .82em;
}
.tf-doc .tf-seg--hw:focus { background: rgba(37,99,235,.14); font-style: normal; }
/* В печати незаполненные рукописные поля видны как место, не как наш текст */
@media print {
  .tf-doc .tf-seg--hw { border-color: #94a3b8; }
}

/* Печать страницы — только сам документ */
@media print {
  .tf-result-toolbar, .site-header, .lf, #tfModeReview { display: none !important; }
  .tf-doc { box-shadow: none; border-radius: 0; }
}

/* ── Режим сравнения «оригінал ↔ переклад» ── */
/* align-items:flex-start (НЕ stretch): иначе флекс растягивает панель оригинала
   по высоте перевода, и position:sticky внутри неё не работает (нечему прилипать).
   flex-start → панель своей высоты (80vh) + sticky держит её в поле зрения при
   скролле длинного перевода. */
/* Горизонтальный скролл на мобиле + sticky-панели.
   Раньше тут стоял html{overflow-x:visible !important} (против расширений, что
   ставят hidden и ломают sticky). НО visible позволял странице ехать вбок при
   любом выпирающем элементе, а body{overflow-x:clip} это НЕ чинило: при html
   visible переполнение body не обрезается на уровне вьюпорта.
   Решение: overflow-x:CLIP на html И body. clip (в отличие от hidden/auto/scroll)
   НЕ создаёт скролл-контейнер → position:sticky продолжает работать против
   вьюпорта, расширения с hidden тоже не ломают sticky (clip их перебивает),
   и страница физически не может ехать вбок. */
html { overflow-x: clip !important; }
html, body { max-width: 100%; }
body { overflow-x: clip; }
/* Раскладка сравнения: ПЕРЕВОД на ВСЮ ширину (штатная вёрстка = как в одиночном
   режиме и PDF), а ОРИГИНАЛ — ПЛАВАЮЩЕЕ окно поверх (position:fixed): таскается за
   шапку, ресайзится за угол, сворачивается. Так переводчик сверяет строку с
   оригиналом БЕЗ прокрутки туда-сюда и без ужимания перевода. Раньше панели были
   рядом (50/50) — перевод получал половину и ломался; «рядом» не используем. */
.tf-split { display: block; }
.tf-split-target { width: 100%; }
.tf-compare #tfResultSection,
#tfResultSection.tf-compare { max-width: 100% !important; }

.tf-split-source {
  display: none;                     /* показывается JS-ом в режиме compare */
  /* Выше закреплённой панели кнопок (99997): иначе окно открывалось под ней
     (03.10.2026). Ниже шапки (99999); меню языка и так прячет окно
     (body.tf-langmenu-open). */
  position: fixed; z-index: 99998;
  top: 90px; right: 24px;
  width: 420px; height: 60vh;
  min-width: 240px; min-height: 180px;
  flex-direction: column; overflow: hidden;
  background: #525659; border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.45); border: 1px solid rgba(255,255,255,.12);
}
.tf-split-source.tf-src-open { display: flex; }
/* Свёрнутое = ТОЛЬКО полоска-шапка, прибитая к НИЗУ экрана справа (как свёрнутый
   чат-виджет). Инлайновые width/height/top/left сбрасываем в JS перед сворачиванием,
   но !important здесь страхует высоту. */
.tf-split-source.tf-src-min {
  top: auto !important; bottom: 14px !important; right: 24px !important; left: auto !important;
  height: auto !important; min-height: 0 !important; width: 300px !important;
}
.tf-split-source.tf-src-min #tfSourceHolder,
.tf-split-source.tf-src-min .tf-src-resize { display: none; }
.tf-split-source.tf-src-min .tf-src-zoomhint { display: none; }
/* В свёрнутой полоске прячем кнопки — вся полоска = кнопка «развернуть» (как чат). */
.tf-split-source.tf-src-min .tf-src-winbtns { display: none; }
.tf-split-source.tf-src-min .tf-split-source-head { cursor: pointer; border-radius: 12px; }
/* показываем «развернуть»-стрелку в свёрнутом виде */
.tf-src-expand-hint { display: none; }
.tf-split-source.tf-src-min .tf-src-expand-hint { display: inline; margin-left: auto; color: #cbd5e1; }

/* Шапка окна оригинала — в цвет сайт-шапки соответствующей темы (светлая =
   индиго-градиент, тёмная = тёмно-синий), чтобы окно выглядело «родным». */
.tf-split-source-head {
  background: linear-gradient(180deg, #243060 0%, #1a2448 100%);
  color: #e2e8f0; font-size: .82rem; padding: 8px 12px;
  flex: 0 0 auto; cursor: move; display: flex; align-items: center; gap: 6px;
  user-select: none;
}
html[data-theme="light"] .tf-split-source-head {
  background: linear-gradient(180deg, #5a6bff 0%, #4b59e6 100%); color: #fff;
}
.tf-src-title { font-weight: 600; }
.tf-src-zoomhint { color: #94a3b8; font-size: .72rem; font-style: italic; margin-left: 4px; }
.tf-src-winbtns { margin-left: auto; display: flex; gap: 2px; }
.tf-src-wbtn {
  color: #cbd5e1; background: transparent; border: 0; cursor: pointer;
  padding: 2px 6px; border-radius: 5px; font-size: .9rem; line-height: 1; text-decoration: none;
}
.tf-src-wbtn:hover { background: rgba(255,255,255,.14); color: #fff; }
/* ручка ресайза в правом нижнем углу */
/* Ручки ресайза: правый/левый/нижний края + два нижних угла. Верх не трогаем —
   там шапка для перетаскивания. Явная индикация: рамка подсвечивается при наведении
   на любой край, уголки видны штриховкой. */
.tf-src-rz { position: absolute; z-index: 3; }
.tf-src-rz-e { top: 10px; bottom: 14px; right: 0; width: 8px; cursor: ew-resize; }
.tf-src-rz-w { top: 10px; bottom: 14px; left: 0; width: 8px; cursor: ew-resize; }
.tf-src-rz-s { left: 14px; right: 14px; bottom: 0; height: 8px; cursor: ns-resize; }
.tf-src-rz-se { right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; }
.tf-src-rz-sw { left: 0; bottom: 0; width: 16px; height: 16px; cursor: nesw-resize; }
/* видимая подсветка краёв при наведении на окно (чтобы функция была явной) */
.tf-src-rz-e:hover, .tf-src-rz-w:hover { background: rgba(99,102,241,.55); }
.tf-src-rz-s:hover { background: rgba(99,102,241,.55); }
/* штриховка-«уголок» на обоих нижних углах — явный признак «тянуть тут» */
.tf-src-rz-se {
  background: linear-gradient(135deg, transparent 55%, #94a3b8 55%, #94a3b8 64%, transparent 64%, transparent 74%, #94a3b8 74%, #94a3b8 83%, transparent 83%);
}
.tf-src-rz-sw {
  background: linear-gradient(225deg, transparent 55%, #94a3b8 55%, #94a3b8 64%, transparent 64%, transparent 74%, #94a3b8 74%, #94a3b8 83%, transparent 83%);
}
.tf-split-source.tf-src-min .tf-src-rz { display: none; }
#tfSourceHolder.s-43cf74f0 { flex: 1 1 auto; }
/* Лента выпрямленных страниц оригинала (зум/pan своим JS, без PDF-iframe). */
.tf-src-pages { width: 100%; margin: 0 auto; }
.tf-src-page { display: block; width: 100%; height: auto; user-select: none; }
.tf-src-page + .tf-src-page { margin-top: 8px; }
/* Оригинал не загрузился (обрыв соединения) — вместо молча пустого окна
   кликабельная подсказка: повторить. */
.tf-src-retry { margin: 16px; padding: 12px 14px; border-radius: 8px; cursor: pointer;
  background: var(--surface-2, rgba(127,127,127,.12)); color: var(--fg);
  font-size: .92rem; text-align: center; }
.tf-src-retry:hover { background: var(--surface-3, rgba(127,127,127,.2)); }
.tf-src-wait { display: flex; justify-content: center; padding: 48px 0; font-size: 28px; opacity: .55; }
.tf-split-divider { display: none !important; }

/* На узком экране плавающее окно занимает почти весь низ экрана. */
@media (max-width: 760px) {
  .tf-split-source {
    top: auto; bottom: 8px; right: 8px; left: 8px;
    width: auto; height: 45vh;
  }
}

/* ── Мобильная адаптация шапки и тулбара результата (узкие экраны) ──────────
   Проблема: лого + «Дашборд»/язык/тема/выход + кнопки страницы не влезают.
   Решение: компактные паддинги, скрываем текст кнопок (оставляем иконки),
   тулбар — горизонтальный скролл вместо переполнения. */
@media (max-width: 640px) {
  /* шапка компактнее */
  .header__inner { padding: 8px 12px !important; gap: 8px; }
  .tf-header-actions { gap: 6px; flex: 0 0 auto; }
  /* Лого viewBox 420×82 (5:1) при height:44 = 328px ширины — выдавливало кнопки,
     последняя (выход) обрезалась. Кнопки ужимать нельзя (их набор фиксирован),
     поэтому лого держим на комфортной для мобильной высоте и разрешаем ему
     сжиматься флексом ТОЛЬКО если совсем не хватает места (0 1 auto) — на обычных
     ширинах оно сохраняет свою высоту, на самых узких аккуратно ужмётся, не
     ломая кнопки. */
  .tf-logo { flex: 0 1 auto; min-width: 0; }
  .tf-logo img { height: 48px; }
}
@media (max-width: 480px) {
  /* Склеєний лого (значок + слово + підпис, 420×82) при висоті 44 займає
     ~225px і на 320–360 або лягав під «Дашборд», або ужимався в «точки»
     (20.10.2026). Тут — значок звичайного розміру з того самого SVG (рамка
     40×40 обрізає решту) і слово текстом тим самим шрифтом і кольорами;
     підпис «TRANSLATION WORKSPACE» на вузькому не показуємо. */
  .tf-logo > .tf-logo-dark { display: none; }
  .tf-logo-mini { display: inline-flex; align-items: center; gap: 8px; }
  .tf-logo-mark { flex: 0 0 40px; width: 40px; height: 40px; overflow: hidden; }
  .tf-logo .tf-logo-mark img { height: 40px; width: auto; max-width: none; display: block; }
  .tf-logo { text-decoration: none; }
  .tf-logo-word { font-family: Georgia, 'Times New Roman', serif; font-weight: 700;
    font-size: 21px; line-height: 1; color: #eef2ff; white-space: nowrap; }
  .tf-logo-word-acc { color: #c49020; font-style: normal; }

  /* кнопка «Дашборд» / логин / регистрация — только иконка */
  .tf-dash-btn { padding: 8px 10px; }
  .tf-dash-btn span { display: none; }

  /* язык: убрать код, оставить флаг + стрелку */
  .tf-lang-btn { padding: 6px 8px; }
  .tf-lang-code { display: none; }

  .tf-icon-btn { width: 34px; height: 34px; }

  /* ── Тулбар результата: вкладки + действия переносятся на кілька рядів ──
     Скрол у один ряд не працював: .tf-collapsible > .tf-result-toolbar
     (overflow:hidden, сильніший селектор) його вимикав, і на телефоні
     «Зберегти/Завантажити/Друк/Word» обрізались за краєм (20.10.2026). */
  .tf-result-toolbar {
    flex-wrap: wrap; gap: 6px 8px;
    padding: 8px 10px;
  }
  /* Група дій (рукопис, Зберегти, Завантажити, Друк, Word, …): на всю ширину
     й з переносом. Правило було під div[style], а після виносу inline-стилів
     у класи (.s-5b2be1db) не спрацьовувало. */
  .tf-result-toolbar > .s-5b2be1db { margin-left: 0; flex: 1 1 100%; flex-wrap: wrap; }
  .tf-mode-tabs { flex: 1 1 100%; flex-wrap: wrap; }
  .tf-mode-tab { padding: 7px 11px; font-size: .82rem; white-space: nowrap; }

  /* кнопки действий (Зберегти/Завантажити/Друк/...) — иконка + компактно.
     Текст в <i>…</i> ТЕКСТ — оставляем, но ужимаем; на совсем узких прячем подпись. */
  .tf-result-toolbar .btn-sm {
    padding: 7px 10px; white-space: nowrap; flex: 0 0 auto;
  }
}

/* На совсем узких (<460px) прячем текстовые подписи кнопок действий — только иконки,
   чтобы тулбар не требовал длинного скролла. Вкладки режимов оставляем с текстом. */
@media (max-width: 460px) {
  .tf-result-toolbar .btn-sm { font-size: 0; padding: 8px 11px; gap: 0; }
  .tf-result-toolbar .btn-sm i { font-size: 1rem; }
  #tfSaveStatus { display: none; }
}

/* Лого на 320: справа 4 кнопки (183px), значок 40 + слово 21px не влазять
   (−26px, замір 20.10.2026). Слово лишаємо читаємим (15px — кегль тексту),
   значок трохи менший. */
@media (max-width: 340px) {
  .tf-logo-mini { gap: 6px; }
  .tf-logo-mark { flex-basis: 34px; width: 34px; height: 34px; }
  .tf-logo .tf-logo-mark img { height: 34px; }
  .tf-logo-word { font-size: 15px; }
}

@media print {
  .tf-split-source, .tf-split-divider { display: none !important; }
  #tfResultSection { max-width: 1180px !important; }
}

/* Скролл к началу секции при переключении (якорь #dashRight). Отступ под шапку.
   smooth не ставим — JS делает мгновенный точный скролл (надёжнее на мобильном). */
#dashRight { scroll-margin-top: 16px; }

/* ── Глазик в поле пароля (pw-eye.js вставляет button.pass-eye в .input-wrap).
   В TF-формах вход/регистрация поле обёрнуто .auth-pass > .input-wrap. ── */
/* ПЕРЕОПРЕДЕЛЯЕМ custom.css (форк Auditara): там .auth-pass max-width:360px +
   .input-wrap inline-block — из-за этого поле пароля было уже email. Сбрасываем. */
/* Специфичность повышена (.auth-pass .input-wrap > …) — чтобы гарантированно
   перебить custom.css (форк Auditara), где .input-wrap inline-block + input
   max-width:360px. Без этого глаз «висел» в gutter справа от узкого поля. */
.auth-pass { display: block; width: 100%; max-width: none; }
.auth-pass .input-wrap { position: relative; display: block; width: 100%; max-width: none; }
.auth-pass .input-wrap > input,
.auth-pass .input-wrap > input.form-control {
  display: block; width: 100%; max-width: none; padding-right: 44px; box-sizing: border-box;
}
.auth-pass .input-wrap > .pass-eye {
  position: absolute; top: 50%; right: 8px; left: auto; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted, #9aa0b4); cursor: pointer; z-index: 2;
}
.auth-pass .input-wrap > .pass-eye:hover { color: var(--fg, #e8eaf0); background: rgba(255,255,255,.06); }
.auth-pass .input-wrap > .pass-eye .pw-eye-slash { stroke: currentColor; stroke-width: 2; display: none; }
.auth-pass .input-wrap > .pass-eye.pw-showing .pw-eye-slash { display: inline; }

/* ── Мониторинг (форк Auditara .mon-* — те же стили, что в монiторинге Auditary) ── */
.mon-grid-kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 12px; }
@media (max-width: 900px) { .mon-grid-kpi { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .mon-grid-kpi { grid-template-columns: 1fr; } }
.mon-card {
  background: var(--card, #fff); border: 1px solid var(--border-2, var(--border, #e8edf2));
  border-radius: 10px; padding: 13px 15px; margin-bottom: 10px;
}
.mon-eyebrow {
  font-size: .64rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted, #94a3b8); margin-bottom: 3px;
}
.mon-card-title { font-size: .85rem; font-weight: 700; color: var(--fg, #1e293b); margin: 0 0 11px; }
.mon-kpi { display: flex; align-items: baseline; gap: 5px; }
.mon-kpi-num { font-size: 1.55rem; font-weight: 800; line-height: 1; color: var(--fg, #1e293b); }
/* --sm: для НЕчисловых KPI (дата сертификата, версия ClamAV, время крона) —
   раньше правила не было → падало на 1.55rem и распирало карточку в 3 строки */
.mon-kpi-num--sm { font-size: 1rem; font-weight: 700; line-height: 1.25; }
.mon-kpi-num--md { font-size: 1.25rem; font-weight: 800; line-height: 1.1; }
.mon-load-status { display: inline-block; margin-top: 10px; font-size: .78rem;
  font-weight: 700; padding: 2px 10px; border-radius: 999px; }
.mon-load-ok   { color: #15803d; background: rgba(34,197,94,.14); }
.mon-load-warn { color: #b45309; background: rgba(245,158,11,.16); }
.mon-load-bad  { color: #b91c1c; background: rgba(239,68,68,.16); }
.mon-load-raw  { margin-top: 6px; font-size: .7rem; color: var(--muted); }

/* Панель технических алертов (Огляд) */
.mon-alerts-card { margin-bottom: 16px; }
.mon-alerts-badge { display: inline-block; min-width: 20px; font-size: .78rem;
  font-weight: 700; text-align: center; }
.mon-alerts-badge--on { background: #b91c1c; color: #fff; border-radius: 999px;
  padding: 1px 8px; margin-left: 6px; }
.mon-alert-group { font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); margin: 12px 0 6px; }
.mon-alert-row { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0;
  border-bottom: 1px solid rgba(127,127,127,.12); }
.mon-alert-sev { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%;
  margin-top: 5px; }
.mon-sev-warning  { background: #f59e0b; }
.mon-sev-error    { background: #ef4444; }
.mon-sev-critical { background: #b91c1c; box-shadow: 0 0 0 3px rgba(185,28,28,.25); }
.mon-alert-body { flex: 1; min-width: 0; }
.mon-alert-kind { font-size: .8rem; font-weight: 700; color: var(--fg); }
.mon-alert-msg  { font-size: .78rem; color: var(--muted); line-height: 1.4;
  white-space: pre-wrap; word-break: break-word; }
.mon-alert-when { font-size: .7rem; color: var(--muted); opacity: .8; margin-top: 2px; }
.mon-alert-act  { flex: 0 0 auto; }
.mon-kpi-label { font-size: .76rem; color: var(--muted, #64748b); }
.mon-kpi--ok     .mon-kpi-num { color: #22c55e; }
.mon-kpi--warn   .mon-kpi-num { color: #f59e0b; }
.mon-kpi--danger .mon-kpi-num { color: #ef4444; }
.mon-muted { color: var(--muted, #94a3b8); font-size: .85rem; }

/* Вкладки языков юр-документа. ★ — аутентичная редакция, · — перевода нет. */
.mon-lang-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; }
.mon-lang-tab {
  padding: 4px 10px; border: 1px solid var(--border, #334155);
  background: transparent; color: var(--fg, #e2e8f0);
  border-radius: 6px; cursor: pointer; font-size: .82rem; line-height: 1.4;
}
.mon-lang-tab:hover { border-color: var(--accent, #38bdf8); }
.mon-lang-tab.is-active {
  background: var(--accent, #38bdf8); color: #0b1220; font-weight: 600;
}
/* Язык без перевода виден, но приглушён: вкладка «перевода ещё нет» — это
   рабочее состояние, о котором надо знать, а не отсутствующий пункт. */
.mon-lang-tab.is-empty { opacity: .55; border-style: dashed; }
.mon-legal-note { font-size: .82rem; color: var(--muted, #94a3b8); margin-bottom: 8px; }
.mon-legal-note.is-warn { color: var(--warn, #fbbf24); }
.mon-legal-note.is-authentic { color: var(--ok, #34d399); }
.mon-event-table { width: 100%; border-collapse: collapse; font-size: .77rem; }
.mon-event-table th { text-align: left; padding: 6px 8px; color: var(--muted); border-bottom: 1px solid var(--border-2, var(--border)); font-weight: 600; }
.mon-event-table td { padding: 6px 8px; border-bottom: 1px solid rgba(127,127,127,.12); }
.mon-audit-detail { color: var(--muted); max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mon-audit-filters { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; margin: 6px 0 14px; }
.mon-audit-filters label { display: flex; flex-direction: column; gap: 3px; font-size: .78rem; color: var(--muted); }
.mon-audit-filters input, .mon-audit-filters select { padding: 7px 9px; border-radius: 8px;
  border: 1px solid var(--border, rgba(127,127,127,.3)); background: var(--card, transparent); color: var(--fg, inherit); font-size: .85rem; line-height: 1.2; }
.mon-audit-filters select { min-width: 12rem; }
/* 390 px: селект «Тип дії» з довгою назвою дії не виходить за картку. */
.mon-audit-filters label { max-width: 100%; min-width: 0; }
.mon-audit-filters input, .mon-audit-filters select { max-width: 100%; box-sizing: border-box; }
.mon-audit-filters label.mon-audit-debug { flex-direction: row; align-items: center; gap: 6px; padding-bottom: 8px; cursor: pointer; }
@media (max-width: 480px) {
  .mon-audit-filters label:has(select) { flex: 1 1 100%; }
  .mon-audit-filters select { min-width: 0; width: 100%; }
}
.mon-audit-filters input:focus, .mon-audit-filters select:focus { outline: none; border-color: var(--brand, #6366f1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand, #6366f1) 22%, transparent); }
/* кнопки фильтра — в фирменном стиле (индиго --brand, как основные кнопки сайта) */
.mon-audit-btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 15px; border-radius: 8px;
  font-size: .85rem; font-weight: 600; cursor: pointer; border: 1px solid transparent; line-height: 1.2; transition: background .12s, border-color .12s, box-shadow .12s; }
.mon-audit-btn i { font-size: .9em; }
.mon-audit-btn--apply { background: linear-gradient(135deg, var(--brand, #6366f1), var(--brand-2, #4f46e5)); color: #fff;
  box-shadow: 0 3px 12px color-mix(in srgb, var(--brand, #6366f1) 28%, transparent); }
.mon-audit-btn--apply:hover { box-shadow: 0 6px 18px color-mix(in srgb, var(--brand, #6366f1) 40%, transparent); }
.mon-audit-btn--reset { background: transparent; border-color: var(--border, rgba(127,127,127,.35)); color: var(--muted); }
.mon-audit-btn--reset:hover { background: rgba(127,127,127,.1); color: var(--fg, inherit); border-color: var(--brand, #6366f1); }
.mon-audit-row { cursor: pointer; }
.mon-audit-row:hover { background: rgba(127,127,127,.08); }
.mon-audit-row:focus { outline: 2px solid var(--brand, #6366f1); outline-offset: -2px; }
/* модалка события журнала */
/* z-index С ЗАПАСОМ НАД ШАПКОЙ. Шапка (.s-c0468810) — sticky, z-index 99999;
   здесь стояло 100000, то есть на единицу выше, и модалка всё равно уходила
   под шапку: её видно обрезанной сверху (замечание 21.09.2026). Ровно этот
   случай уже разбирался в тикетах — там взяли 100050 (.sp-modal-overlay в
   support.css) и на том успокоились. Берём то же значение, а не +1: запас
   переживает и тень шапки, и её вложенные слои. */
.mon-modal-overlay { position: fixed; inset: 0; z-index: 100050; display: none; align-items: center; justify-content: center;
  background: rgba(0,0,0,.5); padding: 1rem; }
.mon-modal-overlay.mon-modal-open { display: flex; }
.mon-modal { background: var(--card, #1b1e24); color: var(--fg, #e8e8e8); border: 1px solid var(--border, rgba(127,127,127,.25));
  border-radius: 12px; max-width: 560px; width: 100%; max-height: 85vh; overflow: auto; box-shadow: 0 12px 40px rgba(0,0,0,.4); }
.mon-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px;
  border-bottom: 1px solid var(--border, rgba(127,127,127,.2)); }
.mon-modal-x { background: none; border: none; color: var(--muted); font-size: 1.4rem; line-height: 1; cursor: pointer; padding: 0 4px; }
.mon-modal-x:hover { color: var(--fg, #fff); }
.mon-modal-body { padding: 14px 18px; }
.mon-audit-krow { display: flex; gap: 12px; padding: 6px 0; border-bottom: 1px solid rgba(127,127,127,.1); }
.mon-audit-krow-block { flex-direction: column; gap: 6px; }
.mon-audit-k { flex: 0 0 34%; color: var(--muted); font-size: .82rem; }
.mon-audit-v { flex: 1; word-break: break-word; font-size: .88rem; }
.mon-audit-json { margin: 8px 0 0; background: rgba(127,127,127,.1); border-radius: 8px; padding: 10px 12px;
  font-size: .78rem; overflow-x: auto; white-space: pre; }
.mon-audit-raw { margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(127,127,127,.15); }
.mon-audit-raw > summary { cursor: pointer; color: var(--muted); font-size: .8rem; list-style: none; user-select: none; }
.mon-audit-raw > summary::-webkit-details-marker { display: none; }
.mon-audit-raw > summary::before { content: '▸ '; }
.mon-audit-raw[open] > summary::before { content: '▾ '; }

/* ── table-responsive: горизонтальный скролл широкой таблицы на узких экранах.
   Bootstrap не подключён целиком (только bootstrap-icons), поэтому определяем сами.
   Используется в admin.html (список переводчиков). ── */
.table-responsive { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
.table-responsive > table { min-width: 560px; }

/* ── КОНТЕЙНМЕНТ карточек по ширине (без изменения раскладки) ──
   security-grid/card в TF — обычные блоки (custom.css Auditara не форкнут;
   карточки идут столбиком — НЕ трогаем это). Но карточка не ограничивала ширину
   по содержимому: широкая таблица (.table-responsive > table min-width:560px) в
   секции «Адміністрування» распирала карточку шире вьюпорта → горизонтальный
   скролл страницы. Ограничиваем карточку шириной родителя и прячем переполнение —
   таблица скроллится ВНУТРИ .table-responsive, layout столбиком сохраняется. */
.security-grid { max-width: 100%; }
.security-card { max-width: 100%; min-width: 0; box-sizing: border-box; }

/* ── cron table ── */
.mon-cron-tbl { width: 100%; border-collapse: collapse; font-size: .78rem; min-width: 560px; }
/* JS-таблицы мониторинга (mon-cron-tbl / mon-event-table) рендерятся в контейнеры
   без .table-responsive. На узких экранах их min-width шире вьюпорта → дала бы
   горизонтальный скролл всей страницы (а теперь — обрезку по body:clip, что хуже).
   Делаем сам контейнер таблицы скроллируемым по X, чтобы колонки были доступны. */
@media (max-width: 760px) {
  .mon-cron-tbl, .mon-event-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}
.mon-cron-tbl th { text-align: left; padding: 6px 8px; color: var(--muted); border-bottom: 1px solid var(--border-2, var(--border)); font-weight: 600; }
.mon-cron-tbl td { padding: 6px 8px; border-bottom: 1px solid rgba(127,127,127,.12); vertical-align: top; }
.mon-cron-desc { font-size: .68rem; color: var(--muted); font-weight: 400; margin-top: 2px; line-height: 1.35; max-width: 420px; }
.mon-cron-tbl code { font-size: .8rem; background: rgba(127,127,127,.12); padding: 2px 6px; border-radius: 5px; }
.mon-cron-btn { font-size: .78rem; padding: 5px 10px; border-radius: 7px; border: 1px solid var(--border-2, var(--border)); background: var(--surface, #fff); color: var(--fg); cursor: pointer; margin-right: 6px; }
.mon-cron-btn:hover { background: rgba(99,102,241,.1); }
.mon-cron-btn--run { color: #22c55e; border-color: rgba(34,197,94,.4); }
.mon-cron-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.mon-cron-dot--ok { background: #22c55e; }
.mon-cron-dot--bad { background: #ef4444; }
.mon-cron-dot--none { background: #94a3b8; }

/* ── env settings ── */
.mon-env-row { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.mon-env-row label { flex: 0 0 240px; font-size: .82rem; color: var(--fg); display: flex; flex-direction: column; gap: 1px; }
.mon-env-row .mon-env-key { font-family: monospace; font-size: .68rem; color: var(--muted-2, var(--muted)); }
.mon-env-row input, .mon-env-row select { flex: 1; min-width: 160px; padding: 7px 10px; border: 1px solid var(--border-2, var(--border)); border-radius: 7px; background: var(--surface, #fff); color: var(--fg); font-size: .85rem; }
.mon-env-group { flex-basis: 100%; width: 100%; margin: 16px 0 6px; font-size: .72rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--brand);
  border-bottom: 1px solid var(--border, rgba(127,127,127,.18)); padding-bottom: 4px; }
.mon-env-comment { flex-basis: 100%; width: 100%; font-size: .74rem; color: var(--muted);
  line-height: 1.45; margin-top: 2px; }
/* Поле канала, который сейчас не выбран в LLM_BACKEND. Гасим, а НЕ прячем:
   исчезнувшее поле выглядит как пропажа настройки, а приглушённое честно
   говорит «оно есть, но ни на что не влияет». */
.mon-env-row--off { opacity: .5; }
.mon-env-row--off input, .mon-env-row--off select { cursor: not-allowed; }
.mon-env-off-note { font-style: italic; }

/* Баннер «сохранено, но не действует». .env читается юнитом при СТАРТЕ, поэтому
   до рестарта правка лежит в файле и ни на что не влияет. Раньше форма говорила
   «Сохранено» и умолкала — человек уходил, считая настройку применённой. */
.mon-env-restart-banner { flex-basis: 100%; width: 100%; display: flex; gap: 12px;
  align-items: center; justify-content: space-between; flex-wrap: wrap;
  margin: 0 0 14px; padding: 12px 14px; border-radius: 9px;
  background: var(--warn-bg, rgba(255,176,32,.10));
  border: 1px solid var(--warn-border, rgba(255,176,32,.45)); }
.mon-env-restart-text { font-size: .82rem; line-height: 1.45; flex: 1 1 260px; }
.mon-env-restart-keys { margin-top: 5px; font-family: monospace; font-size: .72rem;
  color: var(--muted); word-break: break-all; }
/* Оговорка сервера: канал LLM или модель не отвечают. Сохранение при этом
   прошло — сообщение о состоянии, а не об отказе. Стоит здесь, а не в
   трёхсекундном toast'е: текст длинный (два канала с ответами AWS и Google),
   прочесть не успеть. Отделено линией, чтобы не слипалось с «нужен рестарт» —
   это про разное. */
.mon-env-restart-warn { margin-top: 8px; padding-top: 8px; font-size: .78rem;
  line-height: 1.5; border-top: 1px solid var(--warn-border, rgba(255,176,32,.45));
  overflow-wrap: anywhere; }
.mon-env-restart-banner .mon-btn-restart { flex: 0 0 auto; }

/* Несохранённые правки. Отдельная роль от жёлтого «нужен рестарт»: там правка
   уже в файле и ждёт перезапуска, здесь она ещё нигде — только на экране.
   Одинаковый цвет слил бы два разных состояния в одно. */
.mon-env-dirty-bar { flex-basis: 100%; width: 100%; display: flex; gap: 12px;
  align-items: center; justify-content: space-between; flex-wrap: wrap;
  margin: 0 0 14px; padding: 12px 14px; border-radius: 9px;
  background: var(--brand-soft, rgba(99,102,241,.10));
  border: 1px solid var(--brand, rgba(99,102,241,.45)); }
.mon-env-dirty-text { font-size: .82rem; line-height: 1.45; flex: 1 1 260px; }
.mon-env-dirty-bar .cron-modal-btn { flex: 0 0 auto; }
/* Полоса слева, а не заливка: строка остаётся читаемой, но глаз находит
   изменённое поле в длинной форме без прокрутки к панели. */
.mon-env-row--dirty { border-left: 3px solid var(--brand, #6366f1);
  padding-left: 8px; margin-left: -11px; }
.mon-env-row--dirty input, .mon-env-row--dirty select {
  border-color: var(--brand, #6366f1); }
.mon-env-dirty-note { flex-basis: 100%; width: 100%; font-size: .74rem;
  line-height: 1.45; margin-top: 2px; color: var(--brand, #6366f1); }

/* На узких экранах фикс-label 220px съедал ширину input → ставим label НАД input
   (стек), оба на всю ширину карточки. */
@media (max-width: 540px) {
  .mon-env-row { flex-direction: column; align-items: stretch; gap: 4px; }
  .mon-env-row label { flex: none; width: 100%; }
  .mon-env-row input, .mon-env-row select { width: 100%; min-width: 0; }
}

/* ── cron edit modal (форк Auditara) ── */
/* z-index 9999 достался от Auditara, где шапка была ниже. Здесь шапка
   (.s-c0468810) — sticky с z-index 99999, и модалка уходила прямо под неё
   (замечание 21.09.2026). Тот же уровень, что у остальных модалок дашборда.
   Внутри этой подложки живёт и .mon-breach-modal — своего z-index у неё нет,
   она поднимается вместе с ней. */
/* Модалка selfcheck/«Повний прогін тестів»: її клас (.s-d6f7d968, автоген inline_extracted)
   несе z-index 1000 — під шапкою (29.10.2026). id важче класу; рівень — як у решти. */
#monTestBackdrop { z-index: 100050; }
.cron-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 100050; display: flex; align-items: center; justify-content: center; padding: 20px; }
.cron-modal { position: relative; background: var(--card, #fff); border: 1px solid var(--border-2, var(--border)); border-radius: 14px; padding: 24px; width: 100%; max-width: 420px; }
.cron-modal-title { font-size: 1.05rem; font-weight: 800; color: var(--fg); margin-bottom: 2px; }
.cron-modal-sub { font-size: .8rem; color: var(--muted); margin-bottom: 16px; font-family: monospace; }
.cron-modal-label { display: block; font-size: .78rem; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.cron-modal-select, .cron-modal-inp { width: 100%; padding: 9px 12px; border: 1px solid var(--border-2, var(--border)); border-radius: 8px; background: var(--surface, #fff); color: var(--fg); font-size: .9rem; }
.cron-modal-row { display: flex; gap: 10px; }
.cron-modal-row > div { flex: 1; }
.cron-modal-section { margin-bottom: 16px; }
.cron-modal-preview { background: rgba(127,127,127,.12); padding: 10px 12px; border-radius: 8px; font-family: monospace; font-size: .95rem; color: var(--fg); }
.cron-modal-btns { display: flex; gap: 10px; justify-content: flex-end; }
.cron-modal-btn { padding: 9px 18px; border-radius: 8px; border: none; font-weight: 600; cursor: pointer; font-size: .88rem; }
.mon-opper-off { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.mon-opper-off .mon-env-key { display: block; }
.mon-btn-sm { flex: 0 0 auto; padding: 3px 10px; border-radius: 6px; border: 1px solid var(--border);
  background: transparent; color: var(--fg); font-size: .76rem; font-weight: 600; cursor: pointer; }
.cron-modal-btn--save { background: #6366f1; color: #fff; }
.cron-modal-btn--cancel { background: rgba(127,127,127,.15); color: var(--fg); }
.cron-modal-close { position: absolute; top: 12px; right: 14px; background: none; border: none; font-size: 1.1rem; color: var(--muted); cursor: pointer; }

/* ── legal WYSIWYG toolbar ── */
.le-tb { background: transparent; border: 1px solid var(--border-2, var(--border)); border-radius: 6px; color: var(--fg, #e2e8f0); min-width: 32px; height: 30px; cursor: pointer; font-size: .85rem; padding: 0 8px; }
.le-tb:hover { background: #6366f1; color: #fff; }
.le-sep { width: 1px; background: var(--border-2, var(--border)); margin: 2px 4px; }
#legalRich h2 { font-size: 1.3rem; font-weight: 700; margin: .6em 0 .3em; }
#legalRich h3 { font-size: 1.1rem; font-weight: 600; margin: .5em 0 .3em; }
#legalRich table { border-collapse: collapse; width: 100%; margin: .5em 0; }
#legalRich td, #legalRich th { border: 1px solid #ccc; padding: 6px 8px; }

/* Уведомления результата (списание + retention) — в ОДИН ряд, не по строке на
   каждое: экономит высоту. На узком экране переносятся друг под друга (flex-wrap). */
.tf-notices { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 0; }
.tf-notices .tf-notice { flex: 1 1 320px; margin-bottom: 0; }

/* Экранная подсказка переводчику (напр. общий профиль заверения). Информирующий,
   не тревожный тон (амбер). НЕ часть документа — @media print скрывает её полностью,
   даже если печатают страницу результата целиком. */
.tf-notice--hint {
  background: #fff8e6; border: 1px solid #f0d488; color: #6b5300;
  border-radius: 8px; padding: 10px 12px; display: flex; gap: 8px; align-items: flex-start;
  font-size: 0.9rem; line-height: 1.4;
}
.tf-notice--hint i { margin-top: 1px; }
:root[data-theme="dark"] .tf-notice--hint {
  background: #2e2717; border-color: #5c4a1e; color: #e8d9a8;
}
@media print { .tf-notice--screen { display: none !important; } }

/* ── Сворачиваемые блоки (тулбар, уведомления) ───────────────────────────────
   Ручка — отдельная кнопка СПРАВА от блока (не налеплена на него), заметная:
   фирменный акцент (--brand). Работает в обеих темах. Свёрнутый блок плавно
   схлопывает содержимое; ручка остаётся, стрелка разворачивается вниз. */
.tf-collapsible {
  position: relative;
  padding-right: 34px;          /* место под ручку справа, рядом с блоком */
  margin-bottom: 16px;
}
.tf-collapse-handle {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%); z-index: 4;
  width: 26px; height: 46px; padding: 0; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  background: rgba(99,102,241,.5);   /* --brand #6366f1 @ 50% заливки */
  color: #fff;
  border: 0; border-radius: 8px; cursor: pointer; font-size: .9rem;
  box-shadow: 0 1px 4px rgba(0,0,0,.18);
  transition: background .15s, transform .15s;
}
.tf-collapse-handle:hover { background: rgba(99,102,241,.8); }
.tf-collapse-handle i { transition: transform .3s cubic-bezier(.4,0,.2,1); display: block; }
/* содержимое блока плавно схлопывается */
.tf-collapsible > .tf-result-toolbar,
.tf-collapsible > .tf-notices {
  overflow: hidden;
  transition: max-height .35s cubic-bezier(.4,0,.2,1), opacity .25s ease, margin .35s, padding .35s;
  /* Стеля лише для анімації згортання. 400px різали нижній ряд панелі на 320px
     (навігація з підписами, 20.10.2026) — з запасом на всі ряди. */
  max-height: 1200px; opacity: 1;
}
.tf-collapsible.tf-collapsed { margin-bottom: 8px; }
.tf-collapsible.tf-collapsed > .tf-result-toolbar,
.tf-collapsible.tf-collapsed > .tf-notices {
  max-height: 0; opacity: 0;
  margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; border-width: 0;
}
/* свёрнутый: ручка компактнее (блока-высоты нет), стрелка смотрит ВНИЗ (=развернуть) */
.tf-collapsible.tf-collapsed .tf-collapse-handle { height: 26px; }
.tf-collapsible.tf-collapsed .tf-collapse-handle i { transform: rotate(180deg); }

/* Экран удаления при значимом балансе (v36): кнопки выбора возврат/отказ в ряд. */
.tf-refund-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.tf-refund-actions form { display: inline; margin: 0; }
.tf-refund-status .sec-card-title,
.tf-refund-choose .sec-card-title { color: inherit; }
.tf-refund-pw { max-width: 260px; }
.tf-refund-free .tf-refund-actions { align-items: center; }

/* Реквизиты возврата (экран удаления при невозможном reverse) */
.tf-refund-iban        { margin: 12px 0; max-width: 460px; }
.tf-refund-iban-hint   { margin-bottom: 10px; }
.tf-refund-lbl         { display: block; font-size: .8rem; margin: 8px 0 3px; opacity: .8; }
.tf-refund-iban .tf-input { width: 100%; font-family: ui-monospace, monospace; letter-spacing: .04em; }
.tf-refund-check       { display: flex; gap: 8px; align-items: flex-start; margin: 12px 0 4px; font-size: .85rem; cursor: pointer; }
.tf-refund-check input { margin-top: 3px; flex-shrink: 0; }

/* ── Контактная форма (/contact) — центрированная компактная карточка ──────────
   Самодостаточно, не зависит от security-card/register-стилей. Поля разной ширины:
   имя/тема уже полной ширины (короткий ввод), email/сообщение — во всю карточку. */
.contact-wrap { max-width: 680px; margin: 40px auto 64px; padding: 0 16px; }
.contact-card {
  position: relative;
  background: var(--surface, #141a2e); border: 1px solid var(--border, #26304a);
  border-radius: 16px; padding: 34px 40px;
  box-shadow: 0 8px 30px rgba(0,0,0,.18);
  overflow: hidden;
}
/* градиентная полоса сверху карточки */
.contact-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: linear-gradient(90deg, #7b5cff, #4aa3ff, #37d0c0);
}
.contact-req { color: #e0603a; margin-left: 2px; }
.contact-head { text-align: center; margin-bottom: 22px; }
.contact-head h1 { font-size: 1.5rem; margin: 0 0 6px; color: var(--fg); }
.contact-head p  { font-size: .92rem; color: var(--muted, #9aa4bd); margin: 0; line-height: 1.5; }
.contact-form { display: flex; flex-direction: column; gap: 4px; }
.contact-form label {
  font-size: .82rem; font-weight: 600; color: var(--fg);
  margin: 12px 0 4px;
}
.contact-form .tf-input, .contact-form input, .contact-form select, .contact-form textarea {
  width: 100%; box-sizing: border-box;
  padding: 9px 12px; font-size: .9rem;
  background: var(--surface-2, #0f1424); color: var(--fg);
  border: 1px solid var(--border, #26304a); border-radius: 9px;
}
/* короткие поля — уже, не на всю карточку */
.contact-form input#c-name  { max-width: 360px; }
.contact-form select#c-category { max-width: 360px; }
.contact-form textarea { resize: vertical; min-height: 130px; line-height: 1.5; }
.contact-form input:focus, .contact-form select:focus, .contact-form textarea:focus {
  outline: none; border-color: var(--accent, #c9a24b);
  box-shadow: 0 0 0 3px rgba(201,162,75,.15);
}
/* невалидное поле после взаимодействия — красная рамка (:user-invalid где есть) */
.contact-form input:user-invalid, .contact-form textarea:user-invalid {
  border-color: #e0603a; box-shadow: 0 0 0 3px rgba(224,96,58,.12);
}
.contact-note { font-size: .78rem; color: var(--muted, #9aa4bd); margin: 10px 0 0; }
.contact-actions { display: flex; gap: 10px; margin-top: 20px; }
.contact-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact-sent { text-align: center; padding: 12px 0; }
.contact-sent .bi { color: #4caf7d; font-size: 1.4rem; }
.contact-sent-hint { opacity: .75; font-size: .92em; margin-top: 6px; }
@media (max-width: 560px) {
  .contact-card { padding: 22px 18px; }
  .contact-form input#c-name, .contact-form select#c-category { max-width: 100%; }
  .contact-actions { flex-direction: column; }
}

/* ── Правка таблицы переводчиком ─────────────────────────────────────────
   Часть дефектов вёрстки угадать кодом нельзя: OCR в одном прогоне отдаёт
   «шапка=2», в другом «шапка=3» на том же листе, и строка нумерации граф то
   в шапке, то в теле. Две попытки отсечь её эвристикой сломали сетку на
   других раскладках (15.09.2026). Переводчик видит оригинал — ему это
   секунда. */
.tf-blk-table td { position: relative; }
.tf-row-del {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; line-height: 1;
  padding: 0; border: 1px solid #cbd5e1; border-radius: 4px;
  background: #fff; color: #b91c1c; font-size: .8rem;
  opacity: 0; cursor: pointer; transition: opacity .12s;
}
.tf-blk-table tr:hover .tf-row-del,
.tf-row-del:focus-visible { opacity: 1; }
.tf-row-del:hover { background: #fee2e2; border-color: #b91c1c; }
/* Вспышка на возвращённой строке: без неё после отмены непонятно, что именно
   вернулось. */
.tf-row-flash { animation: tf-row-flash 900ms ease-out; }
@keyframes tf-row-flash {
  from { background: #fef08a; }
  to   { background: transparent; }
}
.tf-undo-count { font-variant-numeric: tabular-nums; font-size: .75rem; }

/* ── Границы граф тянутся мышью ──────────────────────────────────────────
   Ручка ДОЛЖНА БЫТЬ ВИДНА: без подсказки никто не догадается, что границу
   можно двигать. Отсюда курсор col-resize на всю высоту линии и подсветка
   при наведении. */
/* Кнопка «добавить строку» — ВПЛОТНУЮ слева от «×», тем же приёмом.
   Сначала она была обычным элементом в потоке и вставала ПОД крестиком,
   сдвигая текст ячейки (замечание 22.09.2026). Отступ 24px = 18px ширины
   крестика + 4px промежутка. Появляется при наведении на строку: постоянно
   видимые значки в каждой строке зашумили бы таблицу, которую человек
   читает как документ. */
.tf-row-add {
  position: absolute; top: 2px; right: 24px;
  width: 18px; height: 18px; line-height: 1;
  padding: 0; border: 1px solid #cbd5e1; border-radius: 4px;
  background: #fff; color: #2563eb; font-size: .8rem;
  opacity: 0; cursor: pointer; transition: opacity .12s;
}
.tf-blk-table tr:hover .tf-row-add,
.tf-row-add:focus-visible { opacity: 1; }
.tf-row-add:hover { background: #dbeafe; border-color: #2563eb; }

/* Поворот текста в ЯЧЕЙКЕ. Значок в ЛЕВОМ НИЖНЕМ углу: правый верхний занят
   кнопками строки («×» и «+»), а ячеек в таблице сотни — столкновение было бы
   в каждой строке. Показываем только под курсором или при правке этой ячейки:
   значок в каждой из сотен ячеек превратил бы таблицу в рябь. */
.tf-cell-rot {
  position: absolute; left: 2px; bottom: 2px;
  width: 18px; height: 18px; line-height: 1;
  padding: 0; border: 1px solid #cbd5e1; border-radius: 4px;
  background: #fff; color: #2563eb; font-size: .78rem;
  opacity: 0; cursor: pointer; transition: opacity .12s;
  z-index: 3;
}
.tf-blk-table td:hover > .tf-cell-rot,
.tf-blk-table td:focus-within > .tf-cell-rot,
.tf-cell-rot:focus-visible { opacity: 1; }
.tf-cell-rot:hover { background: #dbeafe; border-color: #2563eb; }
/* Повёрнутая ячейка показывает значок постоянно и приглушённо — иначе
   единственный способ узнать, что поворот ручной, это навести мышь. */
.tf-blk-table td.tf-td-vhead > .tf-cell-rot { opacity: .45; }

.tf-col-grip {
  position: absolute; top: 0; right: -3px; bottom: 0; width: 7px;
  cursor: col-resize; z-index: 2;
  background: transparent; transition: background .12s;
}
.tf-col-grip::after {
  content: ''; position: absolute; top: 15%; bottom: 15%; left: 3px;
  width: 1px; background: #94a3b8; opacity: 0; transition: opacity .12s;
}
/* Линия видна ВСЕГДА и слабо — иначе никто не догадается, что границу можно
   тянуть (замечание 22.09.2026: «нет явных ручек»). При наведении на ЛЮБУЮ
   строку она становится отчётливой; раньше подсветка жила только на
   tr:first-child, то есть намёк был лишь в шапке. */
.tf-col-grip::after { opacity: .22; }
.tf-blk-table tr:hover .tf-col-grip::after { opacity: .6; }
.tf-col-grip:hover { background: rgba(37, 99, 235, .18); }
.tf-col-grip:hover::after { opacity: 1; background: #2563eb; width: 2px; }
/* Во время перетаскивания курсор не должен «прыгать» на текст, а выделение
   текста мешает тянуть. */
.tf-blk-table.tf-col-resizing { cursor: col-resize; user-select: none; }
.tf-blk-table.tf-col-resizing .tf-col-grip { background: rgba(37, 99, 235, .18); }

/* [hidden] в модалках: .btn и другие задают display и перебивают атрибут —
   кнопка «XML» была видна и там, где XML нет (23.09.2026). */
.security-modal [hidden] { display: none !important; }

/* Світла тема «мертвотно бліда» (23.09.2026): фон зливався з картками,
   головні кнопки були лише контуром, поля — ледь помітні. Тільки світла. */
html[data-theme="light"] {
  --bg: #eceff5; --ui-bg: #eceff5;
  --muted: #526077; --ui-muted: #566074;
  --border: #d5dbe5; --ui-border: rgba(25,33,55,.14);
  --ui-shadow: 0 2px 8px rgba(15,23,42,.08);
}
html[data-theme="light"] body .btn.btn-primary:not(:disabled) {
  background: #4f46e5 !important; border-color: #4f46e5 !important; color: #fff !important;
}
html[data-theme="light"] body .btn.btn-primary:not(:disabled):hover {
  background: #4338ca !important; border-color: #4338ca !important;
}
html[data-theme="light"] .dash-right input:not([type=checkbox]):not([type=radio]):not([type=file]),
html[data-theme="light"] .dash-right select,
html[data-theme="light"] .dash-right textarea,
html[data-theme="light"] .tf-input,
html[data-theme="light"] .auth-card input {
  background-color: #fff; border-color: #c3cad6;
}

/* «Усі оплати»: посилання під лотами і модалка з таблицею (balance_lots.js) */
.tf-lots-all { margin-top: 4px; background: none; border: 0; padding: 0;
  color: var(--accent, #c49020); font-size: .82rem; cursor: pointer; text-decoration: underline; }
.tf-lots-box { max-width: 640px; text-align: left; position: relative; }
.tf-lots-close { position: absolute; top: 8px; right: 12px; background: none; border: 0;
  font-size: 1.4rem; line-height: 1; color: inherit; cursor: pointer; }
.tf-lots-title { margin: 0 0 12px; font-size: 1rem; }
.tf-lots-wrap { overflow-x: auto; }
.tf-lots-table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.tf-lots-table th, .tf-lots-table td { padding: 6px 8px; border-bottom: 1px solid rgba(148,163,184,.2);
  text-align: left; white-space: nowrap; }
.tf-lots-table td.tf-lot-soon { color: var(--warn, #b26a00); font-weight: 600; }
.tf-lots-msg { margin: 10px 0 0; color: #94a3b8; font-size: .86rem; }
.tf-lots-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 12px; }
.tf-pack-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* Повернути все на картку / виплачено поза системою — під блоком лотів */
.tf-refund-all { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.tf-refund-outside summary { cursor: pointer; font-size: .8rem; opacity: .7; }
.tf-refund-outside form { margin-top: 8px; }
.tf-lot-expired { color: var(--warn, #b26a00); font-weight: 600; }

/* Поля заверения документа (экран результата) — над надписью, на печать не идут */
.tf-cert-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px 16px;
  margin: 0 0 16px; padding: 14px 16px; border: 1px solid #cbd5e1; border-radius: 10px; font-size: 13px; background: #f8fafc; }
.tf-cert-fields label { display: flex; flex-direction: column; gap: 4px; }
.tf-cert-fields { color: #0f172a; }
.tf-cert-fields input, .tf-cert-fields select, .tf-cert-fields textarea,
[data-theme] .tf-cert-fields input, [data-theme] .tf-cert-fields select, [data-theme] .tf-cert-fields textarea { padding: 6px 8px; border: 1px solid #cbd5e1; border-radius: 6px; font: inherit;
  background: #fff !important; color: #0f172a !important; border-color: #cbd5e1 !important; }
/* !important: theme.css красит все input тёмным с !important, а лист документа белый в любой теме */
.tf-cert-fields-h { grid-column: 1 / -1; font-weight: 600; }
.tf-cert-fields-wide { grid-column: 1 / -1; }
.tf-cert-title { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px 16px; border: 1px solid #cbd5e1; border-radius: 8px; padding: 10px 14px; margin: 0; }
.tf-cert-title legend { font-weight: 600; padding: 0 4px; }
.tf-cert-title label { display: flex; flex-direction: column; gap: 4px; }
.tf-cert-fields-hint { grid-column: 1 / -1; margin: 0; color: #64748b; }
.tf-cert-own { grid-column: 1 / -1; }
.tf-cert-own summary { cursor: pointer; font-weight: 600; }
.tf-cert-own textarea { width: 100%; margin-top: 8px; line-height: 1.5; resize: vertical; box-sizing: border-box; }
.tf-cert-own-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
@media (max-width: 640px) { .tf-cert-fields { margin: 0 0 12px; } }
@media print { .tf-cert-fields { display: none !important; } }
/* «Змінити дані засвідчення» — посилання над аркушем, поля — у модалці (не на папері). */
.tf-cert-edit { margin: 0 0 10px; text-align: right; }
.tf-cert-edit-link { background: none; border: 0; padding: 0; color: var(--brand, #4f46e5); font-size: 13px; cursor: pointer; text-decoration: underline; }
.tf-cert-modal { max-width: 720px; width: calc(100% - 32px); }
.tf-cert-modal .tf-cert-fields { margin: 0; border: 0; background: transparent; max-height: 70vh; overflow: auto;
  grid-template-columns: repeat(2, minmax(0, 1fr)); }   /* одна сітка: «з чого» і «місто» по 50%, решта — на всю ширину */
.tf-cert-modal .tf-cert-fields input, .tf-cert-modal .tf-cert-fields select { width: 100%; box-sizing: border-box; }
.tf-cert-modal .ds-modal-body, .tf-cert-modal .tf-wiz-title, .tf-cert-modal .tf-cert-fields label { text-align: left; }
.tf-cert-modal .tf-cert-fields label > span { font-weight: 600; }
.tf-cf-hint { color: var(--muted, #64748b); font-size: 12px; }
/* DE (MV/SN/ST/TH): галочка «Auffälligkeiten … geprüft» — квадрат поруч із текстом, не поле на всю ширину. */
.tf-cert-modal .tf-cert-fields .tf-cert-aff { display: flex; flex-direction: row; align-items: flex-start; gap: 10px; padding: 8px 10px; border-radius: 8px; }
.tf-cert-modal .tf-cert-fields .tf-cert-aff input { width: auto; flex: 0 0 auto; margin: 2px 0 0; }
.tf-cert-modal .tf-cert-fields .tf-cert-aff.tf-cert-missing { outline: 1px solid #fca5a5; background: #fef2f2; }
/* Поля в модалках потоку засвідчення — як поля профілю (profil-input), а не білі
   поля аркуша: правило .tf-cert-fields input вище — для аркуша, з !important проти theme.css. */
.tf-cert-modal .tf-cert-fields .profil-input,
[data-theme] .tf-cert-modal .tf-cert-fields .profil-input {
  background: #fff !important; color: #0f172a !important; border: 1px solid #d1d5db !important;
  border-radius: 999px; padding: .45rem .9rem; font-size: .9rem; }
.tf-cert-modal .tf-cert-fields .profil-input:focus {
  border-color: #4f46e5 !important; box-shadow: 0 0 0 1px rgba(79,70,229,.35); outline: none; }
html[data-theme="dark"] .tf-cert-modal .tf-cert-fields .profil-input {
  background: #1e2540 !important; color: #e2e8f0 !important; border-color: rgba(255,255,255,.12) !important; }
html[data-theme="dark"] .tf-cert-modal .tf-cert-fields .profil-input::placeholder { color: #7b86a8; }
html[data-theme="dark"] .tf-cert-modal .tf-cert-fields .profil-input:focus {
  border-color: #6d63ff !important; box-shadow: 0 0 0 1px rgba(109,99,255,.4); }
.tf-cert-modal a.ds-btn-primary { text-decoration: none; }
/* Майстер: полів мало й вони різної ваги — одна колонка на всю ширину, без порожнього хвоста. */
.tf-cert-modal .tf-cert-fields--wiz { grid-template-columns: 1fr; }
@media (max-width: 560px) { .tf-cert-modal .tf-cert-fields { grid-template-columns: 1fr; } }
.tf-cert-modal-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
@media print { .tf-cert-edit, #tfCertModal { display: none !important; } }
/* Майстер засвідчення перед оцінкою: кроки «1 · 2 · 3». */
.tf-wiz-steps { display: flex; gap: 6px 14px; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; font-size: 13px; color: #64748b; }
.tf-wiz-steps li { padding: 3px 10px; border-radius: 999px; border: 1px solid #cbd5e1; }
.tf-wiz-steps li.is-on { color: #fff; background: var(--brand, #4f46e5); border-color: var(--brand, #4f46e5); font-weight: 600; }
.tf-wiz-steps li.is-done { color: #15803d; border-color: #86efac; }
.tf-wiz-steps--confirm { margin: 6px 0 12px; }
.tf-wiz-title { font-size: 15px; margin: 0 0 12px; }
.tf-cert-modal .ds-modal-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tf-cert-modal .ds-modal-header h3 { margin: 0; font-size: 16px; }
.tf-cert-modal .ds-modal-header { padding: 14px 18px 0; }
.tf-cert-modal .ds-modal-body { padding: 14px 18px 18px; }
/* Модалка темна в темній темі: підписи полів — кольором теми (на аркуші були темні). */
.tf-cert-modal .tf-cert-fields, .tf-cert-modal .tf-cert-fields label, .tf-cert-modal .tf-cert-own summary { color: var(--fg, inherit); }
.tf-cert-modal .tf-cert-fields-hint { color: var(--muted, #94a3b8); }
.tf-cert-modal .ds-modal-body > .tf-cert-fields { padding: 0; }
.tf-gate-list { margin: 0 0 14px; padding-left: 20px; }
.tf-cert-fields [hidden] { display: none !important; }
/* Обязательное поле заверения страны (PL/CZ/SK reg_no): пусто — PDF не отдаётся */
.tf-cert-req { color: #b91c1c; font-weight: 600; }
.tf-cert-req-note { color: #b91c1c; font-size: 12px; }
/* Гейт профілю: кнопка-посилання без підкреслення, колір вторинної; на вузькому
   екрані кнопки — стовпчиком на всю ширину, текст переноситься. */
#tfCertGate a.ds-btn-secondary { text-decoration: none; color: var(--muted-3); }
#tfCertGate a.ds-btn-secondary:hover { color: var(--fg-2); }
@media (max-width: 560px) {
  #tfCertGate .tf-cert-modal-actions { flex-direction: column-reverse; align-items: stretch; }
  #tfCertGate .tf-cert-modal-actions > * { width: 100%; justify-content: center; white-space: normal; text-align: center; flex-shrink: 1; }
}
/* Переклад без засвідчення (профіль не готовий): плашка замість надпису. */
.tf-cert-pending { margin: 24px 0 0; padding: 14px 16px; border: 1px dashed #94a3b8; border-radius: 8px; background: #f8fafc; color: #334155; font: 14px/1.5 system-ui, sans-serif; }
.tf-cert-pending-msg { margin: 0 0 6px; font-weight: 600; }
.tf-cert-pending-list { margin: 0 0 10px; padding-left: 20px; font-size: 13px; color: #475569; }
.tf-cert-pending .ds-btn-primary { display: inline-flex; text-decoration: none; }
@media print { .tf-cert-pending { display: none; } }
.tf-cert-blocked { margin: 0 0 12px; padding: 10px 14px; border: 1px solid #fca5a5; border-radius: 8px; background: #fef2f2; color: #991b1b; font-size: 13px; }
.tf-cert-fill { background: #fee2e2; color: #b91c1c; padding: 0 3px; border-radius: 3px; }
.tf-cert-missing input, [data-theme] .tf-cert-missing input { border-color: #dc2626 !important; box-shadow: 0 0 0 2px rgba(220, 38, 38, .18); }

.tf-title-pre[hidden] { display: none; }
.tf-title-pre { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 14px; text-align: left; }
.tf-title-pre label { display: flex; flex-direction: column; gap: 4px; font-size: .9rem; }
.tf-title-pre-hint { margin: 0; font-size: .85rem; color: #475569; }
.fin-receipt-missing { color: #dc2626; font-weight: 600; }
.fin-fiscal-bad td { background: rgba(220, 38, 38, .07); }
.fin-fiscal-issues td { padding-top: 0; }
.fin-fiscal-issues ul { margin: 0; padding-left: 18px; font-size: .85rem; }

/* Лічильник під фільтром списку перекладачів (адмінка). */
.adm-count { margin: 6px 0 10px; font-size: .9rem; color: var(--fg-muted); font-weight: 600; }

/* ── Реєстрація: помилка біля поля, живий чек-лист пароля ── */
.reg-field-err { margin:-4px 0 8px; font-size:.82rem; color:var(--danger, #dc2626); }
.tf-input[aria-invalid="true"] { border-color:var(--danger, #dc2626); }
.pw-check { margin:2px 0 10px; font-size:.82rem; }
.pw-check-list { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:4px 14px; }
.pw-check-list li { display:flex; align-items:center; gap:6px; color:var(--fg-muted); }
.pw-check-list li.is-ok { color:var(--success, #16a34a); }
.pw-check-list li.is-miss { color:var(--danger, #dc2626); font-weight:600; }
.pw-check-list li.pw-check-note { flex-basis:100%; }   /* перевіряє сервер — підказка, без позначки */
.pw-match { margin:6px 0 0; }
.pw-match.is-ok { color:var(--success, #16a34a); }
.pw-match.is-bad { color:var(--danger, #dc2626); }

/* Розрив сторінки PDF на екрані: підписана пунктирна лінія (Impfpass 11.10.2026). */
.tf-pgbreak { position: relative; margin: 14px -20px; border-top: 1px dashed #94a3b8; text-align: center; user-select: none; }
.tf-pgbreak span { position: relative; top: -0.75em; padding: 0 10px; background: #fff; color: #64748b; font: 600 11px/1.4 system-ui, sans-serif; letter-spacing: .02em; }
@media print { .tf-pgbreak { display: none !important; } }
/* Розрив сторінки PDF усередині таблиці: пунктир над рядком і підпис (data-pg). */
.tf-blk-table tr.tf-pgrow > td { border-top: 2px dashed #94a3b8; padding-top: 22px; }
.tf-blk-table tr.tf-pgrow > td:first-child { position: relative; }
.tf-blk-table tr.tf-pgrow > td:first-child::before { content: attr(data-pg); position: absolute; left: 4px; top: 3px; padding: 0 6px; background: #fff; color: #64748b; font: 600 11px/1.4 system-ui, sans-serif; white-space: nowrap; z-index: 1; user-select: none; }
@media print { .tf-blk-table tr.tf-pgrow > td { border-top-style: solid; padding-top: 5px; } .tf-blk-table tr.tf-pgrow > td:first-child::before { display: none; } }
.tf-hand-mark { display: none; font-style: italic; color: #475569; margin-right: .25em; user-select: none; }
.tf-hand--label .tf-hand-mark:not(.is-off) { display: inline; }
.tf-hand-x { margin-left: 2px; padding: 0 3px; border: 0; background: none; color: #94a3b8; font: inherit; font-style: normal; line-height: 1; cursor: pointer; }
.tf-hand-x:hover, .tf-hand-x:focus-visible { color: #b91c1c; }
@media print { .tf-hand-x { display: none; } }
.tf-hand-mode { display: inline-flex; align-items: center; gap: 6px; font-size: .8rem; color: var(--muted, #64748b); margin-right: 6px; }
.tf-hand-mode select { width: auto; font-size: .8rem; height: 30px; padding: 2px 28px 2px 8px; }
/* Ручний перенос рядка: «⤓» поруч із «+» і «×»; на лінії — «×» скасувати. */
.tf-row-brk {
  position: absolute; top: 2px; right: 46px;
  width: 18px; height: 18px; line-height: 1;
  padding: 0; border: 1px solid #cbd5e1; border-radius: 4px;
  background: #fff; color: #475569; font-size: .8rem;
  opacity: 0; cursor: pointer; transition: opacity .12s;
}
.tf-blk-table tr:hover .tf-row-brk, .tf-row-brk:focus-visible { opacity: 1; }
.tf-row-brk:hover { background: #e2e8f0; border-color: #475569; }
.tf-blk-table tr.tf-rowbrk > td:first-child::before { left: 26px; }
.tf-brk-cancel {
  position: absolute; top: 2px; left: 4px; z-index: 2;
  width: 18px; height: 18px; line-height: 1; padding: 0;
  border: 1px solid #94a3b8; border-radius: 4px; background: #fff; color: #b91c1c; font-size: .8rem; cursor: pointer;
}
.tf-brk-cancel:hover { background: #fee2e2; border-color: #b91c1c; }
@media print { .tf-row-brk, .tf-brk-cancel { display: none; } }

/* Вікно оплати: VIES не знайшов VAT-ID — попередження, оплата доступна (17.10.2026) */
.tf-vat-warn { margin: 0 0 14px; padding: 12px 14px; border-radius: 10px; font-size: .9rem; line-height: 1.45;
  background: rgba(245,158,11,.10); border: 1px solid rgba(245,158,11,.45); color: var(--text, inherit); }
.tf-vat-warn p { margin: 0; overflow-wrap: anywhere; }
.tf-vat-warn__links { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 8px !important; }
.tf-vat-warn__links a { font-weight: 600; }

/* Екран завантаження: бейдж «Дані обробляються в ЄС» поруч із «Допомога» (18.10.2026) */
.tf-upload-title { flex-wrap: wrap; row-gap: 8px; }
.tf-eu-badge { display: inline-flex; align-items: center; gap: 5px; padding: 4px 12px; border-radius: 999px;
  font-size: .75rem; font-weight: 600; line-height: 1.4; white-space: nowrap; text-decoration: none;
  color: #15803d; background: rgba(34,197,94,.10); border: 1.5px solid rgba(34,197,94,.45); }
.tf-eu-badge i { font-size: .8rem; }
.tf-eu-badge:hover, .tf-eu-badge:focus-visible { background: rgba(34,197,94,.18); color: #166534; }
[data-theme="dark"] .tf-eu-badge { color: #86efac; background: rgba(34,197,94,.12); border-color: rgba(34,197,94,.40); }
[data-theme="dark"] .tf-eu-badge:hover, [data-theme="dark"] .tf-eu-badge:focus-visible { color: #bbf7d0; background: rgba(34,197,94,.20); }

/* «Правове» → прийняті документи: кнопка «Завантажити PDF» праворуч у рядку (18.10.2026) */
.consent-accepted-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.consent-accepted-pdf { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-size: .85rem;
  font-weight: 600; white-space: nowrap; text-decoration: none; }
.consent-accepted-pdf i { font-size: 1rem; }
.consent-accepted-pdf:hover, .consent-accepted-pdf:focus-visible { text-decoration: underline; }

/* ES firma electrónica (Orden AUC/213/2025 art. 3.8): recuadro замість місця під печатку. */
.tf-cert-recuadro { display: inline-block; min-width: 320px; max-width: 100%; box-sizing: border-box; border: 1px solid #0f172a; color: #0f172a;
  padding: 6px 10px; text-align: center; margin-bottom: 10px; }
.tf-cert-recuadro p { margin: 2px 0; }
.tf-cert-es-heading, .tf-cert-es-firma { color: #0f172a; }
.tf-cert-es-heading { margin: 0 0 6px; }
.tf-cert-es-firma { margin-top: 16px; }

/* PDF / Word — контурні, формат видно за кольоровим значком (20.10.2026:
   заливки червоним/синім кричали й роздували картку історії). */
.btn.tf-dl { display: inline-flex; align-items: center; gap: 5px; font-weight: 600;
  color: var(--fg, #0f172a); background: transparent; border: 1px solid var(--border, #cbd5e1);
  border-radius: 8px; }
.btn.tf-dl:hover { background: var(--bg-subtle, rgba(148, 163, 184, .14)); color: var(--fg, #0f172a); }
.btn.tf-dl i { font-size: 1.05em; }
.btn.tf-dl--pdf i  { color: #dc2626; }
.btn.tf-dl--word i { color: #3b82f6; }   /* синій Word #2b579a на темній темі зливався */
/* Поки файл збирається (static/js/tf_download.js): натиснута крутиться, решта — бліді. */
.btn.tf-dl.tf-dl--off { opacity: .55; pointer-events: none; cursor: progress; }
.btn.tf-dl.tf-dl--busy { opacity: 1; }
.btn.tf-dl.tf-dl--busy i::before { content: ""; display: inline-block; width: .95em; height: .95em;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: tf-dl-spin .7s linear infinite; vertical-align: -.1em; }
@keyframes tf-dl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn.tf-dl.tf-dl--busy i::before { animation-duration: 2s; } }
@media (max-width: 460px) {
  /* Панель на телефоні ховає підписи (font-size:0); у PDF/Word підпис — і є формат. */
  .tf-result-toolbar .btn-sm.tf-dl { font-size: .8rem; gap: 5px; }
}

/* Дії картки історії — один ряд компактних кнопок 34px на будь-якій ширині. */
.tf-history-actions { align-items: center; gap: 6px; }
.tf-history-actions .btn-sm { height: 34px; padding: 0 10px; font-size: .85rem;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  white-space: nowrap; border-radius: 8px; }
.tf-history-actions .tf-delete-form .btn-sm { width: 34px; padding: 0; }
@media (max-width: 480px) {
  .tf-history-row > .tf-history-actions { flex: 1 1 100%; flex-wrap: nowrap; }
  .tf-history-actions > .btn-sm { flex: 0 1 auto; min-width: 0; padding: 0 8px; }
  .tf-history-actions > .btn-primary { flex: 1 1 auto; }
  .tf-history-actions .tf-delete-form { flex: 0 0 auto; margin-left: auto; }
}
@media (max-width: 360px) {
  /* Без значків: формат і так у підписі, «Відкрити» — повним словом. */
  .tf-history-actions { gap: 5px; }
  .tf-history-actions > .btn-sm { padding: 0 8px; font-size: .8rem; }
  .tf-history-actions > .btn-sm i { display: none; }
}
@media (max-width: 340px) {
  .tf-history-actions { gap: 4px; }
  .tf-history-actions > .btn-sm { padding: 0 6px; }
}

/* Групи панелі результату: «Зберегти зміни» | «Експорт» PDF·Word·Друк |
   навігація (20.10.2026, варіант A). Група переноситься цілою: підпис
   «Експорт» не відривається від своїх кнопок. */
.tf-act-grp { display: inline-flex; align-items: center; gap: 6px; flex: 0 1 auto;
  flex-wrap: wrap; min-width: 0; }
.tf-act-grp--export { padding-left: 10px; border-left: 1px solid var(--border); }
.tf-act-lbl { font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--fg-muted, #64748b); white-space: nowrap; }
.tf-lbl-short { display: none; }
/* Несохранені правки — кнопка в акценті, щоб її не пропустили. Селектор і
   !important — сильніші за «контурну» btn-primary з custom.css (body .btn.btn-primary
   { background: transparent !important }): без цього клас ставився, а фон
   лишався прозорим (замір у браузері 20.10.2026). */
body .btn.btn-primary.tf-save-btn--dirty { background: #d97706 !important;
  border-color: #d97706 !important; color: #fff !important;
  box-shadow: 0 0 0 3px rgba(217, 119, 6, .28) !important; }
body .btn.btn-primary.tf-save-btn--dirty:hover { background: #b45309 !important;
  border-color: #b45309 !important; }
/* Навігація — у першому ряду праворуч, поруч із вкладками; ряд дій — за нею. */
.tf-result-toolbar > .tf-act-grp--nav { order: 1; margin-left: auto; }
.tf-result-toolbar > .s-5b2be1db { order: 2; }
.tf-result-toolbar > .tf-toolbar-unpin { order: 3; }
@media (max-width: 1024px) {
  .tf-result-toolbar > .s-5b2be1db { margin-left: 0; flex: 1 1 100%; }
  .tf-result-toolbar > .tf-act-grp--nav { order: 3; margin-left: 0; }
  .tf-result-toolbar > .tf-toolbar-unpin { order: 4; }
  /* Планшет і телефон: кожна група — свій ряд; без «висячих» одиночних кнопок. */
  .tf-result-toolbar > .s-5b2be1db { gap: 8px; }
  .tf-result-toolbar > .s-5b2be1db::before { display: none; }
  .tf-act-grp { flex: 1 1 100%; }
  .tf-act-grp--export { padding-left: 0; border-left: 0; padding-top: 8px;
    border-top: 1px solid var(--border); }
  .tf-act-grp--nav { padding-top: 8px; border-top: 1px solid var(--border); }
}
@media (max-width: 460px) {
  /* Підпис «Зберегти» на телефоні видно (раніше font-size:0 лишав лише значок). */
  .tf-result-toolbar .btn-sm.tf-save-btn { font-size: .8rem; gap: 5px; display: inline-flex;
    align-items: center; }
  .tf-lbl-long { display: none; }
  .tf-lbl-short { display: inline; }
  .tf-result-toolbar .tf-act-grp .btn-sm { min-height: 36px; min-width: 36px;
    display: inline-flex; align-items: center; justify-content: center; }
  .tf-act-lbl { flex: 1 1 100%; }
  /* «До історії» / «Новий документ» — з підписом, не лише значком; тісно — у два ряди. */
  .tf-result-toolbar .tf-act-grp--nav .btn-sm { font-size: .8rem; gap: 5px; flex: 1 1 auto; }
  /* Рукописне: підпис над списком, список на всю ширину — не за край (320px). */
  .tf-hand-mode { flex: 1 1 100%; flex-wrap: wrap; margin-right: 0; min-width: 0; }
  .tf-hand-mode select { flex: 1 1 100%; min-width: 0; max-width: 100%; height: 40px; }
}
