/*
  Слой рабочего стола для веб-версии.

  Разметка и базовые стили приходят из hhtgbot как есть — здесь только то, чего
  в мини-приложении быть не может: широкий экран, мышь и клавиатура. Всё
  держится на токенах и классах исходной вёрстки, ни один селектор её не
  переписывает по существу.

  До 1024px не применяется ничего: на телефоне веб-версия обязана выглядеть
  ровно так же, как внутри Telegram.
*/

/*
  Правая половина слоя без выбранного элемента. Её ставит desktop.js, и до
  1024px её быть не должно: там список и открытое сменяют друг друга, и
  показывать «выберите слева» негде и незачем.
*/
.hh-detail-empty {
  display: none;
}

/* ---------- 700–1023px: телефонная колонка с полями ---------- */

@media (min-width: 700px) and (max-width: 1023.98px) {
  .scroll-root {
    padding-left: max(var(--gutter), calc((100vw - 760px) / 2));
    padding-right: max(var(--gutter), calc((100vw - 760px) / 2));
  }
}

/* ---------- 1024px и шире: рельс, главная в центре, список слева, открытое справа ---------- */

@media (min-width: 1024px) {
  :root {
    --rail: 88px;
    /* Ширина колонки на экране, открытом во всю страницу. Не вся ширина
       монитора: читаемая строка кончается задолго до его края. Одна на все
       экраны — иначе переход из настроек в подраздел дёргает вёрстку. */
    --work-col: 980px;
    /* Левая колонка со списком чатов или настроек. Уже читаемой строки: в ней
       стоят строки на два ряда текста, а не сам текст. */
    --list-col: 360px;
    /* Нижней панели больше нет — её место занял рельс слева. */
    --nav-clearance: 0px;
    /* Строка подвала сайта. На телефоне подвал долистывается внутри
       .scroll-root; здесь скролла нет, и без вычитания этой высоты из .app
       подвал резало бы overflow: hidden — навигация /ai, /blog и /download
       с главной пропадала бы на десктопе. */
    --site-footer-h: 40px;
  }

  /* Скролл уезжает внутрь колонок: страница остаётся ровно одним экраном. */
  .scroll-root {
    overflow: hidden;
    padding: var(--gutter);
    padding-left: calc(var(--rail) + var(--gutter));
  }

  .scroll-root > .app {
    min-height: 0;
  }

  .app {
    width: min(100%, 1352px);
    height: calc(
      var(--app-height, 100vh) - var(--gutter) * 2 - var(--site-footer-h, 0px)
    );
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "main";
    gap: var(--space-5);
    align-content: stretch;
  }

  /* Подвал занимает ровно вычтенную из .app строку: сумма высот равна
     контентной области .scroll-root, страница по-прежнему не скроллится. */
  .site-footer {
    margin: 0;
    padding: 0;
    height: var(--site-footer-h);
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
  }

  .site-footer-nav {
    gap: 10px 24px;
  }

  /* Главный экран всегда в центре: кнопка — смысловой центр интерфейса. */
  .view[data-view="home"] {
    grid-area: main;
    min-height: 0;
  }

  /*
    Всё, что не главная и не подключение, открывается слоем поверх главной: она
    остаётся собранной под ним и возвращается целиком, стоит закрыть слой.
    Базовые правила общие для обеих половин слоя — где список, а где открытый
    из него элемент, размечает desktop.js классами hh-list и hh-detail.
  */
  .view:not([data-view="home"]):not([data-view="connect"]) {
    position: fixed;
    top: 0;
    left: var(--rail);
    right: 0;
    bottom: 0;
    z-index: 15;
    min-height: 0;
    /* Верхнего поля у слоя нет: его держит сама шапка, чтобы прилипнуть к краю
       окна и закрыть собой всё, что проезжает под ней. */
    padding: 0 var(--gutter) calc(var(--space-6) * 2);
    overflow-y: auto;
    overscroll-behavior: contain;
    align-content: start;
    /*
      Одна колонка по центру, а не содержимое во всю ширину: строка настроек
      длиной в монитор нечитаема — от подписи до шеврона глаз идёт через полосу
      пустоты, и связь между ними теряется.
    */
    grid-template-columns: minmax(0, min(var(--work-col), 100%));
    justify-content: center;
    /* Фон страницы, а не панели: под слоем ничего не должно просвечивать. */
    background: var(--bg);
    opacity: 0;
    transform: translateY(8px);
    pointer-events: none;
    transition:
      opacity 0.2s ease,
      transform 0.2s ease;
  }

  :root.hh-pane-open .view:not([data-view="home"]):not([data-view="connect"]) {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }

  /*
    Левая половина — список. Он остаётся на экране, пока открыт его элемент:
    из списка чатов видно, какой разговор идёт дальше, а из списка настроек —
    куда пойти после этой. Ширина фиксированная: список не растёт от того, что
    монитор шире, растёт то, что открыто справа.
  */
  /* Через :root.hh-pane-open — чтобы перевесить общее правило слоя выше: у
     него в селекторе два :not, и без этого он оставляет за собой left. */
  :root.hh-pane-open .view.hh-list {
    right: auto;
    width: var(--list-col);
    border-right: 1px solid var(--border);
    /* Содержимое во всю колонку: центрировать в 360px уже нечего. */
    grid-template-columns: minmax(0, 1fr);
    justify-content: stretch;
  }

  /* Правая половина — то, что открыли из списка. */
  :root.hh-pane-open .view.hh-detail {
    left: calc(var(--rail) + var(--list-col));
  }

  /*
    Переписка: поле ответа у нижнего края, а не сразу под последней репликой.

    На телефоне поле липнет к низу экрана само — там панель ровно во весь
    вьюпорт. На рабочем столе правая половина выше своего содержимого, и
    короткий диалог оставлял поле висеть посередине, у самой шапки.

    Колонка держится флексом с явной шириной у детей: грид-раскладка выше
    центрирует единственную колонку, а прижать в ней последнюю строку к низу
    нечем — align-content пакует все строки разом.
  */
  :root.hh-pane-open .view.hh-detail[data-view="chatThread"] {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  :root.hh-pane-open .view.hh-detail[data-view="chatThread"] > * {
    width: min(var(--work-col), 100%);
    flex: 0 0 auto;
  }

  /*
    margin-top: auto прижимает поле к низу, пока диалог короткий; когда реплик
    больше высоты панели, его удерживает sticky при прокрутке.

    Внешняя полоса вокруг поля убрана. На телефоне это панель во всю ширину
    экрана, прижатая к нижнему краю: её фон и верхняя граница отделяют поле от
    переписки, которая проезжает под ним. В окне рабочего стола та же полоса
    читается лишним прямоугольником вокруг и без того обведённого поля.

    Видимой границей ввода остаётся .composer-box — у неё своя рамка, свой
    радиус и непрозрачный фон, так что реплики под полем не просвечивают.
  */
  :root.hh-pane-open .view.hh-detail[data-view="chatThread"] > .composer {
    margin-top: auto;
    margin-inline: 0;
    position: sticky;
    bottom: 0;
    padding: var(--space-3) 0 var(--space-5);
    border-top: 0;
    background: transparent;
    backdrop-filter: none;
  }

  /*
    Открытая строка списка помечена: иначе в левой колонке нечем отличить
    текущий чат от соседних, и после прокрутки списка непонятно, к чему
    относится правая половина.
  */
  .hh-list .tile-row.hh-active,
  .hh-list .chat-row.hh-active {
    background: color-mix(in srgb, var(--button) 12%, var(--surface));
  }

  .hh-list .tile-row.hh-active {
    border-color: color-mix(in srgb, var(--button) 45%, var(--border));
  }

  /*
    Правая половина, пока ничего не выбрано. Пустое место читалось бы как сбой
    загрузки, поэтому здесь стоит подпись — и заодно фон, который закрывает
    собой главную под слоем.
  */
  .hh-detail-empty {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: calc(var(--rail) + var(--list-col));
    z-index: 14;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--gutter);
    background: var(--bg);
    color: var(--muted);
    font-size: 14px;
    text-align: center;
  }

  /*
    Шапка с «назад» и заголовком остаётся на виду при прокрутке: на полной
    странице списка чатов до неё иначе не дотянуться, не пролистав всё обратно.
  */
  .view:not([data-view="home"]):not([data-view="connect"]) > .section-head:first-child {
    position: sticky;
    top: 0;
    z-index: 1;
    padding-block: var(--space-6) var(--space-4);
    border-bottom: 1px solid var(--border);
    background: var(--bg);
  }

  /* Экран без шапки верхнее поле всё-таки получает — своим отступом. */
  .view:not([data-view="home"]):not([data-view="connect"]) > :first-child:not(.section-head) {
    margin-top: var(--space-6);
  }

  /*
    Главная кнопка экрана во всю ширину монитора читается как полоса, а не как
    кнопка: на телефоне её ширину задаёт палец, которому нужна вся строка, здесь
    целится мышь.
  */
  .view:not([data-view="home"]):not([data-view="connect"]) > .button {
    justify-self: center;
    width: min(100%, 420px);
  }

  /*
    Список чатов на телефоне занимает весь экран и рамка ему не нужна — здесь
    он лежит колонкой посреди тёмного поля, и без подложки строки висят в
    пустоте, а разделители не читаются как один список.
  */
  .view[data-view="messages"] .chat-list {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    padding: 0 var(--pad-inset);
  }

  /*
    Реплика во всю ширину колонки перестаёт быть репликой: в переписке важно, с
    какой стороны она пришла, а полоса от края до края одинакова для обеих.
  */
  .chat-bubble {
    max-width: min(88%, 560px);
  }

  /*
    Экран подключения — мастер, ему уместнее модальное окно по центру. Слой
    подобран между панелью настроек (15) и шторками (20): справка по кнопке «?»
    обязана открываться поверх него, а не оказываться под ним.
  */
  .view[data-view="connect"] {
    position: fixed;
    z-index: 16;
    inset: 0;
    align-content: center;
    justify-items: center;
    padding: var(--gutter);
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(6px);
    overflow-y: auto;
  }

  .view[data-view="connect"] > * {
    width: min(100%, 620px);
  }

  /* ---------- Левый рельс вместо нижней панели ---------- */

  /*
    Панель свёрстана гридом в две колонки, поэтому вертикальной её делает смена
    сетки, а не flex-direction. Без align-content: start две строки растянулись
    бы на всю высоту, и кнопки повисли бы по четвертям экрана.
  */
  .bottom-nav {
    left: 0;
    right: auto;
    top: 0;
    bottom: 0;
    width: var(--rail);
    min-height: 0;
    margin: 0;
    border-radius: 0;
    border-top: 0;
    border-bottom: 0;
    border-left: 0;
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: min-content;
    align-content: start;
    gap: var(--gap-list);
    padding: var(--space-4) var(--space-2);
  }

  /* Подложка иконки рассчитана на широкую нижнюю панель — в рельсе она не
     помещается и обрезает подписи. */
  .bottom-nav .nav-item svg {
    padding: var(--space-1) var(--space-3);
  }

  .bottom-nav .nav-item {
    min-height: 64px;
  }

  /*
    switchView прячет панель на экране поддержки и в переписке — на телефоне
    она уступает место полю ответа. На рабочем столе рельс стоит слева, полю
    ответа не мешает и остаётся единственной навигацией: без него из открытого
    чата некуда уйти.

    !important здесь обязателен: в app.css стоит `[hidden] { display: none
    !important }`, и без него правило проигрывает — рельс исчезал, стоило
    открыть диалог. display: grid, а не flex: колонки рельса заданы гридом
    ниже, и flex ломал бы их.
  */
  .bottom-nav[hidden] {
    display: grid !important;
  }

  .home-view {
    min-height: 0;
    height: 100%;
    grid-template-rows: auto auto 1fr auto;
  }

  /* ---------- Кнопка-пульс ---------- */

  .pulse-dial {
    width: clamp(208px, 22vw, 320px);
    height: clamp(208px, 22vw, 320px);
  }

  /*
    Нити — абсолютный SVG фиксированных 600×600. Без масштабирования вместе с
    кнопкой они перестают сходиться к её краю и повисают в стороне.
  */
  .pulse-threads {
    transform: translate(-50%, -50%) scale(clamp(1, 2.2vw / 13.6, 1.55));
  }

  /* ---------- Мышь и клавиатура ---------- */

  @media (hover: hover) {
    .tile-row:hover,
    .nav-item:hover,
    .icon-button:hover,
    .account-card:hover,
    .profile-picker:hover {
      border-color: color-mix(in srgb, var(--button) 45%, var(--border));
      background: color-mix(in srgb, var(--button) 7%, var(--surface));
    }

    .button:hover:not(:disabled) {
      filter: brightness(1.08);
    }

    .pulse-dial:hover:not(:disabled) {
      transform: scale(1.02);
    }
  }

  .pulse-dial {
    transition: transform 0.18s ease;
  }

  :focus-visible {
    outline: 2px solid var(--button);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }

  /* ---------- Шторки становятся окнами ---------- */

  .sheet-backdrop {
    align-items: center;
    justify-items: center;
    padding: var(--gutter);
  }

  .sheet {
    width: min(100%, 520px);
    margin: 0;
    border-radius: var(--radius);
    padding-bottom: var(--space-5);
  }
}

/* ---------- Широкие мониторы: колонке можно немного больше ---------- */

@media (min-width: 1600px) {
  :root {
    --work-col: 1080px;
  }
}

/* ---------- Ноутбуки 1366×768: главный риск появления скролла ---------- */

@media (min-width: 1024px) and (max-height: 820px) {
  :root {
    /* На невысоких экранах каждый пиксель у круга на счету. */
    --site-footer-h: 32px;
  }

  .pulse-dial {
    width: clamp(168px, 17vw, 232px);
    height: clamp(168px, 17vw, 232px);
  }

  .pulse-threads {
    transform: translate(-50%, -50%) scale(0.85);
  }

  .account-card {
    padding: var(--space-3);
  }

  .tile-row {
    min-height: 64px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pulse-dial {
    transition: none;
  }

  .pulse-dial:hover:not(:disabled) {
    transform: none;
  }
}
