/* ── Reset & Base ─────────────────────────────────────────────────────────── */
/* Токены дизайна — в static/tokens.css (подключается перед этим файлом). */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { font-size: 16px; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

body {
  font-family: var(--font-sans);
  background-color: var(--bg);
  background-image: var(--bg-decor);   /* тёмная: золотая аура сверху (эталон .ai) */
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--label);
  min-height: 100vh;
}

/* ── Auth Layout ──────────────────────────────────────────────────────────── */
/* 🔴 Мобильный канон посадки (Fold-first · CEO 27.07):
   · 100dvh вместо 100vh — на телефоне адресная строка динамическая, и 100vh
     считается по «большому» вьюпорту: раскладка думает, что места 844, а видно
     660 → низ карточки уезжает под сгиб, сверху зияет пустота. dvh считает по
     тому, что реально видно СЕЙЧАС.
   · margin-block:auto на контейнере вместо align-items:center — центр в свободной
     высоте, но при нехватке места верх не срезается за край (канон playbook 06,
     группа G п.3). align-items:center на переполнении рубит верх без доступа. */
.auth-body {
  display: flex;
  justify-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 24px 16px;
}

.auth-container { width: 100%; max-width: 420px; margin-block: auto; }

.auth-card {
  background: var(--surface);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 40px 36px;
  box-shadow: var(--elev-2);
}

.auth-logo {
  text-align: center;
  margin-bottom: 32px;
}

.logo-icon { display: flex; justify-content: center; margin-bottom: 10px; color: var(--accent); }
/* Куб холдинга на экране входа — тот же знак, что в шапке рабочих экранов.
   🔴 Размер по канону бренд-доминанты (CEO 27.07): знак — герой этого экрана, а не
   иконка при тексте. 120px в карточке 420 = 29% ширины (было 52px = 12%). Ассет
   gjx-cube-280.png держит запас под экраны с двойной плотностью пикселей.
   Ореол усилен: он растворяет тёмную кайму арта на светлой теме. */
.logo-cube { display: block; width: 120px; height: 120px; margin: 0 auto 14px;
  filter: drop-shadow(0 0 26px rgba(235, 197, 84, .34)); }

.logo-text {
  font-family: var(--font-brand);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: .05em;
  color: var(--c-gold);           /* канон: GOLDJAXE — золотом (эталон .ai) */
}
.logo-text span { color: var(--accent); }
.logo-text .br { color: var(--label4); font-weight: 400; }

.logo-sub {
  font-family: var(--font-brand);
  font-size: 15px;
  color: var(--label);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-top: 7px;
}
/* Канон wordmark (эталон .ai): GOLDJAXE — золото, имя продукта в скобках — цветом
   основного текста. Прежде было наоборот (белое имя холдинга + золотой SCRIBE) —
   это ставило продукт выше холдинга и расходилось с шапками экосистемы. */
.logo-sub .gold { color: var(--label); }
.logo-sub .br { color: var(--label4); font-weight: 400; }

.auth-card h2 {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.3px;
  margin-bottom: 8px;
}

.auth-desc {
  font-size: 15px;
  color: var(--label3);
  line-height: 1.5;
  margin-bottom: 24px;
}

/* ── Sent State ───────────────────────────────────────────────────────────── */
.sent-state { text-align: center; }
.sent-icon { display: flex; justify-content: center; margin-bottom: 16px; color: var(--accent); }
.sent-state h2 { font-size: 22px; font-weight: 700; margin-bottom: 8px; }
.sent-state p { font-size: 15px; color: var(--label3); line-height: 1.5; margin-bottom: 8px; }
.sent-state .note { font-size: 13.5px; color: var(--label4); margin-bottom: 24px; }

/* ── Экран входа на телефоне ────────────────────────────────────────────────
   Десктопный вертикальный ритм (паддинги 40/36, отступ логотипа 32) в телефоне
   выдавливал карточку за сгиб — вместе со 100vh это и давало «сверху пусто,
   низ приходится доскроллить». Здесь ритм ужимается так, чтобы вся карточка
   вместе с кнопкой стояла в видимой части экрана даже при показанной адресной
   строке (~660 CSS-px у Brave/Chrome на Android). Знак холдинга при этом
   остаётся крупным — он бренд-доминанта экрана, ужимаем отступы, не лого. */
@media (max-width: 560px) {
  .auth-body { padding: 14px 12px; }
  .auth-card { padding: 26px 20px; }
  .auth-logo { margin-bottom: 20px; }
  .logo-cube { width: 96px; height: 96px; margin-bottom: 12px;
    filter: drop-shadow(0 0 22px rgba(235, 197, 84, .34)); }
  .logo-text { font-size: 22px; }
  .logo-sub { font-size: 13px; margin-top: 6px; }
  .auth-card h2 { font-size: 20px; }
  .auth-desc { font-size: 14px; margin-bottom: 18px; }
  .sent-state h2 { font-size: 20px; }
  .sent-state p { font-size: 14px; }
  /* Переключатель темы прижимаем к углу — в узком экране он не должен
     висеть посреди пустоты и спорить с карточкой за внимание. */
  .auth-body ~ .app-theme,
  body.auth-body > .app-theme { top: 10px !important; right: 10px !important; }
}

/* Экстрим 358-390: держим тот же строй, срезаем только воздух */
@media (max-width: 400px) {
  .auth-card { padding: 22px 17px; }
  .logo-cube { width: 88px; height: 88px; }
  .auth-logo { margin-bottom: 17px; }
}

/* ── Error Banner ─────────────────────────────────────────────────────────── */
.error-banner {
  background: var(--c-danger-bg);
  border: 1px solid var(--c-danger-line);
  border-radius: var(--radius-sm);   /* панель-уведомление — канон sm (не терминальный бейдж) */
  padding: 12px 14px;
  font-size: 14px;
  color: var(--c-danger);
  margin-bottom: 20px;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.error-icon { flex-shrink: 0; display: inline-flex; }

/* Плашка ошибки живёт до закрытия крестиком: сообщение о сорванной загрузке нужно
   успеть прочитать и передать в поддержку. Поэтому — колонка: строка сообщения,
   раскрывающиеся подробности, кнопка повтора. */
.error-banner { flex-direction: column; gap: 10px; }
/* Нейтральный тон той же плашки: сообщение об отмене — не ошибка, красная рамка
   и треугольник тревоги заставляли бы искать несуществующую проблему. */
/* Рамку выводим из --c-info: отдельного --c-info-line в токенах нет, а хардкод
   цвета разъехался бы с темой. */
.error-banner.is-info {
  background: var(--c-info-bg); color: var(--c-info);
  border-color: color-mix(in srgb, var(--c-info) 35%, transparent);
}
.error-banner__head { display: flex; align-items: flex-start; gap: 8px; width: 100%; }
.error-banner__text { flex: 1; min-width: 0; word-break: break-word; }
.error-banner__close {
  flex: none;
  background: none;
  border: 0;
  padding: 2px;
  margin: -2px -2px 0 0;
  color: inherit;
  opacity: .65;
  cursor: pointer;
  display: inline-flex;
}
.error-banner__close:hover { opacity: 1; }
.error-banner__close:focus-visible { outline: 2px solid var(--c-danger); outline-offset: 2px; }
.error-banner__details { font-size: 13px; }
.error-banner__details > summary { cursor: pointer; opacity: .8; }
.error-banner__details > summary:hover { opacity: 1; }
.error-banner__pre {
  margin: 8px 0 0;
  padding: 10px;
  background: var(--c-bg);
  border: 1px solid var(--c-danger-line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono, monospace);
  font-size: 12px;
  line-height: 1.5;
  color: var(--c-ink);
  white-space: pre-wrap;
  word-break: break-word;
  user-select: all;
}
.error-banner__copy,
.error-banner__retry { align-self: flex-start; margin-top: 8px; }

/* ── Иконки (набор Lucide, наследуют цвет текста) ─────────────────────────── */
.ic  { width: 18px; height: 18px; display: inline-block; vertical-align: -0.18em; flex: none; }
.ic-sm { width: 14px; height: 14px; display: inline-block; vertical-align: -0.15em; flex: none; }
.ic-lg { width: 40px; height: 40px; display: block; flex: none; }

/* ── Forms ────────────────────────────────────────────────────────────────── */
.auth-form { display: flex; flex-direction: column; gap: 16px; }
.form-fields { display: flex; flex-direction: column; gap: 14px; }

.input-group { display: flex; flex-direction: column; gap: 6px; }

/* только МЕТКА поля (прямой ребёнок) — НЕ label.preset-card внутри сетки пресетов */
.input-group > label {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--label2);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.optional { font-weight: 400; color: var(--label4); }

.input-group input {
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid var(--separator);
  border-radius: var(--radius-sm);
  font-size: 16px;
  font-family: inherit;
  color: var(--label);
  background: var(--surface);
  transition: border-color 0.15s, box-shadow 0.15s;
  outline: none;
}
.input-group input:focus {
  border-color: var(--accent);
  box-shadow: var(--focus-ring);
}
.input-group input::placeholder { color: var(--label4); }

/* ── Buttons — фирменный CTA: капс, резкие углы, светлая=бронза+белый,
     тёмная=золото+обсидиан (канон CTA light v2 / dark) ─────────────────────── */
.btn-primary {
  width: 100%;
  min-height: 48px;              /* touch-таргет ≥48 (канон mobile) */
  padding: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--c-gold-contrast);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);   /* главный CTA — канон ui-kit sm (4px), капс-моно сохранён */
  font-size: 14px;
  font-weight: 700;
  font-family: var(--font-mono);
  letter-spacing: .10em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--elev-1);
  transition: background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.1s;
}
.btn-primary:hover:not(:disabled) {
  /* Канон Макса: яркий золотой CTA на hover СВЕТЛЕЕТ (не темнеет) — заливка идёт
     в яркий стоп #EBC554, тёмный текст (--c-gold-contrast) остаётся читаемым
     (~10:1). Прежний уход в тёмную бронзу давал тёмный-на-тёмном. */
  background: var(--c-gold-mid);
  border-color: var(--c-gold-mid);
  color: var(--c-gold-contrast);
  box-shadow: var(--elev-2), 0 0 18px rgba(153,128,24,.22);
}
.btn-primary:active:not(:disabled) { transform: translateY(1px); box-shadow: none; }
.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }

.btn-secondary {
  padding: 10px 20px;
  background: var(--bg);
  color: var(--label);
  border: 1.5px solid var(--separator);
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s;
}
.btn-secondary:hover { background: var(--separator); }

/* Хедер — общий для всех экранов: .app-topbar в components.css. */

/* ── Main Content ──────────────────────────────────────────────────────────
   Десктоп: рабочая карточка (пресеты 3 в ряд) — главный экран влезает в фолд
   ноутбука без вертикального скролла (канон Fold-first 1440×800).
   Потолок 960px намеренный: на широком мониторе форма во всю ширину выглядит
   разреженной, компактный блок в центре читается лучше. */
.main-content {
  max-width: 820px;   /* шире прежних 680: запас под рост числа пресетов; вровень с .wrap отчёта */
  /* width:100% обязателен: .app-shell — колоночный flex, и без явной ширины блок
     ужимается по содержимому. Замер на 1024px: было 583px вместо заявленных 820 —
     карточка годами была уже, чем задумано, на планшетах и небольших ноутбуках.
     max-width при этом продолжает ограничивать сверху. */
  width: 100%;
  margin: 0 auto;
  padding: 20px 20px 48px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* Расширения на широких экранах НЕТ намеренно: 960 читалось растянуто, минус 15%
   даёт 816 — это те же базовые 820, поэтому отдельный медиазапрос не нужен.
   Карточка одинаковой ширины на любом мониторе. */
/* Шире 960 НЕ идём. Пробовали 1120 на широком мониторе: воздуха по бокам меньше,
   но плитки пресетов растягиваются до ~337px, подпись занимает треть строки, и
   панель выглядит разреженной — хуже, чем компактная карточка в центре. Пустое
   поле по краям на 2000px нормально, растянутая форма — нет. */

/* ── Шапка карточки: заголовок слева + статус-плашка справа (экономия фолда) ── */
.card-head {
  display: flex;
  /* center, а не flex-start: заголовок и статус-плашка — два элемента одной строки,
     при flex-start плашка вставала ниже базовой линии заголовка. */
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
/* Базис 240, а не 520: при 520 заголовок и статус-плашка не помещались в строку
   карточки (685px по факту) и плашка падала на второй ряд — шапка карточки росла до
   83px и выталкивала кнопку за сгиб ноутбука. 240 + плашка 410 + зазор 12 = 662 ≤ 685:
   оба стоят в одну линию (канон симметрии), на узких экранах перенос срабатывает сам. */
.card-head__text { flex: 1 1 240px; min-width: 0; }
.card-head .card-title { margin-bottom: 4px; }
.card-head .card-desc { margin-bottom: 0; }
/* Без padding-top: он подгонял плашку под описание, которого в шапке больше нет,
   и она висела ниже заголовка. Выравнивание задаёт align-items у .card-head. */
.card-head .status-bar { flex: none; }
@media (max-width: 700px) {
  .card-head { flex-direction: column; gap: 10px; }
  /* в колонке flex-basis 520px стал бы ВЫСОТОЙ — сбрасываем */
  .card-head__text { flex: 0 0 auto; }
  .card-head .status-bar { padding-top: 0; }
}

/* ── Status Bar — терминальная плашка (канон ai-status-badge эталона .ai) ──── */
.status-bar { display: flex; }

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* Вертикальный отступ 5px, а не 8: при 8 плашка выходила 35px против 25px у
     заголовка рядом и читалась крупнее и ниже него, хотя центры совпадали.
     Теперь высоты сопоставимы, строка выглядит единой. */
  padding: 5px 14px;
  border-radius: 0;   /* капс-моно статус-плашка — терминальный слой, острый край намеренно */
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  border: 1px solid;
}
/* Знак продукта в статус-плашке — приглушён, чтобы вести взгляд к индикатору
   состояния, а не спорить с ним. */
.status-pill__ic { display: inline-flex; align-items: center; opacity: .72; flex-shrink: 0; }
.status-pill.busy {
  background: var(--c-warn-bg);
  color: var(--c-warn);
  border-color: color-mix(in srgb, var(--c-warn) 35%, transparent);
}
.status-pill.ready {
  background: var(--c-success-bg);
  color: var(--c-success);
  border-color: color-mix(in srgb, var(--c-success) 35%, transparent);
}

.pulse {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--c-warn);
  box-shadow: 0 0 7px var(--c-warn);
  animation: pulse 1.4s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.8); }
}

.dot-green {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 7px var(--green);
  flex-shrink: 0;
}

/* ── Card ─────────────────────────────────────────────────────────────────── */
.card {
  background: var(--surface);
  border: 1px solid var(--separator);
  border-radius: var(--radius-lg);
  padding: 24px 26px 26px;
  box-shadow: var(--elev-1);
}
.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: .01em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
/* «?» рядом с ЗАГОЛОВКОМ крупнее строчной help-q — выравниваем к кеглю заголовка */
.card-title .help-q { width: 18px; height: 18px; font-size: 12px; }
.card-desc {
  font-size: 14px;
  color: var(--label3);
  margin-bottom: 24px;
}

/* ── Drop Zone — терминальный приёмник: сетка-фон + угловые скобки бренда.
     Компактная горизонтальная полоса (иконка + тексты) — экономия фолда. ──── */
.drop-zone {
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--radius-md);   /* крупный приёмник — канон md; угловые скобки держат брутал-акцент */
  display: flex;
  align-items: center;
  justify-content: center;           /* группа иконка+текст по центру зоны, а не в углу */
  column-gap: 16px;
  min-height: 112px;
  padding: 20px 22px;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s, box-shadow 0.25s;
  margin-bottom: 18px;
  position: relative;
  background-image:
    linear-gradient(to right, rgba(153,128,24,.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(153,128,24,.045) 1px, transparent 1px);
  background-size: 24px 24px;
}
:root[data-theme="dark"] .drop-zone {
  background-image:
    linear-gradient(to right, rgba(235,197,84,.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(235,197,84,.05) 1px, transparent 1px);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .drop-zone {
    background-image:
      linear-gradient(to right, rgba(235,197,84,.05) 1px, transparent 1px),
      linear-gradient(to bottom, rgba(235,197,84,.05) 1px, transparent 1px);
  }
}
/* угловые маркеры-скобки — square brackets айдентика GOLDJAXE */
.drop-zone::before, .drop-zone::after {
  content: '';
  position: absolute;
  width: 14px; height: 14px;
  border: 2px solid var(--c-gold-line);
  transition: border-color 0.2s;
  pointer-events: none;
}
/* Г-образные скобки сдвинуты внутрь на радиус (md 8px) — обнимают скруглённый
   угол, а не висят вне контура. Свой малый радиус повторяет кривизну угла. */
.drop-zone::before { top: 5px; left: 5px; border-right: 0; border-bottom: 0; border-top-left-radius: var(--radius-xs); }
.drop-zone::after  { bottom: 5px; right: 5px; border-left: 0; border-top: 0; border-bottom-right-radius: var(--radius-xs); }
.drop-zone:hover, .drop-zone.drag-over {
  border-color: var(--accent);
  background-color: var(--accent-bg);
  box-shadow: 0 0 0 1px var(--c-gold-line), 0 0 24px rgba(153,128,24,.12);
}
.drop-zone:hover::before, .drop-zone:hover::after,
.drop-zone.drag-over::before, .drop-zone.drag-over::after { border-color: var(--accent); }
.drop-zone.has-file {
  border-color: var(--green);
  background-color: var(--c-success-bg);
  box-shadow: none;
}
.drop-zone.has-file::before, .drop-zone.has-file::after { border-color: var(--green); }

.drop-icon { flex: none; margin: 0; color: var(--label3); display: flex; justify-content: center; }
.drop-icon .ic-lg { width: 34px; height: 34px; }
.drop-zone:hover .drop-icon, .drop-zone.drag-over .drop-icon { color: var(--accent); }
.drop-text { display: flex; flex-direction: column; }   /* заголовок + подпись + инфо о файле — одна колонка */
.drop-title { font-size: 15px; font-weight: 600; color: var(--label); margin-bottom: 3px; }
.drop-sub { font-family: var(--font-mono); font-size: 13px; letter-spacing: .05em; color: var(--label4); text-transform: uppercase; }

.file-info { margin-top: 8px; }
.file-name { font-size: 14px; font-weight: 600; color: var(--label); }
.file-size { font-size: 13.5px; color: var(--label4); margin-top: 2px; }

/* ── Progress ─────────────────────────────────────────────────────────────── */
/* ══════════════════════════════════════════════════════════════════════════
   Ход работы — ОДИН блок на обе фазы: закачку и обработку.
   Меняется содержимое сцены и подписи ячеек; рамка, высота и дорожка общие,
   поэтому переход между фазами не двигает кнопку и соседние элементы.
   Цвет — единственный признак смены фазы, читается периферийным зрением:
   золото на закачке, зелёный на обработке.
   ══════════════════════════════════════════════════════════════════════════ */
.progress-wrap { margin: 12px 0; }

.gauge {
  --g-line: var(--accent);
  --g-soft: color-mix(in srgb, var(--g-line) 20%, transparent);
  /* Неоновая подсветка двумя слоями: ближний даёт плотность, дальний ореол.
     Компенсирует тонкую линию 1.5px — без свечения она читалась бы бледнее
     прежней двухпиксельной. */
  --g-glow: color-mix(in srgb, var(--g-line) 75%, transparent);

  display: grid;
  /* minmax(0, 1fr), а не 1fr: по умолчанию колонка не сжимается ниже min-content,
     и конвейер этапов раздувал её до 348px внутри блока шириной 296px —
     содержимое вылезало за экран и давало горизонтальную прокрутку на телефоне. */
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: stretch;
  border: 1px solid var(--separator);
  border-radius: var(--radius-md);
  padding: 7px 10px;
  background: var(--bg);
}
.gauge.is-processing { --g-line: #58B368; }   /* фаза обработки — зелёный */

.gauge__stage { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.gauge__view  { flex: 1 1 auto; min-height: 30px; position: relative; }
.gauge__view > * { position: absolute; inset: 0; }
/* Скрытие сцены — КЛАССОМ, а не атрибутом hidden. Для <svg> присваивание
   `el.hidden = true` ставит только свойство и НЕ отражается в атрибут, поэтому
   селектор [hidden] элемент не находил: волна закачки оставалась лежать поверх
   конвейера обработки. !important — потому что ниже .gauge__svg задаёт
   display:block с той же специфичностью. */
.gauge__view .is-off { display: none !important; }

.gauge__svg { display: block; width: 100%; height: 100%; overflow: visible; }
.gauge__area { fill: var(--g-soft); stroke: none; }
.gauge__path {
  fill: none; stroke: var(--g-line); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 2px var(--g-glow)) drop-shadow(0 0 5px var(--g-glow));
}
.gauge__dot { fill: var(--g-line);
  filter: drop-shadow(0 0 3px var(--g-glow)) drop-shadow(0 0 6px var(--g-glow)); }
.gauge__ring { fill: none; stroke: var(--g-line); stroke-width: 1.2; opacity: .4; }

.gauge__bar {
  height: 4px; background: var(--separator);
  border-radius: 2px; overflow: hidden;
}
.gauge__bar i {
  display: block; height: 100%; width: 0%;
  background: var(--g-line);
  box-shadow: 0 0 6px var(--g-glow);
  /* Короткий ease-out: события прогресса приходят раз в ~400 мс, а прежние
     0.3s linear не успевали доехать — полоса вечно отставала от цифры. */
  transition: width .25s ease-out;
}

.gauge__stats { display: flex; gap: 14px; align-items: center; }
/* Подпись ПОД значением: слова перед каждым числом съедали ширину, которая нужнее
   волне. Столбик из двух строк держится в высоте блока, потому что подпись мелкая
   (8.5px) и без своего межстрочного запаса — общая высота ячейки ниже сцены. */
.gauge__cell {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 1px; line-height: 1.15;
}
.gauge__k {
  font-family: var(--font-mono); font-size: 8.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--label3); white-space: nowrap;
}
.gauge__v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 13px; font-weight: 700; color: var(--label);
  white-space: nowrap; display: inline-block; text-align: right;
}
/* Ширина зарезервирована под самое длинное значение: иначе «3 мин 15 с» →
   «3 мин 7 с» укорачивалось и соседние ячейки прыгали на каждом обновлении.
   tabular-nums выравнивает цифры между собой, но не спасает от смены их числа. */
.gauge__v[data-w="pct"]   { min-width: 4ch; }
.gauge__v[data-w="speed"] { min-width: 9ch; }
.gauge__v[data-w="eta"]   { min-width: 11ch; }

/* ── Конвейер этапов (фаза обработки) ────────────────────────────────────── */
/* min-width:0 обязателен на обоих уровнях: без него flex не даёт содержимому
   сжаться ниже «естественной» ширины, и конвейер вылезал за правый край
   экрана на телефоне, давая горизонтальную прокрутку. */
.stg { display: flex; align-items: center; height: 100%; min-width: 0; overflow: hidden; }
.stg__item { display: flex; align-items: center; gap: 6px; min-width: 0; }
.stg__dot {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--separator);
  transition: background .3s ease, box-shadow .3s ease;
}
.stg__item.is-done .stg__dot { background: var(--g-line); opacity: .55; }
.stg__item.is-now  .stg__dot {
  background: var(--g-line); box-shadow: 0 0 7px var(--g-glow);
  animation: gaugePulse 1.4s ease-in-out infinite;
}
@keyframes gaugePulse {
  0%, 100% { opacity: .35; transform: scale(.8); }
  50%      { opacity: 1;   transform: scale(1.15); }
}
.stg__name {
  font-family: var(--font-mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--label3); white-space: nowrap;
}
.stg__item.is-now  .stg__name { color: var(--label); }
.stg__link {
  flex: 1 1 auto; height: 1px; min-width: 10px; margin: 0 8px;
  background: var(--separator); position: relative; overflow: hidden;
}
.stg__item.is-done + .stg__link {
  background: color-mix(in srgb, var(--g-line) 45%, transparent);
}
.stg__link.is-active::after {
  content: ''; position: absolute; inset: 0; width: 30%;
  background: linear-gradient(90deg, transparent, var(--g-line), transparent);
  animation: gaugeFlow 1.5s linear infinite;
}
@keyframes gaugeFlow { from { transform: translateX(-100%) } to { transform: translateX(400%) } }
/* Узкий экран: названия этапов не влезают, остаются точки — этап читается в ячейке.
   min-width связок тоже снимаем: при 10px четыре этапа со связками не влезали
   в 390px и конвейер вылезал за экран, давая горизонтальную прокрутку. */
@media (max-width: 700px) {
  .stg__name { display: none; }
  .stg__link { margin: 0 5px; min-width: 0; }
}

/* ── Реплика над блоком ──────────────────────────────────────────────────── */
/* Маркер — три точки «печатает», а НЕ пульсирующий кружок: рядом уже мигает
   точка текущего этапа, и две зелёные точки с некратными периодами (1,6 с и
   1,4 с) давали мерцающий узор биения. Здесь анимация про ТЕКСТ, не про
   прогресс, и цвет нейтральный — конкуренции за внимание нет. */
.gauge-say {
  display: flex; align-items: center; gap: 7px;
  margin-bottom: 7px; padding-left: 11px;   /* вровень с первой точкой конвейера */
  font-size: 12.5px; color: var(--label2);
  min-height: 18px;
}
.gauge-say[hidden] { display: none; }
.gauge-say__mark { flex: none; display: inline-flex; gap: 3px; align-items: center; }
.gauge-say__mark span {
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--label3); opacity: .35;
  animation: gaugeTyping 1.4s ease-in-out infinite;
}
.gauge-say__mark span:nth-child(2) { animation-delay: .18s; }
.gauge-say__mark span:nth-child(3) { animation-delay: .36s; }
@keyframes gaugeTyping { 0%, 60%, 100% { opacity: .28 } 30% { opacity: .9 } }
.gauge-say__text {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: opacity .3s ease, transform .3s ease;
}
.gauge-say__text.is-out { opacity: 0; transform: translateY(-3px); }

/* ── Ожидание в очереди ──────────────────────────────────────────────────── */
/* Отдельная фаза, а не «обработка с нулём»: пока распознаватель занят ЧУЖОЙ
   записью, сервис не знает, сколько ей осталось, — своего процента и оценки
   времени у нас нет и быть не может. Прежде здесь шла анимация расшифровки,
   и человек в очереди видел, будто его запись уже разбирают. */
.gauge.is-waiting { --g-line: var(--label3); }
.wai {
  display: flex; align-items: center; min-width: 0;
  overflow: hidden; height: 100%; padding-left: 4px;
}
.wai.is-off { display: none !important; }

/* Радар: точка и расходящиеся от неё круги — «слушаю, жду своей очереди».
   Заполняемая шкала здесь соврала бы (любой её процент выдуман), а бегущий блик
   читался как «работа идёт». Круги говорят только о готовности слушать.
   Перекликается со значком микрофона в плашке статуса рядом. */
.wai__radar { position: relative; flex: none; width: 26px; height: 26px; }
.wai__radar b, .wai__radar s {
  position: absolute; left: 50%; top: 50%;
  width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%;
}
.wai__radar b { background: var(--accent); }
.wai__radar s {
  border: 1px solid var(--accent); opacity: 0;
  animation: waiPing 2.6s ease-out infinite;
}
/* Задержки в трети периода — круги идут ровной чередой, без сгущения. */
.wai__radar s:nth-of-type(2) { animation-delay: .87s; }
.wai__radar s:nth-of-type(3) { animation-delay: 1.74s; }
@keyframes waiPing {
  from { transform: scale(1);   opacity: .75; }
  to   { transform: scale(5.2); opacity: 0; }
}
/* Луч вправо: гасящийся градиент связывает радар с остальной шириной блока,
   иначе точка висела бы в пустоте у левого края. */
.wai__line {
  flex: 1 1 auto; min-width: 0; height: 1px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent) 35%, transparent), transparent);
}
/* Дорожка в ожидании — пунктир вместо заливки: та же мысль, что и у блика. */
.gauge__bar.is-indet i {
  width: 100% !important; background: transparent; box-shadow: none;
  background-image: repeating-linear-gradient(90deg,
    var(--separator) 0 6px, transparent 6px 12px);
}
/* Без движения радар остаётся статичным знаком: точка и один круг вокруг неё —
   смысл «жду» читается и без анимации. */
@media (prefers-reduced-motion: reduce) {
  .wai__radar s { animation: none; opacity: .4; transform: scale(3); }
  .wai__radar s:nth-of-type(2), .wai__radar s:nth-of-type(3) { display: none; }
}
/* В очереди у нас нет ни скорости, ни срока — прочерки в этих ячейках занимали бы
   ширину, ничего не сообщая. Прячем их, оставляя только статус. */
.gauge__stats.is-lean .gauge__cell:not(:first-child) { display: none; }

/* ── Отмена ──────────────────────────────────────────────────────────────── */
/* Намеренно тихая: мелкая серая ссылка по центру под основной кнопкой. Красной
   кнопки здесь быть не должно — действие редкое и разрушительное, оно не обязано
   притягивать взгляд. Защита от промаха — не размер, а подтверждение в два шага. */
.cancel-row {
  display: flex; justify-content: center; align-items: center;
  gap: 8px; min-height: 22px; margin-top: 8px; flex-wrap: wrap;
}
.cancel-row[hidden] { display: none; }
.cancel-link, .cancel-yes, .cancel-no {
  font: inherit; font-size: 12px; background: none; border: 0;
  padding: 4px 6px; cursor: pointer; color: var(--label3);
  border-radius: var(--radius-sm);
  transition: color .2s ease, background-color .2s ease;
}
.cancel-link:hover { color: var(--label2); }
.cancel-link:focus-visible, .cancel-yes:focus-visible, .cancel-no:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.cancel-confirm {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--label2);
}
.cancel-confirm[hidden] { display: none; }
/* Подтверждение окрашено, а первый шаг — нет: цвет появляется только тогда,
   когда человек уже выразил намерение. */
.cancel-yes { color: var(--red); font-weight: 600; }
.cancel-yes:hover { background: color-mix(in srgb, var(--red) 12%, transparent); }
.cancel-no { color: var(--label2); font-weight: 600; }
.cancel-no:hover { background: var(--separator); }

/* ── Готово ──────────────────────────────────────────────────────────────── */
.gauge.is-done { --g-line: #58B368; }
.gauge__done {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  font-size: 12.5px; color: var(--label);
}
.gauge__done.is-off { display: none !important; }
.gauge__done svg { flex: none; width: 15px; height: 15px; color: var(--g-line); }
.gauge__done a { color: var(--g-line); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--g-line) 45%, transparent); }
.gauge__done a:hover { border-bottom-color: var(--g-line); }

@media (max-width: 560px) {
  .gauge { grid-template-columns: minmax(0, 1fr); }
  .gauge__stats { justify-content: space-between; gap: 8px; flex-wrap: wrap; }
  /* Резерв ширины снимаем: три ячейки (4+9+11 знаков) не помещались в 390px и
     вылезали за экран. Прокрутка хуже, чем небольшое смещение цифр, а на
     телефоне ячейки и так стоят через space-between — сдвиг почти не виден. */
  .gauge__v[data-w="pct"],
  .gauge__v[data-w="speed"],
  .gauge__v[data-w="eta"] { min-width: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .gauge *, .gauge *::before, .gauge *::after,
  .gauge-say *, .gauge-say *::before, .gauge-say *::after {
    transition: none !important; animation: none !important;
  }
}

.btn-upload { margin-top: 8px; }

/* Стили карточки результата (.result-card, .ios-check, pop-in) удалены вместе с
   самой карточкой: она дублировала блок хода работы худшей версией — её статус
   застывал на «Обработка начнётся сразу» навсегда. */

/* ── Status Page ──────────────────────────────────────────────────────────── */
.job-id-badge {
  display: inline-block;
  background: var(--bg);
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--label3);
  margin-bottom: 24px;
  font-family: var(--font-mono);
}
.status-rows { display: flex; flex-direction: column; gap: 0; }
.srow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 13px 0;
  border-bottom: 1px solid var(--separator);
  font-size: 15px;
}
.srow:last-child { border-bottom: none; }
.slabel { color: var(--label3); }
.sval { font-weight: 500; color: var(--label); text-align: right; max-width: 60%; }

/* Капс-моно бейджи статуса — терминальный слой айдентики: острый край (0) намеренно,
   как .dtable-badge и канон-бейджи ui-kit. Радиусы-токены их не касаются. */
.badge-green {
  background: var(--c-success-bg); color: var(--c-success);
  border: 1px solid color-mix(in srgb, var(--c-success) 35%, transparent);
  padding: 3px 10px; border-radius: 0;
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
}
.badge-orange {
  background: var(--c-warn-bg); color: var(--c-warn);
  border: 1px solid color-mix(in srgb, var(--c-warn) 35%, transparent);
  padding: 3px 10px; border-radius: 0;
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
}
.badge-gray {
  background: var(--c-surface-2); color: var(--label3);
  border: 1px solid var(--c-line);
  padding: 3px 10px; border-radius: 0;
  font-family: var(--font-mono); font-size: 12px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
}

/* Строки .rrow/.rlabel/.rval удалены с карточкой результата — других мест
   применения у них не было. */

/* ── Empty State ──────────────────────────────────────────────────────────── */
.empty-state { text-align: center; padding: 40px 0; }
.empty-icon { font-size: 40px; margin-bottom: 12px; }
.empty-state p { color: var(--label3); font-size: 15px; }

/* ── Preset block ─────────────────────────────────────────────────────────── */
.preset-block { margin-top: 8px; }
.preset-block-label {
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: 12px; font-weight: 700; color: var(--label2);
  text-transform: uppercase; letter-spacing: .08em; margin-bottom: 4px;
}
.preset-sub {
  font-size: 14px; color: var(--label3); margin-bottom: 8px;
}

.help-btn {
  width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--separator); background: var(--surface);
  color: var(--label3); font-size: 13px; font-weight: 700; line-height: 1;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  transition: all 0.15s ease;
}
.help-btn:hover { background: var(--accent-bg); color: var(--accent); border-color: var(--accent); }

.preset-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(172px, 1fr));
  gap: 8px; margin-bottom: 8px;
}
/* Три колонки, а не auto-fill: после фикса ширины (.main-content width:100%) карточка
   на 820-960px наконец занимает заявленное место, и auto-fill стал раскладывать
   пресеты по 4 в ряд шириной ~175px — «Синк / команды» рвался пополам, а подзаголовок
   Q-Check растягивался на 4 строки. Три колонки держат плитку не уже ~240px,
   заголовок помещается в строку. */
@media (min-width: 900px) {
  .preset-grid { grid-template-columns: repeat(3, 1fr); }
}
.preset-card {
  position: relative; display: flex; align-items: flex-start; gap: 9px;
  padding: 10px 12px; border: 1px solid var(--c-line-strong);
  border-radius: var(--radius-md); background: var(--surface);   /* карточка выбора — канон md (8px) */
  cursor: pointer;
  transition: transform 0.25s ease, border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
}
/* брутальный hover — сдвиг + жёсткая золотая тень (мини-версия канона service-card) */
.preset-card:hover {
  border-color: var(--c-gold-line);
  background: var(--accent-bg);
  transform: translate(-2px,-2px);
  box-shadow: 4px 4px 0 rgba(201,163,50,.22), 0 0 18px rgba(153,128,24,.10);
}
:root[data-theme="dark"] .preset-card:hover {
  box-shadow: 4px 4px 0 rgba(235,197,84,.28), 0 0 22px rgba(235,197,84,.14);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .preset-card:hover {
    box-shadow: 4px 4px 0 rgba(235,197,84,.28), 0 0 22px rgba(235,197,84,.14);
  }
}
.preset-card.is-active {
  border-color: var(--accent); background: var(--accent-bg);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.preset-card input[type=radio] {
  position: absolute; opacity: 0; pointer-events: none;
}
.preset-icon { color: var(--label2); display: flex; align-items: center; }
.preset-icon svg { width: 22px; height: 22px; }
.preset-card.is-active .preset-icon { color: var(--accent); }
.preset-body { flex: 1; min-width: 0; }
.preset-name {
  display: flex; align-items: flex-start; gap: 5px;
  font-size: 14px; font-weight: 600; color: var(--label); margin-bottom: 2px;
}
.preset-name-text { flex: 0 1 auto; min-width: 0; line-height: 1.3; }
.preset-short { font-size: 13.5px; color: var(--label3); line-height: 1.35; }
.preset-skeleton, .preset-error {
  grid-column: 1 / -1; text-align: center; color: var(--label3);
  padding: 16px; font-size: 13px;
}
.preset-error { color: var(--red); }

/* Кнопка предпросмотра состава пресета + поповер «Что внутри» */
.preset-info-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; margin-top: 1px;
  width: 18px; height: 18px; padding: 0;
  border: none; background: transparent; color: var(--label3);
  border-radius: 50%; cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}
.preset-info-btn svg { width: 14px; height: 14px; display: block; }
.preset-info-btn:hover,
.preset-info-btn:focus-visible,
.preset-info-btn[aria-expanded="true"] {
  color: var(--accent); background: var(--accent-bg); outline: none;
}
.preset-card.is-active .preset-info-btn { color: var(--accent); }

.preset-popover {
  position: fixed; z-index: 1000; max-width: 300px; width: max-content;
  background: var(--surface); border: 1px solid var(--separator);
  border-radius: var(--radius-md); box-shadow: var(--elev-2);
  padding: 12px 14px; font-size: 13px; color: var(--label2); line-height: 1.5;
  animation: pp-in 0.12s ease;
}
/* Мобила: поповер пресета — по горизонтали центр экрана (координаты ставит JS),
   по вертикали у кнопки. Шире и крупнее для комфортного чтения на телефоне. */
.preset-popover.is-mobile {
  /* Горизонтальный центр — чисто на CSS (не зависит от JS-замера ширины, который
     мог считаться до применения этого класса и мазал). JS ставит только top. */
  left: 50% !important; transform: translateX(-50%);
  width: min(calc(100vw - 28px), 360px); max-width: none;
  padding: 16px 16px 14px; font-size: 14px;
}
@keyframes pp-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: none; }
}
.pp-head { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.pp-ic { display: inline-flex; color: var(--accent); }
.pp-ic svg { width: 16px; height: 16px; display: block; }
.pp-title { font-size: 14px; font-weight: 700; color: var(--label); }
.pp-hint { color: var(--label2); margin-bottom: 10px; }
.pp-label {
  font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.4px; color: var(--label3); margin-bottom: 6px;
}
.pp-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.pp-chip {
  display: inline-block; padding: 3px 9px; font-size: 13px; font-weight: 600;
  color: var(--accent); background: var(--accent-bg);
  border-radius: 999px; white-space: nowrap;
}
.pp-free { color: var(--label2); }

.preset-help, .custom-prompt-help {
  margin-top: 6px; font-size: 13px; color: var(--label3);
}
.preset-help summary, .custom-prompt-help summary {
  cursor: pointer; color: var(--blue); padding: 6px 0; font-size: 13px;
  list-style: none; display: inline-block;
}
.preset-help summary::-webkit-details-marker,
.custom-prompt-help summary::-webkit-details-marker { display: none; }
.preset-help summary::before, .custom-prompt-help summary::before {
  content: "▸ "; transition: transform 0.15s ease;
}
.preset-help[open] summary::before, .custom-prompt-help[open] summary::before { content: "▾ "; }

.preset-help-body { padding: 8px 0 4px; display: flex; flex-direction: column; gap: 12px; }
.preset-help-item {
  padding: 10px 12px; background: var(--bg); border-radius: var(--radius-sm);
}
.preset-help-title { font-size: 13px; font-weight: 600; color: var(--label); margin-bottom: 4px;
  display: flex; align-items: center; gap: 6px; }
.ph-ic { display: inline-flex; color: var(--label2); }
.preset-help-hint { font-size: 13.5px; color: var(--label2); line-height: 1.5; margin-bottom: 4px; }
.preset-help-sections {
  font-size: 13px; color: var(--label3); margin-top: 4px; font-family: monospace;
}

/* ── Custom prompt ────────────────────────────────────────────────────────── */
.custom-prompt-wrap {
  margin-top: 12px; padding: 14px; border: 1.5px dashed var(--separator);
  border-radius: var(--radius-sm); background: var(--bg);
}
.custom-prompt-header {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;
}
.custom-prompt-header label {
  font-family: var(--font-mono);
  font-size: 13px; font-weight: 700; color: var(--label2);
  text-transform: uppercase; letter-spacing: .08em;
}
#customPrompt, #customContext {
  width: 100%; padding: 12px; border: 1px solid var(--separator);
  border-radius: var(--radius-sm); font-family: var(--font-sans);
  font-size: 14px; line-height: 1.5; resize: vertical; background: var(--surface);
  color: var(--label);
}
#customPrompt:focus, #customContext:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(153, 128, 24, 0.18); }
.custom-prompt-meta {
  font-size: 13px; color: var(--label3); text-align: right; margin-top: 4px;
}
.custom-prompt-meta.over-limit { color: var(--red); }
.custom-prompt-help-body { padding: 8px 0; font-size: 13px; color: var(--label2); }
.custom-prompt-template {
  background: var(--surface); border: 1px solid var(--separator);
  border-radius: var(--radius-sm); padding: 10px; font-size: 13px;
  white-space: pre-wrap; word-break: break-word; max-height: 240px; overflow: auto;
  font-family: var(--font-mono); line-height: 1.5; margin: 6px 0 12px;
}
.custom-prompt-tips { padding-left: 18px; line-height: 1.6; }
.custom-prompt-tips li { margin-bottom: 4px; }

.btn-secondary {
  display: inline-block; padding: 8px 14px; border: 1px solid var(--separator);
  background: var(--surface); color: var(--label2); border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.15s ease;
}
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }
.btn-text {
  background: none; border: none; color: var(--label3); font-size: 13.5px;
  cursor: pointer; padding: 8px 6px; font-weight: 500;
}
.btn-text:hover { color: var(--red); }

/* ── Мои (сохранённые) промты ──────────────────────────────────────────────── */
.preset-card--user { border-style: dashed; }
.preset-card--user .preset-name { color: var(--accent); }
.preset-card--user .preset-icon { color: var(--accent); }
.pc-act svg { display: block; }
.preset-card-actions {
  position: absolute; top: 6px; right: 6px; display: flex; gap: 2px;
  opacity: 0; transition: opacity 0.15s ease;
}
.preset-card--user:hover .preset-card-actions,
.preset-card--user.is-active .preset-card-actions { opacity: 1; }
.pc-act {
  border: none; background: var(--surface); color: var(--label3);
  border-radius: var(--radius-sm); width: 24px; height: 24px; line-height: 1;
  font-size: 13px; cursor: pointer; padding: 0;
}
.pc-act:hover { background: var(--accent-bg); color: var(--accent); }

.save-prompt-box {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--separator);
}
.save-prompt-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.save-prompt-name {
  flex: 1 1 200px; min-width: 0; padding: 9px 12px;
  border: 1px solid var(--separator); border-radius: var(--radius-sm);
  font-size: 13px; background: var(--surface); color: var(--label);
  font-family: inherit;
}
.save-prompt-name:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(153, 128, 24, 0.18); }
.save-prompt-type {
  padding: 9px 10px; border: 1px solid var(--separator); border-radius: var(--radius-sm);
  font-size: 13px; background: var(--surface); color: var(--label2); font-family: inherit; cursor: pointer;
}
.save-prompt-type:focus { outline: none; border-color: var(--accent); }
.save-prompt-hint { margin-top: 8px; font-size: 13px; color: var(--label3); line-height: 1.5; }

/* Правка сохранённого промта — кнопка становится основным действием: рядом стоит
   «Отмена правки», и в одинаково-серой паре было непонятно, какое действие
   главное и чего от тебя ждут. Цвет появляется только в режиме правки, чтобы в
   обычном состоянии форма не перетягивала внимание с «Загрузить». */
.save-prompt-row .btn-secondary.is-editing {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--accent);
}
.save-prompt-row .btn-secondary.is-editing:hover {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

/* Контекст — второе поле промта. Заголовок мельче основного: это дополнение к
   инструкции, а не равный ей раздел. */
.custom-context-header { margin-top: 14px; }
.custom-context-opt { color: var(--label3); font-weight: 400; font-size: 12.5px; }

@media (max-width: 520px) {
  .save-prompt-name, .save-prompt-type, .save-prompt-row .btn-secondary { flex: 1 1 100%; }
}

/* ── Телефон: доводка форм ────────────────────────────────────────────────────
   Блок стоит в самом низу файла намеренно: базовые правила форм объявлены ниже
   мобильного блока экрана входа, и при равной силе селектора они перебивали бы
   мобильные значения. Здесь каскад завершается — правила применяются. */
@media (max-width: 560px) {
  /* Межбуквенный интервал у капс-меток снят: с ним «Название встречи
     (необязательно) ?» не влезало в 296px и знак вопроса уезжал на свою строку. */
  .input-group > label { letter-spacing: normal; }
}

/* Узкий экран: капс-CTA ужимается, чтобы влезать в 358-390 без переноса/обрезки.
   Размер держим на 13 (канон-минимум для читаемых капсов), сжимаем интервал. */
@media (max-width: 430px) {
  .btn-primary { font-size: 13px; letter-spacing: .04em; padding: 14px 8px; }
}
