/* Архив личных чатов.
 *
 * Токены --ar-* выставляются из themeParams в archive.js. Они намеренно свои,
 * а не общие со style.css: остальное приложение сейчас нарисовано в собственной
 * тёмной палитре, и перекрашивание его целиком - отдельная задача, не эта.
 */

/* Запасная палитра - на :root, и это принципиально.
 *
 * Тема пишется из themeParams инлайном в <html>, а инлайн бьёт таблицу стилей
 * только на одном и том же элементе. Пока эти же токены объявлялись на .ar,
 * то есть на контейнере ближе к баблам, выигрывали они - и внутри Архива тема
 * не применялась вовсе, всё рисовалось этими запасными цветами. */
:root {
  --ar-nav-h: 92px;
  --ar-bg: #010101;
  --ar-card: rgba(255, 255, 255, 0.04);
  --ar-text: #f3f4f6;
  --ar-hint: #9ca3af;
  --ar-subtitle: #6b7280;
  --ar-accent: #7a6ad0;
  --ar-button-text: #ffffff;
  --ar-border: rgba(255, 255, 255, 0.08);
  --ar-overlay: rgba(255, 255, 255, 0.07);
  --ar-overlay-strong: rgba(255, 255, 255, 0.12);
  --ar-chat-bg: #0b0b0d;
  --ar-bubble-in: #1e1f22;
  --ar-bubble-in-text: #f3f4f6;
  --ar-dashed: rgba(255, 255, 255, 0.28);
  --ar-accent-soft: rgba(122, 106, 208, 0.18);
  /* Акцент, разбавленный фоном: дальний конец перелива на кольце истории. */
  --ar-accent-fade: #40396b;
  --ar-accent-border: rgba(122, 106, 208, 0.5);
  --ar-wall-strong: rgba(122, 106, 208, 0.17);
  --ar-wall-soft: rgba(122, 106, 208, 0.09);
  --ar-chat-bg-half: rgba(11, 11, 13, 0.72);
  --ar-border-faint: rgba(255, 255, 255, 0.04);
  --ar-deleted-bg: #141417;
  --ar-deleted-text: #e5e7eb;
  --ar-deleted-own-tag: #c9cdd6;
  /* Разрушительное действие - один и тот же красный везде, независимо от
   * темы: строка «Очистить архив» и кнопка подтверждения в её листе должны
   * читаться как один и тот же вопрос, а не два разных оттенка. */
  --ar-danger: #e5484d;
  /* Медиа с таймером: исчезло само, а не по чьей-то команде. */
  --ar-ttl: #d9963c;
  --ar-ttl-border: rgba(217, 150, 60, 0.55);
  /* Полоса выгрузки: тонировка поверх фона темы, а не самостоятельный цвет -
   * потому и в rgba, и потому одинаковая в обеих темах. */
  --ar-activity-a: rgba(59, 130, 246, 0.22);
  --ar-activity-b: rgba(16, 185, 129, 0.14);
  --ar-activity-dot: #6ee7b7;
}

.ar,
.ar * {
  box-sizing: border-box;
}

/* Сброс кнопок Архива.
 *
 * Сбрасывать приходится не только вид WebKit, но и глобальное правило из
 * style.css: там у любого button фон #161616, скругление 14px и тень. Мои
 * правила перебивали только то, что объявляли сами, - скругление и тень
 * протекали насквозь и рисовали рамку вокруг каждой строки списка.
 *
 * Селектор обёрнут в :where() намеренно: он не добавляет специфичности, и
 * сброс остаётся слабее любого правила с классом. Иначе .ar button (0,1,1)
 * перебивал бы .ar-btn (0,1,0), и уже основная кнопка осталась бы без фона.
 */
:where(.ar) button {
  -webkit-appearance: none;
  appearance: none;
  width: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: inherit;
  font: inherit;
  font-weight: inherit;
  transition: none;
}

/* Единственное, что нужно погасить у нажатой кнопки, - подскок из style.css.
 * Класс здесь намеренно: правило перебивает button:active из общей таблицы, но
 * трогает одно свойство, которого нет ни в одном правиле Архива. Держать в
 * общем сбросе :active было ошибкой - он выигрывал у .ar-chatrow по
 * специфичности, и строка при нажатии теряла ширину, отступы и фон. */
.ar button:active {
  transform: none;
}

.ar.hidden {
  display: none !important;
}

/* Нижний бар лежит поверх содержимого, поэтому там, где он есть, экранам
 * основного приложения нужен запас снизу - иначе он накроет последнюю кнопку
 * или бейдж. */
body.has-bottom-nav .webapp-container {
  padding-bottom: calc(var(--ar-nav-h) + var(--app-safe-bottom, 0px));
}

/* Экраны Архива - на весь экран и со своим фоном, поэтому всё, что рисует
 * основное приложение, на это время убирается. Иначе общий логотип и
 * контейнер логина просвечивают поверх. */
body.step-archive-chat .webapp-container,
body.step-archive-chat .global-top-logo,
body.step-onboarding .webapp-container,
body.step-onboarding .global-top-logo,
body.step-settings .webapp-container,
body.step-settings .global-top-logo,
body.step-archive .global-top-logo {
  display: none !important;
}

/* На вкладке Архива экран копирования остаётся в дереве ради одной вещи -
 * шапки историй (.stories-top-row). Она position: fixed поверх всего, со своим
 * раскрытием и перетаскиванием, и переиспользовать её честнее, чем рисовать
 * рядом вторую такую же. Всё остальное содержимое того экрана скрыто. */
body.step-archive #step-channels > *:not(.stories-top-row):not(#stories-expanded),
body.step-archive .hero,
body.step-archive #encryption-badge {
  display: none !important;
}

/* Лента историй на Архиве ничем не отличается от ленты на копировании: она
 * лежит в потоке того же экрана, и содержимое ниже едет вместе с ней. Раньше
 * здесь стоял position: fixed, из-за чего она висела неподвижно, а список под
 * ней жил своей жизнью. */

/* Во время поиска шапка уходит: наверху одно место, и две строки там не
 * помещаются. */
body.ar-searching .stories-top-row,
body.ar-searching #stories-expanded {
  display: none !important;
}

/* --- Список чатов ---------------------------------------------------------- */

/* Список чатов - обычный поток страницы, как на вкладке копирования.
 *
 * Раньше он был отдельным фиксированным слоем со своей прокруткой внутри. Это
 * и создавало всю разницу: у страницы не было ни родного отскока, ни того,
 * что лента историй тянется вместе с содержимым, - она висела сверху
 * неподвижным слоем. Теперь структура одна на обе вкладки: сверху шапка с
 * историями (она лежит в потоке экрана копирования, который на Архиве
 * оставлен ради неё), ниже - список. Прокручивается сама страница.
 */
.ar-list {
  display: block;
  background: var(--ar-bg);
  color: var(--ar-text);
}

/* Спейсер больше не нужен: место под шапку держит padding-top у body, а место
 * под раскрытую ленту - сама лента, она в потоке. */
.ar-list__top {
  display: none;
}

/* Поиск - слой поверх текущего экрана. Строка ввода встаёт с того края, с
 * которого её позвали: от кнопки рядом с баром - снизу, на место этой кнопки;
 * от строки наверху вкладки копирования - сверху, на её место. Поиск при этом
 * один и тот же. */
.ar-search {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  background: var(--ar-bg);
}

.ar-search--top {
  justify-content: flex-start;
}

/* Пока поиск открыт, страница под ним стоит на месте: положение прокрутки
 * держит top у body (его ставит archive.js), а сам поиск лежит своим
 * фиксированным слоем и от этого не зависит. */
body.ar-scroll-lock {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

.ar-search.hidden {
  display: none !important;
}

/* Сверху отступ под навигацию самого Telegram: «назад» и меню рисует он, и
 * первая строка результатов не должна оказываться под ними. */
.ar-search__results {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: calc(var(--app-safe-top, 0px) + 64px) 8px 12px 8px;
}

/* Когда строка ввода наверху, отступ под навигацию Telegram держит уже она -
 * находкам остаётся обычный зазор от неё и запас снизу под клавиатуру. */
.ar-search--top .ar-search__results {
  padding: 2px 8px calc(var(--app-safe-bottom, 0px) + 12px) 8px;
}

.ar-search__section {
  padding: 10px 10px 8px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ar-subtitle);
}

.ar-search__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px calc(22px + var(--app-safe-bottom, 0px)) 16px;
}

/* Наверху строке нужен свой отступ под навигацию самого Telegram: «назад» и
 * меню он рисует поверх мини-аппа, и его кнопки в безопасную зону не входят -
 * поле с одним --app-safe-top оказывалось ровно под ними. Высоту этой полосы
 * Telegram не отдаёт, её держит --tg-header-offset (вне Telegram - ноль). */
.ar-search--top .ar-search__bar {
  padding: calc(var(--app-safe-top, 0px) + var(--tg-header-offset, 0px) + 10px) 16px 10px 16px;
}

/* Капсула поля - того же размера и вида, что строка поиска на вкладке
 * копирования: она этот слой и открывает, и поле не должно менять облик по
 * дороге. Голым должен быть сам input внутри капсулы, а не она. */
.ar-search__field {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  height: 54px;
  padding: 0 18px;
  border-radius: 27px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  color: var(--ar-hint);
}

/* [type="text"] в селекторе - не для JS, для специфичности CSS.
 *
 * В style.css есть общее правило input[type="text"] { border: 1px solid
 * rgba(255,255,255,0.08); background: rgba(255,255,255,0.04); color:
 * #f3f4f6; ...} - оно не привязано к теме и весит (0,1,1): элемент + атрибут.
 * Мой .ar-search__input весил (0,1,0) - один класс - и проигрывал ему
 * независимо от порядка подключения таблиц стилей. Отсюда и рамка с фоном,
 * которые я «убирал» раньше, но они возвращались, и захардкоженный цвет
 * текста вместо темы. Тот же класс приёма, что и для сброса кнопок выше:
 * добавляю атрибут, который JS и так ставит (input.type = "text"), и получаю
 * (0,2,0) - выше на класс, побеждает при любом порядке подключения. */
.ar-search__input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  color: var(--ar-text);
  font-size: 17px;
}

.ar-search__input::placeholder {
  color: var(--ar-subtitle);
}

.ar-search__close {
  width: 54px;
  height: 54px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  color: var(--ar-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Своей прокрутки у списка нет - прокручивается страница. Боковых отступов
 * тоже нет: их даёт сама страница, ровно как списку каналов. Свои 16px делали
 * строки чатов уже соседних. Снизу остаётся запас под нижний бар. */
.ar-list__scroll {
  padding: 0 0 calc(var(--ar-nav-h) + var(--app-safe-bottom, 0px)) 0;
}

/* Растушёвку под баром рисует body::after - общая для Архива и копирования.
 * Своя полоса теперь лишняя, но элемент оставлен: он ничего не стоит, а
 * убирать его из разметки ради одного правила незачем. */
.ar-list__fade {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 150px;
  pointer-events: none;
  background: linear-gradient(to top, var(--ar-bg) 42%, transparent);
}

.ar-chatrow {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Между строками воздух: слипшиеся карточки читаются как одна, и попасть в
   * нужную труднее, чем кажется. */
  margin-bottom: 4px;
  padding: 9px 8px;
  border-radius: 14px;
  background: var(--ar-card);
  border: 0;
  width: 100%;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-chatrow {
  transition: background-color 0.1s ease-out;
}

.ar-chatrow > * {
  transition: transform 0.1s ease-out;
}

/* Нажатие красит строку в серый (--ar-overlay-strong - нейтральный оттенок от
 * фона, не от акцента) и слегка стягивает содержимое к центру - тот же эффект,
 * что у ячейки в Telegram. Сжимается содержимое (> *), а не сама строка: у
 * строки своя закраска на всю ширину, и если бы уменьшался весь блок, по краям
 * на миг проглядывал бы фон позади него - светлые щели в тёмной теме, тёмные в
 * светлой.
 *
 * Действует и на тихие чаты без событий: у них тот же обработчик click, что и
 * у остальных, - тап открывает чат, а не переключатель без действия. */
.ar-chatrow:active {
  background: var(--ar-overlay-strong);
}

.ar-chatrow:active > * {
  transform: scale(0.97);
}

.ar-chatrow--quiet {
  background: transparent;
  padding: 7px 8px;
}

.ar-avatar {
  position: relative;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 700;
  color: #ffffff;
  flex: 0 0 auto;
  overflow: hidden;
}

/* Фотография кладётся поверх инициалов, а не вместо них: пока её нет или она
 * не доехала, под ней остаётся цветной круг с буквами. */
.ar-avatar__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

.ar-chatrow--quiet .ar-avatar {
  width: 46px;
  height: 46px;
  font-size: 17px;
  opacity: 0.7;
}

.ar-chatrow__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.ar-chatrow__top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.ar-chatrow__name {
  font-size: 17px;
  font-weight: 600;
  color: var(--ar-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ar-chatrow--quiet .ar-chatrow__name {
  font-size: 16px;
  font-weight: 500;
  color: var(--ar-hint);
}

/* В поиске приглушать нечего: там все строки - находки, и тусклая половина
 * списка читается как «это чем-то хуже». Приглушение остаётся только в списке
 * чатов, где им отмечены чаты без единого события. */
.ar-search .ar-chatrow--quiet .ar-avatar {
  opacity: 1;
}

.ar-search .ar-chatrow--quiet .ar-chatrow__name {
  color: var(--ar-text);
}

.ar-chatrow__time {
  margin-left: auto;
  font-size: 13px;
  color: var(--ar-subtitle);
  flex: 0 0 auto;
}

.ar-chatrow__counters {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Метки канала - везде, где они встречаются: в списке каналов, в карточке и в
 * поиске. Форма и размер приезжают из style.css, цвета - из темы: фон берётся
 * из Telegram и может быть светлым, и белый текст на белой подложке там просто
 * исчезал бы. Зелёный и красный сплошные и одинаковые в обеих темах: это
 * статус, а не оформление. */
body.step-channels .chip,
.ar .chip {
  color: var(--ar-text);
  background: var(--ar-overlay);
  border-color: var(--ar-border);
  box-shadow: none;
}

body.step-channels .chip--green,
.ar .chip--green {
  color: #2f9e63;
  background: rgba(52, 211, 153, 0.16);
  border-color: rgba(52, 211, 153, 0.38);
}

body.step-channels .chip--red,
.ar .chip--red {
  color: var(--ar-danger);
  background: rgba(229, 72, 77, 0.16);
  border-color: rgba(229, 72, 77, 0.38);
}

.ar-counter {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
}

.ar-counter--deleted {
  color: var(--ar-accent);
}

.ar-counter--edited {
  color: var(--ar-hint);
}

/* Медиа с таймером - третий род события, и цвет у него свой. Акцентный занят
 * удалённым, серый - изменённым; тёплый янтарь читается как предупреждение,
 * а не как чужое действие. Одинаков в обеих темах намеренно: это статус, а не
 * элемент оформления. */
.ar-counter--ttl {
  color: var(--ar-ttl);
}

.ar-section-title {
  padding: 16px 10px 8px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ar-subtitle);
}

/* --- Пустые состояния ------------------------------------------------------ */

.ar-empty {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 0 28px calc(var(--ar-nav-h) + 8px) 28px;
  text-align: center;
}

.ar-empty__art {
  position: relative;
  width: 116px;
  height: 96px;
  flex: 0 0 auto;
}

.ar-empty__art i {
  position: absolute;
  display: block;
  border-radius: 16px 16px 16px 5px;
  background: var(--ar-bubble-in);
  border: 1px solid var(--ar-border);
}

.ar-empty__art i:nth-child(1) { left: 4px; top: 0; width: 78px; height: 40px; }
.ar-empty__art i:nth-child(2) { right: 0; top: 30px; width: 86px; height: 44px; border-radius: 16px 16px 5px 16px; }
.ar-empty__art i:nth-child(3) { left: 14px; bottom: 0; width: 62px; height: 34px; background: none; border: 1.5px dashed var(--ar-dashed); }

.ar-empty__title {
  font-size: 23px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--ar-text);
}

.ar-empty__text {
  font-size: 15px;
  line-height: 21px;
  color: var(--ar-hint);
  text-wrap: pretty;
}

.ar-pill {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  border-radius: 999px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  font-size: 13px;
  font-weight: 600;
  color: var(--ar-text);
}

.ar-pill__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #6ee7b7;
  flex: 0 0 auto;
}

/* --- Экран подключения ----------------------------------------------------- */

.ar-connect {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px 22px calc(var(--ar-nav-h) + 16px) 22px;
}

.ar-connect__title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.4px;
  color: var(--ar-text);
}

.ar-connect__sub {
  font-size: 15px;
  line-height: 21px;
  color: var(--ar-hint);
  text-wrap: pretty;
}

.ar-steps {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ar-step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 14px;
  border-radius: 14px;
  background: var(--ar-card);
  border: 1px solid var(--ar-border);
}

.ar-step__no {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--ar-accent);
  color: var(--ar-button-text);
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.ar-step__text {
  font-size: 15px;
  line-height: 20px;
  color: var(--ar-text);
}

.ar-step__text b {
  font-weight: 600;
}

.ar-note {
  font-size: 13px;
  line-height: 18px;
  color: var(--ar-subtitle);
  text-wrap: pretty;
}

.ar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 14px 16px;
  border: 0;
  border-radius: 14px;
  background: var(--ar-accent);
  color: var(--ar-button-text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-btn:active {
  opacity: 0.8;
}

.ar-btn--ghost {
  background: var(--ar-overlay);
  color: var(--ar-text);
  border: 1px solid var(--ar-border);
}

/* --- «С чего начнём» ------------------------------------------------------- */

.ar-onboarding {
  position: fixed;
  inset: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--ar-bg);
  color: var(--ar-text);
  padding: calc(var(--app-safe-top, 0px) + 24px) 16px calc(var(--app-safe-bottom, 0px) + 24px) 16px;
}

.ar-onboarding__head {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 0 4px 2px 4px;
}

.ar-onboarding__title {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--ar-text);
}

.ar-onboarding__sub {
  font-size: 15px;
  line-height: 20px;
  color: var(--ar-hint);
  text-wrap: pretty;
}

.ar-card-block {
  border-radius: 18px;
  background: var(--ar-card);
  border: 1px solid var(--ar-border);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.ar-card-block__head {
  display: flex;
  align-items: center;
  gap: 11px;
}

.ar-card-block__icon {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--ar-overlay);
  color: var(--ar-text);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

/* Пунктир - та же обводка, что у удалённого бабла: иконка Архива и его
 * сообщения должны читаться как одно. */
.ar-card-block__icon--dashed {
  border-radius: 12px;
  border: 1.5px dashed var(--ar-dashed);
  background: var(--ar-overlay);
}

.ar-card-block__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--ar-text);
}

.ar-card-block__sub {
  font-size: 13px;
  color: var(--ar-subtitle);
}

.ar-points {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.ar-point {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 14px;
  line-height: 19px;
  color: var(--ar-text);
}

.ar-point svg {
  flex: 0 0 auto;
  margin-top: 2px;
}

/* --- Чат ------------------------------------------------------------------- */

.ar-chat {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--ar-chat-bg);
  color: var(--ar-text);
  padding-top: var(--app-safe-top, 0px);
}

/* Обои чата. themeParams их не отдаёт, поэтому собираем сами из акцента:
 * четыре мягких пятна разной насыщенности - переливчатая подложка, а не
 * плоская заливка. Фон чата у них общий, так что тема меняет и её. */
.ar-chat__wall {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(58% 40% at 12% 6%, var(--ar-wall-strong), rgba(0, 0, 0, 0) 70%),
    radial-gradient(52% 38% at 88% 22%, var(--ar-wall-soft), rgba(0, 0, 0, 0) 72%),
    radial-gradient(64% 44% at 78% 84%, var(--ar-wall-strong), rgba(0, 0, 0, 0) 70%),
    radial-gradient(56% 40% at 20% 70%, var(--ar-wall-soft), rgba(0, 0, 0, 0) 74%);
}

/* Шапка - капсула по центру. Поля по краям пустые: в fullview у Telegram
 * сверху своя навигация, назад слева и меню справа, и дублировать её нельзя.
 *
 * Она плавает поверх ленты, а не занимает строку в раскладке: сообщения должны
 * проезжать ЗА ней и растворяться в затемнении, а не обрываться о край блока.
 * Затемнение идёт во всю высоту полосы - от непрозрачного фона чата сверху до
 * прозрачного снизу. */
.ar-chat__head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
  display: flex;
  justify-content: center;
  padding: calc(var(--app-safe-top, 0px) + 12px) 72px 22px 72px;
  pointer-events: none;
}

.ar-chat__head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    var(--ar-chat-bg) 24%,
    var(--ar-chat-bg-half) 58%,
    transparent
  );
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent);
  mask-image: linear-gradient(to bottom, #000 62%, transparent);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  pointer-events: none;
}

/* Капсула поверх затемнения. Без position она рисуется в потоке, то есть
 * РАНЬШЕ позиционированного ::before, - и имя уезжает за туман. */
.ar-capsule {
  position: relative;
  z-index: 1;
  pointer-events: auto;
}

.ar-capsule {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 15px 5px 5px;
  border-radius: 999px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  max-width: 100%;
}

.ar-capsule .ar-avatar {
  width: 32px;
  height: 32px;
  font-size: 13px;
}

.ar-capsule__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.ar-capsule__name {
  font-size: 15px;
  font-weight: 600;
  line-height: 18px;
  color: var(--ar-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ar-capsule__sub {
  font-size: 12px;
  line-height: 15px;
  color: var(--ar-accent);
  white-space: nowrap;
}

/* Лента занимает весь экран - и под шапкой, и под переключателем. Место под
 * ними держит сам виртуальный список (CHAT_GUTTER_TOP/BOTTOM), иначе он считал
 * бы высоту окна вместе с padding и промахивался. */
.ar-chat__scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 10px;
  /* Жест по вертикали - наш, и до предков он не доходит: иначе свайп снизу
   * вверх у края достаётся Telegram, и чат перестаёт листаться. */
  overscroll-behavior-y: contain;
  touch-action: pan-y;
}

.ar-chat__sizer {
  position: relative;
  width: 100%;
}

.ar-chat__window {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  will-change: transform;
}

/* Промежуток между сообщениями - padding внутри элемента, а не gap у
 * контейнера. Виртуальный список меряет высоты через offsetHeight, а gap в
 * offsetHeight не входит: с ним модель высот занижала бы каждый элемент на
 * 8px, и чем ниже по списку, тем сильнее расходились бы расчётное и реальное
 * положение. */
.ar-chat__window > * {
  padding-bottom: 8px;
}

.ar-chat__status {
  padding: 18px 10px;
  text-align: center;
  font-size: 14px;
  color: var(--ar-hint);
}

/* Пустой чат: надпись стоит по центру экрана и не участвует в прокрутке. Пока
 * она лежала в потоке ленты, её сносило под подложку списка - ниже панели, да
 * ещё и с прокруткой. */
.ar-chat__empty {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--app-safe-top, 0px) + 76px);
  bottom: calc(var(--app-safe-bottom, 0px) + 88px);
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 32px;
  text-align: center;
  font-size: 15px;
  line-height: 21px;
  color: var(--ar-hint);
  pointer-events: none;
}

.ar-chat__empty.hidden {
  display: none !important;
}

/* Разделитель дня стоит свободнее, чем сообщения: вплотную он читался как
 * подпись к следующему баблу, а не как граница дня. Отступы симметричные и
 * чуть больше того, что между сообщениями. */
.ar-daysep {
  display: flex;
  justify-content: center;
  padding: 6px 0;
}

.ar-daysep span {
  padding: 4px 11px;
  border-radius: 13px;
  background: var(--ar-overlay-strong);
  font-size: 13px;
  font-weight: 500;
  color: var(--ar-text);
}

.ar-row {
  display: flex;
}

.ar-row--in { justify-content: flex-start; }
.ar-row--out { justify-content: flex-end; }

.ar-bubble {
  position: relative;
  max-width: 84%;
  padding: 8px 12px;
  border-radius: 16px 16px 16px 5px;
  background: var(--ar-bubble-in);
  color: var(--ar-bubble-in-text);
}

.ar-row--out .ar-bubble {
  border-radius: 16px 16px 5px 16px;
  background: var(--ar-accent);
  color: var(--ar-button-text);
}

.ar-bubble:has(.ar-media--thumb) {
  padding: 5px;
  max-width: 72%;
}

/* Макеты 3 и 11. Правило одно и стороны не путает:
 *
 *   чужое удалённое  - нейтральный серый фон, серая пунктирная обводка;
 *   своё удалённое   - фон и обводка в цвете темы.
 *
 * Фон непрозрачный и считается от фона чата. Полупрозрачный пропускал бы
 * подложку с акцентным свечением, и «серый» бабл собеседника становился бы
 * цветным - ровно та ошибка, из-за которой стороны и смешивались.
 */
.ar-bubble--deleted,
.ar-bubble--edited {
  background: var(--ar-deleted-bg);
  color: var(--ar-deleted-text);
}

.ar-bubble--deleted {
  border: 1.5px dashed var(--ar-dashed);
}

/* Изменённое - тот же фон, но линия сплошная: сообщение никуда не делось. */
.ar-bubble--edited {
  border: 1.5px solid var(--ar-dashed);
  border-left: 2.5px solid var(--ar-deleted-text);
}

.ar-bubble--deleted .ar-bubble__tag {
  color: var(--ar-hint);
}

.ar-row--out .ar-bubble--deleted,
.ar-row--out .ar-bubble--edited {
  background: var(--ar-accent-soft);
  color: var(--ar-text);
}

.ar-row--out .ar-bubble--deleted {
  border: 1.5px dashed var(--ar-accent-border);
}

.ar-row--out .ar-bubble--edited {
  border: 1.5px solid var(--ar-accent-border);
  border-left: 2.5px solid var(--ar-accent);
}

.ar-bubble__tag {
  color: var(--ar-hint);
}

/* Бабл с картинкой почти целиком из неё и состоит - поля тоньше. */
.ar-bubble:has(.ar-media--thumb),
.ar-bubble:has(.ar-album) {
  padding: 5px;
  max-width: 76%;
}

.ar-bubble__tag {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--ar-hint);
}

/* На чужом изменённом акценту не место - всё рисуется цветом текста этого же
 * сообщения, без приглушения. */
.ar-bubble__tag--edited {
  color: var(--ar-deleted-text);
}

.ar-row--out .ar-bubble__tag--edited {
  color: var(--ar-accent);
}

/* На своём удалённом подпись светло-серая: акцент там уже занят заливкой и
 * обводкой, и акцентный текст поверх него сливается. */
.ar-row--out .ar-bubble--deleted .ar-bubble__tag {
  color: var(--ar-accent);
  opacity: 1;
}

/* У изменённого фон такой же приглушённый, значит и текст на нём обычный - не
 * тот, что на сплошном акцентном бабле. */
.ar-row--out .ar-bubble--edited .ar-bubble__time,
.ar-row--out .ar-bubble--edited .ar-version__text {
  color: var(--ar-hint);
  opacity: 1;
}

.ar-row--out .ar-bubble--edited .ar-version--current .ar-version__text {
  color: var(--ar-text);
}

.ar-bubble__text {
  font-size: 16px;
  line-height: 21px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ar-bubble__old {
  font-size: 15px;
  line-height: 20px;
  color: var(--ar-hint);
  text-decoration: line-through;
  text-decoration-color: var(--ar-dashed);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin-bottom: 3px;
}

.ar-bubble__time {
  display: flex;
  justify-content: flex-end;
  margin-top: 1px;
  font-size: 12px;
  color: var(--ar-hint);
}

.ar-row--out .ar-bubble__time {
  color: var(--ar-button-text);
  opacity: 0.68;
}

.ar-row--out .ar-bubble__old {
  color: var(--ar-button-text);
  opacity: 0.62;
  text-decoration-color: var(--ar-button-text);
}

/* Свой удалённый бабл живёт на приглушённом фоне, и текст на нём - обычный. */
.ar-row--out .ar-bubble--deleted .ar-bubble__time,
.ar-row--out .ar-bubble--deleted .ar-bubble__old {
  color: var(--ar-hint);
  opacity: 1;
  text-decoration-color: var(--ar-dashed);
}

.ar-bubble__tail {
  position: absolute;
  bottom: 0;
  width: 9px;
  height: 18px;
  line-height: 0;
  color: var(--ar-bubble-in);
}

.ar-row--in .ar-bubble__tail {
  left: -7px;
}

.ar-row--out .ar-bubble__tail {
  right: -7px;
  color: var(--ar-accent);
}

.ar-media {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0 4px 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--ar-overlay-strong);
  border: 0;
  width: 100%;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-media:active { opacity: 0.75; }
.ar-media[disabled] { opacity: 0.55; cursor: default; }

/* С превью блок становится картинкой на всю ширину бабла - скруглённые углы,
 * затемнение снизу и время в углу.
 *
 * Высота не фиксирована намеренно. Раньше тут стояли 132px и object-fit:
 * cover, и у всего вертикального срезалась верхушка - ровно лицо на кружке
 * или на фото. Теперь картинка задаёт высоту сама, а потолок нужен лишь для
 * того, чтобы длинный вертикальный кадр не занял весь экран. */
.ar-media--thumb {
  position: relative;
  display: block;
  padding: 0;
  overflow: hidden;
  background: var(--ar-overlay);
}

.ar-media__img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 380px;
  object-fit: contain;
}

.ar-media__shade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 52px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
  pointer-events: none;
}

.ar-media__badge {
  position: absolute;
  left: 9px;
  bottom: 7px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.4);
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.9);
}

.ar-media__stamp {
  z-index: 1;
  position: absolute;
  right: 9px;
  bottom: 7px;
  padding: 2px 7px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.4);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
}

.ar-media__icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  background: var(--ar-overlay);
  color: var(--ar-text);
  font-size: 14px;
}

.ar-media__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.ar-media__kind {
  font-size: 14px;
  font-weight: 600;
  color: var(--ar-text);
}

.ar-media__action {
  font-size: 12px;
  color: var(--ar-hint);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- Переключатель режимов (на месте поля ввода) --------------------------- */

.ar-modes {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  padding: 26px 14px calc(14px + var(--app-safe-bottom, 0px)) 14px;
  pointer-events: none;
}

/* Снизу то же затемнение, что и сверху: лента не обрывается о панель, а уходит
 * в фон. */
.ar-modes::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    var(--ar-chat-bg) 42%,
    var(--ar-chat-bg-half) 72%,
    transparent
  );
  -webkit-mask-image: linear-gradient(to top, #000 62%, transparent);
  mask-image: linear-gradient(to top, #000 62%, transparent);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  pointer-events: none;
}

.ar-modes__inner {
  position: relative;
  pointer-events: auto;
}

.ar-modes__inner {
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: 26px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
}

.ar-mode {
  appearance: none;
  -webkit-appearance: none;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 11px 8px;
  border: 0;
  border-radius: 21px;
  background: transparent;
  color: var(--ar-hint);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-mode--active {
  background: var(--ar-accent);
  color: var(--ar-button-text);
}

.ar-mode__count {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.25);
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

/* --- Нижняя навигация ------------------------------------------------------ */

.ar-nav {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(22px + var(--app-safe-bottom, 0px));
  display: flex;
  align-items: center;
  gap: 10px;
  z-index: 40;
}

.ar-nav.hidden { display: none !important; }

.ar-nav__tabs {
  flex: 1;
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: 30px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.ar-tab {
  appearance: none;
  -webkit-appearance: none;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 4px;
  border: 0;
  border-radius: 25px;
  background: transparent;
  color: var(--ar-hint);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Выбранная вкладка: подложка и акцентный цвет - он красит и текст, и иконку,
 * потому что SVG рисуются currentColor. Невыбранная - без подложки вовсе. */
.ar-tab--active {
  background: var(--ar-overlay-strong);
  color: var(--ar-accent);
}

/* Невыбранная вкладка - просто текст в панели, без своего бабла. Явно, потому
 * что у кнопки в WebKit есть собственный фон по умолчанию. */
.ar-tab:not(.ar-tab--active),
.ar-mode:not(.ar-mode--active) {
  background: none;
  box-shadow: none;
}

.ar-nav__search {
  width: 66px;
  height: 66px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  color: var(--ar-text);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-nav__search.hidden {
  display: none !important;
}

.ar-tab__avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: linear-gradient(145deg, #5f7fb5, #2b3a52);
  border: 1.5px solid var(--ar-border);
  flex: 0 0 auto;
  background-size: cover;
  background-position: center;
}

/* С фотографией градиент не мешает: инлайновый background-image её заменяет,
 * а класс нужен лишь как признак для будущих правил. */
.ar-tab__avatar--photo {
  background-color: transparent;
}

/* --- Просмотр медиа -------------------------------------------------------- */

/* Отдельный экран поверх чата. Показывает превью: оригинал мини-аппу недоступен,
 * песочница не даёт его ни скачать, ни отрисовать, - поэтому единственное
 * действие здесь честное и одно, и оно внизу крупной кнопкой. */
.ar-viewer {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: #000000;
  overflow: hidden;
  /* Тянется за пальцем при свайпе вниз - как просмотр историй. */
  touch-action: none;
  will-change: transform;
}

.ar-viewer.hidden {
  display: none !important;
}

.ar-viewer__capsule {
  z-index: 2;
  position: absolute;
  top: calc(var(--app-safe-top, 0px) + 14px);
  left: 72px;
  right: 72px;
  margin: 0 auto;
  width: fit-content;
  max-width: 100%;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  font-size: 13px;
  font-weight: 600;
  color: #e5e7eb;
  white-space: nowrap;
}

/* Содержимое живёт между капсулой сверху и панелью снизу, и его центр
 * совпадает с центром этой области - а не уезжает под капсулу. Поля заданы
 * симметрично сверху и снизу, поэтому центрирование честное. */
.ar-viewer__stage {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--app-safe-top, 0px) + 68px);
  bottom: calc(var(--app-safe-bottom, 0px) + 188px);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* По ширине - весь экран, по высоте - сколько поместится между капсулой и
 * панелью. Полей по бокам нет: они съедали бы картинку ни за чем. */
.ar-viewer__img {
  width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

/* Половины экрана для листания альбома. Лежат ниже панели и капсулы, чтобы не
 * перехватывать нажатия на кнопку. */
/* Зоны листания невидимы полностью: у кнопки в WebKit свои фон, рамка и тень
 * по умолчанию, и без сброса appearance они проступают тёмными полосами. */
.ar-viewer__zone {
  appearance: none;
  -webkit-appearance: none;
  position: absolute;
  top: calc(var(--app-safe-top, 0px) + 68px);
  bottom: calc(var(--app-safe-bottom, 0px) + 188px);
  width: 42%;
  border: 0;
  outline: none;
  background: none;
  box-shadow: none;
  color: inherit;
  font: inherit;
  padding: 0;
  z-index: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-viewer__zone--prev { left: 0; }
.ar-viewer__zone--next { right: 0; }

.ar-viewer__missing {
  padding: 40px 24px;
  font-size: 15px;
  color: #8b95a5;
  text-align: center;
}

.ar-viewer__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 60px 16px calc(26px + var(--app-safe-bottom, 0px)) 16px;
  background: linear-gradient(to top, #000000 55%, rgba(0, 0, 0, 0));
}

.ar-viewer__strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
}

.ar-viewer__cell {
  width: 54px;
  height: 54px;
  border-radius: 10px;
  border: 2px solid transparent;
  background: rgba(255, 255, 255, 0.08);
  padding: 0;
  overflow: hidden;
  opacity: 0.6;
  flex: 0 0 auto;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-viewer__cell--active {
  border-color: #ffffff;
  opacity: 1;
}

.ar-viewer__cellimg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ar-viewer__meta {
  display: flex;
  align-items: center;
  gap: 11px;
}

.ar-viewer__avatar {
  width: 40px;
  height: 40px;
  font-size: 15px;
}

.ar-viewer__who {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ar-viewer__name {
  font-size: 16px;
  font-weight: 600;
  color: #f3f4f6;
}

.ar-viewer__sent {
  font-size: 13px;
  color: #8b95a5;
}

.ar-viewer__count {
  padding: 6px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  font-size: 13px;
  font-weight: 600;
  color: #d1d5db;
  flex: 0 0 auto;
}

/* --- Лента версий (макет 12) ----------------------------------------------- */

.ar-versions {
  display: flex;
  gap: 11px;
  margin-top: 2px;
}

/* Слева точка - линия - точка: путь от исходного текста к текущему. */
.ar-versions__line {
  width: 9px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 6px;
}

.ar-versions__line i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ar-dashed);
  flex: 0 0 auto;
}

.ar-versions__line span {
  width: 1.5px;
  flex: 1;
  background: linear-gradient(to bottom, var(--ar-dashed), var(--ar-deleted-text));
}

.ar-versions__line b {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ar-deleted-text);
  flex: 0 0 auto;
}

/* Линия и точка в цвете темы - только у своего сообщения. */
.ar-row--out .ar-versions__line span {
  background: linear-gradient(to bottom, var(--ar-dashed), var(--ar-accent));
}

.ar-row--out .ar-versions__line b {
  background: var(--ar-accent);
}

.ar-versions__items {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.ar-version__meta {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--ar-subtitle);
  margin-bottom: 2px;
}

.ar-version__text {
  font-size: 16px;
  line-height: 21px;
  color: var(--ar-hint);
  text-decoration: line-through;
  text-decoration-color: var(--ar-dashed);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Актуальная версия - в полном цвете и без зачёркивания.
 *
 * Акцент - цвет пользователя, и на чужом сообщении ему не место: подпись и
 * точка на линии там обычного текстового цвета. */
.ar-version--current .ar-version__meta {
  color: var(--ar-deleted-text);
}

.ar-row--out .ar-version--current .ar-version__meta {
  color: var(--ar-accent);
}

.ar-version--current .ar-version__text {
  color: var(--ar-bubble-in-text);
  text-decoration: none;
}

/* --- Альбом ---------------------------------------------------------------- */

/* Альбом - одно сообщение: Telegram присылает его отдельными апдейтами, но
 * отправляли и удаляли его целиком. */
.ar-album {
  position: relative;
  display: grid;
  gap: 3px;
  grid-template-columns: 1fr 1fr;
  border-radius: 12px;
  overflow: hidden;
  margin: 2px 0 4px 0;
}

.ar-album--1 {
  grid-template-columns: 1fr;
}

.ar-album--3 .ar-album__cell:first-child {
  grid-column: span 2;
}

.ar-album__cell {
  position: relative;
  padding: 0;
  border: 0;
  background: var(--ar-overlay);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ar-album--1 .ar-album__cell,
.ar-album--3 .ar-album__cell:first-child {
  aspect-ratio: 4 / 3;
}

.ar-album__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ar-album__fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 13px;
  color: var(--ar-hint);
}

.ar-album__more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  font-size: 22px;
  font-weight: 700;
  color: #ffffff;
}

.ar-viewer__audio {
  width: 100%;
  max-width: 320px;
}

/* Спиннер на время загрузки оригинала. Крутится transform - как и всё
 * остальное движение в Архиве. */
.ar-spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.16);
  border-top-color: rgba(255, 255, 255, 0.75);
  animation: ar-spin 0.8s linear infinite;
}

@keyframes ar-spin {
  to {
    transform: rotate(360deg);
  }
}

/* --- Настройки ------------------------------------------------------------- */

.ar-settings {
  position: fixed;
  inset: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  background: var(--ar-bg);
  color: var(--ar-text);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: var(--app-safe-top, 0px) 16px
    calc(var(--ar-nav-h) + var(--app-safe-bottom, 0px)) 16px;
}

.ar-settings__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 70px;
  flex: 0 0 auto;
  /* Гасит свой gap до следующего блока: список Архива начинается сразу под
   * 70px-зоной общей шапки, без дополнительного зазора - тот же отступ
   * сверху здесь даёт safe-top + 70px и ни пикселем больше. .ar-settings
   * держит gap: 14px между ВСЕМИ секциями, и трогать его нельзя - собьётся
   * ритм между остальными карточками; гасим локально, только для первой пары. */
  margin-bottom: -14px;
}

/* Логотип здесь тот же и красится так же, как в шапке приложения: поверх
 * картинки ложится копия её белых букв, залитая цветом текста темы
 * (--app-logo-tint ставит webapp.js). */
.ar-settings__logo {
  position: relative;
}

.ar-settings__logo img {
  width: 70px;
  height: 70px;
  object-fit: contain;
  display: block;
}

@supports (-webkit-mask: url("/static/logo-tint.png")) or (mask: url("/static/logo-tint.png")) {
  .ar-settings__logo::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 70px;
    height: 70px;
    transform: translate(-50%, -50%);
    background-color: var(--ar-text);
    -webkit-mask: var(--app-logo-tint, url("/static/logo-tint.png")) center / contain no-repeat;
    mask: var(--app-logo-tint, url("/static/logo-tint.png")) center / contain no-repeat;
    pointer-events: none;
  }
}

/* Заголовок идёт ПОД карточкой аккаунтов: она не часть настроек, а выбор
 * того, чьи это настройки. */
.ar-settings__title {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.4px;
  padding: 6px 2px 0 2px;
}

/* Обводки у карточек в Telegram нет вовсе. Оставляем еле заметную: она
 * держит край, когда фон карточки почти совпадает с фоном экрана, и не
 * читается как рамка, когда не совпадает. */
/* Карточки настроек - без обводки: их и так разделяет заливка, а рамка на
 * каждой превращала экран в сетку из коробок. */
.ar-card {
  border-radius: 14px;
  background: var(--ar-card);
  border: 0;
  overflow: hidden;
  flex: 0 0 auto;
}

/* Обводка остаётся у «Доступа к чатам»: это единственный переключатель,
 * который выключает Архив целиком, и выделен он намеренно. */
.ar-card--outlined {
  border: 1px solid var(--ar-border-faint);
}

/* --- Аккаунты -------------------------------------------------------------- */

.ar-account {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 7px 14px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.1s ease-out;
}

.ar-account > * {
  transition: transform 0.1s ease-out;
}

/* Тот же эффект нажатия, что у строки чата - серый оттенок на всю строку и
 * сжатие только содержимого (> *), без щелей по краям. Покрывает и выбор
 * аккаунта, и «Добавить аккаунт»: у второго тот же класс. */
.ar-account:active {
  background: var(--ar-overlay-strong);
}

.ar-account:active > * {
  transform: scale(0.97);
}

/* Разделитель начинается после аватара, а не от края карточки - как в списке
 * аккаунтов самого Telegram. */
.ar-account + .ar-account,
.ar-account + .ar-srow {
  position: relative;
}

.ar-account + .ar-account::before,
.ar-account + .ar-srow::before {
  content: "";
  position: absolute;
  left: 62px;
  right: 14px;
  top: 0;
  height: 1px;
  background: var(--ar-border-faint);
}

.ar-account__avatar {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  overflow: hidden;
  flex: 0 0 auto;
}

.ar-account__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ar-account__initials {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-size: 15px;
  font-weight: 700;
  color: #ffffff;
}

/* Только аватар и имя: чем аккаунт подключён - не то, что человек выбирает
 * глазами в этом списке. */
.ar-account__name {
  flex: 1;
  min-width: 0;
  font-size: 17px;
  color: var(--ar-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ar-account__check {
  flex: 0 0 auto;
  color: var(--ar-accent);
}

.ar-account--add .ar-account__name {
  color: var(--ar-hint);
}

.ar-account__plus {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: var(--ar-hint);
}

/* --- Строки настроек ------------------------------------------------------- */

.ar-srow {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 7px 14px;
  min-height: 48px;
  -webkit-tap-highlight-color: transparent;
}

.ar-srow--tappable {
  cursor: pointer;
  transition: background-color 0.1s ease-out;
}

.ar-srow--tappable > * {
  transition: transform 0.1s ease-out;
}

.ar-srow--tappable:active {
  background: var(--ar-overlay-strong);
}

.ar-srow--tappable:active > * {
  transform: scale(0.97);
}

.ar-switch {
  cursor: pointer;
}

.ar-srow + .ar-srow {
  position: relative;
}

/* Разделитель начинается после иконки и не доходит до правой стенки: он
 * кончается там же, где кончается переключатель. И он тусклый - в Telegram
 * линия едва различима. */
.ar-srow + .ar-srow::before {
  content: "";
  position: absolute;
  left: 60px;
  right: 14px;
  top: 0;
  height: 1px;
  background: var(--ar-border-faint);
}

.ar-srow--access + .ar-srow::before,
.ar-srow + .ar-srow--access::before {
  left: 14px;
}

/* Иконка в цветном квадрате - как в настройках Telegram. */
.ar-srow__icon {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: #ffffff;
}

.ar-srow__title {
  flex: 1;
  min-width: 0;
  font-size: 17px;
  color: var(--ar-text);
}

.ar-srow__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.ar-srow__hint {
  font-size: 12px;
  line-height: 16px;
  color: var(--ar-subtitle);
}

.ar-srow__value {
  flex: 0 0 auto;
  font-size: 17px;
  color: var(--ar-hint);
}

.ar-srow__chevron {
  flex: 0 0 auto;
  display: flex;
  color: var(--ar-subtitle);
}

.ar-srow--danger .ar-srow__title {
  color: var(--ar-danger);
}

/* Доступ к чатам: точка состояния и слово справа, менять его отсюда нельзя. */
.ar-srow--access {
  padding: 12px 14px;
}

.ar-srow__state {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  font-size: 14px;
  color: var(--ar-hint);
}

.ar-srow__state i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  display: block;
}

.ar-switch {
  flex: 0 0 auto;
  width: 44px;
  height: 26px;
  border-radius: 13px;
  background: var(--ar-overlay-strong);
  position: relative;
  transition: background 0.18s ease;
}

.ar-switch i {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.18s ease;
}

.ar-switch--on {
  background: var(--ar-accent);
}

.ar-switch--on i {
  transform: translateX(18px);
}

/* --- Баннер Grabee Plus ---------------------------------------------------- */

.ar-plus {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 16px;
  border-radius: 16px;
  background: linear-gradient(135deg, var(--ar-accent-soft), var(--ar-overlay));
  border: 1px solid var(--ar-accent-border);
  flex: 0 0 auto;
}

.ar-plus__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.ar-plus__logo {
  height: 26px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: left center;
  align-self: flex-start;
  display: block;
}

.ar-plus__text {
  font-size: 13px;
  line-height: 18px;
  color: var(--ar-hint);
}

/* Маршрут до настроек Telegram - единственное действующее место в строке. */
.ar-link {
  color: var(--ar-accent);
  cursor: pointer;
}

/* --- Лист подтверждения ---------------------------------------------------- */

/* Необратимое подтверждается листом снизу, как это делает сам Telegram:
 * вопрос, красное действие и отдельной кнопкой отмена. */
.ar-sheet {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 8px calc(var(--app-safe-bottom, 0px) + 10px) 8px;
}

.ar-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
}

.ar-sheet__box,
.ar-sheet__cancel {
  position: relative;
  border-radius: 14px;
  background: var(--ar-card);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  overflow: hidden;
}

.ar-sheet__text {
  padding: 18px 20px;
  text-align: center;
  font-size: 15px;
  line-height: 20px;
  color: var(--ar-hint);
}

.ar-sheet__action {
  padding: 17px 20px;
  text-align: center;
  font-size: 20px;
  color: var(--ar-danger);
  border-top: 1px solid var(--ar-border-faint);
  cursor: pointer;
}

/* Вариант выбора: значение слева, пометка справа. Недоступный не нажимается и
 * говорит почему - отказ после нажатия был бы хуже. */
.ar-sheet__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 15px 20px;
  font-size: 18px;
  color: var(--ar-text);
  border-top: 1px solid var(--ar-border-faint);
  cursor: pointer;
  transition: background-color 0.1s ease-out;
}

.ar-sheet__option > * {
  transition: transform 0.1s ease-out;
}

.ar-sheet__option em {
  font-style: normal;
  font-size: 13px;
  color: var(--ar-accent);
}

.ar-sheet__option--active {
  color: var(--ar-accent);
  font-weight: 600;
}

.ar-sheet__option--locked {
  color: var(--ar-subtitle);
  cursor: default;
}

/* Варианты выбора срока: та же серая заливка на всю строку и сжатие только
 * содержимого, что у остальных строк - недоступный (locked) не откликается
 * вовсе, там нечего выбирать. */
.ar-sheet__option:active {
  background: var(--ar-overlay-strong);
}

.ar-sheet__option:active > * {
  transform: scale(0.97);
}

.ar-sheet__option--locked:active {
  background: none;
}

.ar-sheet__option--locked:active > * {
  transform: none;
}

.ar-sheet__cancel {
  padding: 17px 20px;
  text-align: center;
  font-size: 20px;
  font-weight: 600;
  color: var(--ar-accent);
  cursor: pointer;
}

.ar-sheet__action:active,
.ar-sheet__cancel:active {
  opacity: 0.72;
}

/* --- Полоса выгрузки ------------------------------------------------------- */

/* Узкая полоса над нижним баром: круговой прогресс, тип задачи, источник и
 * «ещё N в очереди». Стоит поверх содержимого на всех вкладках - раньше
 * прогресс жил только на экране сессий, которого в новой навигации нет.
 *
 * Оттенки заливки намеренно фиксированные и полупрозрачные: это тонировка
 * поверх фона темы, а не собственный цвет, поэтому она работает и в светлой.
 * Текст и кольцо берут --ar-text и остаются читаемыми в обеих. */
.ar-activity {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(100px + var(--app-safe-bottom, 0px));
  z-index: 41;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 14px 9px 9px;
  border-radius: 22px;
  background: linear-gradient(140deg, var(--ar-activity-a), var(--ar-activity-b));
  border: 1px solid var(--ar-border);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  color: var(--ar-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Нажатие - как у строк списка: стягивается содержимое, а сама полоса
 * остаётся на месте. Заливку здесь не меняем, её место занял градиент. */
.ar-activity > * {
  transition: transform 0.1s ease-out;
}

.ar-activity:active > * {
  transform: scale(0.97);
}

.ar-activity__ring {
  position: relative;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
}

.ar-activity__ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    var(--ar-text) 0deg var(--ar-activity-deg, 0deg),
    var(--ar-overlay-strong) var(--ar-activity-deg, 0deg) 360deg
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
}

.ar-activity__pct {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 800;
}

.ar-activity__body {
  flex: 1;
  min-width: 0;
}

.ar-activity__title,
.ar-activity__meta,
.ar-queue__title,
.ar-queue__row-title,
.ar-queue__meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ar-activity__title {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.2px;
}

.ar-activity__meta {
  font-size: 12px;
  opacity: 0.86;
}

.ar-activity__chev {
  flex: 0 0 auto;
  color: var(--ar-text);
}

/* Точка на вкладке «Копирование», пока задача жива. Обводка цветом фона
 * отделяет её от иконки под ней. */
.ar-tab__icon {
  position: relative;
  width: 24px;
  height: 24px;
}

.ar-tab__dot {
  position: absolute;
  right: -2px;
  top: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ar-activity-dot);
  border: 2px solid var(--ar-bg);
}

.ar-tab__dot.hidden {
  display: none !important;
}

/* --- Очередь --------------------------------------------------------------- */

/* Лист очереди - тот же снизу, что у подтверждения, но во всю ширину и со
 * своим содержимым, поэтому у обёртки гасятся боковые поля и зазор. */
.ar-sheet--queue {
  padding: 0;
  gap: 0;
}

.ar-queue {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 10px 16px calc(var(--app-safe-bottom, 0px) + 26px) 16px;
  border-radius: 22px 22px 0 0;
  border-top: 1px solid var(--ar-border);
}

.ar-queue__grabber {
  width: 38px;
  height: 4px;
  margin: 0 auto;
  border-radius: 2px;
  background: var(--ar-overlay-strong);
}

.ar-queue__head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 2px;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: var(--ar-text);
}

.ar-queue__head em {
  font-style: normal;
  font-size: 13px;
  font-weight: 400;
  color: var(--ar-subtitle);
}

.ar-queue__current {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 13px 14px;
  border-radius: 16px;
  background: linear-gradient(140deg, var(--ar-activity-a), var(--ar-activity-b));
  border: 1px solid var(--ar-border);
  color: var(--ar-text);
}

.ar-queue__head-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.ar-queue__body {
  flex: 1;
  min-width: 0;
}

.ar-queue__title {
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.2px;
}

.ar-queue__row-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--ar-text);
}

.ar-queue__meta {
  margin-top: 2px;
  font-size: 12px;
  color: var(--ar-hint);
}

.ar-queue__current .ar-queue__meta {
  color: var(--ar-text);
  opacity: 0.86;
}

.ar-queue__btn {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ar-overlay-strong);
  color: var(--ar-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Отмена красится тем же красным, что «Очистить архив» и его подтверждение:
 * разрушительное действие в приложении одно и то же независимо от экрана. */
.ar-queue__btn--cancel {
  color: var(--ar-danger);
}

.ar-queue__btn > * {
  transition: transform 0.1s ease-out;
}

.ar-queue__btn:active > * {
  transform: scale(0.88);
}

.ar-queue__line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.ar-queue__track {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--ar-overlay-strong);
  overflow: hidden;
}

.ar-queue__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--ar-text);
  transition: width 0.2s ease-out;
}

.ar-queue__pct {
  font-size: 12px;
  font-weight: 800;
  color: var(--ar-text);
}

.ar-queue__rest {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.ar-queue__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-radius: 14px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border-faint);
}

.ar-queue__tile {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--ar-overlay-strong);
  color: var(--ar-hint);
}

.ar-queue__pill {
  flex: 0 0 auto;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--ar-overlay);
  border: 1px solid var(--ar-border);
  font-size: 11px;
  font-weight: 700;
  color: var(--ar-hint);
}

.ar-queue__note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 0 2px;
  font-size: 12px;
  line-height: 17px;
  color: var(--ar-subtitle);
}

.ar-queue__note svg {
  flex: 0 0 auto;
  margin-top: 1px;
}

.ar-queue__collapse {
  padding: 13px;
  border-radius: 14px;
  background: var(--ar-overlay-strong);
  color: var(--ar-text);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.1s ease-out;
}

.ar-queue__collapse > * {
  display: block;
  transition: transform 0.1s ease-out;
}

.ar-queue__collapse:active {
  background: var(--ar-overlay);
}

.ar-queue__collapse:active > * {
  transform: scale(0.97);
}

/* Медиа с таймером. В самом Telegram оно исчезнет с первым просмотром - в
 * архиве оно есть потому, что слушатель на сессии забрал копию заранее.
 * Пометка рамкой, чтобы такое сообщение не выглядело обычным. */
/* Обводка медиа с таймером идёт с воздухом, а не впритык к кадру: вплотную
 * она читается как рамка самой фотографии, а не как пометка над ней. */
.ar-media--ttl {
  outline: 1px solid var(--ar-ttl-border);
  outline-offset: 4px;
  border-radius: 14px;
  margin: 5px;
}

/* У кружка обводка обязана быть круглой: прямоугольная рамка вокруг круга -
 * это рамка вокруг пустоты. Поэтому у круглого медиа она уезжает с блока на
 * саму картинку, где уже есть border-radius: 50%. */
.ar-media--ttl.ar-media--round {
  outline: none;
}

.ar-media--ttl.ar-media--round .ar-media__img {
  border: 1px solid var(--ar-ttl-border);
  padding: 4px;
  /* Рамка по внешнему краю, картинка внутри - иначе padding съел бы кадр. */
  box-sizing: border-box;
  background-clip: content-box;
}

/* Подпись на превью у исчезающего - тем же янтарём, что и счётчик: человек
 * должен связать строку в списке с баблом в чате без подсказок. */
.ar-media--ttl .ar-media__badge {
  color: var(--ar-ttl);
}

/* Плашка начала архива: пояснение под заголовком и подпись о переписке. */
.ar-chat__status-hint {
  margin-top: 4px;
  font-size: 13px;
  line-height: 18px;
  color: var(--ar-subtitle);
}

/* Счётчики в шапке чата - те же значки, что в списке. Строка узкая, поэтому
 * между ними не разделитель, а просто отступ. */
.ar-capsule__sub {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* --- Кружок ---------------------------------------------------------------- */

/* Видеосообщение в Telegram круглое, и в архиве оно должно быть таким же:
 * квадратный кадр в прямоугольном бабле читался как обычное видео.
 *
 * Круг вписывается в блок, а сам блок остаётся прямоугольным - подпись с
 * типом и время стоят в его углах и остаются на прежних местах. Затемнение
 * снизу для круга гасится: под ним пустые углы, а у подписи и времени есть
 * своя подложка. */
/* Ширину задаёт сам блок, а не картинка. Бабл под кружком прозрачный и без
 * полей, ширины своей у него нет - а у картинки с width: 100% внутри такого
 * бабла ширина схлопывалась в ноль, и кружок пропадал с экрана целиком. */
.ar-media--round {
  width: 240px;
  max-width: 100%;
}

.ar-media--round .ar-media__img {
  width: 100%;
  max-height: none;
  aspect-ratio: 1 / 1;
  height: auto;
  margin: 0 auto;
  border-radius: 50%;
  /* Исходник и так квадратный - cover здесь ничего не срезает, а страхует от
   * кадра с чуть другим соотношением. */
  object-fit: cover;
}

.ar-media--round .ar-media__shade {
  display: none;
}

/* Медиа появляется только после загрузки: пустой элемент занимает место и
 * растёт по мере готовности, а спиннер из-за этого уезжал с центра. */
.ar-viewer__media--pending {
  display: none !important;
}

/* Кружок без бабла.
 *
 * В Telegram видеосообщение висит прямо на фоне чата: ни подложки, ни
 * хвостика. У нас круг лежал на прямоугольном барельефе - серый квадрат
 * вокруг круга и цветной бабл под ним. Гасим и то, и другое; подпись с типом
 * и время остаются, у них своя подложка.
 *
 * :has() поддерживают все клиенты Telegram актуальных версий - на нём уже
 * держатся отступы баблов с превью выше. */
.ar-media--round {
  background: none;
}

.ar-bubble:has(.ar-media--round) .ar-media--thumb {
  height: auto;
}

.ar-bubble:has(.ar-media--round),
.ar-bubble:has(.ar-media--ttl) {
  padding: 0;
  background: none;
  box-shadow: none;
}

.ar-bubble:has(.ar-media--round) {
  max-width: 260px;
}

.ar-row--out .ar-bubble:has(.ar-media--round) {
  background: none;
}

/* Хвостик бабла у кружка не нужен: он указывал бы на пустой угол. */
.ar-bubble:has(.ar-media--round) .ar-bubble__tail,
.ar-bubble:has(.ar-media--ttl) .ar-bubble__tail {
  display: none;
}

/* Найденное сообщение: одна строка текста, дальше многоточие - в списке
 * результатов важно, где нашлось, а не весь текст. */
.ar-search__snippet {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ar-hint);
}

/* Открытое одноразовое: в Telegram его больше нет. Сплошная рамка читалась бы
 * как «ещё цело», поэтому у открытого она пунктирная - тот же приём, что у
 * удалённых баблов, и тот же янтарь, что у неоткрытого. */
/* Рамка на самой картинке - только у кружка: у него обводка блока отключена,
 * потому что прямоугольник вокруг круга обводил бы пустоту. У остальных линия
 * ровно одна, на блоке, иначе их становится две. */
.ar-media--ttl.ar-media--ttl-opened.ar-media--round .ar-media__img {
  border: 1px dashed var(--ar-ttl-border);
}

.ar-media--ttl-opened:not(.ar-media--round) {
  outline: 1px dashed var(--ar-ttl-border);
  outline-offset: 4px;
}

/* --- Туман под нижним баром ------------------------------------------------ */

/* В Архиве список уходит под бар растушёвкой (.ar-list__fade). На вкладке
 * копирования бар висит над обычной прокруткой страницы, и содержимое
 * упиралось в него обрывом. Тот же приём: фиксированная полоса поверх фона
 * приложения, сквозная для нажатий.
 *
 * Цвет берём у самого приложения, а не у палитры Архива: экран копирования
 * нарисован в своей тёмной теме и светлеть от темы Telegram не должен. */
body.has-bottom-nav.step-channels::after,
body.has-bottom-nav.step-archive::after {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 150px;
  pointer-events: none;
  z-index: 30;
  /* Фон берётся из темы Telegram: обе вкладки красятся ею. */
  background: linear-gradient(to top, var(--ar-bg) 42%, transparent);
}

/* Пока открыта карточка канала, у экрана своя нижняя кнопка - туман поверх
 * неё только мешал бы. */
body.has-bottom-nav.step-channels.channel-detail::after {
  display: none;
}

/* Двойное нажатие по вкладке - обычный жест «вернуться к началу», а не зум.
 * Без этого браузер ждёт второго тапа как double-tap-to-zoom и подтягивает
 * страницу, из-за чего она и съезжала вниз. */
.ar-tab,
.ar-nav__search,
.ar-mode,
.ar-chatrow,
.ar-media {
  touch-action: manipulation;
}

/* Пока аватарка не доехала, под ней видны инициалы - это и есть запасной
 * вариант. Как только доехала (или уже известна по прошлой отрисовке),
 * показываем её сразу, без проявления: мигание инициалами при переходе между
 * вкладками раздражает сильнее, чем резкая смена. */
.ar-avatar__img {
  opacity: 0;
  transition: opacity 0.12s ease-out;
}

.ar-avatar__img--ready {
  opacity: 1;
  transition: none;
}

/* Свайп по списку - это жест ленты историй, а не нажатие на чат. Пока он
 * идёт, подсветку строки гасим: иначе выделяется тот чат, с которого начали
 * движение, и выглядит это как промах. */
body.stories-dragging .ar-chatrow:active,
body.stories-dragging .ar-srow:active,
body.stories-dragging .ar-media:active {
  background: none;
}

body.stories-dragging .ar-chatrow:active > *,
body.stories-dragging .ar-srow:active > * {
  transform: none;
}

/* Экстра-прокрутка: списки Архива тянутся за край и возвращаются, как
 * страница на вкладке копирования. Раньше стоял contain - он гасил и
 * собственный отскок заодно с прокруткой страницы под ним. */
.ar-list__scroll,
.ar-settings {
  overscroll-behavior-y: auto;
}

/* Лента чата остаётся с contain намеренно: там это не про отскок, а про то,
 * чтобы свайп снизу вверх у края не достался Telegram - иначе чат перестаёт
 * листаться до перезахода. Менять это ради резинки нельзя. */

/* Свайп назад: чат уезжает вправо, а под ним уже виден список, в который мы
 * возвращаемся. Список скрыт классом .hidden, поэтому на время жеста его
 * показываем правилом посильнее - у него и id, и два класса. */
body.ar-back-swipe #step-archive.ar.hidden {
  display: block !important;
}

/* Сам чат на время жеста - слой поверх списка, без перехода по умолчанию:
 * переход ставится из кода только на доводку и откат. */
body.ar-back-swipe .ar-chat {
  z-index: 5;
  box-shadow: -12px 0 30px rgba(0, 0, 0, 0.35);
}

/* Верхняя грань Архива - тем же способом, что у копирования: отступ у body, а
 * не спейсер внутри экрана. Иначе на одной вкладке прокручивается страница, а
 * на другой - внутренний контейнер, и ведут они себя по-разному. */
.webapp.step-archive {
  padding-top: calc(env(safe-area-inset-top, 0px) + var(--app-safe-top, 0px) + 70px);
}

/* На Архиве в контейнере остаются только шапка с историями и список. Прочие
 * экраны скрыты, но сам контейнер должен вести себя как обычная колонка -
 * иначе список становится соседом по флексу, уезжает вбок и появляется
 * горизонтальная прокрутка. */
body.step-archive .webapp-container {
  display: block;
  width: 100%;
}

body.step-archive #step-archive {
  width: 100%;
}

/* Пока грузится первая страница чата, показываем спиннер по центру, а ленту
 * держим скрытой: полупустой экран, в который на глазах падают сообщения,
 * выглядит хуже честного ожидания. */
.ar-chat__loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 3;
  pointer-events: none;
}

.ar-chat__loading.hidden {
  display: none !important;
}

.ar-chat--loading .ar-chat__scroll {
  visibility: hidden;
}

/* Список под уезжающим чатом на время жеста - отдельный слой на весь экран.
 *
 * В обычном состоянии он лежит в потоке страницы, но на экране чата вокруг
 * него скрыто всё остальное, и в потоке он оказывается не там, где человек его
 * оставил: видно чёрное поле. На двести миллисекунд жеста показываем его
 * фиксированным слоем с тем же верхним отступом, что и на своей вкладке. */
body.ar-back-swipe #step-archive.ar.hidden {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  background: var(--ar-bg);
  padding: calc(var(--app-safe-top, 0px) + 70px) 16px 0 16px;
}

/* Контейнер на экране чата спрятан целиком - вместе со списком, который
 * теперь лежит внутри него. Пока идёт жест выхода, показываем контейнер
 * обратно, но пустым: видно должен быть только список, всё остальное в нём
 * к Архиву отношения не имеет.
 *
 * Правило сильнее того, что прячет контейнер: там один класс на body, здесь
 * два. */
body.step-archive-chat.ar-back-swipe .webapp-container {
  display: block !important;
  background: none;
}

body.step-archive-chat.ar-back-swipe .webapp-container > *:not(#step-archive) {
  display: none !important;
}
