/* ═══════════════════════════════════════════════════════════
   RocketCDN · посадка сайта на реальные устройства

   Заказчик смотрит сайт с Android и из встроенного браузера
   Телеграма. Это самая жёсткая среда, какая у нас есть: узкий
   экран, толстые пальцы, вырез сверху, полоса жеста снизу,
   движок WebView на пару лет старше настольного Chrome и сеть,
   которая любит доставить один файл и потерять другой.

   Здесь не меняется ни вёрстка, ни ритм, ни палитра - этим
   заняты rc.css и rc-compact.css. Здесь страница только
   подгоняется под железо:

     0. безопасные зоны и высота экрана одним именем;
     1. шапка на 360-412 пикселях;
     2. вырез, скруглённые углы, полоса жеста;
     3. палец: ни одна цель нажатия не меньше 44×44;
     4. липкая нижняя панель с заявкой;
     5. горизонтальные ленты под свайп;
     6. планшет;
     7. ландшафт телефона;
     8. подстраховки под Android-браузеры и WebView;
     9. запрет перелива по горизонтали.

   Файл подключается ПОСЛЕДНИМ, после rc.css, rc-interior.css,
   rc-reduced.css и rc-compact.css: он правит их значения, а не
   вводит свои. Своих цветов, шрифтов и теней здесь нет.

   Главное правило: увеличиваем зону нажатия, а не размер
   элемента. Заказчик жаловался на длину страницы - раздувать
   кнопки ради пальца значит вернуть эту длину. Поэтому почти
   везде цель растёт невидимым прямоугольником поверх элемента,
   а сам элемент остаётся ровно таким, каким его нарисовали.

   И второе: ни одно правило здесь не полагается на то, что
   свойство поддерживается. Всё, что моложе Android 12, стоит
   парой «сначала старое, потом новое» или закрыто @supports.
   ═══════════════════════════════════════════════════════════ */


/* ═══ 0. ИМЕНА ДЛЯ ЖЕЛЕЗА ════════════════════════════════════
   env() понимают не все движки, поэтому каждое обращение идёт
   через var(...,0px): если переменная не собралась, элемент
   получит ноль и ничего не сломается. */

:root {
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  /* Высота липкой нижней панели. Ноль, пока панели нет: класс
     has-mcta на body включает её одной строкой в разметке. */
  --mcta-h: 0px;
}

/* Высота экрана. Единица svh появилась в 2022-м: где её нет,
   второе объявление отбрасывается целиком и остаётся vh - экран
   выходит чуть выше из-за адресной строки, но блок не
   схлопывается в нулевую высоту и страница не рассыпается.
   Стоит в начале файла, чтобы разделы 6 и 7 могли эти значения
   переопределять. */
body { min-height: 100vh; min-height: 100svh; }
.hero { min-height: 100vh; min-height: 100svh; }
.hs-stage { height: 100vh; height: 100svh; }
@media (max-width: 640px) { .hero { min-height: 0; } }
@media (max-width: 900px) { .hs-stage { height: auto; } }


/* ═══ 1. ШАПКА НА УЗКОМ ЭКРАНЕ ═══════════════════════════════
   На 360 в шапке живут логотип, кнопка «Регистрация» и бургер.
   Втроём они занимают 338 пикселей из 360 - зазора почти нет, и
   любое удлинение подписи (английский, крупный системный шрифт
   в настройках Android, вырез слева в ландшафте) выталкивает
   бургер за край экрана.

   Поэтому: строке разрешено ужиматься, логотипу - обрезаться,
   кнопке - терять горизонтальные отступы. Бургер не ужимается
   никогда: это единственный вход в меню. */

.hdr-in {
  padding-left: calc(var(--pad) + var(--safe-l, 0px));
  padding-right: calc(var(--pad) + var(--safe-r, 0px));
}

@media (max-width: 900px) {
  /* Ни один элемент шапки не имеет права распирать строку */
  .hdr-in > * { min-width: 0; }
  .hdr-act { gap: 7px; }
  .logo { overflow: hidden; }
}

@media (max-width: 412px) {
  .hdr-in { height: 58px; gap: 8px; }
  .logo img { height: 26px; }
  /* Кнопка сжимается по содержимому, но подпись не переносится
     на вторую строку */
  .hdr-act .btn-sm { padding: 0 13px; font-size: var(--fs-3); white-space: nowrap; }
}

@media (max-width: 359px) {
  /* Совсем узкие аппараты и режим крупного системного шрифта:
     логотип отдаёт место кнопке, знак остаётся читаемым */
  .logo img { height: 23px; }
  .hdr-act .btn-sm { padding: 0 11px; font-size: var(--fs-3); }
}

/* Якорная прокрутка: заголовок раздела не должен уезжать под
   шапку. На телефоне шапка ниже настольной, зато к ней
   добавляется вырез.

   Отступ считается от реальной высоты шапки на этой ширине плюс
   18 пикселей воздуха - одна и та же добавка на всех размерах.
   Раньше стояло одно число 74 на всё, и на самых узких экранах
   заголовок отъезжал от шапки на 16 пикселей дальше, чем на
   широких: переход по якорю выглядел каждый раз по-разному. */
@media (max-width: 900px) {
  /* шапка 70 */
  html { scroll-padding-top: calc(88px + var(--safe-t, 0px)); }
}
@media (max-width: 640px) {
  /* шапка 62 */
  html { scroll-padding-top: calc(80px + var(--safe-t, 0px)); }
}
@media (max-width: 412px) {
  html { scroll-padding-top: calc(76px + var(--safe-t, 0px)); }
}


/* ═══ 2. ВЫРЕЗ, УГЛЫ И ПОЛОСА ЖЕСТА ══════════════════════════
   viewport-fit=cover в разметке уже стоит, значит страница
   рисуется под вырезом и под полосой жеста. Дальше наша забота:
   ни одна буква и ни одна кнопка не должны попасть в эти зоны.

   Главный случай - телефон в ландшафте: вырез уходит вбок и
   съедает до 48 пикселей слева или справа. Вертикальный отступ
   контейнера от этого не спасает, нужен горизонтальный. */

.wrap {
  padding-left: calc(var(--pad) + var(--safe-l, 0px));
  padding-right: calc(var(--pad) + var(--safe-r, 0px));
}

/* Выдвижное меню, модалка и кнопка «наверх» стоят вне потока,
   поэтому безопасные зоны им прописываются отдельно */
.drawer {
  padding-left: calc(var(--pad) + var(--safe-l, 0px));
  padding-right: calc(var(--pad) + var(--safe-r, 0px));
  padding-bottom: calc(34px + var(--safe-b, 0px));
  overscroll-behavior: contain;
}
/* Меню - колонка на flex, и при переполнении оно ужимало кнопку
   «Зарегистрироваться» до 31 пикселя высотой: попасть по такой
   невозможно. Запрещаем сжатие, лишнее уводим в прокрутку. */
.drawer > * { flex: none; }

.modal {
  padding: calc(var(--pad) + var(--safe-t, 0px))
           calc(var(--pad) + var(--safe-r, 0px))
           calc(var(--pad) + var(--safe-b, 0px))
           calc(var(--pad) + var(--safe-l, 0px));
}
.modal-box { overscroll-behavior: contain; }

.totop {
  right: calc(16px + var(--safe-r, 0px));
  bottom: calc(16px + var(--safe-b, 0px) + var(--mcta-h));
}


/* ═══ 3. ПАЛЕЦ: 44×44 ════════════════════════════════════════
   Ниже 44 пикселей человек начинает промахиваться, и промах по
   ссылке в правовой строке обиднее промаха по чему угодно
   другому: страница уезжает не туда, и он уходит.

   Цель нажатия растим прозрачным прямоугольником поверх
   элемента. Высота строки, плотность блока и длина страницы при
   этом не меняются ни на пиксель - меняется только то, куда
   попадает палец.

   Условие было одно: pointer: coarse. Оно опиралось на то, что
   браузер честно сознаётся, что перед ним палец. Приёмка померила
   страницу на 412 пикселях, и весь этот раздел не сработал:
   бургер остался 38×38, «Регистрация» 103.7×38, строка вопроса
   40, флажок согласия 22. Так ведут себя WebView без сенсорных
   флагов, эмуляция телефона в отладчике и настольный Chrome,
   сжатый до ширины телефона - а именно в них сайт и смотрят чаще
   всего перед сдачей.

   Поэтому условий теперь два, через запятую: сенсорный экран ИЛИ
   ширина телефона и планшета. Достаточно любого. На настольном
   мониторе шире 900 под мышью ничего не меняется - там всё и так
   попадается, и раздел по-прежнему выключен. */

@media (pointer: coarse), (max-width: 900px) {

  /* Общий приём: невидимая накладка ростом в 44 пикселя */
  .legal a,
  .contact-list a { position: relative; }

  .legal a::after,
  .contact-list a::after {
    content: '';
    position: absolute;
    left: -6px; right: -6px;
    top: 50%; height: 44px; transform: translateY(-50%);
  }

  /* Логотипу накладка не годится: разделом выше ему поставлен
     overflow: hidden, чтобы длинная подпись не распирала шапку, и
     этот же overflow срезает накладку по краю картинки - палец
     ловил 26 пикселей вместо 44. Проверено обстрелом точками:
     настоящая высота цели совпадала с высотой картинки.
     Поэтому здесь честная высота. Шапка от неё не растёт: строка
     и так 58 пикселей на самом узком экране и 70 на настольном. */
  .logo { min-height: 44px; }

  /* Накладки не должны перекрывать друг друга: в правовой
     строке ссылки идут в две-три строки через восемь пикселей,
     и соседние прямоугольники наезжали бы один на другой.
     Разводим строки ровно настолько, чтобы они не спорили. */
  .legal { gap: 22px 20px; }
  .contact-list { gap: 16px; }

  /* Бургер и круглые кнопки-иконки: у них нет подписи, промах
     по ним - тупик, поэтому растим сам элемент */
  .icon-btn { width: 44px; height: 44px; }
  .icon-btn svg { width: 19px; height: 19px; }

  /* Кнопка в шапке: нажимают её чаще всего на странице */
  .hdr-act .btn-sm { min-height: 44px; }

  /* Вкладки регионов остаются компактными на вид, но ловят
     палец с запасом сверху и снизу */
  .reg-tabs button { position: relative; }
  .reg-tabs button::after {
    content: '';
    position: absolute; left: 0; right: 0;
    top: 50%; height: 44px; transform: translateY(-50%);
  }

  /* Строка города и строка вопроса: обе открываются нажатием и
     стоят вплотную друг к другу, поэтому им честная высота, а
     не накладка - накладки соседних строк перекрывались бы */
  .node-row { min-height: 44px; }
  .faq-q { min-height: 46px; }

  /* Пункты выдвижного меню. Было 50 и 50 - в сумме с полями и
     переключателями меню не влезало в экран (см. раздел 4а).
     Опускаем до 44: это минимум пальца, ниже нельзя, а выше
     меню себе позволить не может. */
  .drawer a { min-height: 44px; }
  .drawer .btn { min-height: 48px; }
  .pill.wide button { height: 44px; }

  /* Флажок согласия. Квадратику 22 пикселя не дотянуть до 44 -
     у поля ввода нет псевдоэлементов, накладку туда не поставить.
     Зато вся подпись лежит внутри label и переключает флажок,
     поэтому настоящая цель здесь - строка целиком, ей и даём
     высоту. Ссылка на политику внутри той же строки - отдельная
     цель, ей нужна своя накладка, иначе палец по ней всегда
     будет попадать в согласие. */
  .consent input { width: 22px; height: 22px; }
  .consent { padding: 6px 0; min-height: 44px; }
  /* Строки-цели мало: приёмка меряет сам флажок, и он остаётся
     квадратом 22. Рисунок флажка трогать нельзя - его собирает
     rc-rail.css из appearance: none, рамки и ::before с галочкой.
     Зато ::after у контрола свободен, и накладка на нём даёт
     честные 44×44 вокруг квадратика: палец попадает по кругу
     радиусом 11 пикселей от центра, а нарисованный флажок
     остаётся прежнего размера и на своём месте.

     Накладка лежит внутри самого input, поэтому нажатие по ней -
     это нажатие по флажку, без всякой зависимости от label. */
  .consent input[type="checkbox"] { position: relative; }
  .consent input[type="checkbox"]::after {
    content: '';
    position: absolute; left: 50%; top: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }
  .consent a { position: relative; }
  .consent a::after {
    content: '';
    position: absolute; left: -6px; right: -6px;
    top: 50%; height: 44px; transform: translateY(-50%);
  }

  /* Кнопки форм и крупные кнопки-ссылки.
     Раньше здесь стояло .btn { min-height: 46px } - и оно молча
     съедало размер .btn-lg: правила равны по весу, а этот файл
     подключён позже, поэтому крупная кнопка первого экрана на
     телефоне становилась ростом с обычную. Теперь базовые 46
     объявлены в самой кнопке (rc.css), а здесь только то, чего
     там быть не может: мелкая кнопка обязана дорасти до пальца. */
  .btn-sm { min-height: 44px; }
  .totop { width: 48px; height: 48px; }
}


/* ═══ 3а. ВЫДВИЖНОЕ МЕНЮ ЦЕЛИКОМ В ЭКРАНЕ ════════════════════
   Замер приёмки на 412×800: ящик меню 800, содержимое 941. Три
   переключателя стояли столбиком в самом низу - язык на 747, звук
   на 805, тема на 863. Два из трёх оказывались за сгибом, и меню
   ничем не показывало, что его можно прокрутить: фон сплошной,
   полосы прокрутки на Android нет, последний видимый элемент -
   кнопка «Зарегистрироваться», после которой всё выглядит
   законченным. Человек просто не знал, что тема и звук там есть.

   Чиним причину, а не следствие: меню обязано помещаться. Ни один
   пункт из него не убран, убран только воздух.

   1. Поля ящика. Сверху 90 - это высота настольной шапки, а на
      телефоне шапка 58-62. Снизу 40 - воздух под последним
      переключателем, которого никто не видит.
   2. Зазор между пунктами 6 при том, что у каждого пункта своя
      разделительная черта: черта и есть зазор, второго не нужно.
   3. Отступы кнопки и блока переключателей.
   4. Сами переключатели. Три полосы во всю ширину подряд - это
      162 пикселя на три переключателя, из которых два (звук и
      тема) занимают по трети своей полосы. Язык остаётся во всю
      ширину, потому что в нём слова, а звук и тема встают в один
      ряд: у них значки.

   Итог замера после правки лежит в отчёте. На аппаратах ниже 700
   пикселей меню всё равно прокручивается - там его не собрать
   никаким сжатием, - поэтому ниже отдельно включена видимая
   полоса прокрутки: теперь меню о прокрутке говорит. */

@media (max-width: 900px) {
  .drawer {
    padding-top: calc(62px + var(--safe-t, 0px));
    padding-bottom: calc(12px + var(--safe-b, 0px));
    gap: 0;
  }
  .drawer a { padding: 10px 4px; }
  /* Плитка входа в VPN приезжает в меню скриптом (rc-vpn), и
     воздуха вокруг неё стояло 19 пикселей: семь сверху и
     двенадцать снизу, а следом ещё отступ блока переключателей.
     Плитку не трогаем - она ростом со свою картинку, - сокращаем
     только зазор под ней, он там задваивался. */
  .drawer .rc-vpn-entry { margin: 6px 0 4px; }
  /* Правовые ссылки - не навигация, а сноска. Им хватает роста
     пальца без запаса и кегля на ступень мельче: иначе две
     служебные строки весят столько же, сколько «Продукты» и
     «Инфраструктура» вместе. */
  .drawer .drawer-law { font-size: var(--fs-3); font-weight: 500; }
  .drawer .btn { margin-top: 10px; }
  .drawer-tools { margin-top: 8px; gap: 8px; }
  /* Язык и звук делят строку пополам, тема остаётся строкой.
     Минус одна полоса из трёх - это 54 пикселя, ровно те,
     которых не хватало.

     Пополам делятся именно язык и звук: у языка подписи короткие
     («Русский», «English»), у звука одно слово. У темы подписи
     самые длинные из трёх («Светлая тема», «Тёмная тема»), и в
     половине строки они ломались на две строки внутри кнопки. */
  .drawer-tools {
    display: grid; grid-template-columns: 1fr 1fr;
  }
  .drawer-tools > .pill.theme { grid-column: 1 / -1; }
}

/* Меню всё-таки прокручивается (низкий экран, крупный системный
   шрифт, английский язык с длинными подписями) - полоса прокрутки
   обязана быть видна. По умолчанию на Android она появляется на
   время движения и пропадает, то есть сообщает о прокрутке только
   тому, кто уже прокрутил. */
.drawer { scrollbar-width: thin; }
.drawer::-webkit-scrollbar { width: 4px; }
.drawer::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 4px;
}
.drawer::-webkit-scrollbar-track { background: transparent; }


/* ═══ 4. ЛИПКАЯ НИЖНЯЯ ПАНЕЛЬ ════════════════════════════════
   По сценарию кнопка заявки дублируется внизу экрана на всём
   протяжении страницы: человек может решиться на любом блоке, и
   искать форму прокруткой он не пойдёт.

   Панель появляется только на телефоне и только на сенсорном
   экране. Разметка - в index.html (фрагмент отдан
   координатору), класс mcta, и вместе с ней на body ставится
   has-mcta. Пока разметки нет, весь раздел ничего не делает.

   Ни одного :has() здесь нет намеренно: в WebView Телеграма на
   старых Android его может не быть, а от него зависит, не
   перекроет ли панель последнюю строку страницы. */

.mcta {
  position: fixed; z-index: 190;
  left: 0; right: 0; bottom: 0;
  display: none;
  gap: 10px;
  padding: 10px calc(var(--pad) + var(--safe-r, 0px))
           calc(10px + var(--safe-b, 0px))
           calc(var(--pad) + var(--safe-l, 0px));
  background: var(--head-bg);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  /* Панель уезжает вниз, пока человек не прочитал первый экран,
     и возвращается после него: класс on ставит скрипт прокрутки */
  transform: translateY(110%);
  transition: transform .38s var(--ease);
}
.mcta.on { transform: none; }
/* Кнопки делят ширину поровну. Подпись не режется и не уезжает
   за край даже по-английски, где она длиннее: кегль плавает по
   ширине экрана, а длинная подпись переносится на вторую строку
   с плотным межстрочным - панель от этого растёт вверх, а не
   наезжает на содержимое. */
.mcta .btn {
  flex: 1 1 0; min-width: 0; min-height: 46px;
  padding: 10px 12px; text-align: center;
  font-size: clamp(13px, 3.4vw, 15px); line-height: 1.16;
  white-space: normal;
}
.mcta .btn > span { display: block; min-width: 0; }

@media (max-width: 900px) and (pointer: coarse) {
  .mcta { display: flex; }
  /* Ровно на высоту панели поднимается низ страницы, чтобы
     правовая строка не оказалась под ней. Семьдесят два - это
     десять отступа сверху, сорок шесть кнопки, десять снизу,
     пиксель рамки и запас на округление кегля. */
  .has-mcta { --mcta-h: calc(76px + var(--safe-b, 0px)); }
  .has-mcta main { padding-bottom: var(--mcta-h); }
}

/* Пока открыто меню или окно обратного звонка, панель мешает:
   она перекрывает кнопку отправки и последний пункт меню.
   Соседский комбинатор работает потому, что в разметке панель
   стоит после #drawer и после #cbModal. */
.drawer.on ~ .mcta,
.modal.on ~ .mcta { transform: translateY(110%); }

/* В ландшафте телефона панель забирает пятую часть экрана -
   отказываемся от неё совсем */
@media (max-height: 520px) and (orientation: landscape) {
  .mcta { display: none; }
  .has-mcta { --mcta-h: 0px; }
  .has-mcta main { padding-bottom: 0; }
}


/* ═══ 5. ГОРИЗОНТАЛЬНЫЕ ЛЕНТЫ ════════════════════════════════
   Маршрут запроса и двенадцать сценариев на телефоне листаются
   пальцем вбок. Три вещи ломают этот жест на Android:

   - свайп добегает до края ленты и уходит в системный жест
     «назад», страница закрывается посреди чтения;
   - снап по центру не даёт доехать до первой и последней
     карточки: у ленты есть боковой отступ, и центр крайней
     карточки физически не совпадает с центром окна;
   - до конца ленты не докрутить, последняя карточка упирается
     в правый край и выглядит обрезанной.

   Первое лечится overscroll-behavior, второе - снапом по
   началу и полем прокрутки, третье - распоркой в хвосте.
   touch-action не трогаем нигде: вертикальная прокрутка должна
   остаться нативной, это условие приёмки. */

@media (max-width: 900px) {
  .hs-view {
    overscroll-behavior-x: contain;
    scroll-padding-left: calc(var(--pad) + var(--safe-l, 0px));
    scroll-padding-right: calc(var(--pad) + var(--safe-r, 0px));
  }
  .hs-track {
    padding-left: calc(var(--pad) + var(--safe-l, 0px));
    padding-right: calc(var(--pad) + var(--safe-r, 0px));
  }
  .hs-track > * { scroll-snap-align: start; }
  /* Распорка в хвосте ленты: без неё последняя карточка не
     доезжает до левого края и лента ощущается сломанной */
  .hs-track::after {
    content: ''; flex: none; width: 26vw;
  }
}

/* Бегущая строка городов: на слабом Android её анимация даёт
   пропуски кадров - дорожка длиной в тридцать семь тысяч
   пикселей перекладывается каждый кадр. Замедляем ход. */
@media (max-width: 640px) {
  .mq-track { animation-duration: 190s; }
}

/* Раньше здесь стоял запрет на передачу прокрутки странице. Он
   решал одну задачу и создавал худшую: список занимал пол-экрана,
   палец почти всегда попадал в него, и страница не двигалась вовсе.
   Теперь у списка нет своего окна прокрутки, и запрет не нужен. */
/* ...но на телефоне запрет вышел боком: список занимает пол-экрана,
   палец почти всегда попадает в него, и страница не двигалась вовсе -
   человек застревал на разделе сети. Там, где ведут пальцем, цепочку
   возвращаем: список докрутился до края - дальше едет страница.
   И сам список делаем ниже, чтобы под ним было куда положить палец.
   Обе правки сняты: у списка больше нет собственного окна прокрутки,
   поэтому воровать ход страницы ему нечем. */


/* ═══ 6. ПЛАНШЕТ ═════════════════════════════════════════════
   768×1024 попадает в мобильные правила по ширине, но экран у
   него вдвое шире телефона. Карточки, сжатые под палец на 360,
   выглядят на нём потерянными, а половина ширины пустует. */

@media (min-width: 601px) and (max-width: 900px) {
  /* Лента: карточка в 68vw - это 522 пикселя, во весь экран.
     Показываем две с половиной, и лента читается как лента */
  .hs-track > * { width: 40vw; }
  .hs-track::after { width: 18vw; }

  /* Показатели: четыре в ряд помещаются, два на два оставляли
     половину экрана пустой */
  .kpi { grid-template-columns: repeat(4, 1fr); }

  /* Три собственных ЦОД встают в ряд, как на настольном */
  .dc-grid { grid-template-columns: repeat(3, 1fr); }
  .dc-grid > .dc:last-child:nth-child(3) { grid-column: auto; }
}

@media (min-width: 601px) and (max-width: 1023px) {
  /* Карту ужали до 268 пикселей заодно с телефоном - здесь ей
     есть куда развернуться */
  .map-wrap { max-width: 400px; }

  /* Форма стоит в колонку, но тянуться во всю ширину планшета
     ей незачем: поле ввода длиной в семьсот пикселей неудобно */
  .form-card { max-width: 620px; }
}

/* Планшет в ландшафте (1024×768) получает настольную раскладку
   по ширине, но пальцем по нему водят так же. Правила пальца из
   раздела 3 завязаны на pointer: coarse и работают и здесь. */


/* ═══ 7. ЛАНДШАФТ ТЕЛЕФОНА ═══════════════════════════════════
   844×390. Высота меньше, чем ширина иного телефона в портрете:
   на экран влезает четыре строки текста. Всё, что рассчитано на
   высоту экрана (первый экран, липкие сцены, меню, модалка),
   надо пересчитать, иначе человек видит один заголовок и не
   понимает, куда попал. */

@media (max-height: 520px) and (orientation: landscape) {

  /* Первый экран перестаёт быть «в рост экрана»: содержимое
     важнее композиции, пусть занимает столько, сколько нужно */
  .hero { min-height: 0; padding: 74px 0 26px; }
  .hero-logo img { width: clamp(96px, 16vw, 132px); }
  .hero h1 { font-size: clamp(26px, 4.6vw, 38px); }
  .hero-sub { font-size: 14px; margin-bottom: 14px; }
  /* Планета в ландшафте налезает на текст справа. Гасить её до
     трети нельзя - владелец справедливо назвал это «почти
     прозрачная»: за текстом должна стоять планета, а не её след.
     Держим плотной, читаемость даёт подложка под самим текстом. */
  .hero-globe { opacity: .68; }
  .scroll-hint { display: none; }

  /* Кнопки встают в строку: во всю ширину они съедали бы
     половину видимой высоты */
  .btn-row .btn { flex: 0 1 auto; width: auto; }

  /* Липкие сцены на 390 пикселях высоты не работают: карточка
     не помещается целиком. Лента листается пальцем. */
  .hs-stage { position: static; height: auto; padding: var(--sec) 0; }
  .hs-track { transform: none !important; }
  .hs-track > * { width: 38vw; }
  /* ── МЁРТВЫЕ ТОЧКИ УБИРАЕМ ВЕСОМ, А НЕ ЗНАКОМ ВАЖНОСТИ ──────
     Строкой выше лента расфиксирована со знаком важности, значит
     точки под ней уже ничего не переключают: нажатие двигало бы
     трансформ, который отключён. А место они занимают, и человек в
     них тыкает - двенадцать целей по сорок четыре точки, и все
     мёртвые.

     Просто `display:none` тут не работал: лежачий телефон 844x390
     подходит и под этот запрос, и под `max-width:900` в rc-rail.css,
     где у точек стоит `display:flex !important`. Веса селекторов
     равны, оба со знаком важности, а rc-rail подключён ПОЗЖЕ - и
     побеждает он. Добавляем `body` в селектор: вес становится выше,
     и порядок подключения перестаёт решать. */
  body .hs-bar { display: none !important; }

  /* Меню: семь пунктов по пятьдесят пикселей в 390 не влезают,
     и кнопка «Зарегистрироваться» оказывалась ниже экрана - её
     не видно, а именно она здесь главная. Разворачиваем пункты
     в две колонки, кнопку и инструменты кладём во всю ширину:
     меню собирается в один экран. */
  .drawer {
    display: grid; grid-template-columns: 1fr 1fr;
    align-content: start; gap: 4px 16px;
    padding-top: calc(62px + var(--safe-t, 0px));
  }
  .drawer a:not(.btn) { min-height: 38px; padding: 5px 4px; font-size: 15.5px; }
  .drawer .btn { grid-column: 1 / -1; margin-top: 8px; min-height: 44px; }
  .drawer-tools {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  }
  .drawer-tools .pill.snd { grid-column: 1 / -1; }
  .pill.wide button { height: 38px; }

  /* Окно обратного звонка прокручивается внутри себя, а не
     уезжает за край экрана */
  .modal-box { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); }

  /* Высокие блоки, посчитанные от ширины экрана: в ландшафте
     ширина большая, и они вырастают выше самого экрана */
  .rack { height: clamp(180px, 30vh, 240px); min-height: 0; }
  .map-wrap { max-width: min(300px, 62vh); }
  /* Высоту списку больше не задаём: внутренней прокрутки у него нет,
     длину держит кнопка «показать все» */
}


/* ═══ 8. ANDROID-БРАУЗЕРЫ И ВСТРОЕННЫЙ БРАУЗЕР ТЕЛЕГРАМА ═════
   Движок в приложении отстаёт от настольного Chrome, и каждое
   современное свойство надо подпирать простым. Ни одна из
   подстраховок ниже не меняет вид страницы там, где всё
   поддерживается. */

/* Размытие за шапкой. Без него полупрозрачный фон превращается
   в окно, сквозь которое едет содержимое страницы, и подписи в
   шапке становятся нечитаемыми - ровно то, на что жаловался
   заказчик, когда текст «вылез поверх страницы». */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .hdr { background: var(--bg); }
  .mcta { background: var(--bg); }
  .modal { background: rgba(3, 8, 14, .93); }
  .chip { backdrop-filter: none; }
  -webkit-backdrop-filter: none;
  .sec-head::before, .hero-in::before, .hs-head::before { background: var(--read-veil-2); }
}

/* Приближение при фокусе. Ниже 16 пикселей Safari и часть
   Android-оболочек увеличивают страницу, когда человек ставит
   курсор в поле, и обратно её уже не уменьшают. */
@media (pointer: coarse) {
  .field input, .field textarea, .field select,
  .search input { font-size: 16px; }
}

/* Инерция прокрутки внутри блоков со своим окном */
.modal-box, .drawer, .hs-view { -webkit-overflow-scrolling: touch; }

/* Тап-подсветка и меню по долгому нажатию: в WebView они
   рисуются поверх наших состояний и выглядят как дефект */
.btn, .icon-btn, .pill button, .reg-tabs button,
.faq-q, .node-row, .mcta .btn {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

/* Курсорные затеи не нужны там, где нет курсора: это и лишние
   слои композитинга, и лишний расход заряда */
@media (hover: none) {
  .cur-dot, .cur-ring { display: none; }
  .card::before { display: none; }
}

/* Режим экономии трафика человек включает сам, и означает он
   одно: покажи содержимое, а не представление */
@media (prefers-reduced-data: reduce) {
  .hero-globe, #spaceBg, #rocketCanvas { display: none; }
  .mq-track { animation: none; }
}


/* ═══ 9. НИКАКОГО ПЕРЕЛИВА ПО ГОРИЗОНТАЛИ ════════════════════
   Страницу, которую можно сдвинуть вбок, человек считает
   сломанной - и он прав. У html уже стоит overflow-x: clip, но
   клип прячет следствие, а не причину: под ним карточка
   по-прежнему шире экрана, просто её край не виден, а текст в
   ней обрезан. Ниже - сами причины, какие встречаются на 360. */

/* Длинное слово без пробелов (адрес почты, домен, название
   тарифа) распирает свою колонку и тянет за собой всю сетку */
h1, h2, h3, h4, p, li,
.kpi-n, .node-row .nm, .legal, .chip, .inc-item {
  overflow-wrap: break-word;
  word-break: break-word;
}

/* Заголовок переносить по слогам некрасиво, но красивее, чем
   заголовок, уехавший за край экрана */
@media (max-width: 412px) {
  .sec-h, .hero h1 { hyphens: auto; -webkit-hyphens: auto; }
}

/* Ячейка грид-сетки по умолчанию не уже своего содержимого.
   Из-за этого одна широкая карточка расширяет всю сетку, а
   сетка - страницу. */
.grid > *, .kpi > *, .contact > *, .infra > *,
.form-2 > *, .dc-grid > *, .viz-grid > *, .inc-grid > * { min-width: 0; }

/* Внутренности виджетов считаются от ширины родителя, а не от
   ширины экрана */
.viz-card, .form-card, .faq, .node-list { min-width: 0; }

/* Имя и телефон стоят в анкете парой ради плотности. Порог был
   380 пикселей, и он оказался занижен: приёмка померила на 412 и
   получила два поля по 168, в которых плейсхолдер
   «+7 900 000-00-00» обрезан, а подпись «Как к вам обращаться»
   не помещается в строку. То есть человек и на обычном телефоне
   набирает номер вслепую, а не только на узком.

   Считаем честно. Номер «+7 900 000-00-00» это 16 знаков, при
   обязательных 16 пикселях кегля поля (мельче нельзя, iOS
   приближает страницу при фокусе) ему нужно около 150 пикселей
   плюс 26 внутренних отступов поля. Значит паре нужно 352 плюс
   зазор и поля карточки - это ширина от 420 пикселей и выше.
   Ни один телефон в портрете столько не даёт.

   Поэтому на всю телефонную ширину пара разводится в столбик.
   Планшет и монитор пару сохраняют - там места хватает с запасом. */
@media (max-width: 640px) {
  .form-2 { grid-template-columns: 1fr; }
}

/* Всё, что нарисовано в canvas, обязано жить в своей коробке */
canvas { max-width: 100%; }


/* ── Правки приёмки (аудит игры) ─────────────────────────────ы */
@media (max-width: 760px) {
  /* Контакты: подпись и ссылки-документы после формы, а не перед ней.
     Левая колонка распускается, и каждый её блок получает своё место
     в общем столбце. */
  /* align-items: start у .contact написан для сетки, где он про
     вертикаль. Здесь блок становится колонкой на flex, и та же
     строка начинает работать по горизонтали: каждый ребёнок ужимается
     по содержимому. Из-за этого кнопка «Перезвоните мне» на телефоне
     выходила шириной 174 пикселя и висела у левого края, тогда как
     обе кнопки первого экрана шли во всю ширину. Возвращаем растяжку. */
  .contact { display: flex; flex-direction: column; align-items: stretch; }
  .contact > .rv:first-child { display: contents; }
  .contact .legal { order: 99; margin-top: 26px; }
  .contact .form-card { order: 50; }

  /* Кнопка «наверх» не должна лежать на полях формы */
  .totop { width: 40px; height: 40px; }
}
/* Вторая подсказка прокрутки у героя: чип «Листайте дальше» уже
   есть, двойной призыв - шум. Оставляем анимированную стрелку
   только на широких экранах, где она не липнет к кнопкам. */
@media (max-width: 1100px) {
  .hero .scroll-hint { display: none; }
}


/* ═══ 10. КОЛЬЦО ФОКУСА НЕ МЕНЯЕТ ФОРМУ ЭЛЕМЕНТА ════════════
   В rc-reduced.css правило доступности объявлено как

       :focus-visible { outline: ...; border-radius: 4px; }

   и вторая строка тут лишняя: border-radius меняет форму САМОГО
   элемента, а не обводки. В момент фокуса круглая пилюля
   становилась прямоугольником со скруглением 4, кнопка теряла
   свои 18, карточка - свои 24. Обстрел табом: из 46 элементов,
   до которых можно дойти с клавиатуры, форму теряли 28.

   Тот файл правится смежной задачей, поэтому не трогаем его, а
   возвращаем радиус здесь - rc-adapt.css подключён последним.
   Селектор с классом весит больше голого :focus-visible, значит
   !important не нужен, и кино-сцена по-прежнему может перебить
   нас своими правилами.

   Элементам без собственного радиуса (логотип, строка города,
   пункт меню) четвёрка не мешает - им ничего не возвращаем. */

.btn:focus-visible, .icon-btn:focus-visible,
.card:focus-visible, .viz-card:focus-visible, .dc:focus-visible,
.inc-item:focus-visible, .flow-node:focus-visible {
  border-radius: var(--r-md);
}
.btn-sm:focus-visible, .card-ico:focus-visible,
.nav a:focus-visible, .soc a:focus-visible,
.search input:focus-visible,
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  border-radius: var(--r-sm);
}
.faq:focus-visible, .form-card:focus-visible, .kpi:focus-visible,
.node-list:focus-visible, .modal-box:focus-visible, .rack:focus-visible {
  border-radius: var(--r-lg);
}
.chip:focus-visible, .tag:focus-visible,
.pill:focus-visible, .pill button:focus-visible,
.reg-tabs button:focus-visible {
  border-radius: var(--r-full);
}
.totop:focus-visible { border-radius: 50%; }


/* ═══ 11. ПЕРЕНОС ПО СЛОГАМ - ТОЛЬКО В ЗАГОЛОВКАХ ═══════════
   В rc-rail.css стоит правило

       html[lang="ru"] .card p, html[lang="ru"] .sec-p,
       html[lang="ru"] .faq-a p { hyphens: auto }

   и оно работает не там, где задумано. Заголовок раздела перенос
   по слогам спасает: он крупный, строк в нём две-три, и уехавшее
   за край слово хуже дефиса. А тело карточки - это кегль 11-12 в
   колонке 185 пикселей, и перенос там срабатывает почти в каждой
   строке.

   Замер приёмки на 412: в продуктах шесть разрывов («ста-тики»,
   «фай-лов», «из-вестные», «по-коления», «ва-шим»,
   «медиа-контента»), в преимуществах восемь («по-следних»,
   «Ре-сурсы», «ме-диа», «ARM-про-цессоры», «раз-мера»,
   «кото-рый», «полу-тора», «пре-вышает»), в надёжности шесть.
   Двадцать разорванных слов на трёх блоках - карточка перестаёт
   читаться с одного взгляда, глаз каждый раз собирает слово
   заново.

   Снимаем перенос с тела карточек и оставляем в заголовках. Длинные
   слова при этом за край не уедут: выше в этом же файле у p, li и
   плиток стоит overflow-wrap: break-word - слово, которое шире
   колонки, всё равно перенесётся, просто по месту, а не по слогу.

   Про вес селектора. rc-rail.css подключён после нас, а его
   правило весит ровно столько же, сколько напрашивающееся
   html[lang] .card p. Поэтому здесь добавлен :root - тот же
   элемент html, только записанный псевдоклассом, он и даёт
   перевес на один класс. !important не нужен, и кино-сцена
   по-прежнему может перебить нас своими правилами. */

html:root[lang] .card p,
html:root[lang] .card li,
html:root[lang] .case-card p,
html:root[lang] .prod-card li,
html:root[lang] .step p,
html:root[lang] .inc-item,
html:root[lang] .inc-item span,
html:root[lang] .kpi-l,
html:root[lang] .dc p {
  hyphens: manual;
  -webkit-hyphens: manual;
}


/* ═══ 12. КНОПКА «НАВЕРХ» НЕ ЛОЖИТСЯ НА ТЕКСТ ═══════════════
   На телефоне у страницы одна колонка, и она занимает всю ширину:
   на 412 пикселях содержимое идёт с 15 по 397. Кнопка «наверх»
   стоит вне потока, 40 пикселей шириной, справа - замер приёмки
   дал 356..396. То есть она лежит прямо на тексте: накрывала
   строку «Россия и СНГ» у Калининграда и хвост последней карточки
   продуктов. Отодвинуть её некуда - поле у края всего 15
   пикселей, а меньше 40 кнопка быть не может, иначе по ней не
   попасть пальцем.

   Поэтому на телефоне её нет. Дорога наверх при этом никуда не
   девается и даже короче: шапка приклеена к верху экрана
   (position: fixed) и возвращается на первом же движении вверх, а
   логотип в ней - это ссылка на #top. Плюс внизу постоянно висит
   панель заявки, то есть главное действие под пальцем и так.

   На планшете и мониторе кнопка остаётся: там между колонкой
   текста и краем окна есть поле, и она стоит в нём, а не на
   тексте. */

@media (max-width: 900px) {
  .totop { display: none; }
  /* Кроме одного места: внутри корабля. Там и шапка с логотипом, и
     липкая панель заявки погашены - то есть ровно те две вещи,
     которыми кнопку «наверх» на телефоне и заменяли. Без неё на дне
     страницы не остаётся ни одного видимого выхода: подняться можно
     только прокруткой, а человеку с клавиатуры и прокруткой нельзя -
     страница внутри корабля заглушена целиком. */
  html.rc-inside .totop { display: grid; }
}


/* ═══ 13. КАРТОЧКИ В ОДНОЙ ДОРОЖКЕ - ОДНОЙ ВЫСОТЫ ═══════════
   «Как работает» и «Сценарии» - это горизонтальные дорожки на
   flex. У дорожки выравнивание по умолчанию, то есть растяжка, и
   в rc-rail.css ей же прописано align-self: stretch. Всё равно
   первая карточка выходила ниже соседних: в «Как работает» 177.8
   против 202.1, в «Сценариях» 129.9 против 154.2. В ряду из шести
   карточек одна на два с лишним сантиметра короче - дорожка
   выглядит сломанной.

   Причина в соседней строке того же файла: .hs-track > .card
   получает height: 100%. Растяжка по спецификации работает только
   тогда, когда размер по поперечной оси равен auto. Процент - это
   не auto, поэтому растяжка молча выключается, а сам процент
   считать не от чего: высота дорожки не задана, она сама
   собирается по содержимому. В итоге карточка получает высоту
   своего текста, и у кого текст короче, тот и ниже.

   Возвращаем auto - и растяжка снова включается сама. Высоту
   ряда, как и положено, задаёт самая высокая карточка, остальные
   дотягиваются до неё.

   Вес селектора: у rc-rail.css два класса, у нас три (.hs-stage
   добавлена настоящим предком дорожки), поэтому правило
   перебивает его без !important. */

.hs-stage .hs-track > .card,
.hs-stage .hs-track > .case-card {
  height: auto;
  align-self: stretch;
}


/* ═══ 14. ГАЛОЧКА В СОСТАВЕ ПОДКЛЮЧЕНИЯ - У ПЕРВОЙ СТРОКИ ═══
   Плитка «Что входит» - это галочка и подпись в строку, и
   выравнивались они по центру. Пока подпись в одну-две строки,
   разницы не видно. На трёхстрочной («Запросы без ограничений:
   Google, Яндекс...») галочка уезжала к середине абзаца и
   переставала читаться как маркер первой строки - выглядела
   значком, поставленным посреди текста.

   Ставим по верху. Галочка - это маркер строки, а не всей плитки,
   и её место рядом с первым словом при любой длине подписи.
   Замер до правки: у однострочной плитки центр галочки совпадал с
   центром первой строки (0.6 пикселя расхождения), у двухстрочной
   уезжал на 8.8, у трёхстрочной на 16.9 - то есть на полторы
   строки вниз.

   Одного flex-start мало. Кружок галочки вместе со своим полем
   выше строки текста (21 пиксель против 16), и при выравнивании
   по верху он начинает казаться приподнятым. Поправка в em, а не
   в пикселях, намеренно: кегль плитки разный на телефоне и на
   мониторе, а доля от кегля - одна и та же, и поправка держится
   сама, без отдельной ступени под каждую ширину. */

.inc-item { align-items: flex-start; }
.inc-item svg { margin-top: -0.25em; }

/* ═══ Пальцевые цели ═══════════════════════════════════════════
   Обмер на телефоне 412x915 нашёл 36 управляющих элементов мельче
   44 пикселей: точки каруселей 26x30, кнопки копирования 34x34,
   вкладки узлов и строки контактов по 34, ссылка эпилога 36,
   выпадающий список 41, согласие 43. Сорок четыре - не круглое
   число из воздуха: это размер подушечки пальца, ниже которого
   промахи растут, и он же порог в руководствах обеих мобильных
   систем.

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

   Растим настоящий размер там, где соседям есть куда потесниться, и
   только точкам каруселей даём невидимую подложку: их в ряду
   двенадцать, на 412 пикселях ширины на каждую приходится 34, и
   честные 44 налезли бы друг на друга. Перекрытые цели хуже мелких:
   палец попадает в соседнюю. */
@media (pointer: coarse) {

  /* Строки контактов и вкладки: просто выше, макет это терпит */
  .contact-list > a,
  .contact-list > div { min-height: 48px; }
  .reg-tabs button { min-height: 44px; }
  .node-more,
  .epi-alt { min-height: 44px; }
  .form-card select,
  .form-card input:not([type=checkbox]):not(.vh) { min-height: 44px; }
  .btn { min-height: 44px; }

  /* Кнопка копирования стоит в правом краю строки контакта. Строка
     теперь 48 в высоту, значит квадрат 44 умещается в неё целиком и
     ничего не распирает. */
  .copy-btn { min-width: 44px; min-height: 44px; }

  /* Согласие: сама метка выше порога на волос (43), а вложенная
     ссылка на политику всего 12. Метку поднимаем, ссылке даём
     поле сверху и снизу - она вторая строка внутри метки, и растить
     её в стороны некуда. */
  .form-card label:has(input[type=checkbox]) { min-height: 48px; }
  .form-card label a { display: inline-block; }

  /* Правовые строки подвала и ссылка внутри согласия. Обе мелкие не
     от небрежности, а намеренно: это тихий текст, который не должен
     спорить с главным. Поэтому кегль не трогаем совсем, растим
     только поле вокруг буквы - палец получает свои 44, а глаз
     видит ту же строку, что и раньше. */
  .epi .legal a { display: inline-block; padding: 15px 0; }
  .form-card label a { padding: 15px 0; }

  /* Наверх и точки каруселей: рисунок оставляем, растим только то,
     во что попадает палец. */
  .totop,
  .icon-btn { min-width: 44px; min-height: 44px; }

  .rail-dot { position: relative; }
  .rail-dot::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    /* Ширина ровно по ШАГУ ряда: точка 26 плюс зазор 2. Стояло 34 при
       шаге 28, и зоны налезали друг на друга по три точки с каждой
       стороны. Палец у края точки попадал в СОСЕДНЮЮ - карусель
       прыгала не туда, куда целились, и понять это было нельзя:
       промах выглядел как своя же кнопка. Замер тычком показывал у
       крайних точек зону уже двадцати четырёх, хотя в стилях стояло
       тридцать четыре: лишнее забирал сосед.

       Смыкающиеся зоны отдают каждой точке всю её долю ряда и не
       отнимают чужого. Шире ряд не сделать: точек внизу двенадцать,
       телефон 412, двенадцать зон по сорок это 480. */
    width: calc(100% + 2px); height: 44px; transform: translate(-50%, -50%);
    /* Подложка ловит палец и ничего не рисует */
    background: transparent;
  }
}
