/* 40-mobile.css — накладной слой мобильной адаптации капсулы TeamON One.
   Подключается ПОСЛЕ app.css и после остальных файлов redesign/, ничего в них не
   меняет и не переопределяет цвета и типографику: это чужие зоны (00-tokens.css и
   соседние слои). Здесь только геометрия, безопасные зоны, размеры тач-целей и
   способ показа боковых панелей.

   Зачем файл существует. Мобильные правила боевого CSS расщеплены на два
   несовместимых набора:
     • app.css:2215–2249 — блок @media (max-width: 900px), где ВСЕ двенадцать
       правил начинаются с .app-shell.team-edition;
     • app.css:2260–2352 и 2368–2373 — безусловные правила @media (max-width: 760px).
   Класс team-edition навешивается в app.js:4461 только когда сервер вернул хотя бы
   одно пространство (state.spaces.length > 0). То есть на одном и том же телефоне
   раскладка была разной в зависимости от данных с сервера. Этот файл сводит обе
   ветки в одну систему.

   Как достигается независимость от team-edition. Вместо .app-shell.team-edition
   селекторы опираются на атрибут [data-teamon-workspace-shell], который стоит на #app
   статически в index.html:78 и присутствует всегда, в обоих режимах. Специфичность
   .app-shell[data-teamon-workspace-shell] .foo равна (0,3,0) — ровно как у боевого
   .app-shell.team-edition .foo, а файл подключён позже, поэтому переопределение
   срабатывает без !important.

   Почему это безопасно для режима без пространств. #team-rail, #team-rail-backdrop
   и #team-rail-open в этом случае получают HTML-атрибут hidden (app.js:4466–4468,
   teamon-workspace-shell.js:78–83), а app.css:35 объявляет [hidden] { display: none
   !important }. Никакое правило отсюда не может показать рельс, которого по данным
   быть не должно: !important боевого файла всегда выигрывает. Поэтому правила
   рельса написаны без оглядки на team-edition — их страхует сам HTML.

   Брейкпоинты выбраны не произвольно, а по константам, уже зашитым в JS:
     1099px — на единицу ниже WORK_SURFACE_DESKTOP_BREAKPOINT = 1100 (work-surface.js:3);
              то же значение использует app.css:2354, здесь оно повторено, чтобы не
              разъехаться с боевым файлом ни на один пиксель;
      900px — WORKSPACE_SHELL_CONTRACT.drawerBreakpoint = 900 (teamon-workspace-shell.js:9),
              им же меряет workspaceShellUsesDrawer(); ниже него рельс обязан быть
              наложением, иначе CSS и JS разойдутся в трактовке режима;
      820px — на единицу ниже STUDIO_DIALOGUE_DESKTOP_BREAKPOINT = 821 (work-surface.js:7);
      760px — граница, по которой app.js:4357 (syncSurfaceModality) решает, что Холст
              перекрывает диалог; менять её из CSS нельзя, поэтому «телефон» здесь
              ровно 760, а не 768.
   Целевые ширины 360 / 390 / 430 попадают в «телефон», 768 — в планшетную полосу
   761–900. */


/* ГЕОМЕТРИЧЕСКИЕ ПЕРЕМЕННЫЕ СЛОЯ
   Префикс --m- (mobile) выбран, чтобы гарантированно не пересечься с токенами
   соседних слоёв: в 00-tokens.css объявлено 65 свойств, среди них нет ни одного
   с этим префиксом. Значения не несут цветовой или шрифтовой семантики. */
@media (max-width: 1099px) {
  :root {
    /* Второй аргумент env() — фолбэк для браузеров и устройств без вырезов.
       В index.html:5 стоит viewport-fit=cover, поэтому на iPhone эти отступы
       реально ненулевые, в том числе в обычном Safari, а не только в PWA. */
    --m-safe-top: env(safe-area-inset-top, 0px);
    --m-safe-bottom: env(safe-area-inset-bottom, 0px);
    --m-safe-left: env(safe-area-inset-left, 0px);
    --m-safe-right: env(safe-area-inset-right, 0px);

    /* Минимальная сторона тач-цели. 46px — требование владельца; это на 2px
       больше рекомендации Apple HIG (44pt) и совпадает с рекомендацией Material
       (48dp) с точностью до округления. */
    --m-tap: 46px;
  }

  .app-shell[data-teamon-workspace-shell] {
    /* Высота шапки без выреза. 64px — значение app.css:170. */
    --m-header-base: 64px;
    --m-header-h: calc(var(--m-header-base) + var(--m-safe-top));
  }
}

@media (max-width: 760px) {
  .app-shell[data-teamon-workspace-shell] {
    /* 60px — значение app.css:2292, здесь только повторено, чтобы --m-header-h
       считалась от той же базы, что и боевая шапка. */
    --m-header-base: 60px;
  }
}


/* ШАПКА И ВЫСОТА РАБОЧЕЙ ОБЛАСТИ ПОД ЧЁЛКОЙ
   Разбор проблемы. app.css:2292 задаёт .product-header { height: 60px;
   padding: max(9px, env(safe-area-inset-top)) 12px 7px }. При box-sizing: border-box
   (app.css:21) и safe-area-inset-top = 59px (iPhone 14/15 Pro) внутренняя область
   шапки получается 60 − 59 − 7 = −6px, то есть содержимое шапки выпадает за её
   границы и наезжает на верх диалога. При этом .workbench берёт height:
   calc(100dvh − 60px) (app.css:2304) и вниз не сдвигается. То же на 64px в полосе
   761–1099.

   Решение. Высота шапки перестаёт быть фиксированной и становится «база + вырез»,
   а рабочая область вычитает ровно ту же величину. padding-top не трогаем: боевое
   max(9px, env(...)) уже корректно, переписывать его — значит дублировать логику. */
@media (max-width: 1099px) {
  /* Режим без пространств: шапка в потоке, .workbench идёт под ней. */
  .app-shell[data-teamon-workspace-shell]:not(.team-edition) .product-header {
    height: auto;
    min-height: var(--m-header-h);
  }
  .app-shell[data-teamon-workspace-shell]:not(.team-edition) .workbench {
    height: calc(100dvh - var(--m-header-h));
  }

  /* Боковые вырезы (альбомная ориентация iPhone). В app.css нет ни одного
     обращения к safe-area-inset-left/right — проверено грепом, — поэтому в
     ландшафте шапка уходит под вырез. Здесь только горизонтальные отступы,
     вертикальные оставлены боевому файлу. */
  .app-shell[data-teamon-workspace-shell] .product-header {
    padding-right: max(12px, var(--m-safe-right));
    padding-left: max(12px, var(--m-safe-left));
  }
}


/* ЛЕВЫЙ РЕЛЬС #team-rail — НАЛОЖЕНИЕ, А НЕ КОЛОНКА
   Решение и его обоснование. Рядом с диалогом рельс на телефоне не помещается:
   даже свёрнутый он занимает 64px (--teamon-space-rail-collapsed), а развёрнутый
   224px — это 62% ширины экрана 360px. Поэтому он показывается ВНЕ ПОТОКА:
   position: fixed поверх содержимого, с затемняющей подложкой и выездом слева.
   Это тот же механизм, что уже есть в app.css:2217–2227, но здесь он снят с
   привязки к team-edition и работает в обоих режимах.

   Почему именно наложение, а не сворачивание в узкую колонку: JS в этом диапазоне
   уже считает режим «ящиком» (workspaceShellUsesDrawer, teamon-workspace-shell.js:13–18) и
   при открытии выставляет role="dialog" + aria-modal="true" и inert на .product-header
   и #workbench (teamon-workspace-shell.js:91–101, app.js:4385–4391). Узкая колонка в
   потоке противоречила бы этой семантике: страница была бы заблокирована рядом с
   видимым, но не модальным элементом. Наложение — единственный вариант, согласованный
   с уже существующим поведением JS.

   Управление видимостью остаётся за JS: класс .team-rail-visible ставится в
   app.js:4384. CSS только описывает две позиции. */
@media (max-width: 900px) {
  .app-shell[data-teamon-workspace-shell] .team-rail {
    position: fixed;
    z-index: 30;
    inset: 0 auto 0 0;
    width: min(84vw, 292px);
    /* 104% вместо 100%: рельс уезжает чуть дальше своей ширины, чтобы за краем
       экрана не осталась полоса тени. Значение взято из app.css:2222. */
    transform: translateX(-104%);
    transition: transform .22s ease;
    /* Внутренние отступы под вырез: сверху чёлка, снизу домашняя полоса,
       слева боковой вырез в ландшафте. */
    padding-top: max(12px, var(--m-safe-top));
    padding-bottom: calc(12px + var(--m-safe-bottom));
    padding-left: max(10px, var(--m-safe-left));
  }
  .app-shell[data-teamon-workspace-shell].team-rail-visible .team-rail {
    transform: translateX(0);
  }

  /* Подложка. display: block здесь безопасно: если пространств нет, у элемента
     стоит атрибут hidden и app.css:35 гасит его через display: none !important. */
  .app-shell[data-teamon-workspace-shell] .team-rail-backdrop {
    position: fixed;
    z-index: 29;
    inset: 0;
    display: block;
    border: 0;
  }
  .app-shell[data-teamon-workspace-shell]:not(.team-rail-visible) .team-rail-backdrop {
    display: none;
  }

  /* Список проектов внутри рельса: свой скролл, чтобы резиновый отскок iOS не
     утаскивал страницу под наложением. */
  .app-shell[data-teamon-workspace-shell] .team-project-list {
    overscroll-behavior: contain;
  }

  /* Колонка под кнопку сворачивания расширена с 26px (app.css:1846) до тач-размера,
     иначе увеличенная ниже .team-rail-toggle не помещается в свой трек грида. */
  .app-shell[data-teamon-workspace-shell] .team-rail-brand {
    grid-template-columns: 34px minmax(0, 1fr) var(--m-tap);
  }
}


/* ЯЩИК #drawer — НАЛОЖЕНИЕ НА ВСЮ ШИРИНУ
   Решение. Ящик настроек в app.css:1471 уже position: fixed, то есть вне потока, —
   переносить его никуда не надо. Не хватало другого: на телефоне он раскрывается на
   всю ширину (app.css:2339), но его содержимое ничем не отделено от домашней полосы
   и боковых вырезов. Здесь добавлены только безопасные зоны и собственный скролл.
   На планшете (761–900) ящик остаётся боковой панелью 520px — на 768px это ~68%
   ширины, читаемо, и менять там нечего. */
@media (max-width: 900px) {
  .drawer {
    /* Правый вырез в ландшафте: ящик прижат к правому краю (inset: 0 0 0 auto). */
    padding-right: var(--m-safe-right);
  }
  .drawer-content {
    /* 36px — боевое значение app.css:1479, к нему добавляется домашняя полоса.
       Без этого последний элемент списка настроек оказывается под ней. */
    padding-bottom: calc(36px + var(--m-safe-bottom));
    overscroll-behavior: contain;
  }
  .drawer-tabs {
    overscroll-behavior-x: contain;
  }
}

@media (max-width: 760px) {
  .drawer {
    /* Левый вырез появляется, когда ящик занимает всю ширину. */
    padding-left: var(--m-safe-left);
  }
}


/* ХОЛСТ (.work-surface) — СОГЛАСОВАНИЕ С ГЕОМЕТРИЕЙ ИЗ JS
   Ниже 1100px Холст уже выведен из потока (app.css:2354–2360, position: fixed), и
   это правильно: по расчёту work-surface.js:18–30 при ширине окна меньше ~960px
   доступный максимум ширины схлопывается в WORK_SURFACE_MIN_WIDTH = 360, потому что
   из окна вычитается WORK_SURFACE_CHAT_MIN_WIDTH = 600. Рядом с диалогом Холст в
   этой полосе существовать не может по самой формуле. Здесь только два исправления:
   полная высота рабочей поверхности и уход от 100vw. */
@media (max-width: 1099px) {
  .work-surface {
    /* Холст — правый слой Workspace, поэтому его поверхность накрывает и бывшую
       полосу шапки. Safe-area учитывают внутренние controls, а не геометрия панели. */
    top: 0;
  }
}

@media (max-width: 760px) {
  .workbench.space-open .work-surface {
    /* app.css:2370 задаёт width: 100vw и min-width: 100vw. 100vw — ширина layout
       viewport, она не обязана совпадать с шириной видимой области; надёжнее
       растянуть уже позиционированный элемент двумя краями. Элемент фиксированный,
       правый край задан в app.css:2357 (right: 0), поэтому достаточно левого. */
    left: 0;
    width: auto;
    min-width: 0;
  }
  .work-surface-note {
    /* Было max(14px, env(...)): при вырезе 34px отступ становился ровно 34px и
       подпись прилипала к домашней полосе. Теперь всегда остаётся видимый зазор. */
    padding-bottom: calc(14px + var(--m-safe-bottom));
  }
}


/* КОМПОЗЕР
   Композер лежит в третьей строке грида .chat-stage (app.css:1365, grid-row: 3),
   то есть в потоке, и ничего не перекрывает. Правки только по краям. */
@media (max-width: 760px) {
  .composer {
    /* app.css:2317: margin-bottom: max(8px, env(safe-area-inset-bottom)).
       При домашней полосе 34px это ровно 34px — композер садится на неё вплотную.
       calc даёт постоянный зазор поверх системной зоны. */
    margin-bottom: calc(10px + var(--m-safe-bottom));
    /* Боковые вырезы в ландшафте. Композер центрируется автоотступами
       (app.css:1366), поэтому симметричного сужения достаточно. */
    width: calc(100% - 16px - var(--m-safe-left) - var(--m-safe-right));
  }
  .composer-row {
    /* Было 44px (app.css:2320) — поднято до общей тач-высоты. */
    min-height: var(--m-tap);
  }
  .ask-teamon {
    min-height: var(--m-tap);
    padding-inline: 12px;
  }
  .composer-status {
    /* Всплывающая подсказка над композером не должна вылезать за вырезы. */
    max-width: min(72vw, 260px);
    right: max(10px, var(--m-safe-right));
  }
}


/* ТАЧ-ЦЕЛИ: НЕ МЕНЬШЕ 46px
   Меняется только геометрия — min-height, размеры и внутренние отступы. Кегль,
   цвет, фон и рамки не трогаются: это зоны других слоёв.
   Полоса взята до 900px, а не до 760px: планшет 768px — такое же сенсорное
   устройство, и на нём боевые размеры 26–40px остаются недостижимо мелкими,
   потому что безусловные мобильные правила app.css заканчиваются на 760px. */
@media (max-width: 900px) {
  /* app.css:405 — padding: 0 при кегле 10px, фактическая высота около 15px. */
  .text-button {
    min-height: var(--m-tap);
    display: inline-flex;
    align-items: center;
    padding-inline: 6px;
  }
  /* app.css:737 внутри @media (max-width: 620px) задаёт этим же кнопкам 36px и
     имеет специфичность (0,2,0). Повторяем селектор с той же специфичностью —
     наш файл идёт позже и выигрывает без !important. */
  .world-member-actions .text-button {
    min-height: var(--m-tap);
  }
  .world-member-role {
    min-height: var(--m-tap);
  }

  /* app.css:1476 — вкладки ящика были 32px. */
  .nav-item {
    min-height: var(--m-tap);
  }
  /* app.css:1248–1250 — действия карточки были 32px при кегле 9px. */
  .space-item-action {
    min-height: var(--m-tap);
    padding-inline: 14px;
  }
  /* app.css:1978–1979 — кнопка сворачивания рельса была 26×26. */
  .team-rail-toggle {
    width: var(--m-tap);
    height: var(--m-tap);
  }
  /* app.css:418 — сегменты переключателя лент были 30px. */
  .conversation-lane {
    min-height: var(--m-tap);
  }
  .conversation-lanes {
    /* Компактная полоса режимов остаётся частью toolbar над полем ввода. */
    padding: 2px;
    margin-top: 0;
  }
  /* app.css:683 — 42px, чуть меньше нормы. */
  .space-surface-tab {
    min-height: var(--m-tap);
  }
  /* app.css:307 — 30px. */
  .task-tab {
    min-height: var(--m-tap);
  }
  /* app.css:1256–1258 — кнопки оценки были 30×30. */
  .space-rating button {
    width: var(--m-tap);
    height: var(--m-tap);
  }
  /* app.css:1404 и 2330–2332 — круглые кнопки и отправка были 39–40px. */
  .round-button,
  .send-button {
    flex-basis: var(--m-tap);
    width: var(--m-tap);
    height: var(--m-tap);
  }
  .composer .round-button {
    /* Селектор (0,2,0) повторяет app.css:2330, иначе тот перебьёт правило выше. */
    flex-basis: var(--m-tap);
    width: var(--m-tap);
    height: var(--m-tap);
  }
  /* Подпись сохраняется: назначение командного действия остаётся явным. */
  .ask-teamon { min-height: var(--m-tap); }
  /* app.css:245 — крестик профиля был 28×28. */
  .account-menu .icon-button {
    width: var(--m-tap);
    height: var(--m-tap);
  }
  /* app.css:514–516 — стартовые подсказки около 36px по высоте. */
  .starter-prompt {
    min-height: var(--m-tap);
    display: inline-flex;
    align-items: center;
  }
  /* app.css:2234 — гамбургер рельса был 38×38. Специфичность (0,3,0) повторяет
     .app-shell.team-edition .team-rail-open, но опирается на постоянный атрибут,
     поэтому размер одинаков в обоих режимах. */
  .app-shell[data-teamon-workspace-shell] .team-rail-open {
    display: grid;
    place-items: center;
    width: var(--m-tap);
    height: var(--m-tap);
  }

  /* Соседний слой redesign/30-components.css задаёт .primary и полям форм
     min-height: 44px безусловно, для всех ширин. Для десктопа это нормально, но
     на сенсорном экране 44 < 46. Здесь поднимается только высота и только в
     мобильной полосе; вид кнопки, её цвет и радиус остаются за слоем компонентов.
     Наш файл подключается после 30-components.css, специфичность совпадает,
     поэтому переопределение срабатывает без !important. */
  .primary {
    min-height: var(--m-tap);
  }
  /* app.css:312–314 — поля формы задачи набирают около 42px за счёт паддинга.
     .composer textarea сюда сознательно не включён: он растущий, его собственный
     min-height 24px (app.css:1386) обязан остаться, высоту строки держит
     .composer-row. */
  .task-form input,
  .task-form select,
  .task-form textarea {
    min-height: var(--m-tap);
  }

  /* Мелкие крестики внутри чипов. Увеличивать сами кнопки нельзя — раздует чипы
     и сломает перенос строк. Поэтому расширяется только область попадания:
     невидимый псевдоэлемент 46×46, центрированный по кнопке. Раскладка не меняется. */
  .attachment-chip button,
  .shared-reply button,
  .studio-selection-chip button {
    position: relative;
  }
  .attachment-chip button::after,
  .shared-reply button::after,
  .studio-selection-chip button::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--m-tap);
    height: var(--m-tap);
    transform: translate(-50%, -50%);
  }
}


/* МЕНЮ ПРОФИЛЯ — ОДИН СЦЕНАРИЙ ДЛЯ ОБОИХ РЕЖИМОВ
   Расхождение, которое здесь убирается: при наличии пространств меню профиля
   прижималось к низу экрана (app.css:2237–2243), без пространств — всплывало под
   шапкой справа (app.css:2295). Ниже 900px оставлен один вариант — нижняя панель:
   на телефоне она достижима большим пальцем, а на 768px не упирается в край.
   Специфичность (0,4,0) равна боевой .app-shell.team-edition .session-account
   .account-menu, файл идёт позже. */
@media (max-width: 900px) {
  .app-shell[data-teamon-workspace-shell] .session-account .account-menu {
    position: fixed;
    top: auto;
    right: max(12px, var(--m-safe-right));
    bottom: calc(12px + var(--m-safe-bottom));
    left: max(12px, var(--m-safe-left));
    width: auto;
    /* Без ограничения меню могло вырасти выше экрана: max-height в app.css:228–241
       не задан вообще. */
    max-height: calc(100dvh - 24px - var(--m-safe-top) - var(--m-safe-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}


/* ЗАПРЕТ ГОРИЗОНТАЛЬНОЙ ПРОКРУТКИ
   Страница целиком прокручиваться вбок не может: body { overflow: hidden }
   (app.css:24) и .app-shell { overflow: hidden } (app.css:147). Опасность в другом —
   широкое содержимое внутри этих контейнеров молча обрезается и становится
   недоступным. Ниже страховки для случаев, где такое возможно на 360–430px. */
@media (max-width: 900px) {
  /* Классическая причина распирания флекс- и грид-раскладок: у элемента
     min-width по умолчанию auto, и он отказывается сжиматься меньше содержимого. */
  .workbench > *,
  .chat-stage > *,
  .drawer > *,
  .team-rail > * {
    min-width: 0;
  }

  /* Медиа и вложения не должны задавать ширину контейнера. */
  .messages img,
  .bubble img,
  .drawer-content img,
  .work-surface img {
    max-width: 100%;
    height: auto;
  }

  /* Длинные слова и ссылки. app.css:539 закрывает только .bubble p,
     у заголовков и списков внутри ответа переноса нет. */
  .bubble li,
  .bubble h1,
  .bubble h2,
  .bubble h3,
  .shared-message-bubble li {
    overflow-wrap: anywhere;
  }

  /* Широкое содержимое прокручивается внутри себя, а не распирает страницу.
     .bubble pre уже так устроен (app.css:575), здесь добавлены соседние случаи. */
  .tool-card pre,
  .artifact-card pre,
  .space-item pre,
  .drawer-content pre {
    max-width: 100%;
    overflow-x: auto;
  }

  /* Вертикальные скроллы не должны утаскивать соседей резиновым отскоком iOS. */
  .messages {
    overscroll-behavior: contain;
  }
}


/* УЗКИЙ ANDROID: 360px
   Отдельная полоса нужна только там, где на 390px ещё помещается, а на 360px уже
   нет. Всё остальное решается общими правилами выше. */
@media (max-width: 375px) {
  .app-shell[data-teamon-workspace-shell] .team-rail {
    /* min(84vw, 292px) на 360px даёт 292px и оставляет всего 68px подложки —
       промахнуться мимо рельса пальцем почти невозможно. */
    width: min(82vw, 280px);
  }
  .composer-row {
    /* Проверка на 360px: композер 344px, за вычетом padding остаётся 328px.
       Четыре колонки (app.css:2321) — вложение 46, «Позвать TeamON» 46, поле ввода,
       блок действий 46+5+46=97 — плюс три зазора по 5px съедают 204px, полю ввода
       достаётся 124px. Зазор 3px возвращает ему ещё 6px. */
    gap: 3px;
  }
  .space-item-action {
    padding-inline: 10px;
  }
}


/* ПЛАНШЕТ: 761–900px
   В этой полосе не действует ни один безусловный мобильный блок app.css (они все
   на max-width: 760px), но JS уже считает режим ящиком: workspaceShellUsesDrawer
   сравнивает с 900. Раньше здесь совпадение CSS и JS обеспечивалось только
   правилами с .team-edition, то есть на планшете без пространств рельс мог
   оказаться в потоке при том, что JS уже перевёл его в модальный режим. Правила
   рельса выше сняты с этой привязки и закрывают дыру; ниже — только то, что
   специфично для планшета. */
@media (min-width: 761px) and (max-width: 900px) {
  .app-shell[data-teamon-workspace-shell] .team-rail {
    /* На 768px 84vw — это 645px, почти весь экран. Ящику хватает фиксированной
       ширины развёрнутого рельса (--teamon-space-rail-expanded = 224px)
       с запасом на увеличенные тач-цели. */
    width: 320px;
  }
  .app-shell[data-teamon-workspace-shell]:not(.team-edition) .product-header {
    /* Шапка режима без пространств на планшете живёт по десктопным отступам
       app.css:171 (до 32px по краям). На 768px это съедает ширину впустую. */
    padding-inline: max(16px, var(--m-safe-left)) max(16px, var(--m-safe-right));
  }
}


/* ПЕРЕТАСКИВАНИЕ ДИАЛОГА СТУДИИ НА СЕНСОРНОМ ЭКРАНЕ
   Ниже 821px (STUDIO_DIALOGUE_DESKTOP_BREAKPOINT, work-surface.js:7) боевой CSS уже
   игнорирует результат перетаскивания: app.css:2968–2971 задаёт диалогу
   фиксированные top/right/bottom/left и не читает --studio-dialogue-x/y/width/height.
   При этом ручки .studio-dialogue-resizer остаются видимыми (app.css:2778–2789) и
   имеют touch-action: none, то есть перехватывают касания и глушат прокрутку в
   полосе шириной 11px вдоль края диалога, ничего при этом не изменяя. Убираем их
   ровно в той полосе, где они уже бессмысленны. */
@media (max-width: 820px) {
  .workbench.canvas-full .studio-dialogue-resizer {
    display: none;
  }
}


/* ЭКРАН ВХОДА
   Не относится к .app-shell, но это тот же телефон и тот же вырез. Карточка входа
   центрируется, поэтому достаточно расширить отступы оболочки (app.css:103). */
@media (max-width: 760px) {
  .login-shell {
    padding: max(24px, var(--m-safe-top)) max(20px, var(--m-safe-right))
             max(24px, var(--m-safe-bottom)) max(20px, var(--m-safe-left));
  }
}


/* ЧТО СОЗНАТЕЛЬНО НЕ ТРОНУТО И ПОЧЕМУ

   1. Цвета, фоны, рамки, тени, кегли и начертания — ни одного объявления.
      Это зоны других слоёв (00-tokens.css и соседние файлы redesign/). В этом
      файле нет ни одного hex, rgba, color, background, font-size и border-color.

   2. 100vh → 100dvh. Правка не понадобилась: в app.css нет ни одного вхождения
      100vh — проверено грепом, всё уже переведено на 100dvh (.app-shell:147,
      .workbench:291 и 2304, .login-shell:103). Формулы высот здесь тоже написаны
      на dvh. Отдельного адресного фикса мобильного Safari вносить не за что.

   3. Блок app.css:2215–2249 не удалён и не переписан. Слой накладной: боевые
      правила продолжают действовать, а этот файл добавляет к ним недостающую
      ветку «без team-edition». Дублирование части объявлений — осознанная цена
      обратимости: удалить redesign/ достаточно, чтобы вернуть исходное поведение.

   4. Декоративные слои .boot-cosmos i, .login-orbit, .ambient-grid,
      .app-shell::after и #particle-canvas на мобильных не отключены. Их судьба —
      вопрос визуального языка, а не адаптации; если светлый слой их убирает,
      это должно произойти в его файле, а не здесь.

   5. Ширина Холста ниже 1100px намеренно оставлена за app.css:2361 и 2370
      (min(440px, 100vw) и на всю ширину). Значение --work-surface-width, которое
      считает JS, в этой полосе всё равно не используется: app.css:2361 имеет ту же
      специфичность (0,2,0), что и app.css:649, и идёт позже. Это не противоречие,
      а согласованное поведение, и трогать его из мобильного слоя нельзя.

   6. .starter-prompt:nth-child(n+4) { display: none } (app.css:2310) не отменено:
      сколько подсказок показывать на телефоне — продуктовое решение.

   7. Прозрачная плавающая шапка в режиме с пространствами (position: fixed,
      pointer-events: none, app.css:2163–2177) оставлена как есть. Сообщения
      прокручиваются под ней — это композиционное решение светлого языка, а не
      дефект адаптации; добавлять .messages отступ сверху здесь было бы вторжением
      в чужую зону.

   ПРОТИВОРЕЧИЯ С КОНСТАНТАМИ JS, О КОТОРЫХ НАДО ЗНАТЬ

   A. Требование «планшет 768» и константа 760 в app.js:4357 несовместимы напрямую.
      syncSurfaceModality() ставит .chat-stage в inert при window.innerWidth <= 760,
      и этот порог из CSS не виден. Если бы «телефонные» правила были написаны на
      768px, в полосе 761–768 CSS считал бы экран телефоном, а JS — нет: диалог
      остался бы интерактивным под полноэкранным Холстом. Поэтому телефонная полоса
      здесь ровно 760px, а 768px обслуживается планшетным блоком 761–900. Ширина
      768px протестирована как планшет, а не как телефон — это сознательный выбор,
      а не упущение.

   B. WORK_SURFACE_MIN_WIDTH = 360 и WORK_SURFACE_CHAT_MIN_WIDTH = 600
      (work-surface.js:4, 6) в сумме требуют 960px окна, чтобы Холст и диалог
      помещались рядом. Формула workSurfaceWidthBounds при окне 900px возвращает
      min = max = 360, то есть «диапазон» вырождается в точку и ползунок ширины
      теряет смысл. CSS этому не противоречит только потому, что ниже 1099px
      выводит Холст из потока. Но сам брейкпоинт 1100 в JS выбран шире, чем
      требует его же арифметика (960): в полосе 960–1099 JS всё ещё считает
      раскладку десктопной и позволяет тянуть ползунок, а CSS уже показывает
      Холст наложением. Из CSS это не лечится — нужна правка константы
      WORK_SURFACE_DESKTOP_BREAKPOINT или самой формулы. Вынесено за пределы
      этого слоя как задача для владельца work-surface.js.

   C. Порог рельса 900 задан дважды и независимо: в CSS (медиазапросы) и в JS
      (WORKSPACE_SHELL_CONTRACT.drawerBreakpoint, teamon-workspace-shell.js:9). Значения
      сейчас совпадают, но связи между ними нет. Изменение одного без другого
      разведёт визуальный режим и семантику доступности: рельс будет выглядеть
      колонкой, но выставлять aria-modal, либо наоборот. Единственный способ
      устранить дубль — отдавать порог из JS в CSS-переменную; это изменение
      боевого файла и в накладной слой не помещается. */
