/* Облик пульта сбора: один файл на все пять страниц.

   Сборки фронтенда в проекте нет вовсе - решение чертежа, а не экономия
   (architecture/05-стек.md, часть 2: «ни npm, ни сборки, ни node_modules»).
   Отсюда всё здесь: обычный CSS, ни одной переменной сборщика, ни одного импорта.

   Цвета, шкала отступов и радиусы перенесены из УТВЕРЖДЁННОГО МАКЕТА владельца
   ~/map-fxmaxim/assets/tg_collector/как-это-будет-работать-tg_collector.html
   (токены брендбука FX Maxim, ред. 3 от 22.08.2026). Они здесь не выдумываются
   заново: макет владелец видел и утверждал, и облик пульта - его слово.

   ⚠️ ШРИФТЫ ЗАМЕНЕНЫ НА СИСТЕМНЫЕ, И ЭТО НЕ ВКУС.
   В макете стоят Onest и JetBrains Mono, которые браузер тянет с чужого хоста.
   Запрет З2 - «ни одного сетевого вызова наружу, кроме Telegram». Формально их
   тянул бы браузер владельца, а не наш процесс, но результат тот же: третья
   сторона узнаёт точное время каждого входа владельца в пульт. Имя пульта и так
   попадает в публичные реестры прозрачности сертификатов (05-стек.md, цена №1),
   и складывать к утечке имени ещё и утечку времени входа ради начертания букв -
   плохая сделка. Положить файлы шрифтов к себе тоже нельзя: это новые имена в
   раскладке продукта, то есть дверь С7, а не решение вёрстки.

   ТЕМА ОДНА - ТЁМНАЯ. Светлой нет намеренно: пульт открывают ночью с телефона,
   а вторая тема - это вторая версия правды в вёрстке, ровно тот дефект, против
   которого стоит правило В8.

   ВЁРСТКА MOBILE-FIRST. Требование владельца записано в макете дословно:
   «с телефона - да, тот же адрес и тот же бот», «терминал - не нужен ни разу».
   Поэтому одна колонка, цели не меньше 44 пикселей, поля 16-м кеглем (меньший
   кегль заставляет мобильный Safari зумить страницу при фокусе) и ни одного
   состояния, которое видно только при наведении мышью. */

/* Перенесены ТОЛЬКО те токены, которым нашлась работа. Полный брендбук живёт в
   business/assets/brand-guidelines.md и в наглядном брендбуке профиля - копия
   всей палитры здесь означала бы вторую её версию, которую однажды поправят в
   одном месте из двух (В8). Понадобился новый цвет - он берётся оттуда. */
:root {
  /* зелёная гамма */
  --g700: #00613A;
  --g600: #0D774D; --g500: #1D9062; --g400: #34AD7C; --g300: #65C39D;
  /* чернила */
  --ink950: #0E1110; --ink900: #151917; --ink800: #1C211F; --ink700: #292E2C;
  --ink600: #353B39; --ink400: #697773; --ink200: #A8B3AF; --ink50: #E3E8E6;
  /* латунь - цвет предупреждения и служебных подписей */
  --brass: #C2A56B; --brass-d: #AB8B49;

  --s8: 8px; --s12: 12px; --s16: 16px; --s24: 24px; --s32: 32px; --s48: 48px;
  --r6: 6px; --r8: 8px; --r12: 12px;

  /* Системный стек вместо Onest и JetBrains Mono - см. шапку файла. */
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Высота цели пальца. 44 - нижняя граница, принятая всеми руководствами по
     мобильному вводу; берём 48, потому что владелец жмёт это одной рукой ночью. */
  --cel: 48px;

  color-scheme: dark;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink950);
  color: var(--ink50);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.2; letter-spacing: -0.02em; }
h1 { font-size: 26px; }
h2 { font-size: 20px; }
h3 { font-size: 17px; }
p { margin: 0 0 var(--s12); }

a { color: var(--g300); text-decoration: none; border-bottom: 1px solid rgba(101, 195, 157, .3); }

.mono { font-family: var(--mono); letter-spacing: 0; }
.muted { color: var(--ink200); }
.dim { color: var(--ink400); font-size: 14px; }
.small { font-size: 14px; }

/* Надпись-глазок над заголовком: латунь, моноширинный, вразрядку. Из макета. */
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: var(--s8);
}

/* ===== каркас ===== */

/* Шапка липкая: на длинном списке диалогов имя пульта и выход не должны уезжать. */
.top {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(14, 17, 16, .94);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--ink700);
}
.top-in {
  display: flex;
  align-items: center;
  gap: var(--s12);
  max-width: 720px;
  margin: 0 auto;
  padding: var(--s8) var(--s16);
  /* Вырез экрана на телефонах: без этого шапка уезжает под «чёлку». */
  padding-left: max(var(--s16), env(safe-area-inset-left));
  padding-right: max(var(--s16), env(safe-area-inset-right));
}
.mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--r8);
  background: var(--g700);
  color: var(--ink50);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
}
.top-name { font-weight: 600; letter-spacing: -0.02em; }
.top-nav { display: flex; align-items: center; gap: var(--s8); margin-left: auto; }
.top-form { margin: 0; }

.shell {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--s24) var(--s16) var(--s48);
  padding-left: max(var(--s16), env(safe-area-inset-left));
  padding-right: max(var(--s16), env(safe-area-inset-right));
}

/* ===== сообщение вверху страницы ===== */
.flash {
  margin-bottom: var(--s16);
  padding: var(--s12) var(--s16);
  border-radius: var(--r8);
  border: 1px solid var(--ink600);
  background: var(--ink900);
  font-size: 15px;
}
.flash-ok { border-color: var(--g600); background: rgba(52, 173, 124, .12); color: var(--g300); }
.flash-error { border-color: var(--brass-d); background: rgba(194, 165, 107, .14); color: var(--brass); }

/* ===== примитивы ===== */
.card {
  background: var(--ink900);
  border: 1px solid var(--ink700);
  border-radius: var(--r12);
  padding: var(--s16);
}
.card + .card { margin-top: var(--s12); }

.note {
  border-left: 2px solid var(--g600);
  background: var(--ink900);
  border-radius: 0 var(--r8) var(--r8) 0;
  padding: var(--s12) var(--s16);
  margin-bottom: var(--s12);
  font-size: 14px;
  color: var(--ink200);
}
.note b { color: var(--ink50); }
.note-brass { border-left-color: var(--brass-d); }

.tag {
  display: inline-block;
  font-family: var(--mono);
  font-size: 12px;
  padding: 3px 8px;
  border-radius: var(--r6);
  background: var(--ink800);
  border: 1px solid var(--ink700);
  color: var(--ink200);
  white-space: nowrap;
}
.tag-ok { background: rgba(52, 173, 124, .14); border-color: var(--g600); color: var(--g300); }
.tag-brass { background: rgba(194, 165, 107, .12); border-color: var(--brass-d); color: var(--brass); }
.tag-off { opacity: .55; }

/* Аватар-инициалы. Картинок нет ни одной: любая аватарка из Telegram - это
   выход в чужую сеть за файлом (З2) и чужие персональные данные на диске. */
.av {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 999px;
  background: var(--ink700);
  color: var(--ink200);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
}
.av-g { background: var(--g700); color: var(--ink50); }

/* ===== кнопки ===== */
.btn, .btn-ghost, .btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s8);
  min-height: var(--cel);
  padding: 0 var(--s24);
  border-radius: var(--r8);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  /* Мгновенный отклик на касание вместо задержки 300 мс. */
  touch-action: manipulation;
}
.btn { background: var(--g400); color: var(--ink950); border: 1px solid var(--g400); }
.btn:active { background: var(--g500); border-color: var(--g500); }
.btn-ghost { background: transparent; color: var(--ink50); border: 1px solid var(--ink600); font-weight: 500; }
.btn-ghost:active { background: var(--ink800); }
.btn-quiet {
  background: transparent;
  color: var(--ink200);
  border: 1px solid transparent;
  min-height: 40px;
  padding: 0 var(--s12);
  font-size: 14px;
  font-weight: 500;
}
.btn-quiet:active { color: var(--ink50); }
.btn-wide { width: 100%; }

/* Недоступная кнопка обязана выглядеть недоступной и не ловить касание:
   иначе владелец жмёт «Обновить список» во время забора и не понимает, почему
   ничего не происходит. Причина всегда написана рядом словами, а не спрятана. */
.btn[disabled], .btn-ghost[disabled], .btn-quiet[disabled] {
  opacity: .45;
  cursor: not-allowed;
  pointer-events: none;
}

/* Обводка фокуса общая на все интерактивные элементы: пульт открывают и с
   клавиатуры, а состояний «только при наведении» в интерфейсе нет вовсе. */
.btn:focus-visible, .btn-ghost:focus-visible, .btn-quiet:focus-visible,
.field:focus-visible, .pick-in:focus-visible + .pick-ui, a:focus-visible {
  outline: 2px solid var(--g300);
  outline-offset: 2px;
}

/* ===== поля ===== */
.label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--ink400);
}
.field {
  display: block;
  width: 100%;
  min-height: 52px;
  margin-bottom: var(--s16);
  padding: var(--s12);
  border-radius: var(--r8);
  border: 1px solid var(--ink600);
  background: var(--ink950);
  color: var(--ink50);
  font-family: inherit;
  /* Ровно 16 пикселей: при меньшем кегле мобильный Safari зумит всю страницу
     на фокусе, и владелец каждый раз возвращает её пальцами. */
  font-size: 16px;
}
.field::placeholder { color: var(--ink400); }
.field:focus { border-color: var(--g500); }

/* Поле кода: цифры крупно, вразрядку, по центру - его вводят вслепую с телефона. */
.field-code {
  font-family: var(--mono);
  font-size: 28px;
  letter-spacing: .35em;
  text-align: center;
  padding-left: .35em;
}

.form { margin: 0; }

/* ===== шаги подключения ===== */
.steps { margin-bottom: var(--s16); }
.steps-n { font-family: var(--mono); font-size: 12px; color: var(--brass); letter-spacing: .06em; }
.steps-bar { display: flex; gap: 6px; margin-top: 6px; }
.steps-bar i { flex: 1; height: 4px; border-radius: 999px; background: var(--ink700); }
.steps-bar i.on { background: var(--g400); }

/* ===== строка списка ===== */
.rows { border-top: 1px solid var(--ink700); }
.row {
  display: flex;
  align-items: center;
  gap: var(--s12);
  min-height: 64px;
  padding: var(--s12) 0;
  border-bottom: 1px solid var(--ink700);
}
.row-grow { flex: 1; min-width: 0; }
.row-name {
  display: block;
  font-size: 15px;
  font-weight: 500;
  /* Чужое имя может быть длиной в абзац: рвём его, а не ломаем строку. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-sub { display: block; font-size: 13px; color: var(--ink400); overflow: hidden; text-overflow: ellipsis; }
.row-acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s8); }

/* Карточка аккаунта: имя с состоянием сверху, кнопки под ними. Одной строкой это
   не встаёт - на телефоне у аккаунта до трёх действий, и в 360 пикселей ширины
   они не помещаются рядом с именем ни при каком кегле. */
.acct { padding: var(--s12) 0; border-bottom: 1px solid var(--ink700); }
.acct-top { display: flex; align-items: center; gap: var(--s12); }
.acct-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s8);
  margin-top: var(--s12);
  /* Отступ ровно на ширину аватара с промежутком: кнопки встают под именем,
     а не под кружком. */
  padding-left: 52px;
}
.row-head {
  display: flex;
  align-items: center;
  gap: var(--s12);
  padding-bottom: var(--s12);
}

/* Вся строка диалога - одна цель: касание в любом её месте переключает выбор. */
.row-pick { cursor: pointer; }
.row-pick:active { background: var(--ink900); }

/* Двухпозиционный переключатель «беру / не трогаю». Настоящий флажок оставлен
   в разметке и только спрятан: он несёт значение формы, состояние фокуса и
   работу с клавиатуры. Нарисованная поверх пара сегментов - его отражение,
   поэтому без JavaScript страница остаётся полностью рабочей.

   ⚠️ ОТМЕЧЕННЫЙ ФЛАЖОК - ЭТО «НЕ ТРОГАЮ», А НЕ «БЕРУ», И ЗДЕСЬ ЭТО ВИДНО.
   Причина в устройстве формы, а не во вкусе: браузер отправляет только отмеченные
   поля, а на сервер уезжает список ИСКЛЮЧЁННЫХ диалогов (`routes.dialogi_sohranit`,
   поле skip). Стили переворачивают это обратно, чтобы владелец видел положение
   строки, а не внутренности формы. */
.pick { position: relative; flex: 0 0 auto; }
.pick-in {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.pick-ui {
  display: inline-flex;
  border: 1px solid var(--ink600);
  border-radius: var(--r8);
  overflow: hidden;
  font-size: 12px;
  font-family: var(--mono);
  user-select: none;
}
.pick-ui span {
  display: grid;
  place-items: center;
  min-height: 44px;
  padding: 0 10px;
  color: var(--ink400);
}
.pick-ui span + span { border-left: 1px solid var(--ink700); }
.pick-in:not(:checked) + .pick-ui .pick-a { background: var(--g400); color: var(--ink950); font-weight: 600; }
.pick-in:checked + .pick-ui .pick-b { background: var(--ink600); color: var(--ink50); font-weight: 600; }
.pick-in[disabled] { cursor: not-allowed; }
.pick-in[disabled] + .pick-ui { opacity: .6; }

/* ===== нижняя панель действия ===== */
/* «Сохранить» липнет к низу: список диалогов длинный, и кнопка, до которой надо
   долистать четыреста строк, - это кнопка, которую не нажмут. */
.dock {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--s12);
  margin: var(--s16) calc(-1 * var(--s16)) 0;
  padding: var(--s12) var(--s16);
  padding-bottom: max(var(--s12), env(safe-area-inset-bottom));
  background: rgba(14, 17, 16, .94);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--ink700);
}
.dock .btn { flex: 1; }
.dock-count { font-family: var(--mono); font-size: 13px; color: var(--ink200); white-space: nowrap; }

/* ===== пустое состояние ===== */
.empty {
  padding: var(--s32) var(--s16);
  border: 1px dashed var(--ink600);
  border-radius: var(--r12);
  text-align: center;
  color: var(--ink200);
}
.empty h2 { margin-bottom: var(--s8); }

/* ===== страница входа ===== */
.vhod { margin-top: var(--s32); }
.attempts { margin-top: var(--s16); }
.vhod .card { padding: var(--s24); }

@media (min-width: 560px) {
  h1 { font-size: 32px; }
  .shell { padding-top: var(--s32); }
}

/* Владелец мог выключить анимации системно - уважаем. Своих анимаций в пульте
   нет ни одной, поэтому здесь гасятся только переходы браузера. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Возврат к списку аккаунтов. Отдельная строка над заголовком, а не в шапке: в шапке
   она читалась бы как раздел, а это именно шаг назад из текущего места. Цель крупная -
   страницу открывают пальцем с телефона. */
.back-link {
  display: inline-block;
  margin-bottom: var(--s16);
  padding: 10px 14px;
}
