/*
 * Оформление страницы веб-терминала (BL-2026-10-25-24ffd1).
 *
 * Тема тёмная и единственная: терминал читается на тёмном, а переключатель
 * темы — лишняя сущность на странице, у которой одна задача.
 *
 * ГЛАВНОЕ ПРАВИЛО ЭТОГО ФАЙЛА — страница НИКОГДА не шире экрана.
 * Первая редакция этим правилом не владела: ряд служебных клавиш не помещался
 * в 390 px, а у элемента grid `min-width` по умолчанию равен `auto`, то есть
 * ширине содержимого. Колонка растягивалась до 610 px, и вместе с ней
 * растягивалась вся страница: панель сессий обрезалась за краем, шапка
 * перехватывала нажатия по списку, а xterm считал 78 колонок там, где их
 * помещается 50. Поэтому у сетки явная колонка `minmax(0, 1fr)`, у каждого
 * её ребёнка `min-width: 0`, а клавиши переносятся, а не уезжают.
 *
 * Высота держится на `100dvh`: в webview Telegram и в мобильном Safari
 * адресная строка съедает часть `vh`, и нижний ряд клавиш уходил под край
 * экрана ровно там, где он нужнее всего.
 *
 * Связанные файлы: index.html, term.js.
 */

:root {
  --bg: #0f1115;
  --bg-soft: #171a21;
  --bg-raised: #1e232c;
  --line: #262b36;
  --line-soft: #1d222b;
  --fg: #d8dee9;
  --fg-muted: #8b94a7;
  --accent: #5aa9e6;
  --accent-ink: #0b0f14;
  --warn: #e0a458;
  --danger: #e06c75;
  --ok: #8fbf73;

  /* Палец, а не курсор: меньше 44 px по меньшей стороне не попасть. */
  --tap: 44px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);

  color-scheme: dark;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html,
body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overscroll-behavior: none;
}

body {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* Явная колонка — без неё содержимое диктует ширину страницы (см. шапку). */
  grid-template-columns: minmax(0, 1fr);
  height: 100dvh;
  overflow: hidden;
}

body > * {
  min-width: 0;
}

/* ───────────────────────────── верхняя строка ───────────────────────────── */

.bar {
  display: grid;
  /*
   * ЧЕТЫРЕ колонки: кнопка списка, название, режим ввода, состояние связи.
   * С тремя четвёртый элемент переносился на вторую строку, и шапка на
   * телефоне занимала две строки с пустотой посередине.
   */
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  padding: 6px calc(8px + var(--safe-r)) 6px calc(8px + var(--safe-l));
  background: var(--bg-soft);
  border-bottom: 1px solid var(--line);
}

.bar__menu {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap);
  padding: 0 12px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

.bar__menu:active {
  background: var(--accent);
  color: var(--accent-ink);
}

.bar__menu-icon {
  font-size: 16px;
  line-height: 1;
}

.bar__title {
  display: grid;
  min-width: 0;
}

.bar__name,
.bar__sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bar__name {
  font-weight: 600;
}

.bar__sub {
  font-size: 12px;
  color: var(--fg-muted);
}

/* Режим ввода — кнопка с явным текстом, а не молчаливый значок. */
.mode {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1px solid var(--warn);
  background: transparent;
  color: var(--warn);
  font: inherit;
  font-size: 12px;
  white-space: nowrap;
  cursor: pointer;
}

.mode--rw {
  border-color: var(--ok);
  color: var(--ok);
  cursor: default;
}

.mode--hidden {
  display: none;
}

.state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--fg-muted);
  white-space: nowrap;
}

.state__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fg-muted);
  flex: 0 0 auto;
}

.state--ok .state__dot {
  background: var(--ok);
}

.state--bad .state__dot {
  background: var(--danger);
}

.state--wait .state__dot {
  background: var(--warn);
}

/*
 * На узком экране слова состояния не помещаются рядом с именем сессии —
 * остаётся цветная точка, а текст доступен долгим нажатием (title).
 */
@media (max-width: 560px) {
  .state__text {
    display: none;
  }
  .bar__menu-text {
    display: none;
  }
  .bar__menu {
    padding: 0 14px;
  }
}

/* ─────────────────────────────── терминал ──────────────────────────────── */

.main {
  position: relative;
  min-height: 0;
  min-width: 0;
  padding: 4px calc(4px + var(--safe-r)) 4px calc(4px + var(--safe-l));
}

.terminal {
  height: 100%;
  width: 100%;
}

/* Пустое состояние: раньше здесь было просто чёрное поле без объяснений. */
.empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--bg);
}

.empty--hidden {
  display: none;
}

.empty__box {
  max-width: 340px;
  text-align: center;
}

.empty__title {
  margin: 0 0 6px;
  font-size: 17px;
  font-weight: 600;
}

.empty__text {
  margin: 0 0 16px;
  color: var(--fg-muted);
  font-size: 14px;
}

.notice {
  position: absolute;
  inset: auto 12px 12px;
  padding: 12px 14px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--fg);
  font-size: 14px;
  white-space: pre-line;
  box-shadow: 0 8px 24px rgb(0 0 0 / 45%);
}

.notice--hidden {
  display: none;
}

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

/* ─────────────────────────── служебные клавиши ─────────────────────────── */

/*
 * Переносятся, а не прокручиваются. Горизонтальная прокрутка здесь означала
 * бы, что половина клавиш невидима ровно в тот момент, когда они нужны, —
 * и именно она растягивала всю страницу.
 */
.keys {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px calc(8px + var(--safe-r)) calc(6px + var(--safe-b)) calc(8px + var(--safe-l));
  background: var(--bg-soft);
  border-top: 1px solid var(--line);
}

.key {
  flex: 1 1 auto;
  min-width: 46px;
  min-height: var(--tap);
  padding: 0 8px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  touch-action: manipulation;
}

.key:active {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.key--wide {
  flex: 3 1 140px;
}

.key--accent {
  border-color: #33506b;
  color: #cfe6fb;
}

.key--danger {
  border-color: #4a2f33;
  color: #f0a9af;
}

.keys--disabled .key {
  opacity: 0.4;
  pointer-events: none;
}

/* ───────────────────────────── панель сессий ───────────────────────────── */

.btn {
  min-height: var(--tap);
  padding: 0 14px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  cursor: pointer;
}

.btn--primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
  font-weight: 600;
}

.btn--block {
  width: 100%;
}

/*
  Заблокированная кнопка обязана ВЫГЛЯДЕТЬ заблокированной: синяя и нажимаемая
  «Создать и подключиться» при отсутствии связи и была тем, что человек читал
  как исправный терминал без рабочих копий.
*/
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  background: none;
  border: none;
  border-radius: 10px;
  color: var(--fg-muted);
  font-size: 18px;
  cursor: pointer;
}

.icon-btn:active {
  background: var(--bg-raised);
  color: var(--fg);
}

.scrim {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 55%);
  z-index: 20;
}

.scrim--hidden {
  display: none;
}

/*
 * Телефон: нижний лист. Большой палец дотягивается до низа экрана, а до
 * верхнего правого угла — нет, поэтому список начинается снизу.
 * Широкий экран (ниже по медиазапросу): боковая панель справа.
 */
.panel {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  max-height: 86dvh;
  background: var(--bg-soft);
  border-top: 1px solid var(--line);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -12px 32px rgb(0 0 0 / 50%);
}

.panel--hidden {
  display: none;
}

.panel__grip {
  width: 36px;
  height: 4px;
  margin: 8px auto 0;
  border-radius: 999px;
  background: var(--line);
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 8px 6px 16px;
  border-bottom: 1px solid var(--line);
}

.panel__build {
  margin-left: auto;
  margin-right: 4px;
  color: var(--fg-muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.panel__title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.panel__body {
  padding: 12px 16px calc(16px + var(--safe-b));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.sessions {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.session {
  display: grid;
  gap: 6px;
  width: 100%;
  text-align: left;
  padding: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--fg);
  font: inherit;
  cursor: pointer;
}

.session:active {
  border-color: var(--accent);
}

.session__top {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.session__name {
  font-weight: 600;
  font-size: 15px;
  /* Имена сессий длинные — рвём по символам, а не прячем за край. */
  overflow-wrap: anywhere;
}

.session__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tag {
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--fg-muted);
  white-space: nowrap;
}

.tag--live {
  border-color: var(--ok);
  color: var(--ok);
}

.session__path {
  font-size: 12px;
  color: var(--fg-muted);
  overflow-wrap: anywhere;
}

.owner {
  margin-left: auto;
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid var(--line);
  color: var(--fg-muted);
  white-space: nowrap;
}

.owner--bridge {
  color: var(--warn);
  border-color: var(--warn);
}

.owner--term {
  color: var(--accent);
  border-color: var(--accent);
}

.hint {
  margin: 0;
  color: var(--fg-muted);
  font-size: 13px;
}

.hint--hidden {
  display: none;
}

.hint--warn {
  color: var(--warn);
}

/*
  Блок причины внутри панели.

  Зачем отдельно от #notice: панель сессий перекрывает весь main, и причина,
  нарисованная под ней, человеку недоступна ровно тогда, когда он её ищет —
  открыв панель и не найдя ни сессий, ни рабочих копий.
*/
.panel-notice {
  display: grid;
  gap: 8px;
  margin-bottom: 14px;
  padding: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--warn);
  border-radius: 10px;
}

.panel-notice--hidden {
  display: none;
}

.panel-notice__text {
  margin: 0;
  color: var(--fg);
  font-size: 14px;
  line-height: 1.4;
}

.panel-notice__link {
  color: var(--accent);
  font-weight: 600;
  /* Ссылка — цель для пальца, а не строчка текста. */
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
}

.panel-notice__hint {
  margin: 0;
  color: var(--fg-muted);
  font-size: 13px;
}

.panel-notice__retry {
  justify-self: start;
}

.create {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

.create__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: var(--tap);
  padding: 0 12px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.create__chevron {
  transition: transform 0.15s ease;
  color: var(--fg-muted);
}

.create__toggle[aria-expanded="true"] .create__chevron {
  transform: rotate(180deg);
}

.create__form {
  display: grid;
  gap: 12px;
  margin-top: 12px;
}

.create__form--hidden {
  display: none;
}

.field {
  display: grid;
  gap: 4px;
}

/*
  Скрытие идёт ПОСЛЕ правила .field: у обоих селекторов одна специфичность,
  и выше по файлу display:none молча проигрывал бы display:grid.
*/
.field--hidden {
  display: none;
}

.field__label {
  font-size: 12px;
  color: var(--fg-muted);
}

.field__input {
  width: 100%;
  min-height: var(--tap);
  padding: 8px 10px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit;
  /* 16px — иначе iOS увеличивает страницу при фокусе в поле. */
  font-size: 16px;
}

.field__input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* ──────────────────────── широкий экран: боковая панель ─────────────────── */

@media (min-width: 720px) {
  .panel {
    inset: 0 0 0 auto;
    width: 420px;
    max-height: none;
    border-top: none;
    border-left: 1px solid var(--line);
    border-radius: 0;
    box-shadow: -12px 0 32px rgb(0 0 0 / 45%);
  }

  .panel__grip {
    display: none;
  }

  .panel__head {
    padding: 10px 8px 10px 16px;
  }

  .key {
    flex: 0 0 auto;
    min-width: 56px;
  }

  .key--wide {
    flex: 0 0 180px;
  }
}

/* ────────────────────────── лист ввода текста ──────────────────────────── */

/*
  Нижний лист поверх терминала: в нём настоящий textarea, потому что холст
  xterm полем ввода не является — системное «Вставить» на него не наводится,
  а длинный промпт пальцем в терминале не набрать.

  Высота ограничена, а не задана: с открытой клавиатурой лист обязан помещаться
  в видимую часть экрана (её держит trackVisualViewport в term.js).
*/
.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: grid;
  gap: 10px;
  max-height: 85%;
  overflow-y: auto;
  padding: 12px calc(12px + var(--safe-r)) calc(12px + var(--safe-b)) calc(12px + var(--safe-l));
  background: var(--bg-soft);
  border-top: 1px solid var(--line);
  border-radius: 14px 14px 0 0;
  box-shadow: 0 -10px 30px rgb(0 0 0 / 50%);
}

.sheet--hidden {
  display: none;
}

.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.sheet__title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.sheet__area {
  width: 100%;
  min-height: 112px;
  padding: 10px 12px;
  background: var(--bg-raised);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 10px;
  /* 16px — ниже этого размера iOS САМ увеличивает страницу при фокусе поля,
     и вёрстка уезжает вместе с масштабом. */
  font: 16px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  resize: vertical;
}

.sheet__area:focus {
  outline: none;
  border-color: var(--accent);
}

.sheet__row {
  display: flex;
  gap: 8px;
}

.sheet__grow {
  flex: 1 1 0;
}
