/**
 * Оформление приложения «Очаг»: система из трёх частей.
 *
 *   1. ТОКЕНЫ    — все значения оформления: цвета, материалы, радиусы, отступы, тени,
 *                  типографика, длительности. Единственный источник значений.
 *   2. РАСКЛАДКА — расположение областей по ширине окна.
 *   3. ЭЛЕМЕНТЫ  — шапка, список, сообщения, поле ввода, экраны.
 *
 * Правила, которые проверяются механически (`tools/check-design.mjs`,
 * `tools/check-css-syntax.mjs`):
 *   * в частях 2 и 3 нет числовых цветов и «магических» размеров — только переменные;
 *   * комментарии не вложены, скобки сбалансированы, стили не «съедены» комментарием.
 *
 * ПРО РАСКЛАДКУ — важный урок. В первой попытке этой версии области были сделаны
 * через `position: absolute` внутри родителя с `height: 100%`. На телефоне это
 * сломалось: адресная строка меняет высоту окна, `height: 100%` не даёт определённой
 * высоты, абсолютная область получила нулевой размер, а вместе с ним — нулевую ширину,
 * и текст пошёл по одной букве в строке.
 *
 * Поэтому теперь раскладка — обычный поток: колонка из трёх частей (шапка, лента,
 * поле ввода), где прокручивается только лента. Никакого абсолютного позиционирования
 * и никаких долей высоты, зависящих от браузера. Высоту задаёт `100dvh` — единица,
 * которая специально введена для мобильных браузеров и меняется вместе с адресной строкой.
 */

/* =========================================================================
   1. ТОКЕНЫ
   ========================================================================= */

:root {
  color-scheme: light dark;

  /* --- Цвета: светлая тема -------------------------------------------------
     Слоистость вместо рамок: фон → материал панели → содержимое. */
  --фон: #f2f2f7;
  --фон-второй: #f7f7fa;
  /* Материал боковой панели: полупрозрачный, как боковая панель на планшете
     в присланных слайдах Apple. Панель не просто «чуть темнее фона» — сквозь неё
     угадывается подложка, и этим она читается как отдельный слой. */
  --фон-области-разговоров: rgba(247, 247, 250, 0.72);
  --поверхность: #ffffff;
  --поверхность-тихая: #e9e9ee;
  --поверхность-стекло: rgba(255, 255, 255, 0.82);
  --текст: #1c1c1e;
  --текст-второй: #3c3c43;
  --текст-тихий: #636366;
  --текст-на-акценте: #ffffff;
  --разделитель: #d1d1d6;
  --граница: #d1d1d6;
  /* Выбранный разговор: мягкий синий фон. Отличается от нажатия: нажатие —
     серая поверхность, выбор — синяя. Так видно и «где я», и «что нажимаю». */
  --цвет-выбранного-чата: #eaf3ff;
  --цвет-активного-пункта: #eaf3ff;
  /* Пузыри: входящие серые, исходящие синие — значения из документа владельца
     («incoming #E5E5EA», «outgoing #007AFF»). Входящий взят на шаг светлее
     (вместо #E5E5EA): на нём время сообщения давало 4.77:1 при пороге 4.5 —
     формально проходило, но запаса почти не было. Здесь время даёт 5.22:1. */
  --чужой-фон: #efeff4;
  --свой-фон: #007aff;
  --свой-край: #007aff;
  --акцент: #007aff;
  /* Акцент для мелкого текста. Белый текст на #007AFF даёт 4.02:1 — ниже порога
     4.5, о чём документ владельца и предупреждал. Поэтому для надписей на синем
     берём более тёмный оттенок: на #0062CC белый текст даёт 5.80:1. */
  --акцент-для-текста: #0062cc;
  --акцент-мягкий: rgba(0, 122, 255, 0.12);
  --опасно: #ff3b30;
  --опасно-текст: #c9342b;
  --опасно-мягкий: rgba(255, 59, 48, 0.12);
  /* Цвета состояний: спокойно — всё хорошо, внимание — идёт подключение.
     Держим их отдельно от акцента: связь и оформление — разные вещи.
     Оба затемнены замером: системный жёлтый #9A6407 давал 4.48:1 — ниже порога. */
  --спокойно: #1f7a4d;
  --внимание: #8a5900;
  /* Множитель размера текста: его ставит настройка «Размер текста».
     Обычный — единица. */
  --масштаб-текста: 1;

  /* --- Радиусы ------------------------------------------------------------ */
  /* Радиусы — из документа владельца: карточки 16, поиск 14, пузыри 18,
     панель ввода 24. */
  --радиус-крошечный: 6px;
  --радиус-малый: 10px;
  --радиус-поиска: 14px;
  --радиус: 16px;
  --радиус-большой: 20px;
  --радиус-пузыря: 18px;
  --радиус-поля-ввода: 24px;
  --радиус-круглый: 999px;

  /* --- Отступы ------------------------------------------------------------ */
  --отступ-крошечный: 4px;
  --отступ-малый: 8px;
  --отступ: 12px;
  --отступ-средний: 16px;
  --отступ-большой: 24px;
  --отступ-огромный: 32px;

  /* --- Тени: мягкие, почти незаметные. Резкая тень выглядит как веб-страница.
     Размытия и теней на пузырях и строках списка нет намеренно: в документе
     владельца сказано «не применять размытие к каждой строке списка или пузырю
     сообщения», а тень без размытия там только шумит. */
  --тень-плавающей-панели: 0 4px 18px rgba(0, 0, 0, 0.06);

  /* --- Материал: размытие под полупрозрачной панелью --------------------- */
  --размытие: 16px;
  --насыщенность: 180%;

  /* --- Длительности ------------------------------------------------------- */
  --быстро: 120ms;
  --плавно: 180ms;
  --переход: 180ms ease-out;

  /* --- Размеры ------------------------------------------------------------ */
  --ширина-области-разговоров: 320px;
  --ширина-области-разговоров-узкая: 280px;
  --ширина-рельса: 72px;
  --ширина-колонки-сообщений: 880px;
  --ширина-окна-узкого: 720px;
  --ширина-настроек: 760px;
  --высота-поля-ввода: 44px;
  --размер-нажатия: 44px;

  /* --- Типографика --------------------------------------------------------
     Размеры умножаются на --масштаб-текста: его ставит настройка «Размер текста»
     (Обычный / Крупный / Очень крупный). Умножаем именно значения, а не корневой
     размер шрифта: тогда масштабируется только текст приложения, а размеры
     элементов управления остаются предсказуемыми. */
  --шрифт: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', sans-serif;
  --шрифт-моно: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  --размер-текста: calc(16px * var(--масштаб-текста));
  --размер-поля-ввода: calc(16px * var(--масштаб-текста));
  --размер-мелкий: calc(15px * var(--масштаб-текста));
  --размер-крошечный: calc(13px * var(--масштаб-текста));
  --размер-маленький: calc(11px * var(--масштаб-текста));
  --размер-заголовка: calc(17px * var(--масштаб-текста));
  --размер-крупного-заголовка: calc(32px * var(--масштаб-текста));
  --размер-заголовка-группы: calc(12px * var(--масштаб-текста));
  --межстрочный: 1.45;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Тёмная тема построена на тех же ролях, что светлая, из системных тёмных
       значений. Документ владельца описывает только светлую тему, поэтому тёмные
       значения — мои: светлая остаётся основной, тёмная нужна тем, у кого она
       выбрана в системе. */
    --фон: #000000;
    --фон-второй: #1c1c1e;
    --фон-области-разговоров: rgba(28, 28, 30, 0.72);
    --поверхность: #1c1c1e;
    --поверхность-тихая: #2c2c2e;
    --поверхность-стекло: rgba(28, 28, 30, 0.82);
    --текст: #ffffff;
    --текст-второй: #d1d1d6;
    /* Приглушённый текст подобран замером: системный #8E8E93 на входящем пузыре
       давал 4.27:1 — ниже порога 4.5. Взят #98989D: на пузыре 4.85:1,
       на чёрном фоне 7.31:1. */
    --текст-тихий: #98989d;
    /* В тёмной теме акцент светлее фона, поэтому текст на нём — тёмный. */
    --текст-на-акценте: #0b1220;
    --разделитель: rgba(84, 84, 88, 0.65);
    --граница: #38383a;
    --цвет-выбранного-чата: rgba(10, 132, 255, 0.22);
    --цвет-активного-пункта: rgba(10, 132, 255, 0.22);
    --чужой-фон: #2c2c2e;
    --свой-фон: #0a84ff;
    --свой-край: #0a84ff;
    --акцент: #0a84ff;
    --акцент-для-текста: #409cff;
    --акцент-мягкий: rgba(10, 132, 255, 0.2);
    --опасно: #ff453a;
    --опасно-текст: #ff6961;
    --опасно-мягкий: rgba(255, 69, 58, 0.16);
    --спокойно: #34c759;
    --внимание: #ff9f0a;
  }
}

/**
 * Просьба системы об уменьшенной прозрачности: заменяем стекло на плотную
 * поверхность. Это часть доступности, а не украшение: полупрозрачные панели
 * мешают читать людям с нарушением контрастной чувствительности.
 */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --поверхность-стекло: var(--поверхность);
    --размытие: 0px;
    --насыщенность: 100%;
  }
}

/**
 * То же самое, но выбранное человеком внутри приложения.
 *
 * Настройка внутри приложения ДОПОЛНЯЕТ системную, а не заменяет её: системная
 * говорит «мне так удобнее всегда», настройка приложения — «сейчас мне так надо».
 * Поэтому здесь отдельные классы, а не подмена медиазапроса.
 */
.приложение--меньше-прозрачности {
  --поверхность-стекло: var(--поверхность);
  --размытие: 0px;
  --насыщенность: 100%;
}

.приложение--меньше-движения *,
.приложение--меньше-движения *::before,
.приложение--меньше-движения *::after {
  transition-duration: 0.01ms !important;
  animation-duration: 0.01ms !important;
}

/* Нажатие кнопки тоже перестаёт «пружинить»: это движение, а его просили убрать. */
.приложение--меньше-движения .кнопка:active,
.приложение--меньше-движения .карточка--диалог:active {
  transform: none;
}

/* =========================================================================
   2. РАСКЛАДКА
   -------------------------------------------------------------------------
   Обычный поток: колонка из трёх частей, прокручивается только лента.
   Никакого абсолютного позиционирования и долей высоты от браузера.
   ========================================================================= */

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
}

/* Корень приложения: занимает окно целиком, прокручивается только лента сообщений.
   Одна колонка, а внутри — либо оболочка разговоров, либо экран входа.
   Так экраны и раскладка не спорят за высоту.

   Селектор по одному идентификатору, а не по `#app.app`: класса у корня больше
   нет. Раньше он был, и общее правило `.app` с ограничением ширины 720 попадало
   на корень приложения — из-за этого список чатов и переписка оказывались
   в узкой полосе посреди экрана. Это и было причиной «узкого контейнера». */
#app {
  display: grid;
  grid-template-columns: 1fr;
  height: 100vh;
  height: 100dvh;
  /* Безопасные края: вырез камеры и скруглённые углы. Нижнюю полосу жеста
     учитывает тот, кто стоит внизу экрана (панель вкладок или поле ввода),
     а не корень: иначе под содержимым остаётся пустая полоса. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
  overflow: hidden;
}

body {
  background: var(--фон);
  color: var(--текст);
  font: var(--размер-текста) / var(--межстрочный) var(--шрифт);
  -webkit-text-size-adjust: 100%;
  /* Горизонтальной прокрутки быть не должно ни при каких условиях: она ломает
     ощущение приложения, а заодно уводит за экран поле ввода.
     Безопасные края сюда НЕ выносим намеренно: у body отступы вместе с
     height: 100% при установке значка на домашний экран iOS давали лишнюю ширину,
     и поле ввода с кнопкой отправки уезжали за край. В обычном браузере этого
     не было — поэтому проверять надо оба режима (DESIGN.md, «test browser and
     installed PWA modes»). Края учитывает #app выше. */
  overflow-x: hidden;
  overscroll-behavior: none;
}

/* --- Оболочка разговоров: список и переписка --------------------------------- */

.оболочка {
  display: grid;
  /* На узком окне область одна и занимает всё место. */
  grid-template-columns: 1fr;
  /* Высоту задаёт корень (#app), поэтому здесь только минимум.
     Нижней полосы жеста здесь НЕТ намеренно: раньше она стояла тут, и под полем
     ввода оставалась пустая полоса — «composer не у нижнего края». Нижнюю полосу
     теперь учитывает только то, что стоит внизу: панель вкладок на телефоне
     или поле ввода в открытом чате. */
  min-height: 0;
  margin: 0 auto;
}

/**
 * Область переписки — колонка из трёх частей обычным потоком: шапка, лента,
 * поле ввода. Прокручивается только лента.
 *
 * Здесь важно, чего НЕ делаем: никакого абсолютного позиционирования и никаких
 * долей высоты, зависящих от браузера. Первая попытка этой версии использовала
 * `position: absolute` внутри родителя с `height: 100%` — на телефоне адресная
 * строка меняет высоту окна, родитель получил нулевую высоту, вместе с ней
 * нулевую ширину, и текст пошёл по одной букве в строке. Обычный поток такой
 * возможности не даёт.
 */
.область {
  display: flex;
  flex-direction: column;
  /* Ноль в минимуме — страховка от «нулевой ширины»: если содержимое вдруг попросит
     больше места, область не начнёт его сжимать до одной буквы в строке.
     Именно это случилось в первой попытке раскладки, сделанной через абсолютное
     позиционирование внутри родителя с неопределённой высотой. */
  min-width: 0;
  min-height: 0;
  background: var(--фон);
}











/* Экран входа рисуется прямо в корне: корень — сетка в одну колонку, а экран
   внутри неё занимает всё место и центрируется. Отдельной обёртки с ограничением
   ширины нет намеренно: раньше она называлась `.app`, совпадала с корнем и
   незаметно ограничивала ширину ВСЕГО приложения. */

/* =========================================================================
   3. ЭЛЕМЕНТЫ
   ========================================================================= */

/* --- Навигация: рельс на компьютере, вкладки внизу на телефоне ------------
   Одно дерево, разное расположение. Знак приложения и аватар видны только
   на рельсе: на телефоне место дорогое, а вкладок две. */

.навигация {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--отступ-малый);
  flex: none;
  padding: var(--отступ-малый) 0;
  background: var(--поверхность);
  border-right: 1px solid var(--граница);
}

.навигация__знак {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--отступ-малый);
  border-radius: var(--радиус);
  background: var(--акцент);
  color: var(--текст-на-акценте);
  font-weight: 700;
  font-size: 20px;
  user-select: none;
}

.навигация__пункты {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--отступ-крошечный);
}

.навигация__пункт {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: var(--размер-нажатия);
  min-height: var(--размер-нажатия);
  padding: 0;
  border: none;
  border-radius: var(--радиус);
  background: transparent;
  color: var(--текст-тихий);
  font: inherit;
  cursor: pointer;
  transition: background var(--переход), color var(--переход);
}

/* Подпись под значком показывается только на телефоне: там вкладки без слов
   непонятны. На компьютере значок стоит вертикально и подписи не нужны. */
.навигация__подпись {
  font-size: 10px;
  line-height: 1;
  white-space: nowrap;
}

@media (min-width: 768px) {
  .навигация__подпись {
    display: none;
  }
}

.навигация__пункт:hover {
  background: var(--поверхность-тихая);
}

/* Активный раздел: мягкий синий фон и синий значок. */
.навигация__пункт[aria-current='true'] {
  background: var(--цвет-активного-пункта);
  color: var(--акцент-для-текста);
}

/* Аватар внизу рельса. Не кнопка: открывать по нему нечего, а неработающая
   кнопка обманывает — документ запрещает фиктивные элементы. */
.аватар--в-навигации {
  margin-top: auto;
  width: 40px;
  height: 40px;
  font-size: var(--размер-мелкий);
}

/* --- Основная область ----------------------------------------------------- */

.основная-область {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
  background: var(--фон);
}

/**
 * Список чатов: ширина задаётся ЯВНО, а не «растянется по умолчанию».
 *
 * Это правило появилось после шести поломок раскладки. Список лежит в ряду
 * (`.ряды`), а у элемента ряда без `flex` ширина считается ПО СОДЕРЖИМОМУ.
 * Внутри строки стоит `width: 100%` — то есть сто процентов от ширины
 * по содержимому, и получалась узкая колонка посреди экрана.
 *
 * Здесь база: ширина по содержимому, но не меньше нуля. На телефоне область
 * растягивается, на планшете получает фиксированную ширину, на компьютере
 * её ширину задаёт колонка сетки. Все три случая — в блоках раскладки в конце файла.
 */
.область--разговоры {
  flex: 0 0 auto;
  min-width: 0;
}

/**
 * В основной области лежат ДВЕ части: открытый разговор и настройки.
 * Показывается ровно одна — какая, решает класс на оболочке.
 *
 * Без этого правила они видны одновременно: настройки дописывались ПОД переписку,
 * и человек видел поле ввода, а под ним заголовок «Настройки» с группами. Именно
 * это и было на снимке владельца.
 */
.основная-область > .область--настройки {
  display: none;
}

.оболочка--настройки .основная-область > .область--переписка {
  display: none;
}

.оболочка--настройки .основная-область > .область--настройки {
  display: flex;
}

/* Настройки: содержимое ограничено по ширине и по центру. Иначе строки
   растянулись бы на весь экран, и это как раз то, чего документ не хочет. */
.область--настройки {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
}

.область--настройки .экран {
  width: 100%;
  max-width: var(--ширина-настроек);
  margin: 0 auto;
  padding: var(--отступ-большой) var(--отступ-средний);
}

/* --- Шапка ---------------------------------------------------------------- */

.шапка {
  display: flex;
  align-items: center;
  gap: var(--отступ-малый);
  flex: none;
  min-height: 52px;
  padding: var(--отступ-малый) var(--отступ);
  border-bottom: 1px solid var(--разделитель);
  background: var(--поверхность-стекло);
  /* Стекло только на панелях: шапка, поле ввода, меню. Пузыри и строки списка
     остаются плотными — читаемость важнее эффекта. */
  backdrop-filter: blur(var(--размытие)) saturate(var(--насыщенность));
  -webkit-backdrop-filter: blur(var(--размытие)) saturate(var(--насыщенность));
  /* Полупрозрачная панель на светлом фоне без границы расплывается: граница
     отделяет материал от содержимого надёжнее, чем тень. */
  box-shadow: inset 0 -1px 0 var(--разделитель);
  /* Шапка не должна выезжать за экран: на телефоне её содержимое шире окна,
     и без этого крайние кнопки уходят за край — так и было видно надпись
     «владельцу», обрезанную справа. */
  overflow-x: clip;
}

/* Если браузер не умеет размытие, полупрозрачная панель станет нечитаемой:
   даём плотную подложку. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .шапка,
  .поле-ввода {
    background: var(--поверхность);
  }

  /* Боковая панель — тоже материал: без размытия полупрозрачность сделала бы её
     мутной, поэтому подставляем плотный цвет. */
  .область--разговоры {
    background: var(--фон-второй);
  }
}

.шапка__имя {
  /* Название сжимается первым и обрезается многоточием: лучше обрежется длинное
     название, чем уедет за экран нужная кнопка. */
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  font-size: var(--размер-заголовка);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Подпись под названием: в чате — имя собеседника или число участников.
   Показывается только при наличии настоящих данных (документ владельца, раздел 6). */
.шапка__подпись {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Крупный заголовок экрана списка: 32 точки, вес 700, слева. Такой заголовок
   в iOS стоит над содержимым и исчезает при прокрутке; у нас он просто часть шапки. */
.крупный-заголовок {
  margin: 0;
  font-size: var(--размер-крупного-заголовка);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

/* Шапка списка разговоров: крупный заголовок слева, действие справа. */
.шапка--список {
  align-items: flex-end;
  padding: var(--отступ-средний) var(--отступ-средний) var(--отступ-малый);
  background: var(--фон-области-разговоров);
}

/* Кнопки и значки в шапке не сжимаются: они должны оставаться целыми. */
.шапка .кнопка,
.шапка .значок-связи,
.шапка .аватар {
  flex: none;
}

.шапка .аватар {
  /* Кружок не должен сплющиваться в овал при нехватке места. */
  aspect-ratio: 1;
}

.шапка__подпись {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Аватар чата: первая буква названия. Данных о картинках у нас нет, поэтому
   буква — честный вариант, а не заглушка-картинка. */
/* Аватар буквой. Фотографий в приложении нет, поэтому буква — честный вариант:
   она несёт столько же смысла, сколько снимок, и не выглядит заглушкой.
   Размеры по документу владельца: 48 в списке, 56 в профиле, 36 в шапке чата. */
.аватар {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: var(--радиус-круглый);
  background: var(--акцент-мягкий);
  color: var(--акцент-для-текста);
  font-weight: 600;
  font-size: var(--размер-заголовка);
  text-transform: uppercase;
  user-select: none;
}

.аватар--общий {
  background: var(--акцент);
  color: var(--текст-на-акценте);
}

/* В шапке чата аватар меньше: там он подпись к названию, а не главный элемент. */
.шапка .аватар {
  width: 36px;
  height: 36px;
  font-size: var(--размер-крошечный);
}

/* В профиле настроек аватар крупнее. */
.профиль .аватар {
  width: 56px;
  height: 56px;
}

/* --- Колонка сообщений ----------------------------------------------------
   На компьютере лента занимает всю ширину основной области, но сами сообщения
   идут колонкой до 880 точек по центру: тянуть строку на 1400 точек нельзя —
   читать такое неудобно. Ограничивается ВНУТРЕННЯЯ колонка, а не приложение:
   так требует OCHAG_REDESIGN_GUIDE. */

@media (min-width: 1024px) {
  .область--переписка .лента,
  .область--переписка .поле-ввода,
  .область--переписка .сообщение-об-ошибке {
    width: 100%;
    max-width: var(--ширина-колонки-сообщений);
    margin-inline: auto;
    padding-inline: var(--отступ-большой);
  }
}



/* --- Подтверждение удаления ---------------------------------------------- */

.подтверждение {
  display: flex;
  flex-direction: column;
  gap: var(--отступ);
  max-width: 420px;
}

.подтверждение__текст {
  color: var(--текст-второй);
  font-size: var(--размер-мелкий);
}

/* --- Токены, которые пока не используются --------------------------------
   Их не удаляю, и это осознанно: они из шкалы документа владельца, а не мусор.

   * `--радиус-поиска` (14), `--радиус-большой` (20), `--отступ-огромный` (32) —
     ступени шкалы. Убрать ступень значит потерять её для следующей задачи,
     а шкала ценна именно полнотой.
   * `--быстро` (120ms), `--плавно` (180ms), `--радиус-малый` (10) — то же самое.
   * `--свой-край` — пара к `--свой-фон`: граница исходящего пузыря. Сейчас не
     нужна, потому что пузырь и так отличается цветом, но при смене палитры
     она понадобится.

   Что убрано по-настоящему: `--стекло-граница` — от неё отказались в пользу
   тонкой границы разделителя, и она не ступень шкалы, а конкретное решение. */

/* --- Точка состояния связи ------------------------------------------------
   Маленький кружок вместо капсулы с текстом: зелёный — связь есть, жёлтый —
   подключаемся, красный — связи нет. Когда всё хорошо, сообщать об этом постоянно
   незачем; когда связь пропала, рядом с точкой появляется словесная подпись.
   Раньше это была капсула «на связи», и она занимала в шапке столько места,
   что вытесняла за экран другие кнопки. */

.значок-связи {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  color: var(--спокойно);
  white-space: nowrap;
}

.значок-связи__точка {
  width: 9px;
  height: 9px;
  border-radius: var(--радиус-круглый);
  background: currentColor;
  flex: none;
}

.значок-связи__подпись {
  color: var(--текст-тихий);
  font-size: var(--размер-маленький);
}

.значок-связи--на-связи {
  color: var(--спокойно);
}

.значок-связи--подключение {
  color: var(--внимание);
}

.значок-связи--нет-связи,
.значок-связи--сервер-не-отвечает {
  color: var(--опасно);
}

/* --- Кнопки --------------------------------------------------------------- */

.кнопка {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* Область нажатия не меньше 44 точек: палец не должен промахиваться. */
  min-height: var(--размер-нажатия);
  padding: 0 var(--отступ-средний);
  border: none;
  border-radius: var(--радиус);
  /* Не --акцент, а --акцент-для-текста: на кнопке белая надпись, а белый текст
     на ярком #007AFF даёт 4.02:1 — ниже порога читаемости. Замерено проверкой. */
  background: var(--акцент-для-текста);
  color: var(--текст-на-акценте);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--переход), opacity var(--переход);
}

.кнопка:disabled {
  opacity: 0.5;
  cursor: default;
}

.кнопка--тихая {
  min-height: 36px;
  padding: 0 var(--отступ);
  background: transparent;
  color: var(--акцент);
  font-weight: 500;
}

.кнопка--тихая:hover {
  background: var(--акцент-мягкий);
}

.кнопка--опасная {
  background: transparent;
  /* Мелкий красный текст на белом: системный #FF3B30 даёт 3.5:1 — ниже порога 4.5,
     поэтому у надписи отдельный, более тёмный цвет (документ владельца, раздел 2). */
  color: var(--опасно-текст);
  border: 1px solid currentColor;
}

.кнопка--круглая {
  width: var(--размер-нажатия);
  min-width: var(--размер-нажатия);
  padding: 0;
  border-radius: var(--радиус-круглый);
}

.кнопка--отправка {
  width: var(--размер-нажатия);
  min-width: var(--размер-нажатия);
  padding: 0;
  border-radius: var(--радиус-круглый);
}

.кнопка--есть-новое {
  font-weight: 600;
}

input:focus-visible,
textarea:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--акцент);
  outline-offset: 2px;
}

/* --- Лента сообщений ------------------------------------------------------ */

.лента {
  display: flex;
  flex: 1;
  flex-direction: column;
  /* Промежутки задаются самими сообщениями: внутри серии одного автора 4–6 точек,
     при смене автора 10–12. Общий gap здесь мешал бы — он одинаков для всех,
     а серия сообщений должна читаться как одно высказывание. */
  gap: 0;
  min-height: 0;
  padding: var(--отступ-средний) var(--отступ);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.пусто {
  margin: auto;
  padding: var(--отступ-большой);
  color: var(--текст-тихий);
  text-align: center;
}

/* Кнопка «показать более старые»: не должна растягиваться на всю ленту. */
.лента > .кнопка {
  align-self: center;
  flex: none;
}

/* --- Сообщения ------------------------------------------------------------
   Пузыри плотные, без размытия: размытие в списке сообщений ухудшает чтение
   (документ владельца, раздел 1). Входящие серые, исходящие синие. */

.сообщение {
  /* Ширину ограничиваем от родителя, а не от содержимого: иначе длинное
     слово без пробелов растянет пузырь на весь экран.
     Предел — 72% области чата и не больше 560 точек, как в OCHAG_REDESIGN_GUIDE. */
  max-width: min(72%, 560px);
  position: relative;
  /* Поля в em: при крупном тексте пузырь растёт вместе с надписью, а не обрезает её. */
  padding: 0.55em 0.85em;
  border-radius: var(--радиус-пузыря);
  background: var(--чужой-фон);
  /* Промежуток внутри серии одного автора: 5 точек. */
  margin-top: 5px;
  /* Длинные слова и ссылки переносятся и не ломают вёрстку. */
  overflow-wrap: anywhere;
  word-break: normal;
  white-space: pre-wrap;
}

/* Смена автора: промежуток больше, серия отделяется от следующей. */
.сообщение[data-группа='true'] {
  margin-top: 11px;
}

/* Первое сообщение в ленте не должно добавлять отступ сверху. */
.лента > .сообщение:first-of-type {
  margin-top: 0;
}

.сообщение--своё {
  align-self: flex-end;
  background: var(--свой-фон);
  color: var(--текст-на-акценте);
}

.сообщение--чужое {
  align-self: flex-start;
}

/* Время и состояние внутри своего пузыря читаются на синем фоне: приглушённый
   цвет там не годится — он рассчитан на светлую подложку. */
.сообщение--своё .сообщение__низ,
.сообщение--своё .сообщение__автор {
  color: var(--текст-на-акценте);
  opacity: 0.85;
}

.сообщение--удалено {
  font-style: italic;
}

.сообщение:not(.сообщение--своё).сообщение--удалено {
  color: var(--текст-тихий);
}

/* Метка даты: отделяет сообщения разных дней. Не пузырь, а подпись по центру. */
.метка-даты {
  align-self: center;
  margin: var(--отступ-малый) 0;
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
}

.сообщение__автор {
  margin-bottom: 2px;
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
  font-weight: 600;
}

.сообщение__низ {
  display: flex;
  align-items: center;
  gap: var(--отступ-малый);
  margin-top: var(--отступ-крошечный);
  color: var(--текст-тихий);
  font-size: var(--размер-маленький);
}

.сообщение__статус--ошибка {
  color: var(--опасно);
}

.сообщение__действие {
  min-height: 24px;
  padding: 0 var(--отступ-крошечный);
  border: none;
  border-radius: var(--радиус-крошечный);
  background: transparent;
  color: var(--текст-тихий);
  font-size: var(--размер-маленький);
  cursor: pointer;
  text-decoration: underline;
}

/* --- Поле ввода ----------------------------------------------------------- */

.поле-ввода {
  display: flex;
  align-items: flex-end;
  gap: var(--отступ-малый);
  flex: none;
  padding: var(--отступ-малый) var(--отступ);
  border-top: 1px solid var(--разделитель);
  background: var(--поверхность-стекло);
  backdrop-filter: blur(var(--размытие)) saturate(var(--насыщенность));
  -webkit-backdrop-filter: blur(var(--размытие)) saturate(var(--насыщенность));
  /* Граница отделяет панель от содержимого надёжнее тени — см. пояснение у шапки. */
  box-shadow: inset 0 1px 0 var(--разделитель);
}

.поле-ввода textarea {
  /* Ширину задаёт flex, а не width: 100%: вместе со 100% текстовая область
     распирала строку ввода шире экрана, и панель уезжала за край.
     Именно это было видно на телефоне владельца. */
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  min-height: var(--высота-поля-ввода);
  max-height: 132px;
  padding: 0.6em var(--отступ-средний);
  border: 1px solid var(--граница);
  /* Панель ввода — скруглённая «таблетка», как в документе владельца. */
  border-radius: var(--радиус-поля-ввода);
  background: var(--поверхность);
  resize: none;
  font-size: var(--размер-поля-ввода);
}

.счётчик {
  align-self: center;
  color: var(--текст-тихий);
  font-size: var(--размер-маленький);
  white-space: nowrap;
}

/* --- Список разговоров ---------------------------------------------------- */

/* Строка разговора: аватар слева, название и превью в центре, время и счётчик
   справа (документ владельца, раздел 5). Фон — поверхность карточки, а не строка
   в таблице: так список читается как список карточек. */
.карточка--диалог {
  display: flex;
  align-items: center;
  gap: var(--отступ-средний);
  width: 100%;
  /* Высота с запасом на крупный текст: 76 точек при обычном размере.
     Высота в em, а не в точках, — иначе на крупном тексте строка обрежет содержимое. */
  min-height: calc(76px * var(--масштаб-текста));
  padding: var(--отступ) var(--отступ-средний);
  border: none;
  border-radius: var(--радиус);
  background: var(--поверхность);
  color: var(--текст);
  text-align: left;
  cursor: pointer;
  font: inherit;
  font-size: var(--размер-текста);
  transition: background var(--переход);
}

.карточка--диалог:active {
  background: var(--поверхность-тихая);
}

/* Разделитель между строками: 1px, начинается от аватара — как в списках iOS.
   Нарисован псевдоэлементом, а не рамкой: рамка шла бы через всю ширину,
   включая отступ слева от аватара, и выглядела бы жёстче. */
.карточка--диалог + .карточка--диалог {
  position: relative;
}

.карточка--диалог + .карточка--диалог::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  /* Отступ от аватара: 16 (поле) + 48 (аватар) + 16 (промежуток). */
  left: calc(var(--отступ-средний) + 48px + var(--отступ-средний));
  height: 1px;
  background: var(--разделитель);
  pointer-events: none;
}

.карточка--общий {
  background: var(--поверхность);
}

.карточка__содержимое {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

/**
 * Правая часть строки: время и счётчик непрочитанного.
 *
 * Столбцом и с прижатием к правому краю: время сверху, счётчик под ним — так
 * в списках iOS и так на образце владельца. Столбец не сжимается: время
 * и счётчик должны быть видны целиком, а обрезается название или превью.
 */
.карточка__справа {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: var(--отступ-крошечный);
  flex: none;
  /* Ширина по содержимому, но не больше трети строки: иначе длинное слово
     в превью выдавило бы правую часть за край. */
  max-width: 30%;
}

.карточка__время {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
  white-space: nowrap;
}

.карточка__имя {
  display: flex;
  align-items: center;
  gap: var(--отступ-малый);
  font-size: var(--размер-заголовка);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.карточка__последнее {
  color: var(--текст-тихий);
  font-size: var(--размер-мелкий);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.карточка__время {
  flex: none;
  color: var(--текст-тихий);
  font-size: var(--размер-маленький);
  white-space: nowrap;
}

/* Счётчик непрочитанного: видно, где есть новое. Число передаётся не только
   цветом, но и самим значком с цифрой. */
.счётчик-непрочитанного {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--радиус-круглый);
  background: var(--акцент);
  color: var(--текст-на-акценте);
  font-size: var(--размер-маленький);
  font-weight: 600;
}

/* --- Общие элементы экранов ---------------------------------------------- */

.экран {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--отступ-средний);
  min-height: 0;
  padding: var(--отступ-большой) var(--отступ-средний);
  overflow-y: auto;
}

.экран--центр {
  justify-content: center;
}

.заголовок {
  margin: 0;
  font-size: var(--размер-заголовка);
  font-weight: 600;
}

.подзаголовок {
  margin: 0;
  color: var(--текст-тихий);
}

.раздел {
  display: flex;
  flex-direction: column;
  gap: var(--отступ);
  margin-top: var(--отступ-малый);
}

.поле {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.поле__подпись {
  color: var(--текст-второй);
  font-size: var(--размер-мелкий);
}

.поле__подсказка {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
}

input,
textarea,
button,
select {
  font: inherit;
  color: inherit;
}

input:not([type='checkbox']),
textarea {
  padding: var(--отступ) var(--отступ-средний);
  border: 1px solid var(--граница);
  border-radius: var(--радиус);
  background: var(--поверхность);
}

/* Растягиваем на всю ширину только там, где поле стоит одно в колонке.
   Внутри строки (например, в поле ввода сообщения) ширину задаёт flex:
   `width: 100%` вместе с flex распирает строку шире экрана. */
.поле input,
.поле textarea,
.раздел input,
.раздел textarea {
  width: 100%;
}

.строка-кнопок {
  display: flex;
  gap: var(--отступ-малый);
  flex-wrap: wrap;
}

.сообщение-об-ошибке,
.сообщение-об-успехе {
  margin: var(--отступ) var(--отступ-средний) 0;
  padding: var(--отступ) var(--отступ-средний);
  border-radius: var(--радиус);
  font-size: var(--размер-мелкий);
}

.сообщение-об-ошибке {
  background: var(--опасно-мягкий);
  color: var(--опасно);
}

.сообщение-об-успехе {
  background: var(--акцент-мягкий);
}

.код-приглашения {
  display: block;
  padding: var(--отступ-средний);
  border: 1px dashed var(--граница);
  border-radius: var(--радиус);
  background: var(--поверхность);
  font-family: var(--шрифт-моно);
  font-size: 20px;
  letter-spacing: 2px;
  text-align: center;
  user-select: all;
}

.карточка {
  display: flex;
  flex-direction: column;
  gap: var(--отступ-крошечный);
  padding: var(--отступ);
  border: 1px solid var(--граница);
  border-radius: var(--радиус);
  background: var(--поверхность);
}

.карточка__состояние {
  color: var(--текст-тихий);
  font-size: var(--размер-мелкий);
}

.карточка--отключён {
  opacity: 0.65;
}

/* --- Настройки ------------------------------------------------------------
   Группы — матовые белые карточки со скруглением и тонкими разделителями
   (документ владельца, раздел 7). Строки внутри разделяются линией
   от текста, а не через всю ширину. */

.профиль {
  display: flex;
  align-items: center;
  gap: var(--отступ-средний);
  padding: var(--отступ-средний);
  border-radius: var(--радиус);
  background: var(--поверхность);
}

.профиль__текст {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.профиль__имя {
  font-size: var(--размер-заголовка);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.профиль__подпись {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
}

.группа {
  display: flex;
  flex-direction: column;
  gap: var(--отступ-малый);
  margin-top: var(--отступ-средний);
}

.заголовок-группы {
  margin: 0 0 0 var(--отступ-средний);
  color: var(--текст-тихий);
  font-size: var(--размер-заголовка-группы);
  font-weight: 500;
  letter-spacing: 0.04em;
}

.строка-настройки {
  display: flex;
  align-items: center;
  gap: var(--отступ-средний);
  padding: var(--отступ) var(--отступ-средний);
  border-radius: var(--радиус);
  background: var(--поверхность);
}

/* Разделитель между строками одной группы: от текста, а не через всю ширину. */
.строка-настройки + .строка-настройки {
  position: relative;
}

.строка-настройки + .строка-настройки::before {
  content: '';
  position: absolute;
  top: calc(-1 * var(--отступ-малый) / 2);
  right: 0;
  left: var(--отступ-средний);
  height: 1px;
  background: var(--разделитель);
  pointer-events: none;
}

.строка-настройки__текст {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.строка-настройки__имя {
  font-size: var(--размер-текста);
}

.строка-настройки__подпись {
  color: var(--текст-тихий);
  font-size: var(--размер-крошечный);
}

/* Раскрывающаяся часть группы: приглашения показываются по нажатию, чтобы
   настройки оставались обозримыми. Отступ слева отделяет её от строки-переключателя. */
.группа__раскрытие {
  display: flex;
  flex-direction: column;
  gap: var(--отступ-малый);
  padding: var(--отступ) var(--отступ-средний);
  border-radius: var(--радиус);
  background: var(--поверхность);
}

/* Переключатель: настоящая галочка, а не нарисованная «крутилка». Нарисованная
   не работает с клавиатуры и не читается программами чтения с экрана. */
.строка-настройки--переключатель {
  cursor: pointer;
}

.переключатель {
  flex: none;
  width: 51px;
  height: 31px;
  margin: 0;
  /* appearance: none убирает системный вид, чтобы нарисовать свой. */
  appearance: none;
  -webkit-appearance: none;
  border-radius: var(--радиус-круглый);
  background: var(--поверхность-тихая);
  border: 1px solid var(--граница);
  cursor: pointer;
  transition: background var(--переход);
}

.переключатель::after {
  content: '';
  display: block;
  width: 27px;
  height: 27px;
  margin: 1px;
  border-radius: var(--радиус-круглый);
  background: var(--поверхность);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
  transition: transform var(--переход);
}

.переключатель:checked {
  background: var(--акцент);
  border-color: var(--акцент);
}

.переключатель:checked::after {
  transform: translateX(20px);
}

.кнопка--на-всю-ширину {
  width: 100%;
}

/* =========================================================================
   Доступность
   ========================================================================= */

/* Человек попросил систему уменьшить движение: убираем переходы. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* =========================================================================
   РАСКЛАДКА ПО РАЗМЕРАМ ОКНА
   -------------------------------------------------------------------------
   Это единственное место, где решается, какой ширины и высоты какая часть.
   Блок стоит в КОНЦЕ файла намеренно: в CSS при равном весе селекторов
   побеждает то правило, что записано НИЖЕ.

   ТРИ ПРАВИЛА, которые появились после шести поломок раскладки:

   1. ШИРИНА ЗАДАЁТСЯ ЯВНО на каждом уровне. Не «растянется по умолчанию»:
      у элемента в горизонтальном ряду без `flex` ширина считается по содержимому,
      и тогда `width: 100%` внутри означает сто процентов от узкой колонки.
      Именно это давало узкий список посреди экрана.

   2. НИКАКИХ `margin: auto` в каркасе. Автоматические поля центрируют только
      при ограниченной ширине, а при её отсутствии ведут себя непредсказуемо.
      Наружу ограничивать нечего — каркас занимает окно целиком.

   3. ОДНО МЕСТО ДЛЯ РАСКЛАДКИ. Пока правила были разбросаны и перемешаны
      с правилами вида, ошибку нельзя было увидеть: базовое правило перебивало
      мобильное, а проверки смотрели на текст, а не на результат каскада.

   Проверяется механически: `node tools/check-layout-rules.mjs`, и он же
   запускается при каждой сборке.
   ========================================================================= */

/* --- Корень: окно целиком ------------------------------------------------- */

html,
body {
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
}

#app {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  min-width: 0;
  height: 100vh;
  height: 100dvh;
  /* Верхний вырез камеры и боковые скругления. Нижнюю полосу жеста учитывает
     тот, кто стоит внизу экрана. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
  overflow: hidden;
}

/* --- Каркас разговоров: колонка ------------------------------------------- */

.оболочка {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

/* Список и основная область. На телефоне это ряд, в котором видна одна часть;
   на компьютере обёртка растворяется и части становятся колонками сетки. */
.ряды {
  display: flex;
  flex-direction: row;
  width: 100%;
  min-width: 0;
  min-height: 0;
  /* Занимает всё место между верхом каркаса и нижними вкладками. */
  flex: 1 1 auto;
}

.область {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
  min-height: 0;
  flex: 0 0 auto;
  background: var(--фон);
}

/* Список чатов: на телефоне растягивается, на планшете и компьютере получает
   свою ширину. Здесь только общая часть — раскладка по размерам ниже. */
.область--разговоры {
  min-width: 0;
}

/* Основная область: занимает остаток ширины и всю высоту. */
.основная-область {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: 0;
  background: var(--фон);
}

/* В основной области ДВЕ части: разговор и настройки. Показывается одна. */
.основная-область > .область--настройки {
  display: none;
}

.область--переписка {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: 0;
}

.область--настройки {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
}

/* --- Навигация: рельс на компьютере, вкладки внизу на телефоне ------------- */

.навигация {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  flex: 0 0 auto;
  background: var(--поверхность);
}

/* --- Выбранный разговор --------------------------------------------------- */

.карточка--диалог[aria-current='true'] {
  background: var(--цвет-выбранного-чата);
}

/* --- ТЕЛЕФОН: одна часть за раз, вкладки внизу ---------------------------- */

@media (max-width: 767px) {
  /* Вкладки идут после содержимого: порядок в разметке — навигация, затем ряды. */
  .ряды {
    order: 1;
  }

  .навигация {
    order: 2;
    flex-direction: row;
    height: auto;
    border-top: 1px solid var(--разделитель);
    border-right: none;
    /* Полосу жеста учитывает панель вкладок: она стоит внизу экрана. */
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* Знак приложения и аватар на телефоне не нужны: места мало, а вкладок две. */
  .навигация__знак,
  .аватар--в-навигации {
    display: none;
  }

  .навигация__пункты {
    flex-direction: row;
    width: 100%;
  }

  .навигация__пункт {
    flex: 1 1 0;
    min-height: var(--размер-нажатия);
  }

  /* Растягивается ровно то, что показано. Ширина задана явно. */
  .область--разговоры {
    flex: 1 1 auto;
    width: 100%;
  }

  /**
   * В открытом чате горизонтальные жесты браузер не трогает.
   *
   * `touch-action: pan-y` разрешает вертикальную прокрутку и запрещает
   * горизонтальную: без этого браузер и наш жест возврата борются за одно и то же
   * движение, и страница дёргается. Настройка касается ТОЛЬКО переписки: список
   * чатов и поле ввода остаются как были, чтобы не сломать ни прокрутку списка,
   * ни выделение текста в поле.
   */
  .оболочка:not(.оболочка--список):not(.оболочка--настройки) .область--переписка {
    touch-action: pan-y;
  }

  /* Показ частей: ровно одна. */
  .оболочка--список .основная-область {
    display: none;
  }

  .оболочка:not(.оболочка--список) .область--разговоры {
    display: none;
  }

  .оболочка--настройки .область--разговоры {
    display: none;
  }

  .оболочка--настройки .основная-область > .область--переписка {
    display: none;
  }

  .оболочка--настройки .основная-область > .область--настройки {
    display: flex;
  }

  /**
   * В открытом чате нижних вкладок НЕТ: поле ввода должно стоять у нижнего края.
   * Требование документа: «composer у нижнего края, без tab bar под ним».
   */
  .оболочка:not(.оболочка--список):not(.оболочка--настройки) .навигация {
    display: none;
  }

  /* Без вкладок полосу жеста учитывает поле ввода — оно теперь внизу. */
  .оболочка:not(.оболочка--список):not(.оболочка--настройки) .поле-ввода {
    padding-bottom: calc(var(--отступ-малый) + env(safe-area-inset-bottom));
  }

  /* --- Строка разговора на телефоне: как в образце владельца ---------------
     Слева кружок с первой буквой, в середине название и превью последнего
     сообщения, справа время и счётчик непрочитанного. Строки идут одним белым
     блоком с разделителями, а не отдельными карточками: так список читается
     как список, а не как набор кнопок. */

  .область--разговоры .лента {
    padding-inline: var(--отступ-средний);
    padding-block: 0;
  }

  .карточка--диалог {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--отступ);
    width: 100%;
    /* Ориентир из документа — 76–84 точки; на телефоне берём с запасом на крупный текст. */
    min-height: calc(72px * var(--масштаб-текста));
    padding: var(--отступ-малый) var(--отступ-средний);
    /* Рамок у строки нет: их роль выполняют разделители. */
    border: none;
    border-radius: 0;
    background: var(--поверхность);
  }

  /* Первая и последняя строки блока закругляются, чтобы список выглядел цельным. */
  .карточка--диалог:first-of-type {
    border-top-left-radius: var(--радиус);
    border-top-right-radius: var(--радиус);
  }

  .карточка--диалог:last-of-type {
    border-bottom-left-radius: var(--радиус);
    border-bottom-right-radius: var(--радиус);
  }

  /* Кружок с первой буквой: 48 точек, как в образце. */
  .карточка--диалог .аватар {
    width: 48px;
    height: 48px;
    font-size: var(--размер-текста);
  }

  .карточка__имя {
    font-size: var(--размер-заголовка);
    font-weight: 600;
  }

  /* Превью одной строкой: длинное сообщение обрезается, а не ломает строку. */
  .карточка__последнее,
  .карточка__состояние {
    font-size: var(--размер-мелкий);
    color: var(--текст-тихий);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Разделитель от края кружка: 16 (поле) + 48 (кружок) + 12 (промежуток). */
  .карточка--диалог + .карточка--диалог::before {
    left: calc(var(--отступ-средний) + 48px + var(--отступ));
  }
}

/* --- ПЛАНШЕТ: список и основная область рядом ----------------------------- */

@media (min-width: 768px) and (max-width: 1023px) {
  .ряды {
    order: 1;
  }

  .навигация {
    order: 2;
    flex-direction: row;
    height: auto;
    border-top: 1px solid var(--разделитель);
    border-right: none;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .навигация__знак,
  .аватар--в-навигации {
    display: none;
  }

  .навигация__пункты {
    flex-direction: row;
    width: 100%;
  }

  .навигация__пункт {
    flex: 1 1 0;
    min-height: var(--размер-нажатия);
  }

  /* Список фиксированной ширины: ширина задана явно, а не по содержимому. */
  .область--разговоры {
    flex: 0 0 var(--ширина-области-разговоров-узкая);
    width: var(--ширина-области-разговоров-узкая);
    border-right: 1px solid var(--граница);
    background: var(--фон-области-разговоров);
  }

  .основная-область {
    display: flex;
  }

  .оболочка--настройки .область--разговоры {
    display: none;
  }

  .оболочка:not(.оболочка--список) .область--разговоры {
    display: flex;
  }
}

/* --- КОМПЬЮТЕР: рельс, список и основная область -------------------------- */

@media (min-width: 1024px) {
  .оболочка {
    display: grid;
    grid-template-columns: var(--ширина-рельса) var(--ширина-области-разговоров) minmax(0, 1fr);
    width: 100%;
  }

  /* Обёртка растворяется: список и основная область становятся колонками сетки.
     `display: contents` убирает саму обёртку из раскладки. */
  .ряды {
    display: contents;
  }

  .навигация {
    width: var(--ширина-рельса);
    height: 100%;
  }

  .область--разговоры {
    width: 100%;
    min-width: 0;
    flex: 1 1 auto;
    display: flex;
    border-right: 1px solid var(--граница);
    background: var(--фон-области-разговоров);
  }

  .основная-область {
    display: flex;
    width: 100%;
  }

  /* На компьютере список виден, поэтому путь к нему не нужен. */
  .кнопка--назад {
    display: none;
  }

  /* Настройки: список чатов скрыт, содержимое ограничено по ширине и по центру.
     Это единственное место, где ограничение ширины уместно: строки настроек
     растягивать на весь экран нельзя. */
  .оболочка--настройки {
    grid-template-columns: var(--ширина-рельса) minmax(0, 1fr);
  }

  .оболочка--настройки .область--разговоры {
    display: none;
  }

  /* Колонка сообщений: ограничивается ВНУТРЕННЯЯ колонка, а не приложение. */
  .область--переписка .лента,
  .область--переписка .поле-ввода,
  .область--переписка .сообщение-об-ошибке {
    width: 100%;
    max-width: var(--ширина-колонки-сообщений);
    margin-inline: auto;
    padding-inline: var(--отступ-большой);
  }

  .область--настройки .экран {
    width: 100%;
    max-width: var(--ширина-настроек);
    margin-inline: auto;
  }
}

/* --- Кнопка «ещё» у сообщения --------------------------------------------- */

@media (max-width: 767px) {
  /* На телефоне меню открывается долгим нажатием, а место в строке дорогое.
     Для клавиатуры кнопка нужна на широком окне — там она и остаётся. */
  .сообщение__ещё {
    display: none;
  }
}

/* =========================================================================
   МЕНЮ ДЕЙСТВИЙ НАД СООБЩЕНИЕМ
   -------------------------------------------------------------------------
   Постоянной ссылки «удалить» под сообщением нет: действия собраны в меню,
   которое открывается долгим нажатием, правым щелчком или кнопкой.
   Кнопка обязательна — иначе действие недоступно с клавиатуры и для программ
   чтения с экрана, то есть работающая функция потерялась бы ради вида.
   ========================================================================= */

.сообщение__меню {
  position: absolute;
  z-index: 5;
  min-width: 200px;
  padding: var(--отступ-крошечный);
  border: 1px solid var(--разделитель);
  border-radius: var(--радиус);
  background: var(--поверхность);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.16);
}

.меню__пункт {
  display: flex;
  align-items: center;
  gap: var(--отступ-малый);
  width: 100%;
  min-height: var(--размер-нажатия);
  padding: 0 var(--отступ);
  border: none;
  border-radius: var(--радиус-малый);
  background: transparent;
  color: var(--текст);
  font: inherit;
  font-size: var(--размер-текста);
  text-align: left;
  cursor: pointer;
}

.меню__пункт:hover {
  background: var(--поверхность-тихая);
}

.меню__пункт--опасный {
  color: var(--опасно-текст);
}

/* Кнопка «ещё»: открывает то же меню с клавиатуры. */
.сообщение__ещё {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: var(--радиус-круглый);
  background: transparent;
  color: var(--текст-тихий);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.сообщение__ещё:hover {
  background: var(--поверхность-тихая);
}

/* --- Подтверждение удаления ---------------------------------------------- */

.подтверждение {
  display: flex;
  flex-direction: column;
  gap: var(--отступ);
  max-width: 420px;
}

.подтверждение__текст {
  color: var(--текст-второй);
  font-size: var(--размер-мелкий);
}
