/* =========================================================================
   APOLLO EXCHANGE - дом-стиль Apollo Production (редизайн 17.08.2026)

   Стиль снят с эталонного дека «Условия сотрудничества» и с шаблона
   ~/apollo-vault/Apollo/Tools/apollo-deck-template/deck.css. Оттуда взяты
   ровно четыре узнаваемые вещи, всё остальное - производные от них:
     1. фон #0C0D11 по углам, к центру подсветка до rgb(21,22,26);
     2. акцентная полоса СЛЕВА ровно 3px цветом #4FC4E9 у важных блоков;
     3. серебряный градиент по тексту заголовков (не плоский серый);
     4. капсы с трекингом .27em и линейка 220x3, гаснущая слева направо.

   ПОЧЕМУ плашки светлее фона, а не темнее: жалоба владельца была
   «серый цвет, плашка очень сильно затемняет всё, надпись нечитаемая».
   Поэтому поверхности здесь - БЕЛЫЙ с малой альфой поверх тёмного фона
   (панель светлее подложки), а текст на них не ниже 4.5:1 к этой панели.
   Тёмных плашек и серого текста на сером в файле нет вообще.

   ЗАПРЕТ: длинное и среднее тире в текстах для людей, только обычный дефис.
   ========================================================================= */

:root{
  /* ---------- фон и поверхности ---------- */
  --bg:          #0C0D11;                      /* замер угла эталона */
  --bg-lift-1:   #15161B;                      /* подсветка к центру */
  --bg-lift-2:   #16181D;

  /* Панель = белый с альфой. На #0C0D11 это даёт светлее подложки,
     то есть плашка ПОДНИМАЕТ содержимое, а не затемняет его. */
  --panel:       linear-gradient(103deg, rgba(255,255,255,.085) 0%,
                                         rgba(255,255,255,.050) 42%,
                                         rgba(255,255,255,.028) 100%);
  --panel-hi:    linear-gradient(103deg, rgba(255,255,255,.115) 0%,
                                         rgba(255,255,255,.068) 42%,
                                         rgba(255,255,255,.040) 100%);
  --panel-flat:  rgba(255,255,255,.045);
  --line:        rgba(255,255,255,.10);
  --line-2:      rgba(255,255,255,.145);       /* кромка плашки в эталоне */
  --line-3:      rgba(255,255,255,.24);

  /* ---------- текст (все значения проверены на контраст к #0C0D11) ---------- */
  --ink:         #FFFFFF;                      /* 19.6:1 */
  --body:        #C7CDD5;                      /* 11.2:1 - тело текста */
  --muted:       rgba(255,255,255,.62);        /* 7.3:1  - подписи */
  --dim:         rgba(255,255,255,.48);        /* 4.9:1  - служебное, ниже не опускаемся */

  /* ---------- акцент ---------- */
  --accent:      #4FC4E9;                      /* замер полосы callout эталона */
  --accent-ink:  #9BE0F7;                      /* акцент по тексту: 10.6:1 */
  --accent-soft: rgba(79,196,233,.10);
  --accent-line: rgba(79,196,233,.48);
  --accent-glow: 0 0 18px 2px rgba(79,196,233,.34), 0 0 46px 9px rgba(79,196,233,.12);

  /* ---------- служебные состояния ---------- */
  --up:          #63C6A2;
  --down:        #E5938A;
  --danger:      #E5938A;
  --warn:        #E3C088;

  /* ---------- градиенты эталона ---------- */
  --silver:      linear-gradient(158deg,#FFFFFF 0%,#F4F7FA 26%,#C3CBD5 63%,#98A2AE 100%);
  --silver-num:  linear-gradient(165deg,#FFFFFF 0%,#EFF3F7 34%,#BCC4CF 100%);
  --rule:        linear-gradient(90deg, rgba(255,255,255,.92) 0%,
                                        rgba(255,255,255,.78) 46%,
                                        rgba(255,255,255,0) 100%);

  /* ---------- гарнитуры ----------
     Первой идёт SF Pro Display (канон дома), следом самохостный Golos Text -
     он закрывает кириллицу там, где SF нет (Windows, Android). Моно IBM Plex
     держит служебный слой: капсы-надзаголовки, номера, коды валют, цифры. */
  --font:        "SF Pro Display","SF Pro Text",-apple-system,BlinkMacSystemFont,
                 "Golos Text","Inter","Segoe UI",Arial,sans-serif;
  --font-mono:   "IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* ---------- шкала кегля (пропорции эталона, пересчёт 1920 -> экран) ---------- */
  --fs-eyebrow:  12.5px;   --ls-eyebrow:  .27em;   /* капс эталона */
  --fs-topcaps:  10.5px;   --ls-topcaps:  .42em;   /* верхняя плашка эталона */
  --fs-100:      12px;
  --fs-200:      13px;
  --fs-300:      14.5px;
  --fs-400:      16px;
  --fs-500:      17.5px;
  --fs-600:      clamp(19px, 1.35vw, 22px);
  --fs-700:      clamp(25px, 3vw, 38px);
  --fs-800:      clamp(33px, 4.3vw, 56px);

  --measure:     66ch;
  --measure-tight: 48ch;

  /* ---------- геометрия ----------
     Скругление 6px - замер плашек эталона (4-7px). Пилюль в дом-стиле нет:
     дек держится на прямых углах, кнопки-таблетки его ломали. */
  --r:           6px;
  --r-sm:        4px;
  --bar:         3px;      /* ширина акцентной полосы, ровно 3px */
  --rule-w:      220px;    /* линейка под надзаголовком */
  --rule-h:      3px;

  /* ---------- тайминги ---------- */
  --t-fast:      140ms cubic-bezier(.22,.61,.36,1);
  --t-base:      300ms cubic-bezier(.22,.61,.36,1);
  --t-slow:      560ms cubic-bezier(.16,.84,.44,1);

  /* z-порядок: панели 40 < шапка 60 < шторка 65 < тоггл 70 < модалка 90 */
  --z-side: 40; --z-header: 60; --z-sheet: 65; --z-toggle: 70; --z-modal: 90;

  --maxw: 1180px;
}

/* =========================================================================
   БАЗА
   ========================================================================= */
*,*::before,*::after{ box-sizing:border-box; }

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:88px;
  background:var(--bg);
}

body{
  margin:0;
  background:var(--bg);
  color:var(--body);
  font-family:var(--font);
  font-size:var(--fs-400);
  line-height:1.72;
  font-feature-settings:"liga" 1,"kern" 1;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

h1,h2,h3,h4{ margin:0; font-family:var(--font); line-height:1.1; font-weight:700; letter-spacing:-.03em; text-wrap:balance; color:var(--ink); }
p{ margin:0; text-wrap:pretty; }
ul,ol{ margin:0; padding:0; list-style:none; }
img,svg{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
b,strong{ font-weight:700; color:#EDF1F5; }
code{
  font-family:var(--font-mono); font-size:.88em; color:#E4EAF1;
  background:rgba(255,255,255,.07); border:1px solid var(--line);
  padding:2px 6px; border-radius:var(--r-sm);
}
::selection{ background:rgba(79,196,233,.30); color:#fff; }
:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:var(--r-sm); }

/* =========================================================================
   ФОНОВЫЕ СЛОИ. Ровно как на слайде: два радиальных подъёма к центру плюс
   еле заметная «шлифованная сталь». Сетку-миллиметровку убрали - она давала
   ту самую «грубость», на которую ругался владелец.
   ========================================================================= */
.bg-glow{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(120% 90% at 16% 6%,  var(--bg-lift-1) 0%, rgba(21,22,27,0) 58%),
    radial-gradient(95% 85% at 86% 92%,  var(--bg-lift-2) 0%, rgba(22,24,29,0) 62%);
}
.bg-glow::after{
  content:""; position:absolute; inset:0; opacity:.20;
  background:repeating-conic-gradient(from 0deg at 46% 40%,
    rgba(255,255,255,.012) 0deg, rgba(255,255,255,0) 1.7deg,
    rgba(255,255,255,.012) 3.4deg);
}

/* =========================================================================
   СЕТКА
   ========================================================================= */
.wrap{
  width:100%; max-width:var(--maxw);
  margin:0 auto; padding:0 28px;
  position:relative; z-index:1;
}
.wrap--narrow{ max-width:860px; }

.shell{ position:relative; }
.center{ min-width:0; container-type:inline-size; container-name:center; }
.side{ display:block; }

/* =========================================================================
   ОБЩИЙ МАТЕРИАЛ ПЛАШЕК
   Светлее фона, кромка волосяная, скругление 6. Blur только там, где
   поверхность не скроллится тяжело.
   ========================================================================= */
.calc, .card, .svc, .guard, .step, .honest, .offline, .faq__item,
.trust li, .spot, .qcard, .market, .feed, .modal__dialog, .stats,
.final__inner, .vs__col, .rate-strip{
  position:relative; isolation:isolate;
  background:var(--panel);
  border:1px solid var(--line-2);
  border-radius:var(--r);
}

/* Верхний блик: свет падает сверху, как на плашках эталона. */
.calc::after, .card::after, .svc::after, .guard::after, .step::after,
.honest::after, .offline::after, .spot::after, .qcard::after,
.market::after, .feed::after, .modal__dialog::after, .stats::after,
.final__inner::after, .vs__col::after, .rate-strip::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  border-radius:inherit;
  background:linear-gradient(180deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,0) 38%);
}

/* -------- АКЦЕНТНАЯ ПОЛОСА: главный узнаваемый элемент дом-стиля --------
   Ровно 3px, цвет #4FC4E9, слева, со слабым свечением. Ставится ТОЛЬКО на
   смысловые узлы: калькулятор, наша колонка сравнения, финальный шаг,
   доп. услуги, честные оговорки, офлайн, спотлайт, финальный CTA, модалка. */
.calc::before, .spot::before, .svc::before, .honest::before,
.vs__col--good::before, .step--final::before, .offline::before,
.final__inner::before, .modal__dialog::before, .rate-strip::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:var(--accent);
  box-shadow:var(--accent-glow);
}
/* Серебряная полоса - для блоков рангом ниже: карточки, шаги, гарантии. */
.card::before, .guard::before, .step::before, .stats::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:linear-gradient(180deg, rgba(255,255,255,.72) 0%, rgba(255,255,255,.10) 100%);
}
.step--final::before{ background:var(--accent); box-shadow:var(--accent-glow); }
/* Колонка «обычная биржа» - тёплая полоса, чтобы разница читалась цветом. */
.vs__col--bad::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:linear-gradient(180deg, rgba(229,147,138,.85) 0%, rgba(229,147,138,.12) 100%);
}

/* Подъём на наведении: только transform и кромка. */
.card, .svc, .guard, .step, .qcard{
  transition:transform var(--t-base), border-color var(--t-base), background var(--t-base);
}
.card:hover, .svc:hover, .guard:hover, .step:hover, .qcard:hover{
  transform:translateY(-3px);
  border-color:var(--line-3);
  background:var(--panel-hi);
}

/* =========================================================================
   НАДЗАГОЛОВКИ, ЛИНЕЙКА, СЕРЕБРЯНЫЕ ЗАГОЛОВКИ
   ========================================================================= */
.eyebrow{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--font-mono);
  font-size:var(--fs-eyebrow); font-weight:600; line-height:1;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase;
  color:#E9EEF4;                     /* контраст 16:1, не «серо» */
}
/* Линейка эталона: 220x3, гаснет слева направо. */
.rule{
  margin-top:18px; width:var(--rule-w); max-width:60%;
  height:var(--rule-h); background:var(--rule); border-radius:1px;
}
.rule--short{ width:140px; }

h1, .section__head h2, .final h2, .offline h2{
  background:var(--silver);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* =========================================================================
   ИКОНОЧНАЯ СИСТЕМА
   Одна сетка 24x24, одна толщина штриха, скругления одинаковые. Обводка
   наследуется от .ico, поэтому один символ горит металлом или акцентом
   в зависимости от места, а не дублируется в разметке.
   ========================================================================= */
.ae-defs{ position:absolute; width:0; height:0; overflow:hidden; }
.ico{
  width:24px; height:24px; flex:0 0 auto; fill:none;
  stroke:url(#aeMetal); stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round;
  color:var(--accent);
}
.ico--neon{ stroke:url(#aeNeon); }
.ico--metal{ stroke:url(#aeMetal); }
.ico--rust{ stroke:url(#aeRust); color:var(--danger); }
.ico--sm{ width:20px; height:20px; stroke-width:1.6; }
.ico--xs{ width:14px; height:14px; stroke-width:1.9; }
.btn--primary .ico{ stroke:#04161E; color:#04161E; }
.ico-tg{ flex:0 0 auto; }

/* =========================================================================
   КНОПКИ. Прямоугольные со скруглением 6px - как CTA в деке.
   ========================================================================= */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  height:50px; padding:0 24px;
  border-radius:var(--r); border:1px solid transparent;
  font-family:var(--font); font-size:15px; font-weight:600; letter-spacing:-.006em;
  cursor:pointer; white-space:nowrap;
  transition:transform var(--t-fast), background var(--t-fast),
             border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.btn:active{ transform:translateY(1px); }

/* УСТАРЕЛО с 19.08: правило ниже перекрыто БЛОКОМ 5 в конце файла. Кнопка
   больше НЕ голубая заливка с почти чёрным текстом - это серый градиент,
   уходящий вправо в чёрный, с белым текстом. Значения ниже держатся только
   как запасной слой. Правду смотреть в БЛОКЕ 5 (.btn--primary). */
.btn--primary{
  background:linear-gradient(180deg,#66D2F3 0%,#3EAED6 100%);
  color:#04161E; border-color:rgba(255,255,255,.20); font-weight:700;
  box-shadow:0 0 0 1px rgba(79,196,233,.18), 0 14px 34px -20px rgba(79,196,233,.8);
}
.btn--primary:hover{ background:linear-gradient(180deg,#79DAF7 0%,#4CBBE1 100%); }

/* Вторая по силе - стекло с акцентной кромкой, ровно как CTA деке. */
.btn--tg{
  background:var(--accent-soft); color:var(--ink);
  border-color:var(--accent-line);
}
.btn--tg:hover{ background:rgba(79,196,233,.16); border-color:rgba(79,196,233,.7); }

.btn--ghost{
  background:rgba(255,255,255,.045); color:#EDF1F5; border-color:var(--line-2);
}
.btn--ghost:hover{ background:rgba(255,255,255,.09); border-color:var(--line-3); }

.btn--sm{ height:40px; padding:0 16px; font-size:13.5px; }
.btn--lg{ height:58px; padding:0 32px; font-size:16.5px; }
.btn--full{ display:flex; width:100%; }
/* Длинная подпись («Открыть сделку в Telegram») с nowrap задавала кнопке
   min-content 283px и вместе с паддингами ломала сетку на экранах 320-350px.
   Разрешаем перенос и мягкий разрыв - визуально кнопка та же, но больше не
   диктует ширину всей страницы. */
.btn--full{ white-space:normal; overflow-wrap:anywhere; text-align:center; }

/* =========================================================================
   ШАПКА
   ========================================================================= */
.header{
  position:sticky; top:0; z-index:var(--z-header);
  background:rgba(12,13,17,.72);
  backdrop-filter:blur(16px) saturate(140%);
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  border-bottom:1px solid transparent;
  transition:background var(--t-base), border-color var(--t-base);
}
.header.is-stuck{
  background:rgba(12,13,17,.90);
  border-bottom-color:var(--line);
}
.header__inner{
  max-width:var(--maxw); margin:0 auto; padding:14px 28px;
  display:flex; align-items:center; gap:16px;
}
.header__right{ margin-left:auto; flex:0 0 auto; display:flex; align-items:center; gap:12px; }

.logo{ display:inline-flex; align-items:center; gap:11px; flex:0 0 auto; }
.logo__mark{
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:var(--r);
  background:rgba(255,255,255,.055); border:1px solid var(--line-2);
  position:relative;
}
/* Тонкая акцентная засечка на знаке - тот же приём, что и полоса у блоков. */
.logo__mark::before{
  content:""; position:absolute; left:0; top:6px; bottom:6px; width:2px;
  background:var(--accent); border-radius:2px 0 0 2px;
}
.logo__mark .ico{ width:20px; height:20px; }
.logo__text{
  font-size:16px; font-weight:700; letter-spacing:-.02em; color:var(--ink);
  white-space:nowrap;                /* иначе в тесной шапке ломается на две строки */
}
.logo__text em{
  font-style:normal; font-weight:400; color:var(--muted);
}

.nav{ display:flex; align-items:center; justify-content:flex-end; gap:2px; flex:1 1 auto; min-width:0; }
.nav a{
  padding:8px 8px; border-radius:var(--r-sm); white-space:nowrap;
  font-size:13px; color:var(--muted);
  transition:color var(--t-fast), background var(--t-fast);
}
.nav a:hover{ color:var(--ink); background:rgba(255,255,255,.06); }

/* =========================================================================
   ИНТРО НА ЧАСТИЦАХ
   ========================================================================= */
html.intro-lock, html.intro-lock body{ overflow:hidden; }
.intro{
  position:fixed; inset:0; z-index:120;
  display:grid; place-items:center;
  background:
    radial-gradient(120% 90% at 20% 8%, var(--bg-lift-1) 0%, rgba(21,22,27,0) 58%),
    var(--bg);
  opacity:1; transition:opacity 500ms ease;
}
.intro.is-done{ opacity:0; pointer-events:none; }
.intro__canvas{ position:absolute; inset:0; width:100%; height:100%; }
.intro__logo{
  position:relative; width:230px; max-width:46vw; height:auto;
  opacity:0; transform:scale(.92); transition:opacity 420ms ease, transform 420ms ease;
}
.intro__logo.is-on{ opacity:1; transform:scale(1); }
.intro__caption{
  position:absolute; left:0; right:0; bottom:20%;
  display:flex; flex-direction:column; align-items:center; gap:10px;
  opacity:0; transform:translateY(6px); transition:opacity 380ms ease, transform 380ms ease;
}
.intro__caption.is-on{ opacity:1; transform:none; }
.intro__caption-brand{
  font-size:15px; font-weight:700; letter-spacing:.29em; text-transform:uppercase; color:var(--ink);
}
.intro__caption-curr{
  font-family:var(--font-mono);
  font-size:11.5px; letter-spacing:.42em; text-transform:uppercase; color:var(--muted);
}
.intro__skip{
  position:absolute; right:20px; bottom:20px;
  height:38px; padding:0 16px;
  background:rgba(255,255,255,.05); border:1px solid var(--line-2); border-radius:var(--r);
  color:var(--muted); font-family:var(--font); font-size:13px; cursor:pointer;
  transition:color var(--t-fast), border-color var(--t-fast);
}
.intro__skip:hover{ color:var(--ink); border-color:var(--line-3); }

/* =========================================================================
   ГЕРОЙ
   ========================================================================= */
.hero{ padding:56px 0 32px; }
.hero__grid{ display:grid; grid-template-columns:minmax(0,1fr) 420px; gap:44px; align-items:start; }
/* 🔴 min-width:0 нужен ОБЕИМ колонкам, не только левой. У грид-элемента по
   умолчанию min-width:auto, то есть пол трека равен min-content. У калькулятора
   min-content = 325px (кнопка «Открыть сделку в Telegram» с white-space:nowrap
   даёт 283px плюс паддинги), и на экране 320px он распирал всю страницу: 55
   элементов уезжали за правый край. Замер: scrollWidth 350 при clientWidth 320. */
.hero__copy,
.hero__grid > .calc{ min-width:0; }

.pill{
  display:inline-flex; align-items:center; gap:10px;
  padding:8px 14px; border-radius:var(--r);
  background:rgba(255,255,255,.05); border:1px solid var(--line-2);
  font-size:13px; color:#DDE3EA;
}
.pill__dot{
  width:7px; height:7px; border-radius:50%; background:var(--accent);
  box-shadow:0 0 10px 2px rgba(79,196,233,.6);
}

/* Кегль заголовка считаем от ширины ЦЕНТРАЛЬНОЙ КОЛОНКИ (cqi), а не от окна.
   По vw заголовок раздувался: панели слева и справа съедают до 620px, и
   строка «а не с незнакомцем на бирже» ломалась пополам на 1280px. */
/* Первая строка font-size - страховка для браузеров без единиц cqi:
   они отбросят вторую строку как невалидную и останутся на шкале по vw. */
.hero h1{ margin-top:22px; font-size:var(--fs-800); font-size:clamp(30px, 6.1cqi, 52px); line-height:1.06; }
/* Правило .hero h1 .accent СНЯТО 22.08: оно было мёртвым (перекрыто зоной 1,
   строка ниже по файлу), и две версии одного селектора с разными градиентами
   заставляли читать файл дважды, чтобы понять, какой из них действует. */

/* Ротор смыслов: варианты лежат друг на друге, строка не прыгает. */
.rotor{ margin-top:18px; display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
.rotor__label{
  font-family:var(--font-mono); font-size:var(--fs-100); font-weight:600;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:var(--dim);
}
.rotor__slot{ position:relative; display:block; min-height:1.6em; flex:1 1 260px; }
/* 🔴 Правка 02.09 - ДВОЙНАЯ ПЕЧАТЬ ПОДЗАГОЛОВКА. Снимок мобильной шапки поймал
   момент смены, и в нём читались ДВЕ фразы разом, наложенные друг на друга:
   «живой менеджер, не бот» поверх «крипта заморожена до вашего слова».

   Это не случайность съёмки, а устройство перехода. app.js:554-555 снимает
   is-on с уходящей строки и ставит is-on приходящей В ОДНОМ КАДРЕ, а обе едут
   одинаковые 420ms без задержки. Значит ровно в середине - на 210ms - обе
   строки стоят на opacity около 0.5 и разведены всего на 4px из 8. Высота
   строки 19px, то есть тела перекрываются на две трети. Глаз читает это не
   как движение, а как брак печати. На узком экране хуже всего: там white-space
   nowrap и фразы длинные, поэтому накладываются целые предложения.

   Развожу переход ВО ВРЕМЕНИ вместо того, чтобы играть с прозрачностью.
   Уходящая гаснет первой и быстро (190ms), приходящая ждёт задержку 180ms и
   выезжает за 300ms - к её появлению уходящей на экране уже нет. Общий цикл
   480ms против прежних 420, разница незаметна на интервале 2600ms между
   сменами. Смещение поднято с 8 до 14px: движение теперь читается как
   движение, а не как дрожание. Задержка живёт в БАЗОВОМ правиле, потому что
   его наследует .is-on - у приходящей строки она и должна быть; у .is-out
   переход объявлен заново, без задержки, поэтому гашение стартует мгновенно.

   app.js не трогаю: он снимает is-out через 460ms, а гашение заканчивается на
   190ms - запас есть, и к этому моменту строка уже прозрачна, поэтому возврат
   к базовому состоянию не виден. */
.rotor__slot b{
  position:absolute; left:0; top:0; white-space:nowrap;
  font-size:var(--fs-500); font-weight:600; color:var(--accent-ink);
  opacity:0; transform:translateY(14px);
  transition:opacity 300ms ease 180ms, transform 300ms cubic-bezier(.2,.7,.3,1) 180ms;
}
.rotor__slot b.is-on{ opacity:1; transform:none; }
.rotor__slot b.is-out{
  opacity:0; transform:translateY(-14px);
  transition:opacity 190ms ease, transform 190ms ease;
}

.lead{
  margin-top:20px; max-width:var(--measure);
  font-size:var(--fs-500); line-height:1.75; color:var(--body);
}

.hero__cta{ margin-top:28px; display:flex; flex-wrap:wrap; gap:12px; }

/* Полоса курса: единственное место витрины, где стоят обе цифры. */
.rate-strip{
  margin-top:26px; padding:16px 18px 16px 22px;
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 26px;
}
.rate-strip__item{ display:flex; align-items:baseline; gap:9px; }
.rate-strip__k{
  font-family:var(--font-mono); font-size:var(--fs-100); font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--muted);
}
.rate-strip__v{
  font-family:var(--font-mono); font-size:19px; font-weight:600; letter-spacing:-.01em;
  background:var(--silver-num); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.rate-strip__note{ font-size:var(--fs-200); color:var(--dim); }

.trust{ margin-top:26px; display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.trust li{ padding:14px 16px; }
.trust li b{ display:block; font-size:var(--fs-300); color:var(--ink); }
.trust li span{ display:block; margin-top:3px; font-size:var(--fs-200); color:var(--muted); line-height:1.5; }

/* =========================================================================
   КАЛЬКУЛЯТОР - главный интерактив, поэтому акцентная полоса на нём
   ========================================================================= */
.calc{ padding:26px 24px 24px 28px; }
.calc__head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.calc__title{ font-size:var(--fs-600); letter-spacing:-.02em; color:var(--ink); }
.calc__badge{
  font-family:var(--font-mono); font-size:11px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; color:var(--accent-ink);
  padding:5px 9px; border-radius:var(--r-sm);
  background:var(--accent-soft); border:1px solid var(--accent-line);
}

.seg{
  margin-top:20px; display:grid; grid-template-columns:1fr 1fr; gap:4px;
  padding:4px; border-radius:var(--r);
  background:rgba(255,255,255,.05); border:1px solid var(--line-2);
}
.seg__btn{
  height:40px; border:0; border-radius:var(--r-sm); cursor:pointer;
  background:transparent; color:var(--muted);
  font-family:var(--font-mono); font-size:13px; font-weight:500; letter-spacing:.03em;
  transition:background var(--t-fast), color var(--t-fast);
}
.seg__btn:hover{ color:var(--ink); }
.seg__btn.is-active{
  background:rgba(255,255,255,.13); color:var(--ink); font-weight:600;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.10);
}

.field{ margin-top:16px; }
.field__label{
  display:block; margin-bottom:8px;
  font-family:var(--font-mono); font-size:11.5px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:var(--muted);
}
.field__box{
  display:flex; align-items:center; gap:12px;
  padding:0 16px; height:60px;
  border-radius:var(--r); background:rgba(255,255,255,.05);
  border:1px solid var(--line-2);
  transition:border-color var(--t-fast), background var(--t-fast);
}
.field__box:focus-within{ border-color:var(--accent-line); background:rgba(255,255,255,.07); }
.field__input{
  flex:1 1 auto; min-width:0; width:100%;
  background:transparent; border:0; outline:none;
  font-family:var(--font-mono); font-size:24px; font-weight:600; letter-spacing:-.01em;
  color:var(--ink);
}
.field__input--out{
  background:var(--silver-num); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.field__cur{
  font-family:var(--font-mono); font-size:13px; font-weight:500; letter-spacing:.1em;
  color:#E4EAF1; padding:6px 10px; border-radius:var(--r-sm);
  background:rgba(255,255,255,.07); border:1px solid var(--line-2);
}
.field--out .field__box{ background:rgba(79,196,233,.055); border-color:rgba(79,196,233,.28); }

.swap{
  display:flex; align-items:center; justify-content:center;
  width:40px; height:40px; margin:12px auto -4px;
  border-radius:var(--r); cursor:pointer;
  background:rgba(255,255,255,.06); border:1px solid var(--line-2);
  transition:border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.swap:hover{ background:rgba(79,196,233,.12); border-color:var(--accent-line); transform:rotate(180deg); }

.hint{ margin-top:12px; font-size:var(--fs-200); color:var(--muted); line-height:1.55; }
.hint.is-error{ color:#F0A69C; }

.calc__rate{
  margin-top:16px; padding:14px 16px;
  border-radius:var(--r); background:rgba(255,255,255,.05); border:1px solid var(--line-2);
}
.calc__rate #rateLine{
  display:block; font-family:var(--font-mono); font-size:18px; font-weight:600;
  background:var(--silver-num); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.calc__rate-note{ display:block; margin-top:5px; font-size:var(--fs-100); color:var(--muted); line-height:1.5; }

.calc__kzt{ margin-top:14px; font-size:var(--fs-200); color:var(--muted); line-height:1.6; }
.calc .btn--full{ margin-top:18px; }
.calc__disclaimer{ margin-top:12px; font-size:var(--fs-100); color:var(--dim); line-height:1.55; }

/* =========================================================================
   ПОЛОСА ФАКТОВ (proof strip). Цифры - серебряным градиентом, подписи -
   капсами с трекингом. Ни одной выдуманной величины: всё это условия,
   которые уже описаны ниже на самой странице.
   ========================================================================= */
.proof{ padding:24px 0 4px; }
.stats{
  margin:8px 0 0; padding:26px 24px 24px 30px;
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:24px;
}
.stats > div{ min-width:0; }
.stats .n{
  font-family:var(--font-mono); font-size:clamp(24px,2.6vw,34px); font-weight:600;
  line-height:1; letter-spacing:-.02em; white-space:nowrap;
  background:var(--silver-num); -webkit-background-clip:text; background-clip:text; color:transparent;
}
.stats .l{
  display:block; margin-top:10px;
  font-family:var(--font-mono); font-size:11px; font-weight:500; line-height:1.45;
  letter-spacing:.14em; text-transform:uppercase; color:var(--muted);
}

/* =========================================================================
   СЕКЦИИ
   ========================================================================= */
.section{ padding:76px 0; position:relative; }
.section--alt{
  background:rgba(255,255,255,.018);
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
}
.section__head{ max-width:760px; margin-bottom:38px; }
.section__head h2{ margin-top:22px; font-size:var(--fs-700); font-size:clamp(24px, 4.2cqi, 38px); }
.section__lead{ margin-top:18px; font-size:var(--fs-400); line-height:1.75; color:var(--body); max-width:var(--measure); }

/* =========================================================================
   СРАВНЕНИЕ С БИРЖЕЙ
   ========================================================================= */
.vs{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px; }
.vs__col{ padding:26px 24px 26px 28px; }
.vs__col h3{
  display:flex; align-items:center; gap:12px;
  font-size:var(--fs-600); letter-spacing:-.02em; color:var(--ink);
}
.vs__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:var(--r);
  background:rgba(229,147,138,.10); border:1px solid rgba(229,147,138,.28);
}
.vs__ico--good{ background:var(--accent-soft); border-color:var(--accent-line); }
.vs__col ul{ margin-top:20px; display:grid; gap:12px; }
.vs__col li{
  position:relative; padding-left:28px;
  font-size:var(--fs-300); line-height:1.6; color:var(--body);
}
.vs__col li::before{
  content:""; position:absolute; left:0; top:.42em;
  width:15px; height:15px;
}
/* Маркеры - иконки маской, чтобы не тащить <svg> в каждый пункт списка. */
.vs__col--good li::before{
  background:var(--accent);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.6 9.5 17.6 19.5 7'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.6 9.5 17.6 19.5 7'/%3E%3C/svg%3E") center/contain no-repeat;
}
.vs__col--bad li::before{
  background:var(--danger);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M6 6 18 18M18 6 6 18'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M6 6 18 18M18 6 6 18'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* =========================================================================
   ШАГИ СДЕЛКИ
   Правила прежней сетки 3x2 (.steps/.step/.step__num) сняты 21.08.2026
   вместе с разметкой: раздел «Как проходит сделка» переехал на ленту с
   раскрытием, её стили лежат ниже в блоке 4. Имена .step остались только
   в общих перечислениях материала выше по файлу - там они уже ни на что
   не действуют, ни один элемент страницы этих классов не носит.
   ========================================================================= */

/* =========================================================================
   КАРТОЧКИ ОПЦИЙ И УСЛУГ
   ========================================================================= */
.cards{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
.cards--2{ grid-template-columns:repeat(2,minmax(0,1fr)); }

.card{ padding:26px 24px 26px 28px; display:flex; flex-direction:column; }
.card__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:46px; height:46px; border-radius:var(--r);
  background:rgba(255,255,255,.06); border:1px solid var(--line-2);
}
.card__tag{
  align-self:flex-start; margin-top:18px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:#DFE5EC;
  padding:5px 9px; border-radius:var(--r-sm);
  background:rgba(255,255,255,.07); border:1px solid var(--line-2);
}
.card__tag--accent{ color:var(--accent-ink); background:var(--accent-soft); border-color:var(--accent-line); }
.card h3{ margin-top:14px; font-size:var(--fs-600); }
.card p{ margin-top:12px; font-size:var(--fs-300); line-height:1.65; color:var(--muted); }
.card__for{ margin-top:auto; padding-top:14px; color:#DDE3EA !important; font-weight:500; }

.svc{ padding:28px 26px 28px 30px; display:flex; flex-direction:column; }
.svc__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:48px; height:48px; border-radius:var(--r);
  background:var(--accent-soft); border:1px solid var(--accent-line);
}
.svc h3{ margin-top:18px; font-size:var(--fs-600); }
.svc p{ margin-top:12px; font-size:var(--fs-300); line-height:1.7; color:var(--body); }
/* Нижний отступ вместо отступа у кнопки: кнопка прижата к низу (margin-top:auto),
   поэтому в паре карточек разной длины обе кнопки стоят на одной линии. */
.svc__list{ margin-top:18px; margin-bottom:22px; display:grid; gap:9px; }
.svc__list li{
  position:relative; padding-left:26px;
  font-size:var(--fs-200); line-height:1.55; color:var(--muted);
}
.svc__list li::before{
  content:""; position:absolute; left:0; top:.5em; width:14px; height:2px;
  background:linear-gradient(90deg, var(--accent), rgba(79,196,233,.15));
  border-radius:1px;
}
.svc .btn{ margin-top:auto; }

/* =========================================================================
   ГАРАНТИИ
   ========================================================================= */
.guards{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
.guard{ padding:24px 22px 24px 26px; }
.guard__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px; border-radius:var(--r);
  background:rgba(255,255,255,.06); border:1px solid var(--line-2);
}
.guard h3{ margin-top:16px; font-size:var(--fs-500); }
.guard p{ margin-top:10px; font-size:var(--fs-300); line-height:1.65; color:var(--muted); }
.card__ico .ico, .guard__ico .ico, .svc__ico .ico, .vs__ico .ico{ width:24px; height:24px; }

/* Честная оговорка - блок с акцентной полосой, текст читаемый, не «серо». */
.honest{ margin-top:22px; padding:26px 26px 26px 30px; }
.honest__label{
  display:inline-block;
  font-family:var(--font-mono); font-size:var(--fs-eyebrow); font-weight:600;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:#E9EEF4;
}
.honest p{ margin-top:14px; font-size:var(--fs-300); line-height:1.75; color:var(--body); max-width:var(--measure); }
.honest__cta{ margin-top:20px; display:flex; flex-wrap:wrap; gap:12px; }

/* =========================================================================
   ОФЛАЙН
   ========================================================================= */
.offline{ padding:34px 32px 34px 36px; display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.85fr); gap:32px; align-items:center; }
.offline h2{ margin-top:20px; font-size:var(--fs-700); font-size:clamp(24px, 4cqi, 36px); }
.offline__copy p{ margin-top:16px; font-size:var(--fs-400); line-height:1.75; color:var(--body); }
.offline__rules{ margin-top:20px; display:grid; gap:10px; }
.offline__rules li{
  position:relative; padding-left:26px;
  font-size:var(--fs-300); line-height:1.6; color:var(--muted);
}
.offline__rules li::before{
  content:""; position:absolute; left:0; top:.55em; width:14px; height:2px;
  background:linear-gradient(90deg, var(--accent), rgba(79,196,233,.15)); border-radius:1px;
}
.offline .btn{ margin-top:24px; }
.offline__map-img{
  width:100%; height:auto; border-radius:var(--r);
  border:1px solid var(--line); opacity:.92;
}

/* =========================================================================
   FAQ
   ========================================================================= */
.faq{ display:grid; gap:10px; }
.faq__item{ padding:0; overflow:hidden; }
.faq__item summary{
  list-style:none; cursor:pointer;
  padding:18px 52px 18px 22px; position:relative;
  font-size:var(--fs-400); font-weight:600; color:#EDF1F5; line-height:1.5;
}
.faq__item summary::-webkit-details-marker{ display:none; }
.faq__item summary::after{
  content:""; position:absolute; right:20px; top:50%; width:11px; height:11px;
  margin-top:-6px; border-right:2px solid var(--accent); border-bottom:2px solid var(--accent);
  transform:rotate(45deg); transition:transform var(--t-fast);
}
.faq__item[open] summary::after{ transform:rotate(-135deg); margin-top:-2px; }
.faq__item[open]{ border-color:var(--line-3); background:var(--panel-hi); }
.faq__body{ padding:0 22px 20px; }
.faq__body p{ font-size:var(--fs-300); line-height:1.75; color:var(--body); }
.faq__foot{ margin-top:22px; font-size:var(--fs-200); color:var(--muted); line-height:1.65; }

/* =========================================================================
   ФИНАЛЬНЫЙ CTA
   ========================================================================= */
.final{ padding:20px 0 76px; }
.final__inner{
  padding:34px 32px 34px 36px;
  display:flex; align-items:center; justify-content:space-between; gap:24px; flex-wrap:wrap;
}
.final__copy h2{ margin-top:20px; font-size:var(--fs-700); font-size:clamp(24px, 4cqi, 36px); }
.final__copy p{ margin-top:12px; font-size:var(--fs-400); color:var(--body); }

/* =========================================================================
   ФУТЕР
   ========================================================================= */
.footer{ border-top:1px solid var(--line); padding:52px 0 34px; background:rgba(255,255,255,.014); }
.footer__grid{ display:grid; grid-template-columns:1.4fr 1fr 1fr; gap:32px; }
.footer__brand p{ margin-top:16px; font-size:var(--fs-200); line-height:1.7; color:var(--muted); max-width:36ch; }
.footer__links{ display:flex; flex-direction:column; gap:10px; }
.footer__title{
  font-family:var(--font-mono); font-size:11px; font-weight:600;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:#E9EEF4;
  margin-bottom:4px;
}
.footer__links a{ font-size:var(--fs-200); color:var(--muted); transition:color var(--t-fast); }
.footer__links a:hover{ color:var(--ink); }
.footer__bottom{
  margin-top:38px; padding-top:22px; border-top:1px solid var(--line);
  display:flex; justify-content:space-between; gap:20px; flex-wrap:wrap;
}
.footer__bottom p{ font-size:var(--fs-100); line-height:1.7; color:var(--dim); max-width:76ch; }
.footer__copy{ white-space:nowrap; }

/* 🔴 09.09.2026. Подпись «Разработано в Apollo Production» - flex-basis:100%,
   то есть она ВСЕГДА занимает свою строку и уезжает под юридический текст и
   копирайт. Без этого space-between развёл бы три блока по трём точкам полосы,
   и подпись агентства встала бы вровень с ними - как ещё один равноправный
   пункт, а не как отметка автора. Отбивка сверху 16px и цвет --dim держат её
   тише всего остального: это пометка, а не строка меню. */
.footer__made{
  flex-basis:100%; margin-top:16px;
  display:flex; align-items:center; gap:8px;
  font-size:var(--fs-100); color:var(--dim);
}
.footer__made-mark{ width:16px; height:16px; opacity:.72; flex:none; }
.footer__made a{ color:var(--muted); transition:color var(--t-fast); }
.footer__made a:hover{ color:var(--ink); }

/* =========================================================================
   БОКОВЫЕ ПАНЕЛИ
   ========================================================================= */
.panel__head{ display:flex; align-items:center; gap:10px; padding:16px 16px 12px; }
.panel__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; border-radius:var(--r-sm);
  background:rgba(255,255,255,.06); border:1px solid var(--line-2);
}
.panel__ico .ico{ width:16px; height:16px; }
.panel__title{
  font-family:var(--font-mono); font-size:11px; font-weight:600;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:#E9EEF4;
}

/* ---- Спотлайт услуг ---- */
.spot{ padding:16px 14px 16px 18px; }
.spot__top{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.spot__eyebrow{
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:var(--ls-topcaps); text-transform:uppercase; color:#E9EEF4;
}
.spot__dots{ display:flex; gap:5px; }
.spot__dot{
  width:6px; height:6px; padding:0; border:0; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,.22); transition:background var(--t-fast), transform var(--t-fast);
}
.spot__dot.is-on{ background:var(--accent); transform:scale(1.25); box-shadow:0 0 9px 1px rgba(79,196,233,.55); }
.spot__stage{ position:relative; margin-top:14px; min-height:236px; }
.spot__card{
  position:absolute; inset:0; display:flex; flex-direction:column;
  opacity:0; transform:translateY(8px); pointer-events:none;
  transition:opacity 260ms ease, transform 260ms ease;
}
/* Входящая карточка стартует с задержкой: иначе обе услуги полсекунды
   лежат друг на друге в полную силу и текст читается как каша. */
.spot__card.is-on{ opacity:1; transform:none; pointer-events:auto; transition-delay:200ms; }
.spot__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:var(--r);
  background:var(--accent-soft); border:1px solid var(--accent-line);
}
.spot__ico .ico{ width:22px; height:22px; }
.spot__title{ margin-top:14px; font-size:15.5px; line-height:1.3; letter-spacing:-.02em; color:var(--ink); }
.spot__desc{ margin-top:10px; font-size:var(--fs-100); line-height:1.6; color:var(--muted); }
.spot__cta{
  margin-top:auto; padding-top:14px; display:inline-flex; align-items:center; gap:7px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; color:var(--accent-ink);
}
.spot__cta .ico{ width:14px; height:14px; transition:transform var(--t-fast); }
.spot__card:hover .spot__cta .ico{ transform:translateX(3px); }

/* ---- Быстрые разделы ---- */
.qnav{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
.qcard{ display:flex; flex-direction:column; gap:9px; padding:13px 12px; }
.qcard__ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:var(--r-sm);
  background:rgba(255,255,255,.06); border:1px solid var(--line-2);
}
.qcard__ico .ico{ width:17px; height:17px; }
.qcard__t{ font-size:12.5px; font-weight:600; color:#E4EAF1; }

/* ---- Крипторынок ---- */
.market__list{ padding:4px 10px 12px; display:grid; gap:2px; }
.mrow{
  display:grid; grid-template-columns:auto 1fr auto; grid-template-areas:
    "sym name price" "pair pair chg";
  gap:2px 10px; align-items:baseline;
  padding:10px; border-radius:var(--r-sm);
  transition:background var(--t-fast);
}
.mrow:hover{ background:rgba(255,255,255,.05); }
.mrow__sym{ grid-area:sym; font-family:var(--font-mono); font-size:13px; font-weight:600; color:var(--ink); }
.mrow__name{ grid-area:name; font-size:11.5px; color:var(--dim); }
.mrow__pair{ grid-area:pair; font-family:var(--font-mono); font-size:10.5px; letter-spacing:.08em; color:var(--dim); }
.mrow__price{
  grid-area:price; justify-self:end;
  font-family:var(--font-mono); font-size:13.5px; font-weight:600; color:#EDF1F5;
}
.mrow__price[data-placeholder]{ color:var(--dim); font-weight:500; }
.mrow__chg{
  grid-area:chg; justify-self:end;
  font-family:var(--font-mono); font-size:11px; color:var(--muted);
}
.mrow__chg.is-up{ color:var(--up); }
.mrow__chg.is-down{ color:var(--down); }
.market__stamp{
  margin-left:auto; font-family:var(--font-mono); font-size:10px;
  letter-spacing:.06em; color:var(--dim); text-align:right;
}
.market__stamp:not([data-placeholder]){ color:var(--accent-ink); }

/* ---- Лента ---- */
.feed__list{ padding:4px 10px 12px; display:grid; gap:6px; }
.fcard{
  display:flex; flex-direction:column; gap:7px; width:100%; text-align:left;
  padding:12px; border-radius:var(--r-sm); cursor:pointer;
  background:transparent; border:1px solid transparent;
  font-family:var(--font);
  transition:background var(--t-fast), border-color var(--t-fast);
}
.fcard:hover{ background:rgba(255,255,255,.055); border-color:var(--line-2); }
.fcard__kicker{
  font-family:var(--font-mono); font-size:9.5px; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:var(--accent-ink);
}
.fcard__title{ font-size:12.5px; line-height:1.5; color:#DDE3EA; }
.fcard__more{
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--dim);
}
.fcard__more .ico{ width:13px; height:13px; }
.fcard:hover .fcard__more{ color:var(--muted); }

/* ---- Мобильный тоггл рынка ---- */
.panel-toggle{
  display:none; position:fixed; right:16px; bottom:88px; z-index:var(--z-toggle);
  align-items:center; gap:8px; height:44px; padding:0 16px;
  border-radius:var(--r); cursor:pointer;
  background:rgba(12,13,17,.92); border:1px solid var(--accent-line);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  color:#EDF1F5; font-family:var(--font); font-size:13px; font-weight:600;
}
.panel-toggle .ico{ width:17px; height:17px; }

/* =========================================================================
   МОДАЛКА
   ========================================================================= */
.modal{ position:fixed; inset:0; z-index:var(--z-modal); display:grid; place-items:center; padding:24px; }
.modal[hidden]{ display:none; }
.modal__backdrop{ position:absolute; inset:0; background:rgba(6,7,10,.78); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.modal__dialog{
  position:relative; width:min(640px,100%); max-height:82vh; overflow-y:auto;
  padding:30px 30px 28px 34px;
  background:linear-gradient(103deg, rgba(30,32,38,.98) 0%, rgba(22,24,29,.98) 100%);
  border:1px solid var(--line-2);
  box-shadow:0 40px 90px -40px rgba(0,0,0,.9);
}
.modal__close{
  position:absolute; right:16px; top:16px;
  display:flex; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:var(--r-sm); cursor:pointer;
  background:rgba(255,255,255,.06); border:1px solid var(--line-2); color:#E4EAF1;
  transition:background var(--t-fast), border-color var(--t-fast);
}
.modal__close:hover{ background:rgba(255,255,255,.12); border-color:var(--line-3); }
.modal__eyebrow{
  display:inline-block;
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:var(--ls-eyebrow); text-transform:uppercase; color:var(--accent-ink);
}
.modal__title{ margin-top:14px; font-size:var(--fs-600); line-height:1.28; color:var(--ink); }
.modal__body{ margin-top:16px; display:grid; gap:12px; }
.modal__body p{ font-size:var(--fs-300); line-height:1.75; color:var(--body); }
.modal__note{
  margin-top:20px; padding:14px 16px; border-radius:var(--r);
  background:rgba(255,255,255,.05); border:1px solid var(--line-2);
  font-size:var(--fs-100); line-height:1.65; color:var(--muted);
}

/* =========================================================================
   ПОЯВЛЕНИЕ БЛОКОВ
   ========================================================================= */
.reveal{ opacity:0; transform:translateY(14px); transition:opacity var(--t-slow), transform var(--t-slow); }
.reveal.is-visible{ opacity:1; transform:none; }

/* =========================================================================
   ОБОЛОЧКА: три колонки на широком экране
   Панели переключаются по ШИРИНЕ ОКНА, содержимое центра - по своей
   ширине через @container. Поэтому узкие панели на 1200-1360 не ломают центр.
   ========================================================================= */
@media (min-width:1200px){
  .shell{ display:grid; grid-template-columns:250px minmax(0,1fr) 270px; align-items:start; }
  .side{
    position:sticky; top:0; align-self:start;
    height:100vh; overflow-y:auto; overflow-x:hidden; z-index:var(--z-side);
    scrollbar-width:thin; scrollbar-color:rgba(255,255,255,.14) transparent;
  }
  .side::-webkit-scrollbar{ width:8px; }
  .side::-webkit-scrollbar-thumb{
    background:rgba(255,255,255,.12); border-radius:8px;
    border:2px solid transparent; background-clip:content-box;
  }
  .side__inner{ min-height:100%; display:flex; flex-direction:column; gap:12px; padding:82px 14px 20px; }
  .side--left .side__inner{ padding-left:16px; }
  .side--right .side__inner{ padding-right:16px; }
}
@media (min-width:1400px){
  .shell{ grid-template-columns:300px minmax(0,1fr) 320px; }
  .side__inner{ padding-left:18px; padding-right:18px; }
}

/* =========================================================================
   ПЕРЕСТРОЙКА ЦЕНТРА ПО СОБСТВЕННОЙ ШИРИНЕ (@container)
   ========================================================================= */
@container center (max-width:1080px){
  .hero__grid{ grid-template-columns:1fr; gap:32px; }
  .calc{ max-width:520px; }
  .offline{ grid-template-columns:1fr; }
  .offline__map-img{ order:-1; }
}
@container center (max-width:900px){
  .steps, .guards, .cards{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .stats{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .footer__grid{ grid-template-columns:1fr 1fr; }
}
/* Меню в шапке считаем по ширине ЦЕНТРА, а не окна: при живых боковых панелях
   центру остаётся около 760px. Ниже 790 шесть пунктов уже не помещаются рядом
   с логотипом и кнопкой, поэтому меню уходит - навигацию в этот момент держит
   левая панель быстрых разделов и подвал. */
@container center (max-width:790px){
  .nav{ display:none; }
}
@container center (max-width:680px){
  .vs, .steps, .guards, .cards, .cards--2{ grid-template-columns:1fr; }
  .trust{ grid-template-columns:1fr; }
  .footer__grid{ grid-template-columns:1fr; }
  .final__inner{ flex-direction:column; align-items:flex-start; }
  .final .btn{ width:100%; }
}

/* =========================================================================
   МОБИЛЬНАЯ ОБОЛОЧКА (<1200): левая панель уходит вниз, правая - в шторку
   ========================================================================= */
@media (max-width:1199px){
  .side--left{
    position:static; height:auto;
  }
  .side--left .side__inner{ padding:0; }
  .side--left .spot{ display:none; }          /* спотлайт дублирует секцию услуг */
  .side--left .qnav{
    position:fixed; left:0; right:0; bottom:0; z-index:var(--z-sheet);
    grid-template-columns:repeat(6,minmax(0,1fr)); gap:0;
    padding:8px 6px calc(8px + env(safe-area-inset-bottom));
    background:rgba(12,13,17,.94); border-top:1px solid var(--line-2);
    backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  }
  .qcard{
    background:none; border:0; align-items:center; gap:5px; padding:6px 2px;
    border-radius:var(--r-sm);
  }
  .qcard::after, .qcard::before{ display:none; }
  .qcard:hover{ transform:none; background:rgba(255,255,255,.06); }
  .qcard__ico{ width:26px; height:26px; }
  .qcard__ico .ico{ width:15px; height:15px; }
  .qcard__t{ font-size:10px; letter-spacing:.01em; }

  .side--right{
    position:fixed; top:0; right:0; bottom:0; width:min(340px,88vw); z-index:var(--z-sheet);
    transform:translateX(102%); transition:transform var(--t-base);
    background:rgba(12,13,17,.97); border-left:1px solid var(--line-2);
    overflow-y:auto;
    backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  }
  .side--right.is-open{ transform:none; }
  .side--right .side__inner{ display:flex; flex-direction:column; gap:12px; padding:20px 14px 96px; }

  .panel-toggle{ display:inline-flex; }
  body{ padding-bottom:74px; }               /* место под нижнюю панель */
}

/* =========================================================================
   УЗКИЙ ЭКРАН
   ========================================================================= */
@media (max-width:900px){
  .nav{ display:none; }
  .header__inner{ padding:12px 20px; }
  .wrap{ padding:0 20px; }
  .section{ padding:56px 0; }
  .hero{ padding:36px 0 24px; }
}
@media (max-width:620px){
  .hero h1{ font-size:clamp(28px,7.6vw,38px); }
  .calc{ padding:22px 18px 22px 22px; }
  .stats{ grid-template-columns:1fr 1fr; padding:22px 18px 20px 22px; }
  .offline, .final__inner, .honest, .modal__dialog{ padding-left:22px; padding-right:18px; }
  .rate-strip{ gap:10px 18px; }
  .field__input{ font-size:21px; }
  .footer__bottom{ flex-direction:column; }
}

/* =========================================================================
   ДОСТУПНОСТЬ И ПЕЧАТЬ
   ========================================================================= */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
  html{ scroll-behavior:auto; }
  .reveal{ opacity:1; transform:none; }
}
@media print{
  .side, .panel-toggle, .intro, .bg-glow, .modal{ display:none !important; }
  body{ background:#fff; color:#000; }
}

/* 🔴 Узкий брейкпоинт вернули: в прежнем файле был @media (max-width:400px),
   при переписывании с нуля он потерялся, и самым узким остался 620px.
   На 320-360px (iPhone SE, старые Android) это давало горизонтальную
   прокрутку и обрезанный текст. */
@media (max-width:400px){
  .wrap{ padding-left:14px; padding-right:14px; }
  /* Кнопка «Обменять» в шапке вылезала за правый край на 10px (замер: right=330
     при экране 320). Ужимаем подпись и паддинги - на широких экранах не влияет. */
  .header__cta{ padding-left:10px; padding-right:10px; font-size:12px; letter-spacing:0; }
  .header__right{ gap:6px; min-width:0; }
  .calc{ padding:18px 14px 18px 17px; }
  .svc{ padding:20px 16px 20px 19px; }
  h1{ font-size:clamp(26px,8vw,34px); }
  .rotor__slot b{ white-space:normal; }
  .rotor__slot{ min-height:3.1em; }
}

/* =========================================================================
   ═══ БЛОК 2: ФОН-СОЗВЕЗДИЕ (начало) ═══
   Холст с редкой сеткой точек на первом экране. Рисование - в app.js.
   Здесь только геометрия слоя и его подчинённость контенту.
   ========================================================================= */

/* Герою нужен свой контекст позиционирования: холст растягиваем по нему.
   Раньше .hero был статичным, и absolute-слой цеплялся бы за .shell,
   растекаясь на всю страницу. z-index не задаём: контент внутри уже лежит
   в .wrap с z-index:1, поэтому холсту хватает z-index:0. */
.hero{ position:relative; isolation:isolate; }

.cnst{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%;
  display:block;
  pointer-events:none;          /* курсор и клики уходят сквозь слой в калькулятор */
  /* Края гасим маской, иначе точки обрубаются ровной линией по краю секции
     и слой читается как «прямоугольник поверх фона», а не как глубина. */
  -webkit-mask-image:radial-gradient(115% 92% at 50% 42%, #000 34%, rgba(0,0,0,.55) 68%, transparent 100%);
          mask-image:radial-gradient(115% 92% at 50% 42%, #000 34%, rgba(0,0,0,.55) 68%, transparent 100%);
  /* Плавное проявление после первого кадра: без этого при загрузке видно,
     как точки «прыгают» из стартовых координат. Класс ставит app.js. */
  opacity:0; transition:opacity .9s ease;
}
.cnst.is-live{ opacity:1; }

/* Слой чисто декоративный: при печати он только жрёт тонер. */
@media print{ .cnst{ display:none !important; } }

/* Уважение к системной настройке дублируем и в CSS: даже если JS почему-то
   не отработает ветку статики, слой не будет мигать прозрачностью. */
@media (prefers-reduced-motion: reduce){
  .cnst{ transition:none; }
}
/* ═══ БЛОК 2: ФОН-СОЗВЕЗДИЕ (конец) ═══ */


/* =========================================================================
   БЛОК 4: ЛЕНТА ШАГОВ СДЕЛКИ С РАСКРЫТИЕМ  ==== НАЧАЛО ====
   (переделано 21.08.2026, секция #how. До этого здесь была дуга-карусель)

   ЗАЧЕМ ПЕРЕДЕЛАНО. Дуга ставила шесть карточек по эллипсу внахлёст: соседи
   резали текст активного шага, рядом оказывались номера 06 и 01, а порядок
   сделки по такой картинке не читался вообще. Владелец назвал это прямо.

   ЧТО ВМЕСТО. Вертикальная лента: шесть строк сверху вниз, крупный номер на
   рейке слева, между номерами тянется соединитель - очередь видно физически,
   без единого трюка. Подробности каждого шага лежат внутри строки и
   раскрываются по нажатию, поэтому раздел не превращается в простыню, но и
   ничего не прячет насовсем.

   ПРИНЦИПЫ, КОТОРЫЕ ЗДЕСЬ СОБЛЮДЕНЫ:
   - материал строки взят у карточек страницы (--z3-*): одна плоская заливка,
     волосяная граница, размытие подложки. Значения продублированы запасными
     в var(), чтобы блок пережил переименование токенов в соседней зоне;
   - акцент #4FC4E9 точечный: полоса 3px слева только у РАСКРЫТОЙ строки,
     подпись «что нужно от вас» и рейка до текущего шага. Больше нигде;
   - без JS (нет класса .is-ready) панели раскрыты и читаются как обычный
     текст, кнопки управления скрыты - страница не ломается;
   - раскрытие идёт через grid-template-rows 0fr -> 1fr: высота не задаётся
     руками, значит текст любой длины не обрежется и не оставит дыру;
   - при prefers-reduced-motion переходы сняты полностью, панель открывается
     мгновенно (см. конец блока).

   КОНТРАСТ (поверхность = 3% белого поверх подсвеченного центра, худший
   край rgb(28,29,34)):
     #EDF1F5 заголовок строки   15.3:1
     #D6DBE3 вводный абзац      11.9:1
     #B3BAC5 текст подробностей  8.6:1
     #9CA3AF подписи-капсы       6.6:1
     #9BE0F7 акцент по тексту   11.5:1
   Номер шага помечен aria-hidden и работает как графика, его порядок и так
   озвучен списком <ol>, поэтому к нему применяется планка графики (3:1).
   ========================================================================= */

.flow{
  /* Колонка номера. Одно число задаёт и ширину колонки, и посадку рейки,
     поэтому соединитель между шагами не может разъехаться с цифрой. */
  --flow-num:       clamp(52px, 5.2vw, 80px);
  --flow-pad-x:     24px;
  --flow-gap:       10px;
  /* Пружина: небольшой перелёт в конце, чтобы панель «вставала на место»,
     а не подъезжала линейно. Закрытие идёт другой кривой, без перелёта -
     схлопывание с отскоком читается как сбой. */
  --flow-spring:    cubic-bezier(.22, 1.14, .32, 1);
  --flow-out:       cubic-bezier(.4, 0, .2, 1);

  --flow-surface:    var(--z3-surface,    rgba(255,255,255,.030));
  --flow-surface-hi: var(--z3-surface-hi, rgba(255,255,255,.055));
  --flow-line:       var(--z3-line,       rgba(255,255,255,.085));
  --flow-line-hi:    var(--z3-line-hi,    rgba(255,255,255,.165));
  --flow-r:          var(--z3-r-card,     14px);
  --flow-mut:        var(--z3-mut,        #9CA3AF);
  --flow-body:       var(--z3-body,       #B3BAC5);

  position:relative;
}

/* ---------- строка подсказки и кнопка «раскрыть все» ---------- */
.flow__bar{
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; flex-wrap:wrap;
  margin-bottom:18px;
}
.flow__hint{
  margin:0;
  font-size:var(--fs-200);
  color:var(--flow-mut);
}
/* Кнопка служебная, значит служебная же гарнитура: моно и капсы с трекингом,
   как у надзаголовков дома. Заливки нет - она не должна спорить с шагами. */
.flow__all{
  display:inline-flex; align-items:center; gap:10px;
  padding:9px 14px;
  font-family:var(--font-mono);
  font-size:var(--fs-100);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--flow-mut);
  background:none;
  border:1px solid var(--flow-line);
  border-radius:var(--z3-r-inner, 10px);
  cursor:pointer;
  transition:color var(--t-base), border-color var(--t-base), background var(--t-base);
}
.flow__all:hover{
  color:var(--accent-ink);
  border-color:var(--accent-line);
  background:var(--accent-soft);
}
.flow__all:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.flow__all-ico{
  width:9px; height:9px; flex:0 0 auto;
  border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor;
  transform:translateY(-2px) rotate(45deg);
  transition:transform 420ms var(--flow-spring);
}
.flow__all[aria-expanded="true"] .flow__all-ico{ transform:translateY(1px) rotate(225deg); }

/* ---------- сама лента ---------- */
.flow__list{
  list-style:none; margin:0; padding:0;
  display:grid; gap:var(--flow-gap);
}

.flow__item{
  position:relative;
  background:var(--flow-surface);
  border:1px solid var(--flow-line);
  border-radius:var(--flow-r);
  box-shadow:var(--z3-rim, inset 0 1px 0 rgba(255,255,255,.06)),
             var(--z3-shadow, 0 18px 40px -32px rgba(0,0,0,.92));
  transition:border-color var(--t-base), background var(--t-base), box-shadow var(--t-base);
}
/* За плашками лежит фон-созвездие: без размытия точки видно сквозь строку
   резко, и она перестаёт читаться отдельным слоем. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .flow__item{
    backdrop-filter:var(--z3-blur, blur(12px) saturate(118%));
    -webkit-backdrop-filter:var(--z3-blur, blur(12px) saturate(118%));
  }
}
.flow__item:hover{
  background:var(--flow-surface-hi);
  border-color:var(--flow-line-hi);
}
.flow__item.is-open{
  background:var(--flow-surface-hi);
  border-color:var(--flow-line-hi);
  box-shadow:var(--z3-rim, inset 0 1px 0 rgba(255,255,255,.06)),
             var(--z3-shadow-hi, 0 24px 48px -28px rgba(0,0,0,.95));
}

/* Акцентная полоса 3px слева - узнаваемый приём дома. Здесь она НЕ постоянная:
   загорается только у раскрытой строки, то есть отмечает, где вы сейчас. */
.flow__item::before{
  content:""; position:absolute; left:0; top:14px; bottom:14px;
  width:var(--bar, 3px);
  border-radius:3px;
  background:var(--z3-bar, var(--accent));
  box-shadow:var(--z3-glow, 0 0 10px 0 rgba(79,196,233,.42));
  opacity:0;
  transform:scaleY(.35);
  transition:opacity 260ms var(--flow-out), transform 460ms var(--flow-spring);
  pointer-events:none;
}
.flow__item.is-open::before{ opacity:1; transform:none; }

/* Соединитель между номерами. Высота ровно равна зазору списка, поэтому
   линия не может ни повиснуть в воздухе, ни налезть на соседнюю строку. */
.flow__item::after{
  content:""; position:absolute;
  left:calc(var(--flow-pad-x) + var(--flow-num) / 2);
  top:100%; width:1px; height:var(--flow-gap);
  background:rgba(255,255,255,.14);
  transition:background var(--t-base), box-shadow var(--t-base);
  pointer-events:none;
}
.flow__list > .flow__item:last-child::after{ display:none; }
/* Рейка горит до текущего шага: это единственное место, где акцент говорит
   «вы вот здесь по очереди», и он же гаснет при закрытии всех строк. */
.flow__item.is-lit::after{
  background:var(--accent);
  box-shadow:0 0 8px 0 rgba(79,196,233,.45);
}

/* ---------- шапка строки: она же кнопка ---------- */
.flow__h{ margin:0; font-size:inherit; font-weight:inherit; }

.flow__head{
  display:grid;
  grid-template-columns:var(--flow-num) 44px minmax(0,1fr) auto auto;
  align-items:center;
  gap:0 16px;
  width:100%;
  margin:0;
  padding:18px var(--flow-pad-x);
  font:inherit; color:inherit; text-align:left;
  background:none; border:0;
  border-radius:var(--flow-r);
  cursor:pointer;
}
.flow__head:focus-visible{ outline:2px solid var(--accent); outline-offset:-3px; }

/* Номер - главный графический элемент раздела: крупная моноширинная цифра,
   а не мелкая подпись. В покое приглушён, у раскрытой строки берёт
   серебряный градиент дома. */
.flow__num{
  width:var(--flow-num);
  font-family:var(--font-mono);
  font-size:clamp(30px, 3.4vw, 50px);
  font-weight:500;
  line-height:.92;
  letter-spacing:-.05em;
  font-variant-numeric:tabular-nums;
  color:rgba(255,255,255,.34);
  transition:color 300ms var(--flow-out);
}
.flow__head:hover .flow__num{ color:rgba(255,255,255,.58); }
.flow__item.is-open .flow__num{
  color:transparent;
  background:var(--z3-title, linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 38%,#C3CBD5 100%));
  -webkit-background-clip:text;
          background-clip:text;
  -webkit-text-fill-color:transparent;
}

/* Значок ведёт себя как значки карточек зоны 3: коробка 44, штрих от текста. */
.flow__ico{
  width:44px; height:44px;
  display:grid; place-items:center;
  background:rgba(255,255,255,.045);
  border:1px solid var(--flow-line);
  border-radius:var(--z3-r-ico, 12px);
  color:#E6EAF0;
  transition:color var(--t-base), border-color var(--t-base), background var(--t-base);
}
.flow__ico .ico{
  width:22px; height:22px;
  color:inherit; stroke:currentColor; stroke-width:1.5;
}
.flow__item.is-open .flow__ico{
  color:var(--accent-ink);
  border-color:var(--accent-line);
  background:var(--accent-soft);
}

.flow__title{
  min-width:0;
  font-size:clamp(16.5px, 1.2vw, 19px);
  font-weight:600;
  line-height:1.35;
  letter-spacing:-.015em;
  color:#EDF1F5;
}

/* Метка шага. Дублирует суть подробностей одним словом, поэтому помечена
   aria-hidden: озвучивать её отдельно нечего, текст есть внутри панели. */
.flow__chip{
  font-family:var(--font-mono);
  font-size:10.5px;
  letter-spacing:.16em;
  text-transform:uppercase;
  white-space:nowrap;
  color:var(--flow-mut);
  padding:6px 10px;
  border:1px solid var(--flow-line);
  border-radius:8px;
  transition:color var(--t-base), border-color var(--t-base), background var(--t-base);
}
/* Метка при раскрытии только светлеет, но НЕ становится акцентной. В одной
   строке уже горят полоса, значок и уголок; четвёртый голубой элемент
   превращал акцент из указателя в заливку. */
.flow__item.is-open .flow__chip{
  color:#E6EAF0;
  border-color:var(--flow-line-hi);
}

/* Уголок. Тот же приём, что у вопросов внизу страницы: квадрат с двумя
   границами, повёрнутый на 45deg. Открытая строка разворачивает его вверх. */
.flow__chev{
  width:34px; height:34px;
  display:grid; place-items:center;
  color:var(--flow-mut);
  border:1px solid transparent;
  border-radius:var(--z3-r-inner, 10px);
  transition:transform 460ms var(--flow-spring), color var(--t-base),
             border-color var(--t-base), background var(--t-base);
}
.flow__chev::before{
  content:"";
  width:9px; height:9px;
  border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor;
  transform:translateY(-2px) rotate(45deg);
}
.flow__head:hover .flow__chev{
  color:#E6EAF0;
  border-color:var(--flow-line);
  background:rgba(255,255,255,.04);
}
.flow__item.is-open .flow__chev{
  transform:rotate(180deg);
  color:var(--accent-ink);
  border-color:var(--accent-line);
  background:var(--accent-soft);
}

/* ---------- раскрывающаяся панель ----------
   0fr -> 1fr: браузер сам считает нужную высоту, поэтому текст любой длины
   раскрывается целиком. Высота руками (max-height) либо резала бы длинный
   шаг 06, либо оставляла пустоту под коротким шагом 02. */
.flow__panel{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows 520ms var(--flow-spring);
}
.flow__item.is-open .flow__panel{ grid-template-rows:1fr; }
.flow__clip{ overflow:hidden; min-height:0; }

/* Содержимое подъезжает чуть позже коробки: сначала открывается место,
   потом в него въезжает текст. Обратный порядок читается как рывок. */
/* Отступ слева считается по колонкам шапки, а не «на глаз»: номер, зазор,
   значок, зазор. Тогда первая буква абзаца стоит ровно под первой буквой
   заголовка, и раскрытие не выглядит съехавшим. */
.flow__body{
  padding:2px var(--flow-pad-x) 24px calc(var(--flow-pad-x) + var(--flow-num) + 16px + 44px + 16px);
  opacity:0;
  transform:translateY(-8px);
  transition:opacity 200ms var(--flow-out), transform 260ms var(--flow-out);
}
.flow__item.is-open .flow__body{
  opacity:1;
  transform:none;
  transition:opacity 320ms var(--flow-out) 110ms, transform 460ms var(--flow-spring) 90ms;
}

.flow__lead{
  margin:0;
  max-width:62ch;
  font-size:var(--fs-400);
  line-height:1.7;
  color:#D6DBE3;
}

.flow__meta{ margin:18px 0 0; display:grid; gap:0; }
.flow__row{
  display:grid;
  grid-template-columns:minmax(0,180px) minmax(0,1fr);
  gap:4px 22px;
  align-items:baseline;
  padding:13px 0 0;
  margin-top:13px;
  border-top:1px solid rgba(255,255,255,.07);
}
.flow__row dt{
  font-family:var(--font-mono);
  font-size:var(--fs-100);
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--flow-mut);
}
/* Единственная акцентная подпись в панели: то, что требуется ОТ ЧЕЛОВЕКА.
   Всё остальное делаем мы, и выделять это цветом незачем. */
.flow__row--you dt{ color:var(--accent-ink); }
.flow__row dd{
  margin:0;
  max-width:62ch;
  font-size:var(--fs-300);
  line-height:1.7;
  color:var(--flow-body);
}

/* ---------- страховка на случай выключенного JS ----------
   Класс .is-ready ставит app.js. Пока его нет, схлопывать нечем: панели
   открыты, управление спрятано, раздел читается как обычный текст. */
.flow:not(.is-ready) .flow__panel{ grid-template-rows:1fr; }
.flow:not(.is-ready) .flow__body{ opacity:1; transform:none; }
.flow:not(.is-ready) .flow__bar,
.flow:not(.is-ready) .flow__chev{ display:none; }
.flow:not(.is-ready) .flow__head{ cursor:default; }

/* ---------- узкий экран ----------
   Считаем по колонке .center, как и вся сетка файла: при открытых боковых
   панелях окно широкое, а колонке остаётся ~760px, и мерить по окну нельзя. */
@container center (max-width:680px){
  .flow{ --flow-num:44px; --flow-pad-x:18px; }
  .flow__head{ grid-template-columns:var(--flow-num) 40px minmax(0,1fr) auto; gap:0 13px; padding:16px var(--flow-pad-x); }
  .flow__ico{ width:40px; height:40px; }
  .flow__chip{ display:none; }        /* метка дублирует текст панели, ею и жертвуем */
  .flow__num{ font-size:30px; }
  .flow__body{ padding-left:calc(var(--flow-pad-x) + var(--flow-num) + 13px + 40px + 13px); }
  .flow__row{ grid-template-columns:minmax(0,1fr); gap:6px; }
}

@container center (max-width:460px){
  .flow{ --flow-num:36px; --flow-pad-x:15px; }
  .flow__head{ grid-template-columns:var(--flow-num) minmax(0,1fr) auto; gap:0 12px; }
  .flow__ico{ display:none; }         /* при 320px значок съедает половину строки заголовка */
  .flow__num{ font-size:26px; }
  .flow__title{ font-size:16px; }
  .flow__chev{ width:30px; height:30px; }
  .flow__body{ padding:2px var(--flow-pad-x) 20px var(--flow-pad-x); }
  .flow__bar{ gap:10px; }
  .flow__hint{ font-size:12px; }
}

/* ---------- движение по желанию пользователя ----------
   Глобальное правило файла сокращает ДЛИТЕЛЬНОСТЬ, но панель всё равно
   выезжала бы со сдвигом. Здесь переходы сняты совсем: нажал - открылось. */
@media (prefers-reduced-motion:reduce){
  .flow__panel,
  .flow__body,
  .flow__item,
  .flow__item::before,
  .flow__item::after,
  .flow__num,
  .flow__ico,
  .flow__chip,
  .flow__chev,
  .flow__all,
  .flow__all-ico{ transition:none; }
  .flow__item.is-open .flow__body{ transition:none; }
  .flow__body{ transform:none; }
}
/* ==== БЛОК 4: ЛЕНТА ШАГОВ СДЕЛКИ - КОНЕЦ ==== */

/* =========================================================================
   ==== БЛОК 3: СЕТКА ВОЗМОЖНОСТЕЙ «ПОЧЕМУ ЧЕРЕЗ НАС» - НАЧАЛО ====

   Крупная сетка карточек сразу после первого экрана. Материал плашки тот же,
   что у остальных блоков (белый с малой альфой поверх тёмного фона, кромка
   волосяная, скругление 6px), но карточка здесь ЖИВАЯ, а не статичная:
     1. акцентная полоса 3px слева вырастает сверху вниз по наведению;
     2. под курсором едет мягкое пятно света (координаты ставит app.js
        в --mx/--my, поэтому пятно идёт за указателем, а не стоит по центру);
     3. иконка при появлении карточки прорисовывается штрихом;
     4. на тач-экранах наведения нет, поэтому там ту же роль играет класс
        is-live: подсвечена карточка, которая сейчас в середине экрана.

   ПОЧЕМУ подъём карточки сделан свойством translate, а не transform:
   transform занят появлением (translateY(16px) -> none), и если бы наведение
   писало туда же, правило появления перебивало бы его по весу селектора и
   карточка переставала бы подниматься под курсором.
   ========================================================================= */

.whyus__grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:16px;
}

.whyus-card{
  position:relative; isolation:isolate;
  display:flex; flex-direction:column;
  min-width:0;                                   /* иначе длинное слово растянет колонку */
  padding:26px 24px 26px 28px;                   /* слева больше: там стоит акцентная полоса */
  border:1px solid var(--line-2);
  border-radius:var(--r);
  /* Верхний блик тем же слоем, что и у прочих плашек дома. */
  background:
    linear-gradient(180deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,0) 38%),
    var(--panel);
  transition:translate var(--t-base), border-color var(--t-base), background var(--t-base);
}

/* Акцентная полоса дом-стиля: ровно 3px, #4FC4E9, растёт сверху вниз. */
.whyus-card::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:var(--accent); box-shadow:var(--accent-glow);
  opacity:0; transform:scaleY(0); transform-origin:50% 0;
  transition:transform var(--t-base), opacity var(--t-base);
}

/* Пятно света под курсором. z-index -1 при isolation:isolate кладёт его
   НАД фоном плашки, но ПОД текстом, поэтому контраст букв не падает. */
.whyus-card::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  border-radius:inherit; opacity:0;
  transition:opacity var(--t-base);
  background:radial-gradient(240px 190px at var(--mx,50%) var(--my,0%),
             rgba(79,196,233,.17) 0%, rgba(79,196,233,.06) 42%, rgba(79,196,233,0) 72%);
}

/* ---- иконка ---- */
.whyus-card__ico{
  display:grid; place-items:center;
  width:46px; height:46px; flex:0 0 auto;
  border:1px solid var(--line-2); border-radius:var(--r);
  background:rgba(255,255,255,.05);
  color:#E4EAF1;                                  /* штрих иконки = currentColor */
  transition:color var(--t-base), border-color var(--t-base), background var(--t-base);
}
.whyus-card__svg{
  width:24px; height:24px;
  fill:none; stroke:currentColor;
  stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}

/* ---- текст ---- */
.whyus-card__t{
  margin-top:18px;
  font-size:var(--fs-500); line-height:1.25; letter-spacing:-.02em;
  color:#EDF1F5;                                  /* запасной цвет, если clip:text не поддержан */
}
/* Серебро заголовка карточки светлее общего --silver: у общего нижний стоп
   #98A2AE даёт на этой плашке около 6.6:1, а тут держим 7:1 и выше. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .whyus-card__t{
    background:linear-gradient(160deg,#FFFFFF 0%,#F2F6FA 38%,#C8D0D9 100%);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
}
.whyus-card__p{
  margin-top:11px;
  font-size:var(--fs-300); line-height:1.65;
  color:var(--body);                              /* 10:1 к плашке, не «серо» */
}

/* ---- живая строка курса в четвёртой карточке ----
   Числа приходят из app.js по событию ae:rate, в разметке лежит только
   стартовое значение. margin-top:auto прижимает строку к низу карточки,
   поэтому в ряду она стоит на одной линии независимо от длины текста. */
.whyus-live{
  margin-top:auto; padding-top:16px;
  border-top:1px solid var(--line);
  display:flex; flex-direction:column; gap:9px;
}
/* Две строки, а не одна: в трёхколоночной сетке карточка около 244px, и
   строка «подпись + два числа» рвалась посередине, оставляя тенге одни
   на второй строке. Подпись сверху, числа под ней - читается при любой ширине. */
.whyus-live__head{ display:flex; align-items:center; gap:9px; }
.whyus-live__vals{ display:flex; align-items:baseline; gap:11px; flex-wrap:wrap; }
.whyus-live__dot{
  width:7px; height:7px; flex:0 0 auto; border-radius:50%;
  background:var(--accent); box-shadow:0 0 8px rgba(79,196,233,.7);
  animation:whyusPulse 2.6s ease-out infinite;
}
@keyframes whyusPulse{
  0%,100%{ box-shadow:0 0 0 0 rgba(79,196,233,.42), 0 0 8px rgba(79,196,233,.7); }
  70%    { box-shadow:0 0 0 7px rgba(79,196,233,0), 0 0 8px rgba(79,196,233,.7); }
}
.whyus-live__k{
  font-family:var(--font-mono); font-size:var(--fs-100);
  letter-spacing:.08em; text-transform:uppercase;
  color:#CBD2DA;                                  /* 11.9:1 к плашке */
}
.whyus-live__v{
  font-family:var(--font-mono); font-size:var(--fs-500); font-weight:600;
  letter-spacing:-.01em; color:#FFFFFF;
}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .whyus-live__v{
    background:var(--silver-num);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
}
.whyus-live__sep{
  width:3px; height:3px; border-radius:50%;
  background:rgba(255,255,255,.42);
}

/* =========================================================================
   АКТИВНОЕ СОСТОЯНИЕ КАРТОЧКИ
   Описано дважды намеренно. На тач-экранах :hover «залипает» после тапа и
   карточка остаётся подсвеченной навсегда, поэтому наведение живёт только
   внутри @media (hover:hover), а на тач-устройствах ту же роль играет класс
   is-live, который app.js вешает на карточку в середине экрана.
   ========================================================================= */
.whyus-card.is-live{
  border-color:rgba(79,196,233,.42);
  background:
    linear-gradient(180deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,0) 38%),
    var(--panel-hi);
}
.whyus-card.is-live::before{ opacity:1; transform:scaleY(1); }
.whyus-card.is-live::after{ opacity:1; }
.whyus-card.is-live .whyus-card__ico{
  color:var(--accent-ink); border-color:var(--accent-line); background:var(--accent-soft);
}

@media (hover:hover){
  .whyus-card:hover{
    translate:0 -3px;
    border-color:rgba(79,196,233,.42);
    background:
      linear-gradient(180deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,0) 38%),
      var(--panel-hi);
  }
  .whyus-card:hover::before{ opacity:1; transform:scaleY(1); }
  .whyus-card:hover::after{ opacity:1; }
  .whyus-card:hover .whyus-card__ico{
    color:var(--accent-ink); border-color:var(--accent-line); background:var(--accent-soft);
  }
}

/* =========================================================================
   ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ
   Скрытое состояние включает КЛАСС is-armed, который ставит app.js. Если
   скрипт не отработал (ошибка, отключённый JS), класса нет и карточки видны
   сразу - контент не пропадает. Задержка идёт по индексу карточки (--i),
   и задана она ПОКАДРОВО для opacity/transform, а не общим transition-delay:
   иначе та же задержка прилипла бы к наведению и шестая карточка отзывалась
   бы на курсор через треть секунды.
   ========================================================================= */
.whyus__grid.is-armed .whyus-card{
  opacity:0; transform:translateY(16px);
  transition:
    opacity   620ms cubic-bezier(.16,.84,.44,1) calc(var(--i,0) * 70ms),
    transform 620ms cubic-bezier(.16,.84,.44,1) calc(var(--i,0) * 70ms),
    translate var(--t-base),
    border-color var(--t-base),
    background var(--t-base);
}
.whyus__grid.is-armed .whyus-card.is-in{ opacity:1; transform:none; }

/* Прорисовка иконки штрихом. Работает благодаря pathLength="1" в разметке:
   все контуры приведены к одной длине, поэтому одна пара dasharray/dashoffset
   годится для любой формы. Под prefers-reduced-motion блок не применяется
   вовсе, и иконка сразу целая. */
@media (prefers-reduced-motion:no-preference){
  .whyus__grid.is-armed .whyus-card__svg > *{
    stroke-dasharray:1; stroke-dashoffset:1;
  }
  .whyus__grid.is-armed .whyus-card.is-in .whyus-card__svg > *{
    stroke-dashoffset:0;
    transition:stroke-dashoffset 820ms cubic-bezier(.16,.84,.44,1) calc(180ms + var(--i,0) * 70ms);
  }
}

/* =========================================================================
   РАСКЛАДКА: 3 колонки - 2 - 1

   Считаем ДВУМЯ мерками, и это не перестраховка:
     - @container меряет ширину самого центра. При живых боковых панелях на
       окне 1200-1400px центру остаётся 680-780px, и три колонки там дают
       карточку в 200px - текст встаёт лесенкой по два слова. Поэтому ниже
       800px центра колонок две.
     - @media меряет ОКНО и отвечает за класс устройства: планшет (до 1199px)
       держит две колонки, даже если центр там широкий, потому что панелей
       на нём нет и центр равен всему окну.
   Порядок правил важен: узкие пороги идут последними, иначе планшетное
   правило перебило бы мобильное и на телефоне осталось бы две колонки.
   ========================================================================= */
@container center (max-width:800px){
  .whyus__grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@media (max-width:1199px){
  .whyus__grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
@container center (max-width:560px){
  .whyus__grid{ grid-template-columns:1fr; }
}
@media (max-width:700px){
  .whyus__grid{ grid-template-columns:1fr; }
}
@media (max-width:620px){
  .whyus-card{ padding:22px 18px 22px 22px; }
}
@media (max-width:400px){
  .whyus-card{ padding:18px 14px 18px 17px; }
  .whyus-card__ico{ width:42px; height:42px; }
  .whyus-live{ gap:7px; }
}
/* ==== БЛОК 3: СЕТКА ВОЗМОЖНОСТЕЙ - КОНЕЦ ==== */

/* =========================================================================
   ==== БЛОК 1: КАРТА «ГДЕ МЫ ВЫДАЁМ НАЛИЧНЫЕ» - НАЧАЛО ====

   Заменяет статичную картинку cities-map.svg. Ни одной внешней зависимости:
   подложка - inline SVG, точки - обычные кнопки поверх него.

   ГЛАВНОЕ ПРАВИЛО ГЕОМЕТРИИ: контейнер карты жёстко держит aspect-ratio
   1000/620, ровно как viewBox у SVG, а сам SVG растянут на весь контейнер
   с preserveAspectRatio="xMidYMid meet". Из-за этого единица viewBox всегда
   равна одному и тому же проценту контейнера, и точка на 72.97% попадает
   ровно в конец дуги с координатой 729.7. Ломать aspect-ratio нельзя:
   разъедутся точки и дуги.
   ========================================================================= */
.geo{ display:grid; grid-template-columns:minmax(0,1fr); gap:16px; }

/* ---------- рамка карты ---------- */
.geo__map{
  position:relative; isolation:isolate;
  /* ВЫСОТА КАРТЫ = max(62% ширины, 580px), и сделана она процентным паддингом,
     а НЕ парой aspect-ratio + min-height.

     Почему не aspect-ratio: замерено на окне 900 - при aspect-ratio:1000/620
     вместе с min-height:580 браузер выводит ширину ОБРАТНО из пропорции
     (580 * 1000/620 = 935px), и карта вылезала за колонку на 55px. min-width:0
     это не лечит. Процентный паддинг считается от ширины родителя и обратной
     связи на ширину не имеет, поэтому ширину задаёт колонка, а высоту - паддинг.

     Пол в 580px нужен на узком экране: по пропорции карта была бы 440px, а под
     самой высокой карточкой (Казань, 365px) требуется минимум 553px.
     Пол вообще можно ставить только потому, что подложка идёт с
     preserveAspectRatio="none" и тянется за рамкой, не рассинхронив точки. */
  padding-bottom:62%;
  min-height:580px;
  border:1px solid var(--line-2); border-radius:var(--r);
  background:
    radial-gradient(120% 90% at 62% 22%, rgba(255,255,255,.055) 0%, rgba(255,255,255,0) 62%),
    var(--panel-flat);
  /* Обрезает подложку СТЕЙДЖ, а не карта: если карточка когда-нибудь окажется
     выше свободного места, она вылезет за рамку, но текст не срежется. Терять
     содержимое хуже, чем некрасиво выйти за границу. */
  overflow:visible;
}
/* Акцентная полоса дом-стиля: карта - смысловой узел секции. */
.geo__map::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar); z-index:4;
  background:var(--accent); box-shadow:var(--accent-glow);
}
.geo__stage{ position:absolute; inset:0; overflow:hidden; border-radius:var(--r); }

/* ---------- сетка и дуги ---------- */
.geo__grid{ position:absolute; inset:0; width:100%; height:100%; display:block; }
/* Толщина линий не должна зависеть от масштаба карты, иначе на широком
   экране сетка жирнеет. non-scaling-stroke держит ровно 1px всегда. */
.geo__line{
  fill:none; stroke:rgba(255,255,255,.06); stroke-width:1;
  vector-effect:non-scaling-stroke;
}
/* Подписи сетки - тоже текст, поэтому держим их на служебном пороге --dim
   (4.9:1 к фону), а не на «еле видно». Ниже в файле опускаться запрещено.
   Живут в HTML, а не в SVG: подложка тянется, текст тянуться не должен. */
.geo__deg{
  position:absolute; z-index:1; pointer-events:none; white-space:nowrap;
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.1em; color:var(--dim);
}
.geo__deg--lat{ left:11px; top:var(--y); transform:translateY(-135%); }
.geo__deg--lon{ left:var(--x); bottom:10px; margin-left:7px; }
.geo__arc{
  fill:none; stroke:rgba(255,255,255,.11); stroke-width:1.4;
  stroke-dasharray:5 7; stroke-linecap:round;
  vector-effect:non-scaling-stroke;
  transition:stroke var(--t-base), stroke-width var(--t-base);
}
/* Выбранный маршрут подсвечиваем СЕРЕБРОМ, а не акцентом. Акцент на этой
   карте означает ровно одно - «наличные выдаём». Если красить им выделение,
   выбранный Петербург загорится тем же цветом, что и подтверждённая Москва,
   и легенда начнёт врать. */
.geo__arc.is-active{ stroke:rgba(255,255,255,.40); stroke-width:2; }
/* Искра бежит по дуге всегда (SMIL), но видна только у активного маршрута:
   так не приходится дёргать анимацию из JS и ловить рассинхрон. */
.geo__spark{ fill:#EDF2F7; opacity:0; transition:opacity var(--t-base); }
.geo__spark.is-active{ opacity:.95; }

/* ---------- точки городов ----------
   Точки лежат НАД карточками (z 5 против 3) и вне .geo__stage. Причина
   найдена замером: на узкой карте открытая карточка Петербурга накрывает
   точку Испании, и по ней уже не кликнуть - приходится сначала закрывать
   карточку. Теперь любая точка кликабельна всегда, а подписи соседних
   городов на время гаснут, чтобы не лезть в текст карточки. */
/* 🔴 pointer-events:none обязателен. Слой точек лежит поверх карточек, и без
   этого он перехватывал ВСЕ клики: кнопка «Свернуть» не срабатывала ни разу
   (elementFromPoint отдавал .geo__pins), выделить текст в карточке было
   нельзя - любой клик схлопывал её. Сами точки кликабельность возвращают. */
.geo__pins{ position:absolute; inset:0; z-index:5; pointer-events:none; }
.geo__pin{ pointer-events:auto; }
.geo__pin{
  position:absolute; left:var(--x); top:var(--y);
  width:30px; height:30px; margin:-15px 0 0 -15px;   /* центрируем по точке БЕЗ transform: */
  padding:0; border:0; background:none; cursor:pointer;  /* transform оставлен ховеру */
  z-index:2;
}
.geo__dot, .geo__ping{
  position:absolute; left:50%; top:50%; width:11px; height:11px; margin:-5.5px 0 0 -5.5px;
  border-radius:50%;
}
.geo__dot{
  background:rgba(255,255,255,.42);
  border:1.5px solid rgba(255,255,255,.72);
  box-shadow:0 0 0 5px rgba(12,13,17,.55);            /* тёмный ореол: точка читается поверх сетки */
  transition:transform var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.geo__pin--live .geo__dot{
  background:var(--accent); border-color:#BDECFB;
  box-shadow:0 0 0 5px rgba(12,13,17,.55), var(--accent-glow);
}
/* Пульс только у подтверждённой выдачи. Остальные города серые - это и есть
   честный сигнал «тут пока не работаем», а не украшение. */
.geo__ping{ background:var(--accent); opacity:0; }
.geo__pin--live .geo__ping{ animation:geoPing 2.8s cubic-bezier(.22,.61,.36,1) infinite; }
@keyframes geoPing{
  0%{ transform:scale(1);   opacity:.55; }
  70%{ transform:scale(3.4); opacity:0; }
  100%{ transform:scale(3.4); opacity:0; }
}
.geo__tag{
  position:absolute; left:50%; top:calc(50% + 12px); transform:translateX(-50%);
  white-space:nowrap;
  font-family:var(--font-mono); font-size:11px; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase;
  color:rgba(255,255,255,.66);
  text-shadow:0 1px 7px rgba(12,13,17,.95), 0 0 2px rgba(12,13,17,.95);
  transition:color var(--t-fast), opacity var(--t-base);
}
.geo__pin--live .geo__tag{ color:#E9EEF4; }
/* Карточка открыта - гасим чужие подписи: точка остаётся кликабельной, а
   текст карточки не спорит с надписью города поверх него. */
.geo__map.has-open .geo__pin:not(.is-active) .geo__tag{ opacity:0; }
.geo__pin:hover .geo__dot{ transform:scale(1.35); }
.geo__pin:hover .geo__tag{ color:#FFFFFF; }
/* Выделение = серебряное кольцо и увеличение, цвет точки НЕ меняем: он
   несёт статус выдачи, а не состояние интерфейса. */
.geo__pin.is-active .geo__dot{
  transform:scale(1.45);
  border-color:#FFFFFF;
  box-shadow:0 0 0 5px rgba(12,13,17,.55), 0 0 0 6.5px rgba(255,255,255,.42);
}
.geo__pin--live.is-active .geo__dot{
  box-shadow:0 0 0 5px rgba(12,13,17,.55), 0 0 0 6.5px rgba(255,255,255,.42), var(--accent-glow);
}
.geo__pin.is-active .geo__tag{ color:#FFFFFF; }
.geo__pin:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; border-radius:50%; }

/* ---------- плашка-шапка и легенда внутри карты ---------- */
.geo__plate, .geo__legend{
  position:absolute; z-index:2;
  padding:12px 14px;
  background:linear-gradient(103deg, rgba(255,255,255,.085), rgba(255,255,255,.035)), rgba(12,13,17,.86);
  border:1px solid var(--line-2); border-radius:var(--r);
  transition:opacity var(--t-base), transform var(--t-base);
}
.geo__plate{ left:14px; top:14px; display:grid; gap:6px; }
.geo__legend{ right:14px; bottom:14px; display:grid; gap:7px; max-width:230px; }
/* Открытая карточка важнее служебных плашек - они уходят, чтобы не спорить
   с текстом карточки за одно и то же место. Класс висит на .geo__map, потому
   что это общий предок и подложки, и точек, и карточек. */
.geo__map.has-open .geo__plate,
.geo__map.has-open .geo__legend{ opacity:0; transform:translateY(6px); pointer-events:none; }
.geo__plate-t{
  font-family:var(--font-mono); font-size:10px; font-weight:600;
  letter-spacing:.24em; text-transform:uppercase; color:#E9EEF4;
}
.geo__plate-v{ font-size:12.5px; line-height:1.35; color:var(--body); }
.geo__legend-t{
  font-family:var(--font-mono); font-size:10px; font-weight:600;
  letter-spacing:.24em; text-transform:uppercase; color:#E9EEF4;
}
.geo__legend-i{
  display:flex; align-items:center; gap:9px;
  font-size:12.5px; line-height:1.35; color:var(--body);
}
.geo__key{
  flex:0 0 auto; width:9px; height:9px; border-radius:50%;
  background:rgba(255,255,255,.42); border:1.5px solid rgba(255,255,255,.72);
}
.geo__key--live{ background:var(--accent); border-color:#BDECFB; box-shadow:0 0 9px 1px rgba(79,196,233,.6); }
.geo__legend-h{ margin-top:2px; font-size:11.5px; line-height:1.4; color:var(--muted); }

/* ---------- карточка города ---------- */
.geo__cards{ position:absolute; inset:0; z-index:3; pointer-events:none; }
.geo__card{
  position:absolute; width:min(340px,48%);
  padding:15px 16px 14px 18px;
  border:1px solid var(--line-3); border-radius:var(--r);
  /* Плашка светлее фона, но непрозрачная: под ней сетка, текст поверх неё
     иначе теряет контраст. Белый слой сверху держит дом-стиль. */
  background:linear-gradient(103deg, rgba(255,255,255,.10), rgba(255,255,255,.045)), rgba(13,14,19,.95);
  box-shadow:0 22px 46px rgba(0,0,0,.5);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  opacity:0; visibility:hidden; transform:scale(.94);
  pointer-events:none;
  transition:opacity var(--t-base), transform var(--t-base), visibility var(--t-base);
}
.geo__card::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:linear-gradient(180deg, rgba(255,255,255,.72) 0%, rgba(255,255,255,.10) 100%);
}
.geo__card.is-live::before{ background:var(--accent); box-shadow:var(--accent-glow); }
.geo__card.is-open{ opacity:1; visibility:visible; transform:none; pointer-events:auto; }
/* Две раскладки разворота: вниз-влево и вверх-вправо. Выбраны так, чтобы
   карточка любого города осталась внутри рамки карты на любой ширине. */
.geo__card--dl{ right:calc(100% - var(--x)); top:calc(var(--y) + 22px); transform-origin:top right; }
.geo__card--ur{ left:var(--x); bottom:calc(100% - var(--y) + 22px); transform-origin:bottom left; }
.geo__card--dl{ transform:scale(.94) translate(6px,-6px); }
.geo__card--ur{ transform:scale(.94) translate(-6px,6px); }
.geo__card--dl.is-open, .geo__card--ur.is-open{ transform:none; }
/* Поводок от точки к углу карточки: 22px зазора иначе читаются как «карточка
   висит сама по себе», а не «развернулась вот из этой точки». */
.geo__card--dl::after, .geo__card--ur::after{
  content:""; position:absolute; width:1px; height:22px;
}
/* Ярче у точки, гаснет у карточки - поэтому градиенты зеркальные. */
.geo__card--dl::after{ right:0; top:-22px;
  background:linear-gradient(180deg, rgba(255,255,255,.42), rgba(255,255,255,.05)); }
.geo__card--ur::after{ left:0; bottom:-22px;
  background:linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.42)); }

.geo__status{
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--muted);
}
.geo__status i{
  width:8px; height:8px; border-radius:50%; flex:0 0 auto;
  background:rgba(255,255,255,.5);
}
.geo__status--live{ color:var(--accent-ink); }
.geo__status--live i{ background:var(--accent); box-shadow:0 0 8px 1px rgba(79,196,233,.65); }
.geo__status--soon{ color:#EBCB96; }
.geo__status--soon i{ background:var(--warn); }
.geo__status--off{ color:#EFA79E; }
.geo__status--off i{ background:var(--danger); }
.geo__card-t{ margin-top:9px; font-size:20px; font-weight:650; line-height:1.15; color:var(--ink); }
.geo__card-sub{ margin-top:5px; font-size:12.5px; line-height:1.45; color:var(--muted); }
.geo__facts{ margin-top:13px; display:grid; gap:11px; }
.geo__facts dt{
  font-family:var(--font-mono); font-size:10px; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:#E9EEF4;
}
.geo__facts dd{ margin:4px 0 0; font-size:13px; line-height:1.6; color:var(--body); }
.geo__close{
  margin-top:13px; padding:0; border:0; background:none; cursor:pointer;
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--accent-ink);
}
.geo__close:hover{ color:#FFFFFF; }
.geo__close:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:2px; }

/* ---------- правила выдачи ---------- */
.geo__rules{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
.geo__rule{
  position:relative; padding:16px 16px 16px 19px;
  background:var(--panel); border:1px solid var(--line-2); border-radius:var(--r);
}
.geo__rule::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:linear-gradient(180deg, rgba(255,255,255,.72) 0%, rgba(255,255,255,.10) 100%);
}
.geo__rule--yes::before{ background:var(--accent); box-shadow:var(--accent-glow); }
.geo__rule--no::before{ background:linear-gradient(180deg, rgba(229,147,138,.85) 0%, rgba(229,147,138,.12) 100%); }
.geo__rule-k{
  display:block;
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:#E9EEF4;
}
.geo__rule p{ margin-top:9px; font-size:13.5px; line-height:1.65; color:var(--body); }

/* ---------- живые числа ---------- */
.geo__live{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px 22px;
  padding:16px 18px 15px 21px;
  position:relative;
  background:var(--panel); border:1px solid var(--line-2); border-radius:var(--r);
}
.geo__live::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:var(--bar);
  border-radius:var(--r) 0 0 var(--r);
  background:var(--accent); box-shadow:var(--accent-glow);
}
.geo__live-i{ display:grid; gap:5px; min-width:0; }
.geo__live-k{
  font-family:var(--font-mono); font-size:10px; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; color:var(--muted);
}
.geo__live-v{ font-size:15px; line-height:1.4; color:var(--body); }
.geo__live-v b{
  font-family:var(--font-mono); font-weight:600; font-size:16px;
  color:var(--ink); letter-spacing:-.01em; white-space:nowrap;
}
.geo__live-v b.is-good{ color:var(--accent-ink); }
.geo__live-note{
  grid-column:1/-1; margin-top:2px;
  font-size:12px; line-height:1.5; color:var(--dim);
}

/* ---------- нижняя строка ---------- */
.geo__cta{ display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap; }
.geo__note{ flex:1 1 420px; min-width:0; font-size:13px; line-height:1.7; color:var(--muted); }

/* =========================================================================
   УЗКАЯ РАСКЛАДКА: карта уходит, карточки становятся вертикальным списком.
   Два одинаковых правила специально: @container меряет ширину ЦЕНТРА (на
   широком окне он всего ~760px из-за боковых панелей), @media страхует
   браузеры без контейнерных запросов. Дублирование тут дешевле, чем
   горизонтальная прокрутка на 320px.
   ========================================================================= */
@container center (max-width:770px){
  .geo__map{ padding-bottom:0; min-height:0; border:0; background:none; }
  .geo__map::before{ display:none; }
  .geo__stage, .geo__pins{ display:none; }
  .geo__cards{
    position:static; inset:auto; pointer-events:auto;
    display:grid; gap:12px;
  }
  .geo__card, .geo__card--dl, .geo__card--ur{
    position:static; inset:auto; width:auto; max-width:none;
    transform:none; opacity:1; visibility:visible;
    pointer-events:auto; box-shadow:none; backdrop-filter:none; -webkit-backdrop-filter:none;
    background:var(--panel);
  }
  .geo__card::after{ display:none; }      /* поводок ведёт к точке, а точек тут нет */
  .geo__close{ display:none; }            /* сворачивать нечего: список открыт весь */
  .geo__rules{ grid-template-columns:1fr; }
  .geo__live{ grid-template-columns:1fr; }
}
@media (max-width:770px){
  .geo__map{ padding-bottom:0; min-height:0; border:0; background:none; }
  .geo__map::before{ display:none; }
  .geo__stage, .geo__pins{ display:none; }
  .geo__cards{
    position:static; inset:auto; pointer-events:auto;
    display:grid; gap:12px;
  }
  .geo__card, .geo__card--dl, .geo__card--ur{
    position:static; inset:auto; width:auto; max-width:none;
    transform:none; opacity:1; visibility:visible;
    pointer-events:auto; box-shadow:none; backdrop-filter:none; -webkit-backdrop-filter:none;
    background:var(--panel);
  }
  .geo__card::after{ display:none; }
  .geo__close{ display:none; }
  .geo__rules{ grid-template-columns:1fr; }
  .geo__live{ grid-template-columns:1fr; }
  .geo__cta .btn{ width:100%; }
}
/* Промежуток: карта ещё есть, но три колонки правил уже узкие. */
@container center (min-width:771px) and (max-width:940px){
  .geo__rules{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .geo__rules > :last-child{ grid-column:1/-1; }
}
@media (max-width:400px){
  .geo__card{ padding-left:16px; padding-right:14px; }
  .geo__rule{ padding-left:17px; padding-right:14px; }
  .geo__live{ padding-left:19px; padding-right:14px; }
  .geo__card-t{ font-size:18px; }
  .geo__live-v b{ white-space:normal; }   /* длинное число лучше перенести, чем вылезти за экран */
}

@media (prefers-reduced-motion:reduce){
  .geo__pin--live .geo__ping{ animation:none; opacity:0; }
  .geo__spark{ display:none; }
}
/* ==== БЛОК 1: КАРТА «ГДЕ МЫ ВЫДАЁМ НАЛИЧНЫЕ» - КОНЕЦ ==== */

/* ==== ПОЧИНКА ПОСЛЕ ПРОВЕРКИ: непрозрачные карточки дуги ====
   🔴 Правки для карточек дуги (сплошной тон под наложенными карточками и
   контраст дорожки точек) сняты 21.08.2026 вместе с самой дугой: карточки
   больше не лежат внахлёст, точек-индикаторов нет. Лечить нечего. */

/* =========================================================================
   ==== БЛОК 5: МЯГКАЯ ГЕОМЕТРИЯ И ТЁМНАЯ ГЛАВНАЯ КНОПКА - НАЧАЛО ====
   (добавлено 19.08.2026 по правке владельца)

   ЖАЛОБА (пересказ, не дословно): выглядит очень дёшево; по бокам, слева и
   справа, нужны красивые закруглённые рамки, чтобы всё было мягче; синюю
   кнопку обмена перевести в серый градиент, справа уходящий в чёрный.

   ПОЧЕМУ БЫЛО ДЁШЕВО. Геометрия одноступенчатая: скругление 6px у всего
   подряд, кромка одной толщины, теней нет вовсе. Плашка лежала на фоне
   плоской наклейкой, а не предметом, и глазу не за что зацепиться, чтобы
   отличить крупный блок от мелкой карточки внутри него.

   ЧТО СДЕЛАНО:
     1. Три ступени скругления вместо одной: крупная плашка 16, карточка 12,
        мелочь внутри 9. Разные радиусы читаются как разные уровни
        вложенности - отсюда «мягко», но без пузырькового вида.
     2. Кромка в два слоя, приём .site-glass с apolloproduction.studio:
        внешняя линия border плюс внутренний блик inset 0 1px 0 сверху.
     3. Мягкая тень: панель отрывается от фона, а не наклеена на него.
     4. Акцентная полоса 3px больше не упирается в углы. При радиусе 16
        полоса с прежним радиусом 6 вылезала бы за скруглённый угол, поэтому
        она поджата сверху и снизу на --bar-inset и получила круглые торцы.
     5. Главная кнопка: градиент СЛЕВА НАПРАВО от светло-серого в почти
        чёрный, текст белый. Фирменный голубой остался тонкой полосой слева
        и свечением по наведению - кнопка не потеряла принадлежность к дому.

   КОНТРАСТ КНОПКИ (замер по формуле WCAG, белый #FFFFFF на каждой точке):
     покой  #4A4E56 = 8.35:1 · #33363D = 12.10:1 · #1B1D22 = 16.86:1 · #0B0C10 = 19.55:1
     ховер  #52565F = 7.36:1 · #3B3F47 = 10.56:1 · #212429 = 15.57:1 · #0E0F14 = 19.14:1
   Самая светлая точка градиента - крайняя левая, она и держит нижнюю
   границу. Ниже 7:1 не опускается ни одна точка ни в одном состоянии.

   ПОЧЕМУ ОТДЕЛЬНЫМ БЛОКОМ В КОНЦЕ ФАЙЛА, А НЕ ПРАВКОЙ ИСХОДНЫХ ПРАВИЛ:
   по карте (#offline, классы .geo__*) параллельно работает другой
   исполнитель. Правка общих правил в середине файла столкнулась бы с его
   правками в тех же строках. Здесь нет ни одного селектора .geo__* и ни
   одного правила для .offline - зоны не пересекаются.
   ========================================================================= */

:root{
  --r-panel:   16px;   /* крупная плашка: калькулятор, боковые панели, финальный CTA */
  --r-card:    12px;   /* карточка внутри блока и органы управления калькулятора */
  --r-inner:    9px;   /* мелочь внутри карточки: строка рынка, значок, тег */
  --bar-inset: 14px;   /* на столько акцентная полоса поджата от углов плашки */

  /* Блик по верхней кромке. Даёт «стеклянный» край, который на глаз читается
     как толщина материала, а не как нарисованная линия. */
  --rim:           inset 0 1px 0 rgba(255,255,255,.16);
  /* Тени намеренно с большим отрицательным spread: пятно широкое и мягкое,
     без тёмного ободка вокруг плашки. */
  --shadow-panel:  0 22px 48px -30px rgba(0,0,0,.92), 0 3px 12px -8px rgba(0,0,0,.6);
  --shadow-card:   0 16px 34px -26px rgba(0,0,0,.85);
  --shadow-hover:  0 26px 50px -26px rgba(0,0,0,.95);
}

/* -------------------------------------------------------------------------
   1. КРУПНЫЕ ПЛАШКИ
   ------------------------------------------------------------------------- */
.calc, .stats, .rate-strip, .vs__col, .svc, .honest, .final__inner,
.spot, .market, .feed{
  border-radius:var(--r-panel);
  box-shadow:var(--rim), var(--shadow-panel);
}
/* У модалки своя, намеренно глубокая тень (она висит над затемнением),
   поэтому радиус берём общий, а тень оставляем её собственную. */
.modal__dialog{
  border-radius:var(--r-panel);
  box-shadow:var(--rim), 0 40px 90px -40px rgba(0,0,0,.9);
}

/* -------------------------------------------------------------------------
   2. КАРТОЧКИ ВНУТРИ БЛОКОВ - радиус на ступень меньше
   .qcard сюда НЕ входит: ниже 1200px он превращается в кнопку нижней панели
   навигации, где рамка и тень не нужны. Он настроен отдельно, в ветке 1200+.
   ------------------------------------------------------------------------- */
.card, .step, .guard, .whyus-card, .faq__item, .trust li{
  border-radius:var(--r-card);
  box-shadow:var(--rim), var(--shadow-card);
}
/* Наведение поднимает карточку - тень обязана подрасти вместе с ней, иначе
   карточка «висит» без опоры. Переход перечислен целиком: свойство transition
   не дописывается, а заменяется, и без transform/border-color/background
   прежняя анимация подъёма пропала бы. */
.card, .svc, .guard, .step, .qcard{
  transition:transform var(--t-base), border-color var(--t-base),
             background var(--t-base), box-shadow var(--t-base);
}
.card:hover, .svc:hover, .guard:hover, .step:hover{
  box-shadow:var(--rim), var(--shadow-hover);
}
@media (hover:hover){
  .whyus-card{ transition:translate var(--t-base), border-color var(--t-base),
                          background var(--t-base), box-shadow var(--t-base); }
  .whyus-card:hover{ box-shadow:var(--rim), var(--shadow-hover); }
}

/* -------------------------------------------------------------------------
   3. МЕЛОЧЬ ВНУТРИ КАРТОЧЕК
   ------------------------------------------------------------------------- */
.card__ico, .svc__ico, .vs__ico, .spot__ico, .whyus-card__ico, .step__ico,
.guard__ico, .logo__mark, .swap, .field__box, .seg, .calc__rate, .modal__note{
  border-radius:var(--r-card);
}
.panel__ico, .qcard__ico, .mrow, .fcard, .card__tag, .calc__badge,
.field__cur, .seg__btn, .modal__close, .intro__skip, .pill{
  border-radius:var(--r-inner);
}
/* Подсветка пункта меню в шапке была угловатой заплаткой 4px рядом с
   кнопкой на 9px - на глаз читалось как недоделка. */
.nav a{ border-radius:8px; }

/* ПРАВКА СКЕПТИКА 19.08. Знак в шапке получил выше радиус 12 (был 6), но его
   акцентная засечка осталась поджатой на 6px - ровно на СТАРЫЙ радиус. При
   радиусе 12 кромка в точке y=6 отходит вправо на 1,6px, и засечка шириной
   2px вылезала слева от скругления отдельным синим язычком сверху и снизу.
   Тот же приём, что у .btn--primary::before: поджим равен радиусу. */
.logo__mark::before{ top:12px; bottom:12px; }

/* -------------------------------------------------------------------------
   4. АКЦЕНТНАЯ ПОЛОСА ПОД НОВЫЙ РАДИУС
   Полоса остаётся ровно 3px и ровно слева - это узнаваемый элемент дом-стиля.
   Меняется только посадка: она больше не доходит до скруглённых углов и имеет
   круглые торцы, иначе прямой торец 3px на радиусе 16 торчал бы наружу.
   .offline и .geo__* в списке отсутствуют намеренно: чужая зона.
   ------------------------------------------------------------------------- */
.calc::before, .spot::before, .svc::before, .honest::before,
.final__inner::before, .modal__dialog::before, .rate-strip::before,
.vs__col::before, .step::before, .card::before, .guard::before,
.stats::before, .whyus-card::before{
  top:var(--bar-inset); bottom:var(--bar-inset);
  border-radius:var(--bar);
}

/* -------------------------------------------------------------------------
   5. БОКОВЫЕ ПАНЕЛИ: воздух внутри
   Отступы были рассчитаны на плашку с углом 6px. На радиусе 16 текст, идущий
   вплотную к скруглению, читается как «сжат в угол», поэтому внутренние поля
   подняты. Ширина самих колонок не менялась - сетка .shell не тронута.
   ------------------------------------------------------------------------- */
.panel__head{ padding:18px 18px 14px; }
.market__list{ padding:6px 12px 14px; gap:3px; }
.feed__list{ padding:6px 12px 14px; gap:8px; }
.mrow{ padding:11px 12px; }
.fcard{ padding:13px; }
.spot{ padding:18px 18px 18px 22px; }

@media (min-width:1200px){
  .side__inner{ gap:14px; }
  /* Быстрые разделы - такие же мягкие плашки, как панели над ними. */
  .qcard{
    padding:15px 13px;
    border-radius:var(--r-card);
    box-shadow:var(--rim), var(--shadow-card);
  }
  .qcard:hover{ box-shadow:var(--rim), var(--shadow-hover); }
}

/* Шторка рынка на узком экране: скругляем ту кромку, которая видна.
   Правая уходит за край окна, её скруглять нечем. */
@media (max-width:1199px){
  .side--right{ border-radius:var(--r-panel) 0 0 var(--r-panel); }
}

/* -------------------------------------------------------------------------
   6. КНОПКИ
   Радиус на ступень мягче прежних 6px, но не пилюля: капсульных кнопок в
   дом-стиле нет, и таблетка ломала бы прямую геометрию дека.
   ------------------------------------------------------------------------- */
.btn{ border-radius:var(--r-card); }
.btn--sm{ border-radius:var(--r-inner); }
.btn--lg{ border-radius:14px; }
.panel-toggle{ border-radius:var(--r-card); }

/* ---------- ГЛАВНАЯ КНОПКА: серый градиент слева направо в чёрный ---------- */
.btn--primary{
  position:relative;                    /* нужно для акцентной полосы ::before */
  background:linear-gradient(90deg,
              #4A4E56 0%, #33363D 38%, #1B1D22 72%, #0B0C10 100%);
  color:#FFFFFF;
  border-color:rgba(255,255,255,.22);   /* тонкая светлая кромка: без неё тёмный
                                           правый край сливается с фоном #0C0D11 */
  box-shadow:var(--rim), 0 18px 34px -22px rgba(0,0,0,.95);
}
/* Фирменный голубой остаётся ровно одной деталью - полоса 2px слева, тот же
   приём, что у плашек. Поджата на 12px: ровно на радиус кнопки, иначе торец
   полосы вылез бы за скруглённый угол. */
.btn--primary::before{
  content:""; position:absolute; left:0; top:12px; bottom:12px; width:2px;
  border-radius:2px; pointer-events:none;
  background:linear-gradient(180deg,
              rgba(79,196,233,.35) 0%, var(--accent) 50%, rgba(79,196,233,.35) 100%);
  box-shadow:0 0 10px 1px rgba(79,196,233,.45);
  transition:box-shadow var(--t-fast);
}
.btn--primary:hover{
  background:linear-gradient(90deg,
              #52565F 0%, #3B3F47 38%, #212429 72%, #0E0F14 100%);
  border-color:rgba(79,196,233,.55);
  box-shadow:var(--rim),
             0 0 0 1px rgba(79,196,233,.26),
             0 14px 30px -16px rgba(79,196,233,.42),
             0 18px 34px -22px rgba(0,0,0,.95);
}
.btn--primary:hover::before{ box-shadow:0 0 16px 2px rgba(79,196,233,.7); }
/* Иконка внутри кнопки была почти чёрной под голубую заливку. На тёмном
   градиенте она стала бы невидимой. */
.btn--primary .ico{ stroke:#EAF2F6; color:#EAF2F6; }
.btn--lg.btn--primary::before{ top:14px; bottom:14px; }
.btn--sm.btn--primary::before{ top:9px;  bottom:9px;  }
/* ==== БЛОК 5: МЯГКАЯ ГЕОМЕТРИЯ И ТЁМНАЯ ГЛАВНАЯ КНОПКА - КОНЕЦ ==== */

/* ==== КАРТА: прежний блок «все точки живые + дороги» СНЯТ ====
   Он правил .geo__pin--on, .geo__dot, .geo__pin-label и рисовал дороги
   через .geo__map::before. В новой разметке зоны 2 таких классов нет,
   дороги ушли в SVG, а ::before снова занят акцентной полосой дома.
   Требование Вячеслава «везде оставь, что работает» никуда не делось:
   оно выполнено в блоке ЗОНА 2 ниже - светятся все четыре метки, а
   разницу держат подписи статуса. Оставлять мёртвые !important нельзя:
   следующий, кто полезет в карту, будет драться с невидимым правилом. */


/* =========================================================================
   ═══ ЗОНА 1: ШАПКА И ПЕРВЫЙ ЭКРАН - НАЧАЛО ═══        (21.08.2026)

   Повод: «сейчас говно какое то, сделай лучше всё». Первый экран переписан
   по эталону saa-s-template, который Вячеслав прислал 19.08 со словами «вот
   как оно вроде как должно быть». Из эталона взято ровно то, что разобрано
   в ref/saas_template_reference.md: Poppins, чёрная шапка с размытием,
   НЕжирный заголовок с трекингом минус 0.05em и заливкой сверху вниз,
   плашка-анонс, серый подзаголовок узкой колонкой, свечение под панелью.

   Дом-стиль Apollo при этом НЕ выброшен, а соединён с эталоном:
     - акцент #4FC4E9 остался, но только точкой, кромкой и свечением;
     - полоса 3px слева у калькулятора и полосы курса на месте;
     - серебро заголовка сохранено, просто градиент теперь идёт сверху вниз,
       как в эталоне, а не под 158 градусов.
   Скругления подняты на ступень (16/12/9 -> 18/14/10) - эталон заметно мягче.
   Подняты ИМЕННО общие переменные БЛОКА 5, своей второй шкалы тут нет.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. ГАРНИТУРА
   Poppins стоит ПЕРВОЙ, но кириллицы у неё нет (ответ css2 отдаёт только
   latin, latin-ext и devanagari). Это не проблема, а механизм: браузер
   подбирает гарнитуру ПОГЛИФНО по unicode-range, поэтому латиница получает
   форму эталона, а русский текст сам сваливается на прежний стек и никуда
   не едет. Порядок остальных гарнитур не тронут.
   ------------------------------------------------------------------------- */
:root{
  --font: "Poppins","SF Pro Display","SF Pro Text",-apple-system,BlinkMacSystemFont,
          "Golos Text","Inter","Segoe UI",Arial,sans-serif;

  /* 🔴 СВОЕЙ ШКАЛЫ СКРУГЛЕНИЙ ЗДЕСЬ НЕТ. Мягкая геометрия уже собрана выше
     в БЛОКЕ 5 (--r-panel / --r-card / --r-inner плюс посадка акцентной полосы
     через --bar-inset), и второй набор значений ради одного экрана развалил
     бы страницу на две разные геометрии. Вместо этого поднимаем ОБЩИЕ числа
     на ступень - эталон заметно мягче, этого и просили. Поднимаем именно
     переменные, поэтому новые значения сами разъезжаются по всем правилам
     БЛОКА 5, а его находки (полоса с круглыми торцами, поджатая от углов)
     продолжают работать. Было 16/12/9. */
  --r-panel:  18px;
  --r-card:   14px;
  --r-inner:  10px;
  --bar-inset:16px;

  /* Серый эталона. Один тон на весь служебный текст первого экрана. */
  --ae1-grey: #9CA3AF;
}

/* -------------------------------------------------------------------------
   2. ШАПКА
   Эталон: fixed сверху, bg-black/80, backdrop-blur-md, тонкая нижняя граница,
   логотип слева, пункты по ЦЕНТРУ абсолютом, кнопка справа.

   🔴 ПОЧЕМУ sticky, а не fixed. Шапка лежит внутри .center, а у .center
   стоит container-type:inline-size. Контейнер размеров - это containment,
   и он делает элемент containing block для ЛЮБЫХ position:fixed потомков.
   То есть fixed внутри .center считался бы не от окна, а от колонки, и
   шапка уехала бы вверх вместе со страницей. sticky top:0 даёт ровно то же
   поведение «прибита к верху», но без этой ловушки.
   ------------------------------------------------------------------------- */
.header{
  position:sticky; top:0;
  /* Чёрный, а не наш #0C0D11 с примесью: эталон держит чистый чёрный. */
  background:rgba(8,9,12,.80);
  backdrop-filter:blur(14px) saturate(150%);
  -webkit-backdrop-filter:blur(14px) saturate(150%);
  /* Граница видна ВСЕГДА, а не только после скролла: в эталоне шапка отбита
     от полотна с первого кадра, и без линии она сливалась с первым экраном. */
  border-bottom:1px solid rgba(255,255,255,.085);
}
.header.is-stuck{
  background:rgba(8,9,12,.92);
  border-bottom-color:rgba(255,255,255,.12);
}
/* relative нужен, чтобы меню центровалось по шапке, а не по странице. */
.header__inner{ position:relative; padding:13px 26px; gap:14px; }

/* 🔴 ДОЛГИ ПО ПОДНЯТЫМ РАДИУСАМ.
   В БЛОКЕ 5 правило одно и оно железное: поджим акцентной полосы равен
   радиусу элемента, иначе прямой торец полосы вылезает из-под скругления
   отдельным синим язычком (там это разбирала правка скептика 19.08). Все
   такие поджимы записаны числами, а не переменными, поэтому подъём шкалы
   надо донести до каждого руками. Ниже - полный список, других мест с
   привязкой к радиусу в файле нет.
   Радиус кнопки .btn стал 14, значит .btn--lg обязан уйти выше 14, иначе
   крупная кнопка и обычная перестают различаться. */
.logo__mark::before{ top:14px; bottom:14px; }          /* было 12, радиус знака 14 */
.btn--primary::before{ top:14px; bottom:14px; }        /* было 12, радиус .btn 14 */
.btn--sm.btn--primary::before{ top:10px; bottom:10px; }/* было 9,  радиус .btn--sm 10 */
.btn--lg{ border-radius:16px; }                        /* было 14, теперь на ступень выше .btn */
.btn--lg.btn--primary::before{ top:16px; bottom:16px; }/* было 14, радиус .btn--lg 16 */

/* Знак логотипа: только материал, радиус берётся из общей шкалы. */
.logo__mark{ background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.12); }
.logo__text{ font-size:15.5px; font-weight:600; letter-spacing:-.015em; }
.logo__text em{ color:rgba(255,255,255,.55); font-weight:400; }

/* Меню по центру шапки абсолютом - приём эталона. Из потока оно уходит,
   поэтому логотип прижат влево, а кнопка вправо своим margin-left:auto,
   и длина подписей больше не двигает кнопку. */
.nav{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  justify-content:center; gap:0; flex:0 0 auto;
}
/* Кегль и поля ужаты сознательно. При прежних 13px/10px меню занимало 427px,
   и на самом ходовом ноутбучном экране 1440 (центру достаётся 820) оно
   налезало на логотип - меню приходилось прятать и шапка стояла пустой на
   600px. 12.5px без зазоров дают 383px, и меню помещается уже с 1335px. */
.nav a{
  padding:7px 8px;
  font-size:12.5px; font-weight:400; color:rgba(255,255,255,.58);
}
.nav a:hover{ color:#fff; background:rgba(255,255,255,.07); }

/* 🔴 Порог, ниже которого меню убирается. Считается по ширине ШАПКИ, то есть
   центральной колонки. Замер после ужатия: меню 383px, логотип 172, кнопка
   126, поля по 26. Центрованное абсолютом меню отстоит от логотипа на
   W/2 - 191.5 - 198, и просвет в 16px набирается с W = 813. Ниже прячем.

   Прежний порог 790 из файла выше остался и продолжает работать, но он
   посчитан для меню В ПОТОКЕ. С абсолютным центрованием его мало: на 790-812
   пункты уже налезали бы на «Apollo Exchange», поэтому порог поднят. */
@container center (max-width:779px){
  .nav{ display:none; }
}

/* 🔴 ПРОВАЛ МЕНЮ НА 1400-1432px - правка скептика 21.08.
   Порог выше считался верно, но он мерит ЦЕНТРАЛЬНУЮ КОЛОНКУ, а она растёт
   по окну НЕ монотонно. Сетка .shell расширяет боковые колонки на брейкпоинте
   1400: до него центр = окно минус 520, после - окно минус 620. То есть на
   1400px центр СКАЧКОМ падает с 880 до 780 и снова дорастает до 813 только
   к 1433px. Порог 813 превращал этот скачок в дыру: меню есть на 1350, на
   1400 пропадает, на 1433 возвращается. При тасовке окна это читается как
   мигание. (Дыра была и раньше, при пороге 790, но занимала 1400-1409 - 10px
   против нынешних 33, поэтому в глаза не бросалась.)

   Саму сетку не трогаю - она не в моей зоне. Вместо этого выкраиваю
   недостающие 33px в полосе, где центр 780-812, и только в ней: поля шапки
   26 -> 18 (даёт 16px) и поля пунктов 8 -> 7 при кегле 12 (даёт ещё 17).
   Меню 383 -> ~359, просвет до логотипа на 780 остаётся 18px. Выше 813
   ничего не меняется, вид на широких экранах прежний. */
@container center (min-width:780px) and (max-width:812px){
  /* display возвращаем ЯВНО: выше по файлу (строка ~1027) живёт прежнее
     правило @container center (max-width:790px){ .nav{display:none} }. Оно
     не снято, и на 780-790 гасило бы меню мимо моего порога. Специфичность
     та же, правило моё идёт позже - перебивает без !important. */
  .nav{ display:flex; }
  .header__inner{ padding-left:18px; padding-right:18px; }
  .nav a{ padding:7px 7px; font-size:12px; }
}

/* -------- Шапка во всю ширину окна --------
   Эталон держит шапку от края до края. У нас она лежит в центральной колонке,
   поэтому полоса обрывалась по её границам, а слева и справа над панелями
   зияла пустая лента высотой с шапку. Место под неё в макете УЖЕ было
   зарезервировано: .side__inner отбит сверху на 82px именно под шапку.

   Тянем ФОН, а не сам блок: содержимое шапки остаётся выровненным по колонке
   вместе со всей страницей. Смещения равны ширине боковых колонок из сетки
   .shell, так что полоса ложится точно по краям окна и не зависит от 100vw
   (в Chrome он считается вместе с полосой прокрутки и даёт лишние пиксели). */
@media (min-width:1200px){
  .header{ background:transparent; backdrop-filter:none; -webkit-backdrop-filter:none;
           border-bottom-color:transparent; }
  .header::before{
    content:""; position:absolute; top:0; bottom:0; left:-250px; right:-270px;
    z-index:-1; pointer-events:none;
    background:rgba(8,9,12,.80);
    backdrop-filter:blur(14px) saturate(150%);
    -webkit-backdrop-filter:blur(14px) saturate(150%);
    border-bottom:1px solid rgba(255,255,255,.085);
    transition:background var(--t-base), border-color var(--t-base);
  }
  .header.is-stuck::before{
    background:rgba(8,9,12,.92);
    border-bottom-color:rgba(255,255,255,.12);
  }
}
@media (min-width:1400px){
  .header::before{ left:-300px; right:-320px; }
}

/* Кнопка справа - белая с чёрным текстом, как Sign Up в эталоне: заливка
   градиентом СВЕРХУ ВНИЗ от белого к белому 60%. Это единственная белая
   кнопка на экране, поэтому она и читается как главное действие. */
.header__cta.btn--tg{
  background:linear-gradient(180deg,#FFFFFF 0%,rgba(255,255,255,.95) 52%,rgba(255,255,255,.66) 100%);
  color:#0A0B0E; border-color:rgba(255,255,255,.5); font-weight:600;
  box-shadow:0 6px 18px -10px rgba(0,0,0,.9);
}
.header__cta.btn--tg:hover{
  background:linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 60%,rgba(255,255,255,.8) 100%);
  border-color:rgba(255,255,255,.7);
  transform:scale(1.04);
}
.header__cta.btn--tg:active{ transform:scale(.97); }
/* Глиф Telegram заливается currentColor, на белом фоне он обязан быть тёмным. */
.header__cta .ico-tg{ color:#0A0B0E; }

/* -------------------------------------------------------------------------
   3. ПЕРВЫЙ ЭКРАН: ГЕОМЕТРИЯ И СВЕЧЕНИЕ
   ------------------------------------------------------------------------- */
.hero{ padding:76px 0 48px; }

.hero__grid{ position:relative; row-gap:34px; }

/* Свечение под блоком (пункт 7 эталона). Там это картинка с CDN, у нас
   внешние файлы запрещены, поэтому тот же блик собран градиентами:
   холодный подъём под панелью и еле заметный белый нимб под заголовком.
   Значения намеренно низкие - слой обязан читаться как глубина, а не как
   цветное пятно, и не должен глушить холст-созвездие под ним. */
/* 🔴 По горизонтали слой НЕ выпускаем за секцию. Замер на 390px: при
   inset слева и справа -8% ширина страницы становилась 421 при экране 390,
   то есть слой сам рождал горизонтальную прокрутку (её маскировал
   overflow-x:hidden у body, но контент по краям резался). Выигрыша от выноса
   не было: оба пятна и так гаснут на 44-52% ширины и до краёв не достают. */
.hero__glow{
  position:absolute; inset:-30px 0 0 0; z-index:0; pointer-events:none;
  background:
    radial-gradient(52% 26% at 50% 4%,  rgba(255,255,255,.06), transparent 72%),
    radial-gradient(44% 24% at 50% 56%, rgba(79,196,233,.11),  transparent 74%);
}
/* Контент обязан лежать ВЫШЕ свечения. Позиционированный слой с z-index:0
   рисуется поверх обычных блоков в потоке, поэтому колонке и списку тоже
   нужен свой контекст. */
.hero__copy, .hero .trust{ position:relative; z-index:1; }

/* -------------------------------------------------------------------------
   4. ПЛАШКА-АНОНС НАД ЗАГОЛОВКОМ
   Эталон: rounded-full, полупрозрачный серый, размытие, мелкий текст,
   справа ссылка со стрелкой. Наш вклад - живая точка акцента слева.
   ------------------------------------------------------------------------- */
.hero .pill--announce{
  padding:6px 6px 6px 14px; gap:10px; border-radius:999px;
  background:rgba(38,41,48,.5);
  border:1px solid rgba(255,255,255,.12);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  font-size:12.5px; line-height:1.45; color:var(--ae1-grey);
  max-width:100%; flex-wrap:wrap;
}
.hero .pill--announce .pill__dot{ width:6px; height:6px; }
.hero .pill--announce .pill__txt{ color:var(--ae1-grey); }
/* Цифра курса - единственное белое пятно в плашке, чтобы глаз цеплялся
   именно за неё. Моно, как все показания приборов на сайте. */
.hero .pill--announce b{
  font-family:var(--font-mono); font-weight:500; font-size:12.5px;
  color:#EAF0F6;
}
.hero .pill__link{
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
  padding:4px 11px 4px 10px; border-radius:999px;
  background:rgba(255,255,255,.06);
  color:var(--ae1-grey); font-size:12px;
  transition:color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.hero .pill__link:hover{ color:#fff; background:rgba(255,255,255,.12); }
.hero .pill__link:active{ transform:scale(.96); }
/* Стрелка идёт из общего набора символов, но обводка там не задана -
   она наследуется от svg. Без этих строк путь просто не нарисуется. */
.pill__arr{
  fill:none; stroke:currentColor; stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform var(--t-fast);
}
.hero .pill__link:hover .pill__arr{ transform:translateX(2px); }

/* -------------------------------------------------------------------------
   5. ЗАГОЛОВОК
   Эталон: font-medium (НЕ жирный), letter-spacing -0.05em, заливка градиентом
   сверху вниз от белого к белому 60%. Наше серебро от этого не пропадает -
   середина градиента держит холодный оттенок эталонного дека.
   ------------------------------------------------------------------------- */
.hero h1{
  margin-top:26px;
  font-weight:500;
  letter-spacing:-.05em;
  line-height:1.07;
  font-size:clamp(31px, 6.4cqi, 58px);
  background:linear-gradient(180deg,
              #FFFFFF 0%,
              #F6F9FC 34%,
              rgba(255,255,255,.62) 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
/* Третья строка. 🔴 ПРАВКА 22.08: акцентной заливки здесь больше нет.
   Канон агентства запрещает её прямо - «залить им фон или кнопку целиком
   нарушение», а тут акцентом была залита плоскость 52px во всю ширину, то
   есть самое крупное пятно страницы. Плюс она была приглушена до выцветшего,
   и получалось, что самая крупная надпись сайта читается как самая тусклая.
   Теперь строка держит то же серебро, что строки 1 и 2: заголовок снова
   одна мысль, а не две надписи разного цвета. */
.hero h1 .accent{
  background:linear-gradient(180deg,
              #FFFFFF 0%,
              #F4F7FA 26%,
              #C3CBD5 63%,
              #98A2AE 100%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* -------------------------------------------------------------------------
   6. РОТОР И ПОДЗАГОЛОВОК
   Ротор оставлен рабочим, но опущен по громкости: он был вторым голубым
   пятном подряд после заголовка. Подзаголовок - по эталону: мельче, серый
   #9ca3af, узкой колонкой.
   ------------------------------------------------------------------------- */
/* 🔴 Выравнивание по верху, а не по базовой линии. Варианты бегущей строки
   лежат в слоте АБСОЛЮТОМ, своей базовой линии у слота нет, и подпись
   «APOLLO EXCHANGE» вставала ниже самой строки на несколько пикселей.
   Одинаковая высота строки у подписи и у значения ставит их вровень. */
.hero .rotor{ margin-top:16px; gap:10px; align-items:flex-start; }
.hero .rotor__label{
  font-size:10.5px; line-height:22px; letter-spacing:.34em;
  color:rgba(255,255,255,.34);
}
.hero .rotor__slot b{
  /* Кегль по ширине окна: строка идёт в одну линию, и на 320px самая длинная
     фраза («крипта заморожена до вашего слова») обязана в неё влезть. */
  font-size:clamp(12.5px, 3.4vw, 14.5px); font-weight:500; letter-spacing:-.01em;
  line-height:1.5; color:rgba(255,255,255,.72);
}
/* 🔴 Высота места под бегущую строку. В файле выше она задана в em от кегля
   САМОГО слота (16px), а не вложенной строки, и на экранах до 400px правило
   резервировало 3.1em = 50px под одну строку в 22px. В макете это читалось
   как провал между заголовком и текстом. Считаем в пикселях по фактической
   строке: 22px текста плюс воздух. */
.hero .rotor__slot{ min-height:30px; }
.hero .lead{
  margin-top:18px;
  max-width:min(54ch,100%);
  font-size:clamp(14.5px, 1.15cqi, 16px);
  line-height:1.72;
  color:var(--ae1-grey);
}
/* Подпись под кнопками: тот же серый, ещё мельче. */
/* .52 - это ровно наш нижний порог контраста к #0C0D11 (около 5:1). Ниже в
   доме не опускаемся даже для служебных подписей. */
.hero__under{
  margin-top:14px; font-size:12.5px; line-height:1.5; color:rgba(255,255,255,.52);
}

/* -------------------------------------------------------------------------
   7. КНОПКИ ПЕРВОГО ЭКРАНА
   Радиус кнопок берётся из общей шкалы (.btn 14, .btn--sm 10, .btn--lg 16),
   цвет главной кнопки живёт в БЛОКЕ 5 и она одна на весь сайт: перекрашивать
   её из своей зоны нельзя. Здесь только ритм.
   ------------------------------------------------------------------------- */
.hero__cta{ margin-top:26px; }

/* -------------------------------------------------------------------------
   8. ПОЛОСА КУРСА, КАЛЬКУЛЯТОР, ГАРАНТИИ
   Радиусы и посадку акцентной полосы отдаём БЛОКУ 5. Здесь - только ритм,
   цвет подписи и свечение под главной панелью.
   ------------------------------------------------------------------------- */
.hero .rate-strip{ margin-top:24px; padding:15px 18px 15px 22px; }
.hero .rate-strip__note{ color:rgba(255,255,255,.52); }

/* Свечение под калькулятором - холодная тень вместо картинки с CDN у эталона.
   🔴 Тень ДОПИСЫВАЕТСЯ к штатной, а не заменяет её: box-shadow не
   накапливается, и голое своё значение стёрло бы --rim (стеклянный блик по
   верхней кромке) вместе с --shadow-panel, то есть панель потеряла бы
   материал ради подсветки. */
.hero__grid > .calc{
  box-shadow:var(--rim), var(--shadow-panel),
             0 44px 90px -46px rgba(79,196,233,.42);
}

.hero .trust{ margin-top:0; gap:12px; min-width:0; }
.hero .trust li{ padding:15px 17px; }
.hero .trust li span{ color:var(--ae1-grey); }

/* -------------------------------------------------------------------------
   9. РАСКЛАДКА
   Список гарантий вынесен из текстовой колонки и стал элементом сетки,
   поэтому на ДВУХ колонках его надо вернуть под текст явно. Раскладка
   считается по ширине .center (@container), а не окна: при живых боковых
   панелях центру остаётся 760-1300px, и мерить окно тут бессмысленно.
   ------------------------------------------------------------------------- */
@container center (min-width:1081px){
  .hero__copy{ grid-column:1; grid-row:1; }
  .hero__grid > .calc{ grid-column:2; grid-row:1 / span 2; align-self:start; }
  .hero .trust{ grid-column:1; grid-row:2; }
  /* 🔴 Кегль заголовка на двух колонках считаем ОТДЕЛЬНО. cqi меряет всю
     центральную колонку (на 1920 это 1300px), а текст живёт в левой её
     половине примерно в 660px. По общей шкале заголовок вырастал до 58px,
     и строка «а не с незнакомцем на бирже» переносилась, оставляя внизу
     сироту «бирже». 3.6cqi даёт ~47px и строка встаёт целиком. */
  .hero h1{ font-size:clamp(31px, 3.6cqi, 48px); }
}

/* ОДНА колонка - а это почти все экраны. Тут первый экран становится ровно
   эталоном: всё по центру узкой колонкой, под кнопкой главная панель. */
@container center (max-width:1080px){
  /* 🔴 Центруем ТЕКСТОМ, а не flex-контейнером. Колонка на
     display:flex + align-items:center сжимает каждого ребёнка до ширины его
     содержимого: подзаголовок вставал в четыре строки, а ротор ломался
     пополам. text-align центрует, не трогая ширины. */
  .hero__copy{ text-align:center; }
  .hero .lead{ margin-left:auto; margin-right:auto; }
  .hero .rotor{ justify-content:center; }
  /* Моно-подпись «APOLLO EXCHANGE» на центрованной раскладке убираем. Она
     стоит слева от бегущей строки, и пара получается кривой: подпись у края,
     значение по центру. Одна бегущая строка под заголовком читается чище. */
  .hero .rotor__label{ display:none; }
  /* Варианты ротора лежат друг на друге абсолютом. Без right:0 они бы
     центрировались не по слоту, а прилипли к левому краю. */
  .hero .rotor__slot{ flex:0 1 auto; min-width:min(340px,100%); }
  .hero .rotor__slot b{ left:0; right:0; text-align:center; white-space:nowrap; }
  .hero__cta{ justify-content:center; }
  .hero .rate-strip{ justify-content:center; max-width:600px; margin-left:auto; margin-right:auto; }
  .hero__grid > .calc{ margin-left:auto; margin-right:auto; }
  .hero .trust{ max-width:640px; margin-left:auto; margin-right:auto; }
}

/* -------------------------------------------------------------------------
   10. ПОЯВЛЕНИЕ
   Эталон: fadeIn 0.6s ease-out с подъёмом снизу. Лёгкий разбег по элементам
   даёт ощущение сборки экрана, а не мигания целым куском.

   Заодно это страховка: раньше первый экран висел на .reveal, то есть на
   JS. Не отработал IntersectionObserver - экран пустой. Анимация выставляет
   видимость сама (fill both), поэтому текст на месте даже без скриптов.
   ------------------------------------------------------------------------- */
@keyframes aeHeroIn{
  from{ opacity:0; transform:translateY(14px); }
  to  { opacity:1; transform:none; }
}
.hero .reveal{ opacity:1; transform:none; }
.hero__copy,
.hero__grid > .calc,
.hero .trust{
  animation:aeHeroIn .6s cubic-bezier(.22,.61,.36,1) both;
}
.hero__copy{ animation-delay:20ms; }
.hero__grid > .calc{ animation-delay:110ms; }
.hero .trust{ animation-delay:170ms; }

/* 🔴 Пока идёт интро на частицах, проявление держим на паузе. Иначе оно
   целиком проходит ЗА непрозрачным оверлеем: интро висит несколько секунд,
   а анимация длится 0.6с и к моменту снятия шторки давно отыграна - при
   первом заходе её не видит никто. Класс intro-lock app.js снимает с <html>
   ровно в тот кадр, когда интро начинает растворяться, так что первый экран
   проявляется вместе с ним. Если интро пропущено (второй заход на вкладку
   или системное «меньше движения»), класса нет и пауза не срабатывает. */
html.intro-lock .hero__copy,
html.intro-lock .hero__grid > .calc,
html.intro-lock .hero .trust{ animation-play-state:paused; }

@media (prefers-reduced-motion: reduce){
  .hero__copy,
  .hero__grid > .calc,
  .hero .trust{ animation:none; opacity:1; transform:none; }
  .header__cta.btn--tg:hover,
  .header__cta.btn--tg:active{ transform:none; }
  .hero .pill__link:hover .pill__arr{ transform:none; }
}

/* -------------------------------------------------------------------------
   11. УЗКИЙ ЭКРАН
   Прежнее правило для 620px стоит ВЫШЕ по файлу, а значит проигрывает моему
   кеглю заголовка. Возвращаем мобильную шкалу здесь.
   ------------------------------------------------------------------------- */
@media (max-width:900px){
  .hero{ padding:44px 0 32px; }
  .header__inner{ padding:11px 18px; }
}
@media (max-width:620px){
  .hero h1{ font-size:clamp(26px, 7.4vw, 38px); }
  /* 🔴 Снимаем ТОЛЬКО первый ручной перенос. Он рассчитан на широкую строку,
     а на телефоне держал заголовок рваным. Второй перенос оставлен нарочно:
     он отбивает акцентную фразу, и без него «а не» оставалось хвостом
     предыдущей строки - смена цвета посреди строки читается как сбой
     отрисовки. text-wrap:balance из базы дальше сам ровняет длину строк. */
  .hero h1 br:first-of-type{ display:none; }

  /* 🔴 На телефоне плашка перестаёт быть flex-строкой. Как flex она ломалась
     на строки поэлементно, и акцентная точка уезжала отдельной строкой в
     потолок плашки. Обычный блок с точкой inline-block держит её приклеенной
     к первому слову при любом переносе. */
  .hero .pill--announce{
    display:block; text-align:center;
    font-size:12px; padding:9px 14px; border-radius:16px;
  }
  .hero .pill--announce .pill__dot{
    display:inline-block; vertical-align:middle; margin-right:7px;
  }
  /* Ссылка из плашки на телефоне убрана: прямо под ней стоит кнопка
     «Как проходит сделка» с тем же адресом, и в узкой колонке плашка из-за
     неё разъезжалась на три строки. */
  .hero .pill__link{ display:none; }

  /* Кнопки в столбик и во всю ширину: две центрованные кнопки разной длины
     смотрелись рвано, а палец на телефоне требует широкой цели. */
  .hero__cta{ flex-direction:column; align-items:stretch; }
  .hero__cta .btn{ width:100%; }

  /* Свечение на телефоне слабее, но штатные тени панели по-прежнему на месте:
     box-shadow заменяется целиком, перечисляем всё. */
  .hero__grid > .calc{
    box-shadow:var(--rim), var(--shadow-panel),
               0 28px 60px -40px rgba(79,196,233,.34);
  }
}
/* ═══ ЗОНА 1: ШАПКА И ПЕРВЫЙ ЭКРАН - КОНЕЦ ═══ */

/* =========================================================================
   ==== ЗОНА 2: КАРТА ОФЛАЙН-ВЫДАЧИ - НАЧАЛО ====
   Жалоба владельца 19.08: «карта даже говно, сделай лучше». Раньше это была
   градусная сетка с подписями «55° с.ш.» и четырьмя точками на пустом поле -
   прибор, а не карта. Здесь она переделана по образцу expand-map с 21st.dev,
   который он же прислал: тёмное поле, магистрали толстыми линиями малой
   прозрачности, кварталы-прямоугольники, светящаяся булавка с пульсом,
   координаты моноширинным, метка LIVE в углу, мягко скруглённая рамка.

   Дом-стиль Apollo не выброшен, а соединён с образцом:
     - акцент #4FC4E9 точечно (маршруты, активная метка, полоса слева),
     - акцентная полоса 3px слева у рамки карты осталась,
     - радиусы подняты с 6px до 16px, как в образце.

   Блок идёт последним в файле, поэтому переопределяет прежние правила .geo__*
   без !important везде, где хватает порядка. Разметка зоны - секция #offline.
   ========================================================================= */

/* ---------- рамка карты ----------
   Высоту задаём процентным паддингом, а не aspect-ratio: замерено, что при
   aspect-ratio вместе с min-height браузер выводит ШИРИНУ обратно из пропорции
   и карта вылезает за колонку. Паддинг считается от ширины родителя и обратной
   связи на ширину не имеет.

   60% = 720/1200, ровно пропорция viewBox: значит на широком экране подложка
   не растянута совсем. Пол 500px нужен на узкой колонке (в макете с боковыми
   панелями центр всего ~764px); там растяжение доходит до 5%, что не видно
   ни на дорогах (у них non-scaling-stroke), ни на кварталах. */
.geo__map{
  padding-bottom:60%;
  min-height:500px;
  border:1px solid rgba(255,255,255,.10);
  border-radius:16px;
  background:
    radial-gradient(120% 90% at 58% 40%, rgba(255,255,255,.05) 0%, rgba(255,255,255,0) 62%),
    #101218;
  box-shadow:0 26px 60px -30px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.05);
  overflow:visible;
}
/* Акцентная полоса дом-стиля. Вертикальные отступы обязательны: рамка теперь
   скруглена на 16px, и полоса от угла до угла резала бы скругление. */
.geo__map::before{
  content:""; position:absolute; left:0; top:18px; bottom:18px; width:var(--bar); z-index:6;
  background:var(--accent); box-shadow:var(--accent-glow);
  border-radius:0 3px 3px 0;
}
.geo__stage{ border-radius:15px; overflow:hidden; }
/* Виньетка по краям: без неё поле равномерно светлое и глаз не понимает, куда
   смотреть. Это отдельный слой, а не inset-тень: inset-тень рисуется под
   содержимым элемента и дороги с кварталами она бы не притушила вообще. */
.geo__stage::after{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:radial-gradient(82% 92% at 56% 44%,
             rgba(8,9,12,0) 46%, rgba(8,9,12,.30) 80%, rgba(8,9,12,.58) 100%);
}

/* ---------- подложка: дороги, река, кварталы ----------
   Толщину линий держит non-scaling-stroke: подложка тянется с
   preserveAspectRatio="none", и без него вертикальные улицы стали бы тоньше
   горизонтальных ровно во столько раз, во сколько растянута карта. */
.geo__road{ fill:none; stroke-linecap:square; vector-effect:non-scaling-stroke; }
.geo__road--s{ stroke:rgba(255,255,255,.055); stroke-width:1.4; }  /* поперечные улицы */
.geo__road--m{ stroke:rgba(255,255,255,.07);  stroke-width:4;   }  /* районные */
.geo__road--l{ stroke:rgba(255,255,255,.095); stroke-width:9;   }  /* магистрали */
/* Диагонали дают городу характер, но идут через всё поле без перекрёстков,
   поэтому яркость у них НИЖЕ, чем у магистралей: иначе читаются как царапины
   поверх карты, а не как проспекты. */
.geo__road--d{ stroke:rgba(255,255,255,.035); stroke-width:6; stroke-linecap:round; }
/* Река. Прямые линии есть у любой сетки, изогнутой воды у сетки не бывает -
   поэтому одна кривая делает «вид сверху» узнаваемее десяти улиц.
   Цвет нарочно НЕ акцентный: акцент на этой карте занят смыслом «выдача». */
.geo__river{
  fill:none; stroke:rgba(116,146,178,.115); stroke-width:14;
  stroke-linecap:round; stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
}
/* Тонкая кромка по кварталу - приём из образца (border у «зданий»): без неё
   прямоугольники сливаются в пятна, с ней читаются как застройка. */
.geo__blk{
  fill:rgba(255,255,255,.042);
  stroke:rgba(255,255,255,.07); stroke-width:1;
  vector-effect:non-scaling-stroke;
}
.geo__blk--2{ fill:rgba(255,255,255,.058); stroke:rgba(255,255,255,.095); }
.geo__blk--3{ fill:rgba(255,255,255,.028); stroke:rgba(255,255,255,.045); }
.geo__blk--park{ fill:rgba(99,198,162,.05); stroke:rgba(99,198,162,.075); }

/* ---------- маршруты ----------
   Прежняя карта красила маршрут серебром и зажигала только выбранный. Но
   маршрут тут значит «к вам выезжает наш человек», а это как раз то, ради
   чего блок существует, поэтому нитки горят акцентом всегда, а выбранная
   становится ярче и толще. */
.geo__arc{
  fill:none; stroke:rgba(79,196,233,.36); stroke-width:1.3;
  stroke-dasharray:4 8; stroke-linecap:round;
  vector-effect:non-scaling-stroke;
  transition:stroke var(--t-base), stroke-width var(--t-base);
}
.geo__arc.is-active{ stroke:rgba(79,196,233,.85); stroke-width:2; }
/* Искру двигает SMIL, а не JS: рассинхрона с дугой быть не может по
   построению - у анимации тот же самый path, что у линии. */
/* Искре нужен ореол: без него точка радиусом 3.4 на тёмном поле теряется,
   и «кто-то едет по маршруту» перестаёт читаться. */
.geo__spark{
  fill:#DCF4FD; opacity:.7;
  filter:drop-shadow(0 0 5px rgba(79,196,233,.95));
  transition:opacity var(--t-base);
}
.geo__spark.is-active{ opacity:1; }
.geo__map.has-open .geo__arc:not(.is-active){ stroke:rgba(79,196,233,.14); }
.geo__map.has-open .geo__spark:not(.is-active){ opacity:.18; }

/* ---------- метки городов ----------
   🔴 Слой меток лежит ПОД карточками (2 против 4), и это переворот прежнего
   порядка. Раньше метки были сверху, чтобы соседний город оставался
   кликабельным при открытой карточке. С панелью это дало брак, который видно
   на снимке: булавка и подпись Казани проступали сквозь текст карточки
   Испании, читать было нельзя. Панель теперь непрозрачная и честно накрывает
   то, что под ней, как в любой нормальной карте.

   Кликабельность при этом не потеряна: слой карточек pointer-events:none, auto
   включается только у открытой панели, а панель занимает 41% ширины и
   закрывает максимум две метки из четырёх. Оставшиеся две нажимаются, не
   закрывая текущую.

   pointer-events:none на слое меток обязателен: без него слой перехватывает
   все клики и кнопка «Свернуть» не срабатывает ни разу. */
.geo__pins{ z-index:2; pointer-events:none; }
.geo__pin{
  position:absolute; left:var(--x); top:var(--y);
  /* Коробка кнопки = коробка булавки, остриё приходится ровно на координату
     города. Центруем отрицательными margin, а не transform: transform
     оставлен ховеру, иначе анимация сбивала бы позицию. */
  width:30px; height:38px; margin:-38px 0 0 -15px;
  padding:0; border:0; background:none; cursor:pointer;
  pointer-events:auto; z-index:2;
}
/* Область нажатия шире рисунка: попасть в булавку 30px мышью можно, но
   промахнуться неприятно. Сам рисунок при этом не растёт. */
.geo__pin::after{ content:""; position:absolute; inset:-9px -12px -12px -12px; }
.geo__mark{
  position:absolute; left:0; bottom:0; width:30px; height:38px;
  transition:transform var(--t-fast), filter var(--t-fast);
  transform-origin:50% 100%;
  filter:drop-shadow(0 0 10px rgba(79,196,233,.45));
}
.geo__mark svg{ width:100%; height:100%; display:block; }
/* Тело булавки акцентом, «окошко» внутри - цветом подложки, как в образце.
   Обводка нужна, чтобы метка читалась поверх светлого квартала. */
.geo__mark svg path{ fill:var(--accent); stroke:rgba(255,255,255,.55); stroke-width:1; }
.geo__mark svg circle{ fill:#0E1015; }
/* Москва - единственная постоянная точка, у неё булавка крупнее и ярче. */
.geo__pin--live .geo__mark{
  width:36px; height:46px; left:-3px;
  filter:drop-shadow(0 0 14px rgba(79,196,233,.75));
}
.geo__pin--live .geo__mark svg path{ stroke:#DCF4FD; }
/* Пульс расходится от острия, то есть ровно от координаты города.
   🔴 top:auto ОБЯЗАТЕЛЕН, ровно та же ловушка, что и у подписи. Прежнее
   правило «.geo__dot, .geo__ping» выше по файлу ставит top:50%, и вместе с
   моим bottom:0 при заданной высоте коробка становится переопределённой:
   браузер оставляет top и выбрасывает bottom. Замерено - центр пульса
   оказывался на 11px ВЫШЕ острия, то есть не в координате города, а в
   произвольной точке тела булавки. */
.geo__ping{
  position:absolute; left:50%; top:auto; bottom:0; width:16px; height:16px;
  margin:0 0 -8px -8px; border-radius:50%;
  background:rgba(79,196,233,.55); opacity:0;
  animation:geoPing2 2.9s cubic-bezier(.22,.61,.36,1) infinite;
}
@keyframes geoPing2{
  0%   { transform:scale(.35); opacity:.75; }
  70%  { transform:scale(3.1);  opacity:0; }
  100% { transform:scale(3.1);  opacity:0; }
}
.geo__pin:hover .geo__mark{ transform:translateY(-3px) scale(1.06); }
.geo__pin.is-active .geo__mark{
  transform:translateY(-4px) scale(1.1);
  filter:drop-shadow(0 0 18px rgba(79,196,233,.95));
}
.geo__pin:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:8px; }
/* 🔴 Клавиатура. Метки лежат ПОД карточкой, поэтому при открытой панели две
   метки из четырёх оказываются под ней. Мышью это нормально (так ведёт себя
   любая карта), но у клавиатуры Tab обходит ВСЕ кнопки, и рамка фокуса
   уезжала бы за панель: пользователь не видел бы, где он находится.
   Поэтому слой меток всплывает над карточкой ровно на то время, пока фокус
   внутри него, а сама метка в фокусе перестаёт быть притушенной.

   🔴 Условие именно :focus-visible, а НЕ :focus-within. Замерено: в Chrome
   клик мышью по <button> тоже ставит фокус, поэтому с :focus-within слой
   меток всплывал над карточкой ПОСЛЕ ОБЫЧНОГО КЛИКА и держался там всё
   время, пока панель открыта. Последствий было два, оба видны на снимке:
   булавка и подпись соседнего города рисовались поверх текста карточки
   (тот самый брак, ради которого метки и уводили вниз), а расширенная зона
   нажатия метки Малаги ложилась ровно на кнопку «Свернуть» карточки Москвы,
   и клик по «Свернуть» открывал Испанию вместо закрытия. :focus-visible на
   клик мышью не срабатывает, поэтому слой всплывает только под клавиатурой,
   ради которой правило и написано. */
.geo__pins:has(.geo__pin:focus-visible){ z-index:6; }

/* ---------- подпись города ----------
   Подпись видна ВСЕГДА: карта без названий городов - это узор. Координаты
   моноширинным и мельче, как в образце: они дают ощущение прибора, но не
   спорят за внимание с названием. */
/* 🔴 top/left/transform ОБЯЗАТЕЛЬНО сбрасываются. Прежнее правило .geo__tag
   выше по файлу ставит left:50%, top:calc(50% + 12px) и translateX(-50%).
   Одного нового left мало: старый top остаётся, вместе с моим bottom он
   растягивает подпись по вертикали (замерено: высота схлопывалась до 10px),
   а чужой translateX уводил её на полширины влево, под саму булавку. */
.geo__tag{
  position:absolute; top:auto; right:auto; bottom:auto; left:auto; transform:none;
  display:grid; gap:1px; white-space:nowrap;
  padding:4px 9px 5px; border-radius:8px;
  border:1px solid rgba(255,255,255,.07);
  background:rgba(9,10,14,.72);
  backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px);
  text-transform:none; letter-spacing:normal; text-shadow:none;
  transition:opacity var(--t-base), color var(--t-fast), border-color var(--t-fast);
}
/* Сторона подписи выбрана НЕ по вкусу, а по замеру на самой узкой карте
   (в макете с боковыми панелями поле всего 764px). Подписи имеют постоянную
   ширину в пикселях, а карта сжимается, поэтому на 764px подпись Москвы
   справа наезжала на подпись Казани. Москва подписана слева, Казань снизу,
   Петербург и Малага справа - в этой комбинации пересечений нет ни на одной
   ширине от 771px до максимума. */
.geo__pin--tr .geo__tag{ left:calc(100% + 8px); bottom:-4px; }
.geo__pin--tl .geo__tag{ right:calc(100% + 8px); bottom:-4px; }
.geo__pin--live.geo__pin--tr .geo__tag{ left:calc(100% + 13px); }   /* булавка Москвы шире кнопки */
.geo__pin--live.geo__pin--tl .geo__tag{ right:calc(100% + 13px); }
.geo__pin--tb .geo__tag{ left:50%; transform:translateX(-50%); top:calc(100% + 8px); }
.geo__tag-n{
  font-size:13px; font-weight:650; line-height:1.2; letter-spacing:-.01em;
  color:#E9EEF4; text-transform:none;
}
.geo__tag-c{
  font-family:var(--font-mono); font-size:10px; font-weight:500;
  letter-spacing:.06em; line-height:1.3; color:var(--dim);
}
.geo__pin--live .geo__tag-n{ color:#FFFFFF; font-size:14px; }
.geo__pin:hover .geo__tag-n,
.geo__pin.is-active .geo__tag-n{ color:#FFFFFF; }
.geo__pin.is-active .geo__tag-c{ color:var(--accent-ink); }
/* Когда карточка открыта, чужие подписи гаснут: иначе они лезут в её текст. */
.geo__map.has-open .geo__pin:not(.is-active) .geo__tag{ opacity:.25; }
.geo__map.has-open .geo__pin:not(.is-active) .geo__mark{ filter:none; opacity:.5; }
/* 🔴 Правила фокуса стоят ПОСЛЕ гашения, а не рядом с остальным фокусом.
   Специфичность у них одинаковая (пять классов), поэтому побеждает то, что
   ниже: замерено, что при обратном порядке метка под фокусом оставалась
   притушенной до .5 и рамку фокуса было плохо видно. */
.geo__map.has-open .geo__pin:focus-visible .geo__mark{ opacity:1; }
.geo__map.has-open .geo__pin:focus-visible .geo__tag{ opacity:1; }
.geo__map.has-open .geo__ping{ opacity:0; animation:none; }

/* ---------- служебные плашки на карте ---------- */
.geo__plate, .geo__legend, .geo__now{
  position:absolute; z-index:4; pointer-events:none;
  border:1px solid rgba(255,255,255,.10); border-radius:11px;
  background:rgba(12,13,18,.72);
  backdrop-filter:blur(9px); -webkit-backdrop-filter:blur(9px);
  transition:opacity var(--t-base), transform var(--t-base);
}
.geo__plate{ left:16px; top:16px; right:auto; bottom:auto; padding:9px 13px 10px; display:grid; gap:4px; }
/* Легенда переехала из левого нижнего угла в правый нижний. Причина замерена:
   слева внизу стоит метка Малаги (12% ширины, 79% высоты), и её подпись с
   координатами попадала прямо под легенду. Справа внизу поле пустое. */
.geo__legend{
  right:16px; bottom:16px; left:auto; top:auto;
  padding:11px 14px 12px; display:grid; gap:7px; max-width:262px;
}
/* Метка LIVE в углу, как в образце: зелёная точка + капс. Зелёный тут не
   декор - он отделяет «данные живые» от акцента, которым помечена выдача. */
.geo__now{
  right:16px; top:16px; padding:6px 11px 6px 10px;
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:600;
  letter-spacing:.22em; color:#D6DDE5;
}
.geo__now i{
  width:7px; height:7px; border-radius:50%; background:var(--up);
  box-shadow:0 0 9px 1px rgba(99,198,162,.7);
  animation:geoLive 2.2s ease-in-out infinite;
}
@keyframes geoLive{ 0%,100%{ opacity:1; } 50%{ opacity:.35; } }
/* Вся служебная обвязка уходит, когда открыта карточка: панель занимает то же
   место, и два слоя текста наложились бы друг на друга. */
.geo__map.has-open .geo__plate,
.geo__map.has-open .geo__legend,
.geo__map.has-open .geo__now{ opacity:0; transform:translateY(6px); }
.geo__legend-h{ margin-top:1px; }
/* Ключи легенды обязаны совпадать с тем, что реально нарисовано на карте.
   🔴 Вячеслав 19.08: «везде оставь, что работает, и везде подписывай, какие
   моменты». Работают все четыре города, поэтому серого ключа «сейчас нет»
   тут больше нет: обе метки акцентные, разница только в свечении, как у
   булавок - у Москвы ореол, у остальных ровный цвет. */
.geo__key{
  background:var(--accent); border-color:rgba(189,236,251,.55); box-shadow:none;
}
.geo__key--live{
  background:var(--accent); border-color:#DCF4FD;
  box-shadow:0 0 10px 2px rgba(79,196,233,.7);
}

/* ---------- карточка города ----------
   Прежняя раскладка привязывала карточку к самой метке (вниз-влево от точки),
   и на низкой карте она гарантированно вылезала за рамку: метка Москвы стоит
   на 45% высоты, а карточке нужно 340px вниз, которых там нет.

   Теперь карточка приезжает панелью к краю карты, ПРОТИВОПОЛОЖНОМУ метке:
   Москва и Казань стоят справа - панель слева, Петербург и Малага слева -
   панель справа. Метка остаётся видна, панель ограничена высотой рамки и
   вылезти не может по построению. */
.geo__cards{ z-index:4; pointer-events:none; }
.geo__card{
  position:absolute; top:16px; width:41%; min-width:264px;
  max-height:calc(100% - 32px); overflow:auto;
  padding:16px 18px 15px 20px;
  border:1px solid rgba(255,255,255,.14); border-radius:14px;
  /* 🔴 Подложка НЕПРОЗРАЧНАЯ. При rgba(12,13,18,.94) сквозь текст карточки
     Испании читалась подпись Казани - замерено на снимке, брак очевидный.
     Полупрозрачное стекло годится, когда под ним фон, а не другой текст.
     backdrop-filter поэтому убран: под сплошным цветом он ничего не делает,
     только стоит кадров. */
  background:linear-gradient(103deg, rgba(255,255,255,.085), rgba(255,255,255,.03)), #0E1015;
  box-shadow:0 26px 54px -18px rgba(0,0,0,.75);
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity var(--t-base), transform var(--t-base), visibility var(--t-base);
}
.geo__card::before{ border-radius:14px 0 0 14px; }
.geo__card--l{ left:2.6%;  transform:translateX(-14px) scale(.97); }
.geo__card--r{ right:2.6%; transform:translateX(14px)  scale(.97); }
.geo__card.is-open{ opacity:1; visibility:visible; pointer-events:auto; transform:none; }
/* Поводок к метке не рисуем намеренно: панель стоит у края, метка - в поле,
   прямая между ними всё равно прошла бы по тексту. Связь держат другие
   сигналы: активная булавка ярче и крупнее, её маршрут горит, остальные
   гаснут, а в шапке панели стоят координаты той же самой точки. */
.geo__card--dl::after, .geo__card--ur::after{ display:none; }
/* Координаты в шапке карточки - те же цифры, что под меткой на карте.
   Это и есть подтверждение «панель про вот эту точку». */
.geo__card-geo{
  margin-top:4px;
  font-family:var(--font-mono); font-size:11px; font-weight:500;
  letter-spacing:.07em; color:var(--dim);
}
.geo__card-sub{ margin-top:7px; }
.geo__status--ask{ color:#D8DEE6; }
.geo__status--ask i{ background:rgba(255,255,255,.55); }
/* Замерено: при position:sticky у кнопки Chrome насчитывал карточке лишние
   11px scrollHeight и включал прокрутку там, где содержимое помещается.
   Прокрутка карточке нужна только как страховка при увеличенном шрифте,
   поэтому кнопка обычная. */
.geo__close{ position:static; margin-top:14px; }

/* ---------- узкий экран ----------
   Карта складывается в вертикальный список карточек. Правила повторены для
   @container и @media намеренно: контейнерный запрос меряет ширину ЦЕНТРА
   (в макете с боковыми панелями это ~764px при окне 1440), медиазапрос
   страхует браузеры без поддержки контейнеров. Дублирование дешевле, чем
   горизонтальная прокрутка на 320px.

   Правила продублированы ещё и здесь, в конце файла, потому что в моей
   раскладке у карточек новые модификаторы --l/--r той же специфичности, что
   и .geo__card в старых медиазапросах выше: без повтора позднее правило
   победило бы и на телефоне карточки остались бы абсолютными. */
@container center (max-width:770px){
  .geo__map{ padding-bottom:0; min-height:0; border:0; border-radius:0; background:none; box-shadow:none; }
  .geo__map::before{ display:none; }
  .geo__stage, .geo__pins{ display:none; }
  .geo__cards{ position:static; inset:auto; pointer-events:auto; display:grid; gap:12px; }
  .geo__card, .geo__card--l, .geo__card--r{
    position:static; inset:auto; width:auto; min-width:0; max-width:none;
    max-height:none; overflow:visible;
    transform:none; opacity:1; visibility:visible; pointer-events:auto;
    border-radius:12px; box-shadow:none;
    backdrop-filter:none; -webkit-backdrop-filter:none;
    background:var(--panel);
  }
  .geo__close{ display:none; }
}
@media (max-width:770px){
  .geo__map{ padding-bottom:0; min-height:0; border:0; border-radius:0; background:none; box-shadow:none; }
  .geo__map::before{ display:none; }
  .geo__stage, .geo__pins{ display:none; }
  .geo__cards{ position:static; inset:auto; pointer-events:auto; display:grid; gap:12px; }
  .geo__card, .geo__card--l, .geo__card--r{
    position:static; inset:auto; width:auto; min-width:0; max-width:none;
    max-height:none; overflow:visible;
    transform:none; opacity:1; visibility:visible; pointer-events:auto;
    border-radius:12px; box-shadow:none;
    backdrop-filter:none; -webkit-backdrop-filter:none;
    background:var(--panel);
  }
  .geo__close{ display:none; }
}

@media (prefers-reduced-motion:reduce){
  .geo__ping{ animation:none; opacity:0; }
  .geo__now i{ animation:none; }
  .geo__spark{ display:none; }
  .geo__mark, .geo__card{ transition:none; }
}
/* ==== ЗОНА 2: КАРТА ОФЛАЙН-ВЫДАЧИ - КОНЕЦ ==== */


/* =========================================================================
   ==== ЗОНА 3: БОКОВЫЕ ПАНЕЛИ И КАРТОЧКИ КОНТЕНТА - НАЧАЛО ====
   (добавлено 21.08.2026 по эталону saa-s-template, присланному 19.08)

   ЖАЛОБА ВЛАДЕЛЬЦА: «сейчас говно какое-то, сделай лучше всё».

   ЧТО БЫЛО НЕ ТАК, по пунктам, а не «некрасиво»:

   1. МАТЕРИАЛ ПЛАШКИ. Поверхность была диагональным градиентом белого
      (.085 -> .028 под 103 градуса) плюс ещё один градиентный слой ::after
      сверху. Две наложенные растяжки дают неровное серое пятно: левый край
      карточки заметно светлее правого, и в ряду из трёх карточек глаз ловит
      эту разницу как брак печати. Эталон устроен наоборот: поверхность
      РОВНАЯ и почти чёрная, а форму держит волосяная граница. Здесь ровно
      так и сделано - один плоский слой 3% белого, ::after погашен.

   2. ПЕСТРОТА. Голубым светилось всё подряд: рамки и заливки у восьми
      значков, шесть значков быстрых разделов, тринадцать «галочек» FAQ,
      рубрики ленты, дефисы в списках услуг, ссылки-CTA. Акцент, который
      стоит в двадцати местах, перестаёт быть акцентом. Оставлен ТОЧЕЧНО:
      полоса 3px слева у смысловых блоков, активная точка спотлайта,
      открытый пункт FAQ, живой курс в шапке рынка и свечение по наведению.
      Всё остальное - серо-белое, штрих значка наследуется от текста.

   3. СВЕЧЕНИЕ. Полоса светилась через --accent-glow: 46px размытия с
      разлётом 9px. На тёмном фоне это давало ореол шире самой полосы -
      вид дешёвой неоновой вывески. Здесь своё --z3-glow: 10px без разлёта.

   4. ЗАГОЛОВКИ. Базовое правило файла даёт h3 вес 700. В эталоне заголовки
      medium с лёгким отрицательным трекингом - тяжёлый шрифт на карточке
      выглядит как заголовок объявления, а не как продукт.

   5. ЗНАЧКИ. Штрих был залит SVG-градиентом (url(#aeNeon)/url(#aeMetal)),
      то есть цвет НЕ наследовался от текста и не менялся вместе с ним.
      Размеры коробок гуляли: 46, 44, 48, 38, 40, 30, 28. Теперь два
      согласованных размера - 44 в карточках контента и 32/28 в панелях,
      штрих везде 1.5 и currentColor.

   КОНТРАСТ (WCAG 2.1, замер по композитной поверхности карточки).
   Поверхность = 3% белого поверх фона страницы. Фон у краёв #0C0D11,
   в центре подсвечен до #15161B, поэтому карточка лежит в диапазоне
   rgb(23,24,27) ... rgb(28,29,34). Считаем по СВЕТЛОМУ краю - он даёт
   худший, то есть честный, результат:
     #FFFFFF заголовок          16.8:1
     #C3CBD5 низ градиента      10.3:1
     #B3BAC5 длинный текст       8.6:1
     #9CA3AF вторичный текст     6.6:1   (эталонный серый)
     #9BE0F7 акцент по тексту   11.5:1
     #4FC4E9 полоса и точки      8.4:1
   На наведении поверхность поднимается до 5.5% белого, худший случай
   rgb(34,35,40): #9CA3AF даёт 6.2:1. Ниже 4.5:1 не опускается ничего.

   ГРАНИЦЫ ЗОНЫ. Здесь нет ни одного селектора .geo__*, .offline, .hero,
   .header, .arc, .step, .calc - по ним работают другие исполнители.
   Ни одно правило не трогает разметку калькулятора, полосу курса, ссылки
   на бота и фон-созвездие.
   ========================================================================= */

:root{
  /* Поверхность плоская, без растяжки: см. пункт 1 выше. */
  --z3-surface:    rgba(255,255,255,.030);
  --z3-surface-hi: rgba(255,255,255,.055);   /* наведение и открытый FAQ */
  --z3-line:       rgba(255,255,255,.085);   /* волосяная граница покоя */
  --z3-line-hi:    rgba(255,255,255,.165);   /* она же под курсором */

  /* Блик по верхней кромке слабее прежнего --rim (.16): при плоской
     поверхности сильный блик снова читается как градиент. */
  --z3-rim:        inset 0 1px 0 rgba(255,255,255,.06);
  --z3-shadow:     0 18px 40px -32px rgba(0,0,0,.92);
  --z3-shadow-hi:  0 24px 48px -28px rgba(0,0,0,.95);
  /* Кольцо акцента по наведению вместо заливки: акцент виден, но блок
     остаётся серо-белым. */
  --z3-ring:       0 0 0 1px rgba(79,196,233,.15), 0 0 22px -8px rgba(79,196,233,.26);
  /* Заливка акцентной полосы. Вынесена в переменную, потому что применяется
     в четырёх местах: крупные блоки, карточка сетки, открытый пункт FAQ. */
  --z3-bar:        linear-gradient(180deg,
                    rgba(79,196,233,.10) 0%, var(--accent) 24%,
                    var(--accent) 76%, rgba(79,196,233,.10) 100%);

  /* Скругления на ступень мягче прежних 16/12/9. Числа не свои: это ровно
     шкала первого экрана (--ae1-r-lg/md/sm/xs = 18/14/12/10), которую задал
     исполнитель по шапке и калькулятору. Боковая панель стоит вплотную к
     калькулятору, и своя шкала на 2px в стороне читалась бы как небрежность. */
  --z3-r-panel:    18px;
  --z3-r-card:     14px;
  --z3-r-inner:    10px;
  --z3-r-ico:      12px;

  --z3-body:       #B3BAC5;   /* длинный читаемый текст: оговорки, FAQ, услуги */
  --z3-mut:        #9CA3AF;   /* вторичный текст карточек, серый эталона */

  /* Заголовок карточки: белый сверху, серебро снизу. Дом-стиль и эталон
     тут совпадают, эталон делает то же самое белым с падением до 60%. */
  --z3-title:      linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 38%,#C3CBD5 100%);

  /* Тугое свечение вместо ореола: см. пункт 3 выше. */
  --z3-glow:       0 0 10px 0 rgba(79,196,233,.42);
  --z3-blur:       blur(12px) saturate(118%);
}

/* -------------------------------------------------------------------------
   1. ОБЩИЙ МАТЕРИАЛ ЗОНЫ
   Один слой заливки, одна волосяная граница, мягкое скругление, размытие
   подложки. Всё, что делает форму, живёт здесь; ниже только частности.
   ------------------------------------------------------------------------- */
.spot, .market, .feed, .card, .svc, .guard, .whyus-card,
.faq__item, .vs__col, .honest{
  background:var(--z3-surface);
  border:1px solid var(--z3-line);
  box-shadow:var(--z3-rim), var(--z3-shadow);
}

/* Погашенный верхний градиент. Именно два наложенных градиента давали
   «серую кашу», ради которой всё и переделывается. */
.spot::after, .market::after, .feed::after, .card::after, .svc::after,
.guard::after, .vs__col::after, .honest::after, .qcard::after{
  background:none;
}
.whyus-card{
  /* У этой карточки заливка была прописана прямо в правиле (два слоя в
     одном background), поэтому её мало перебить общим правилом выше. */
  background:var(--z3-surface);
}

/* Размытие подложки. За плашками лежит фон-созвездие, и без размытия
   полупрозрачная поверхность показывает точки резко - плашка перестаёт
   читаться как отдельный слой. @supports нужен ради старых webkit. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .spot, .market, .feed, .card, .svc, .guard, .whyus-card,
  .faq__item, .vs__col, .honest{
    backdrop-filter:var(--z3-blur);
    -webkit-backdrop-filter:var(--z3-blur);
  }
}

/* Скругления по трём ступеням вложенности. */
.spot, .market, .feed, .svc, .vs__col, .honest{ border-radius:var(--z3-r-panel); }
.card, .guard, .whyus-card, .faq__item{ border-radius:var(--z3-r-card); }
.card__ico, .guard__ico, .svc__ico, .whyus-card__ico, .spot__ico{ border-radius:var(--z3-r-ico); }
.vs__ico, .qcard__ico, .panel__ico, .mrow, .fcard, .card__tag{ border-radius:var(--z3-r-inner); }

/* -------------------------------------------------------------------------
   2. АКЦЕНТНАЯ ПОЛОСА 3px СЛЕВА
   Узнаваемый приём дома остаётся. Меняются две вещи: посадка (поджим равен
   НОВОМУ радиусу, иначе прямой торец вылезает за скругление) и свечение
   (тугое вместо ореола).
   ------------------------------------------------------------------------- */
.spot::before, .svc::before, .honest::before, .vs__col--good::before{
  top:var(--z3-r-panel); bottom:var(--z3-r-panel);
  border-radius:var(--bar);
  /* Ровная заливка на всю высоту читалась как неоновая трубка: у карточки
     услуг это 300px сплошного голубого. Гасим концы - полоса становится
     штрихом, поставленным рукой, а не подсветкой. */
  background:var(--z3-bar);
  box-shadow:var(--z3-glow);
}
/* Серебряная полоса блоков рангом ниже. Была почти белой (.72) и спорила
   с заголовком за внимание. */
.card::before, .guard::before{
  top:var(--z3-r-card); bottom:var(--z3-r-card);
  border-radius:var(--bar);
  background:linear-gradient(180deg, rgba(255,255,255,.46) 0%, rgba(255,255,255,.05) 100%);
}
/* Колонка «обычная биржа» была подписана лососевым цветом. Разницу между
   колонками держат сам заголовок и маркеры списка, цвет тут лишний -
   в эталоне цветных заливок нет вовсе. */
.vs__col--bad::before{
  top:var(--z3-r-panel); bottom:var(--z3-r-panel);
  border-radius:var(--bar);
  background:linear-gradient(180deg, rgba(255,255,255,.20) 0%, rgba(255,255,255,.03) 100%);
}

/* -------------------------------------------------------------------------
   3. ЗНАЧКИ: один размер, одна толщина штриха, цвет от текста
   Штрих переводится с SVG-градиента на currentColor - только так значок
   гаснет и загорается вместе с текстом карточки.
   ------------------------------------------------------------------------- */
.card__ico, .guard__ico, .svc__ico, .whyus-card__ico{
  width:44px; height:44px;
  background:rgba(255,255,255,.045);
  border:1px solid var(--z3-line);
  color:#E6EAF0;
  transition:color var(--t-base), border-color var(--t-base), background var(--t-base);
}
.vs__ico{
  width:38px; height:38px;
  background:rgba(255,255,255,.045);
  border:1px solid var(--z3-line);
  color:#E6EAF0;
}
.spot__ico{
  width:40px; height:40px;
  background:rgba(255,255,255,.05);
  border:1px solid var(--z3-line);
  color:#E6EAF0;
}
/* Размеры коробки быстрых разделов НЕ трогаем глобально: ниже 1200px этот
   же элемент живёт в нижней панели навигации и имеет там свои 26px.
   Правило без медиа-запроса стоит в файле позже мобильного и молча
   перебило бы его. */
.qcard__ico{
  background:rgba(255,255,255,.05);
  border:1px solid var(--z3-line);
  color:#E6EAF0;
}
.panel__ico{
  width:28px; height:28px;
  background:rgba(255,255,255,.05);
  border:1px solid var(--z3-line);
  color:#E6EAF0;
}
/* Единый глиф.

   ДВЕ ПОПРАВКИ, БЕЗ КОТОРЫХ НИЧЕГО НЕ РАБОТАЕТ:
   1. color:inherit обязателен. Базовое правило .ico задаёт цвет НА САМОМ svg
      (color:var(--accent)), поэтому одного stroke:currentColor мало: значок
      берёт цвет у себя, а не у карточки, и остаётся голубым. Замер до
      правки: computed stroke = rgb(79,196,233) при цвете родителя
      rgb(230,234,240).
   2. stroke-width переопределяется явно: .ico--sm ставит 1.6, .ico--xs 1.9,
      и в одном ряду значки выглядели разной жирности. */
.card__ico .ico, .guard__ico .ico, .svc__ico .ico, .vs__ico .ico,
.spot__ico .ico, .whyus-card__svg{
  width:22px; height:22px; color:inherit; stroke:currentColor; stroke-width:1.5;
}
.qcard__ico .ico{ color:inherit; stroke:currentColor; stroke-width:1.5; }
.panel__ico .ico{ width:15px; height:15px; color:inherit; stroke:currentColor; stroke-width:1.5; }
/* Стрелки внутри ссылок панели тоже были неоновыми. */
.spot__cta .ico, .fcard__more .ico{ color:inherit; stroke:currentColor; stroke-width:1.6; }

/* -------------------------------------------------------------------------
   4. ТИПОГРАФИКА КАРТОЧЕК
   Заголовок medium с трекингом -.02em (в базе файла у h3 стоит 700).
   ------------------------------------------------------------------------- */
.card h3, .svc h3, .guard h3, .vs__col h3, .whyus-card__t,
.spot__title, .faq__item summary{
  font-weight:500; letter-spacing:-.02em;
}
.card h3, .svc h3, .guard h3, .whyus-card__t{
  line-height:1.28; color:#F4F6F9;
}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .card h3, .svc h3, .guard h3, .whyus-card__t{
    background:var(--z3-title);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
}

/* Вторичный текст карточек - серый эталона. */
.card p, .guard p, .whyus-card__p, .spot__desc, .fcard__title,
.mrow__name, .mrow__pair, .faq__foot{
  color:var(--z3-mut);
}
/* Длинные читаемые абзацы держим на ступень светлее: у оговорок и FAQ
   это по 4-6 строк подряд, там вторичный серый уже утомляет. */
.svc p, .honest p, .faq__body p, .vs__col li{ color:var(--z3-body); }

/* -------------------------------------------------------------------------
   5. НАВЕДЕНИЕ: лёгкий подъём и усиление границы
   Подъём уменьшен с 3px до 2px, добавлено кольцо акцента вместо смены
   заливки на более светлую.
   ------------------------------------------------------------------------- */
.card, .svc, .guard, .whyus-card, .faq__item, .fcard, .mrow{
  transition:transform var(--t-base), translate var(--t-base),
             border-color var(--t-base), background var(--t-base),
             box-shadow var(--t-base);
}
.card:hover, .svc:hover, .guard:hover{
  transform:translateY(-2px);
  background:var(--z3-surface-hi);
  border-color:var(--z3-line-hi);
  box-shadow:var(--z3-rim), var(--z3-shadow-hi), var(--z3-ring);
}
.card:hover .card__ico, .guard:hover .guard__ico, .svc:hover .svc__ico{
  color:#FFFFFF; border-color:var(--z3-line-hi);
}

/* -------------------------------------------------------------------------
   6. СЕТКИ: воздух под увеличенный радиус
   ------------------------------------------------------------------------- */
.cards, .guards, .whyus__grid, .vs{ gap:18px; }
.faq{ gap:8px; }

/* ДЫРКА В РЯДУ. Опций сделки три, а порог перехода на две колонки у .cards
   стоял на 900px ширины центра. При окне 1280-1560 центру достаётся 760-970px,
   то есть ровно этот диапазон: две карточки в первом ряду, третья одна во
   втором, справа от неё пустое место в половину экрана. У соседней сетки
   .whyus__grid тот же порог стоит на 800px, и она в этот момент честно
   держит три колонки - разнобой был виден на одном развороте.

   Здесь пороги .cards и .guards выравнены по .whyus__grid. Замер: при центре
   820px три колонки дают карточку 245px, ровно столько же, сколько у
   .whyus__grid в этом же месте страницы, и текст там не встаёт лесенкой.
   .cards--2 (доп. услуги) исключён: там карточек ровно две.
   .steps не тронут - это чужая зона.

   Порядок правил важен: узкие пороги идут последними, иначе планшетное
   правило перебило бы мобильное. Логика та же, что у .whyus__grid выше. */
@container center (min-width:801px){
  .cards:not(.cards--2), .guards{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}
/* Планшет: панелей нет, центр равен окну, но три колонки там уже тесные. */
@media (max-width:1199px){
  .cards:not(.cards--2), .guards{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
/* На самых узких порогах исключение снимается: в одну колонку встают и
   доп. услуги тоже, иначе в полосе окна 681-700px они остались бы вдвоём,
   пока опции сделки уже сложились в столбик.

   ЛОВУШКА ВЕСА СЕЛЕКТОРА, на которой я уже один раз попался. Написать здесь
   просто «.cards, .guards» нельзя: у планшетного правила выше селектор
   .cards:not(.cards--2), а :not() прибавляет вес своего аргумента, то есть
   он весит как ДВА класса. Голый .cards весит один и планшетное правило его
   перебивало - на 375px три опции сделки стояли в две колонки по 164px.
   Замер после правки: 375px даёт одну колонку 347px. */
@container center (max-width:680px){
  .cards:not(.cards--2), .cards.cards--2, .guards{ grid-template-columns:1fr; }
}
@media (max-width:700px){
  .cards:not(.cards--2), .cards.cards--2, .guards{ grid-template-columns:1fr; }
}

/* -------------------------------------------------------------------------
   7. КАРТОЧКИ ОПЦИЙ (.card)
   ------------------------------------------------------------------------- */
.card{ padding:28px 26px 28px 32px; }
.card h3{ margin-top:16px; }
.card p{ margin-top:12px; }
/* Тег был плашкой с заливкой: белая у обычного, голубая у акцентного.
   Две заливки в одном ряду карточек читались как разноцветные наклейки.
   Оставлен контур - он несёт ту же информацию и не пестрит. */
.card__tag{
  margin-top:20px; padding:5px 10px;
  font-weight:500; letter-spacing:.14em;
  background:none; border:1px solid var(--z3-line-hi); color:var(--z3-mut);
}
.card__tag--accent{
  background:none; border-color:rgba(79,196,233,.38); color:#9BE0F7;
}
/* Строка «кому подходит» была почти белой и того же веса, что заголовок:
   в карточке получались два одинаково громких высказывания и непонятно,
   какое из них главное. Делаем её отдельным ярусом - тише заголовка, громче
   описания, и отбиваем волосяной линией, как живую строку курса в сетке. */
.card__for{
  color:#C7CDD5 !important; font-weight:500;
  margin-top:auto; padding-top:14px;
  border-top:1px solid rgba(255,255,255,.07);
}

/* -------------------------------------------------------------------------
   8. ДОПОЛНИТЕЛЬНЫЕ УСЛУГИ (.svc)
   ------------------------------------------------------------------------- */
.svc{ padding:30px 28px 30px 34px; }
.svc h3{ margin-top:20px; }
/* Дефис перед пунктом был голубым градиентом, три штуки на карточку.
   Маркер списка - служебная деталь, ему цвет не нужен. */
.svc__list li{ color:var(--z3-mut); }
.svc__list li::before{
  background:rgba(255,255,255,.34);
}

/* Кнопка внутри карточки услуг и под честной оговоркой. Была стеклом с
   голубой кромкой и голубой заливкой - после того как всё вокруг стало
   серо-белым, она осталась единственным цветным пятном в карточке и тянула
   взгляд на себя сильнее заголовка.

   ПОЧЕМУ ЭТО НЕ ЗАЛЕЗАНИЕ В ЧУЖУЮ ЗОНУ: .btn--tg на странице встречается
   четыре раза. Один экземпляр - кнопка шапки, её уже перекрасил в белую
   исполнитель по первому экрану правилом .header__cta.btn--tg, и оно
   специфичнее моего. Остальные три лежат внутри .svc и .honest, то есть
   внутри моих карточек. Поэтому правило ниже адресовано ровно им и
   разъехаться с шапкой не может.

   Роль кнопки при этом не меняется: в эталоне белая кнопка одна на экран
   (у нас это шапка), а вторичные действия - нейтральное стекло. Ссылка на
   бот, её href и data-link не тронуты.

   ПРАВКА ПО ЗАМЕЧАНИЮ СКЕПТИКА (21.08). Первая редакция обесцветила кнопку
   до rgba(255,255,255,.05) при кромке .165 - и она стала НЕОТЛИЧИМА от
   соседней .btn--ghost (.045 при кромке --line-2 = .145). Разница в семь
   тысячных заливки глазом не видна вовсе. Под честной оговоркой эти двое
   стоят В ОДНОМ РЯДУ: «Задать вопрос в Telegram» и «Канал сервиса»
   превратились в близнецов, то есть главное действие страницы, ради
   которого сайт и существует, перестало читаться как главное. Обесцветить
   было верно, СРАВНЯТЬ - нет: у базовой .btn--tg была голубая заливка, и
   вместе с цветом ушла иерархия.

   Лечится без возврата неона: приоритет держит ПЛОТНОСТЬ, а не оттенок.
   Заливка .14 против .045 у призрака - ступень уверенно различима, при этом
   кнопка остаётся серо-белой и единственной белой на экран по-прежнему
   остаётся кнопка шапки. Белый текст на такой заливке даёт 11.5:1. */
.svc .btn--tg, .honest .btn--tg{
  background:rgba(255,255,255,.14);
  border-color:rgba(255,255,255,.30);
  color:#FFFFFF;
}
.svc .btn--tg:hover, .honest .btn--tg:hover{
  background:rgba(255,255,255,.20);
  border-color:rgba(255,255,255,.42);
}

/* -------------------------------------------------------------------------
   9. ГАРАНТИИ (.guard)
   ------------------------------------------------------------------------- */
.guard{ padding:26px 24px 26px 30px; }
.guard h3{ margin-top:18px; font-size:var(--fs-500); }

/* -------------------------------------------------------------------------
   10. СРАВНЕНИЕ С БИРЖЕЙ (.vs__col)
   ------------------------------------------------------------------------- */
.vs__col{ padding:28px 26px 28px 32px; }
.vs__col h3{ gap:14px; }
/* Крестик был лососевым, галочка голубой. Оставляем один акцент на
   «нашей» стороне, отрицательные пункты гасим в серый: разницу и так
   держат форма значка и колонка. */
.vs__col--bad li::before{ background:rgba(255,255,255,.40); }
.vs__col ul{ margin-top:22px; }

/* -------------------------------------------------------------------------
   11. ЧЕСТНЫЕ ОГОВОРКИ (.honest)
   ------------------------------------------------------------------------- */
.honest{ margin-top:24px; padding:28px 28px 28px 34px; }
.honest__label{ letter-spacing:.20em; font-weight:500; color:#EDF1F5; }

/* -------------------------------------------------------------------------
   12. FAQ
   Тринадцать одинаковых плашек подряд - самый длинный ряд на странице,
   поэтому здесь важнее всего ровная поверхность и спокойная «галочка».
   ------------------------------------------------------------------------- */
.faq__item summary{ padding:20px 56px 20px 24px; color:#EDF1F5; }
/* «Галочка» была акцентной у всех тринадцати пунктов сразу. Теперь она
   серая в покое и загорается только у ОТКРЫТОГО - это и есть активное
   состояние, ради которого акцент и держат. */
.faq__item summary::after{
  border-right-color:rgba(255,255,255,.38);
  border-bottom-color:rgba(255,255,255,.38);
  transition:transform var(--t-fast), border-color var(--t-fast);
}
.faq__item:hover summary::after{
  border-right-color:rgba(255,255,255,.72);
  border-bottom-color:rgba(255,255,255,.72);
}
.faq__item[open]{
  background:var(--z3-surface-hi);
  border-color:var(--z3-line-hi);
}
.faq__item[open] summary::after{
  border-right-color:var(--accent);
  border-bottom-color:var(--accent);
}
/* Полоса дома появляется у открытого пункта: тот же приём, что у крупных
   блоков, только как индикатор состояния. */
.faq__item[open]::before{
  content:""; position:absolute; left:0; top:var(--z3-r-card); bottom:var(--z3-r-card);
  width:var(--bar); border-radius:var(--bar); pointer-events:none;
  background:var(--z3-bar); box-shadow:var(--z3-glow);
}
.faq__item:hover{ border-color:var(--z3-line-hi); }
.faq__body{ padding:0 24px 22px; }

/* -------------------------------------------------------------------------
   13. СЕТКА «ПОЧЕМУ ЧЕРЕЗ НАС» (.whyus-card)
   ------------------------------------------------------------------------- */
.whyus-card{ padding:28px 26px 28px 32px; }
.whyus-card::before{
  top:var(--z3-r-card); bottom:var(--z3-r-card);
  border-radius:var(--bar);
  background:var(--z3-bar);
  box-shadow:var(--z3-glow);
}
/* Пятно под курсором было заметно голубым (.17). На плоской тёмной
   поверхности эталона такая подсветка выглядит как подтёк, поэтому
   ослаблена до едва различимой. */
.whyus-card::after{
  background:radial-gradient(260px 200px at var(--mx,50%) var(--my,0%),
             rgba(79,196,233,.10) 0%, rgba(79,196,233,.035) 44%, rgba(79,196,233,0) 74%);
}
.whyus-card__t{ margin-top:20px; }
.whyus-card__p{ margin-top:12px; }
/* Активная карточка (тач-экран) и наведение (мышь) описаны отдельно -
   так было и раньше, здесь только приведён материал. */
.whyus-card.is-live{
  background:var(--z3-surface-hi);
  border-color:var(--z3-line-hi);
  box-shadow:var(--z3-rim), var(--z3-shadow-hi), var(--z3-ring);
}
.whyus-card.is-live .whyus-card__ico{
  color:#FFFFFF; border-color:var(--z3-line-hi); background:rgba(255,255,255,.07);
}
@media (hover:hover){
  .whyus-card:hover{
    translate:0 -2px;
    background:var(--z3-surface-hi);
    border-color:var(--z3-line-hi);
    box-shadow:var(--z3-rim), var(--z3-shadow-hi), var(--z3-ring);
  }
  .whyus-card:hover .whyus-card__ico{
    color:#FFFFFF; border-color:var(--z3-line-hi); background:rgba(255,255,255,.07);
  }
}
/* ПОЧЕМУ ЗДЕСЬ ПОВТОРЁН ВЕСЬ СПИСОК ПЕРЕХОДОВ.
   У этой карточки переходы объявлены не на .whyus-card, а на
   .whyus__grid.is-armed .whyus-card - селектор из трёх классов, он весомее
   моего общего правила для карточек зоны. В его списке нет box-shadow,
   поэтому кольцо и тень по наведению вспыхивали мгновенно, пока подъём,
   граница и заливка ехали плавно: ровно тот «резкий скачок», которого быть
   не должно. Дописать одно свойство к чужому transition нельзя, список
   заменяется целиком, поэтому он повторён с добавленным box-shadow.
   Тайминги появления (620ms и ступенька 70ms по --i) взяты один в один. */
.whyus__grid.is-armed .whyus-card{
  transition:
    opacity   620ms cubic-bezier(.16,.84,.44,1) calc(var(--i,0) * 70ms),
    transform 620ms cubic-bezier(.16,.84,.44,1) calc(var(--i,0) * 70ms),
    translate    var(--t-base),
    border-color var(--t-base),
    background   var(--t-base),
    box-shadow   var(--t-base);
}

/* Живая строка курса. Числа приходят по событию ae:rate, разметку не трогаем. */
.whyus-live{ border-top-color:rgba(255,255,255,.08); }
.whyus-live__dot{ box-shadow:0 0 7px rgba(79,196,233,.55); }
.whyus-live__k{ color:var(--z3-mut); letter-spacing:.10em; }

/* -------------------------------------------------------------------------
   14. ЛЕВАЯ ПАНЕЛЬ: СПОТЛАЙТ УСЛУГ
   ------------------------------------------------------------------------- */
.spot{ padding:20px 20px 20px 24px; }
.spot__eyebrow{ letter-spacing:.20em; font-weight:500; color:var(--z3-mut); }
.spot__title{ margin-top:16px; font-size:16px; color:#F4F6F9; }
.spot__desc{ margin-top:11px; }
.spot__dot{ background:rgba(255,255,255,.20); }
/* Активная точка - один из немногих оставшихся акцентов: это ровно
   «активное состояние», ради которого цвет и держат. */
.spot__dot.is-on{ background:var(--accent); box-shadow:var(--z3-glow); }
/* Ссылка карточки была акцентной всегда. Акцент переехал на наведение. */
.spot__cta{
  color:var(--z3-mut); letter-spacing:.12em; font-weight:500;
  transition:color var(--t-fast);
}
.spot__card:hover .spot__cta,
.spot__card:focus-visible .spot__cta{ color:#9BE0F7; }
.spot__card:hover .spot__ico{ color:#FFFFFF; border-color:var(--z3-line-hi); }

/* -------------------------------------------------------------------------
   15. ЛЕВАЯ ПАНЕЛЬ: БЫСТРЫЕ РАЗДЕЛЫ
   Материал даём ТОЛЬКО на широком экране: ниже 1200px .qcard превращается
   в кнопку нижней панели навигации, где рамка и заливка не нужны и уже
   сняты правилом выше по файлу.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .qnav{ gap:10px; }
  .qcard__ico{ width:32px; height:32px; border-radius:var(--z3-r-inner); }
  .qcard__ico .ico{ width:17px; height:17px; }
  .qcard__t{ font-size:12.5px; font-weight:500; letter-spacing:-.01em; color:#E9EDF2; }
  .qcard{
    padding:15px 14px; gap:10px;
    background:var(--z3-surface);
    border:1px solid var(--z3-line);
    border-radius:var(--z3-r-card);
    box-shadow:var(--z3-rim), var(--z3-shadow);
    transition:transform var(--t-base), border-color var(--t-base),
               background var(--t-base), box-shadow var(--t-base);
  }
  .qcard:hover{
    transform:translateY(-2px);
    background:var(--z3-surface-hi);
    border-color:var(--z3-line-hi);
    box-shadow:var(--z3-rim), var(--z3-shadow-hi), var(--z3-ring);
  }
  .qcard:hover .qcard__ico{ color:#FFFFFF; border-color:var(--z3-line-hi); }
}

/* -------------------------------------------------------------------------
   16. ПРАВАЯ ПАНЕЛЬ: ШАПКИ, РЫНОК, ЛЕНТА
   ------------------------------------------------------------------------- */
.panel__head{ padding:18px 18px 12px; flex-wrap:wrap; row-gap:6px; }
.panel__title{ letter-spacing:.20em; font-weight:500; color:#EDF1F5; }
/* Штамп «котировки подгружаются» не влезал рядом с заголовком и ломался
   на две строки прямо под ним. Отдаём ему отдельную строку целиком. */
.market__stamp{
  flex:1 0 100%; margin-left:0; text-align:right;
  font-size:9.5px; letter-spacing:.05em; color:var(--z3-mut);
}
/* Штамп забрал себе отдельную строку, поэтому нижнее поле шапки уже не нужно
   целиком: без этого между временем обновления и первой котировкой набегает
   почти тридцать пикселей пустоты. */
.market .panel__head{ padding-bottom:6px; }
/* Живой курс остаётся акцентным: это индикатор состояния, а не украшение. */
.market__stamp:not([data-placeholder]){ color:#9BE0F7; }

/* Строки котировок. Были расставлены зазорами и рассыпались на отдельные
   плашки. Прибор читается как таблица, поэтому зазор убран, а строки
   разделены волосяной линией - приём панели-дашборда из эталона. */
.market__list{ padding:4px 12px 14px; gap:0; }
/* position:relative нужен под разделитель ниже. Разделитель абсолютный
   намеренно: .mrow - это grid, и обычный поточный псевдоэлемент стал бы
   его ячейкой и поехал бы в сетку колонок. */
.mrow{ padding:12px; position:relative; }
.mrow + .mrow::before{
  content:""; position:absolute; left:12px; right:12px; top:0; height:1px;
  background:rgba(255,255,255,.055); pointer-events:none;
}
.mrow:hover{ background:rgba(255,255,255,.045); }
.mrow:hover + .mrow::before, .mrow:hover::before{ background:transparent; }
.mrow__price[data-placeholder]{ color:var(--z3-mut); }

/* Лента. Рубрика была акцентной у каждой карточки - шесть голубых надписей
   подряд в узкой колонке. Акцент переехал на наведение. */
.feed__list{ padding:4px 12px 14px; gap:8px; }
.fcard{ padding:14px; border:1px solid transparent; }
.fcard__kicker{ color:var(--z3-mut); font-weight:500; letter-spacing:.18em; }
.fcard__more{ color:var(--z3-mut); }
.fcard:hover{
  background:var(--z3-surface-hi);
  border-color:var(--z3-line-hi);
}
.fcard:hover .fcard__kicker{ color:#9BE0F7; }
.fcard:hover .fcard__more{ color:#E4E9EF; }

/* -------------------------------------------------------------------------
   17. УЗКИЕ ЭКРАНЫ: ПОВТОР ПРАВИЛ, КОТОРЫЕ ИНАЧЕ ПОТЕРЯЛИСЬ БЫ

   Выше по файлу у .svc, .honest и .whyus-card уже есть отдельные отступы
   для 620 и 400px. Мой блок стоит в файле ПОЗЖЕ них и задаёт padding
   сокращённой записью, а она сбрасывает все четыре стороны разом - то есть
   молча отменила бы мобильные значения. Поэтому они здесь повторены.
   Медиа-запрос сам по себе приоритета не даёт, решает порядок в файле.
   ------------------------------------------------------------------------- */
@media (max-width:620px){
  .honest{ padding-left:24px; padding-right:20px; }
  .whyus-card{ padding:24px 20px 24px 24px; }
}
@media (max-width:400px){
  .svc{ padding:22px 17px 22px 21px; }
  .whyus-card{ padding:20px 15px 20px 18px; }
  .whyus-card__ico{ width:42px; height:42px; }
}

/* -------------------------------------------------------------------------
   18. ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ
   Глобальное правило файла гасит ДЛИТЕЛЬНОСТЬ переходов, но не сам сдвиг:
   при prefers-reduced-motion карточка всё равно прыгала на 2px мгновенно.
   Здесь подъём снимается совсем, остаются только граница и заливка.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .card:hover, .svc:hover, .guard:hover, .qcard:hover{ transform:none; }
  .whyus-card:hover, .whyus-card.is-live{ translate:none; }
  .spot__card, .spot__card.is-on{ transform:none; }
}
/* ==== ЗОНА 3: БОКОВЫЕ ПАНЕЛИ И КАРТОЧКИ КОНТЕНТА - КОНЕЦ ==== */


/* =========================================================================
   ═══ ЗОНА 4: ОБЩИЕ ЭФФЕКТЫ СТРАНИЦЫ, ПАНЕЛИ И КНОПКИ - НАЧАЛО ═══
   (21.08.2026)

   ЖАЛОБА ВЛАДЕЛЬЦА (дословно, 21.08): «Всё очень темно и сыро... надо тоже
   как-то по-другому немножко сделать эти карточки, максимально ебански
   выглядит... 21st.dev ты используешь полноценно, что-то я не вижу. Накидай
   идей, возьми оттуда много всяких фишек: раскрывающихся окон и прочего.
   Бери оттуда и панели, кнопки, эффекты - всё бери.»

   ДИАГНОЗ. Плашки на странице отличаются друг от друга только текстом: тот
   же прямоугольник, та же кромка, и на наведение все отвечают одинаковым
   подъёмом на 2px, которого на тёмном фоне попросту не видно. Полотно
   длиной 12 500px не даёт глазу ни одной точки, где что-то происходит.
   «Темно» здесь не про цвет фона (он уже светлеет к центру), а про то, что
   на странице нет источника света и нет движения по смыслу.

   ЧТО ВЗЯТО ИЗ КОМПОНЕНТОВ 21st.dev. Перенесены ПРИЁМЫ, не код: у них
   React и framer-motion, у нас статика без сборщика.
     1. expand-map -> пружинный наклон плашки за курсором (в оригинале
        useSpring на rotateX/rotateY, жёсткость 300, затухание 30);
     2. expand-map -> раскрытие: сперва растёт КОРОБКА, содержимое
        проявляется ПОЗЖЕ, с задержкой 0.1s, а не вместе с ней;
     3. features-8 -> плашка отвечает на курсор светом, а не сдвигом:
        под рукой оживают кромка и значок;
     4. saa-s-template -> слой свечения ПОД ключевым блоком (у них
        картинка glows.png за дашбордом; у нас радиальные градиенты,
        внешних файлов не тянем);
     5. saa-s-template -> кнопка с заливкой СВЕРХУ ВНИЗ и микро-масштабом:
        hover:scale-105 / active:scale-95;
     6. constellation-grid -> сетка проявляется ступенькой, а не разом.

   ЧЕГО ЗДЕСЬ НЕТ И ПОЧЕМУ:
     - ни одного нового backdrop-filter и ни одного filter:blur. 19.08 сайт
       грел ноутбук: 34 элемента с размытием давали 12-19 кадров. Свечение
       собрано радиальными градиентами - это заливка, а не размытие;
     - в цикле анимируются ТОЛЬКО transform и opacity;
     - наклон живёт лишь пока курсор на плашке, сам гаснет, когда пружина
       успокоилась, и снят целиком при document.hidden, при coarse-указателе
       и при prefers-reduced-motion.

   ГРАНИЦЫ ЗОНЫ. Здесь нет ни одного селектора .arc / .step (карусель шагов)
   и ни одного .geo__* / #offline (карта офлайн-выдачи) - там параллельно
   работают другие исполнители. Блок стоит в конце файла, поэтому там, где
   он пересекается с ЗОНОЙ 3 по классу, он ДОПОЛНЯЕТ её значения: ни одна
   контрастная величина ЗОНЫ 3 здесь не переопределяется.
   ========================================================================= */

:root{
  /* Дуга успокоения: резкий старт, длинный выкат. Тот же характер, что у
     пружины 300/30 из expand-map, но записанный кривой Безье - на переходах
     CSS это дешевле, чем считать пружину покадрово. */
  --ae4-ease:   cubic-bezier(.16,.84,.44,1);
  /* Второй кривой с ПЕРЕЛЁТОМ здесь нет намеренно. Она была (галочка FAQ
     доворачивалась с отскоком), но отскок на интерфейсе читается как игрушка:
     настоящие предметы тормозят плавно и не отыгрывают назад. Осталась одна
     дуга на весь блок - резкий старт, длинный выкат. */
  --ae4-ring:   rgba(79,196,233,.85);           /* свет кромки = дом-акцент */
}

/* -------------------------------------------------------------------------
   1. КРОМКА, БЕГУЩАЯ ЗА КУРСОРОМ            (приём features-8)

   ЗАЧЕМ, а не «красиво». На одном развороте видно до шести одинаковых
   плашек. Пока курсор ищет нужную, ни одна не отвечает: подъём на 2px на
   тёмном фоне не читается. Светящаяся кромка отвечает мгновенно и, главное,
   показывает ГДЕ рука - свет стоит ровно под курсором и ведёт взгляд туда,
   куда человек ведёт мышь, то есть к ссылке или кнопке внизу карточки.

   ПОЧЕМУ ОТДЕЛЬНЫМ ЭЛЕМЕНТОМ, А НЕ ПСЕВДО. У .card, .svc, .guard, .qcard
   ОБА псевдоэлемента заняты: ::before - акцентная полоса дом-стиля,
   ::after - верхний блик. Кольцо вставляет JS отдельным <i>, поэтому ни
   одно чужое правило не переписывается.

   ЦЕНА КАДРА. Градиент живёт только у ОДНОЙ плашки, той, что под курсором;
   у остальных opacity:0 и перерисовывать нечего. Толщина кольца 1px:
   перекрашивается кромка, а не площадь карточки.
   ------------------------------------------------------------------------- */
.ae4-rim{
  position:absolute; inset:0; z-index:3;
  border-radius:inherit; pointer-events:none;
  padding:1px;                       /* толщина светящегося кольца */
  background:radial-gradient(150px circle at var(--ae4-x,50%) var(--ae4-y,-30%),
             var(--ae4-ring) 0%, rgba(79,196,233,.30) 38%, rgba(79,196,233,0) 72%);
  /* Вырез серединки: два одинаковых слоя маски, у одного область content-box,
     режим exclude оставляет видимой только рамку шириной с padding. */
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite:exclude;
  opacity:0;
  transition:opacity 240ms var(--ae4-ease);
}
/* position:relative проставляем явно: у части плашек его не было, и без него
   кольцо ушло бы к ближайшему позиционированному предку. */
.card, .svc, .guard, .qcard, .faq__item, .final__inner{ position:relative; }
.ae4-lit > .ae4-rim{ opacity:1; }
/* Клавиатура. Кольцо ведёт курсор, но человек может идти по странице
   табом - тогда фокус внутри плашки обязан давать ту же метку «вы здесь».
   Точка света по умолчанию стоит по центру верхней кромки. */
.card:focus-within > .ae4-rim, .svc:focus-within > .ae4-rim,
.guard:focus-within > .ae4-rim, .qcard:focus-visible > .ae4-rim,
.faq__item:focus-within > .ae4-rim, .final__inner:focus-within > .ae4-rim{ opacity:1; }

/* Значок под рукой перестаёт быть серой наклейкой - тот же приём «плашка
   отвечает светом», что и кромка. */
.ae4-lit .card__ico, .ae4-lit .svc__ico,
.ae4-lit .guard__ico, .ae4-lit .qcard__ico{
  border-color:rgba(79,196,233,.45);
  box-shadow:0 0 0 1px rgba(79,196,233,.16), 0 0 18px -6px rgba(79,196,233,.7);
}

/* -------------------------------------------------------------------------
   2. ПРУЖИННЫЙ НАКЛОН ЗА КУРСОРОМ           (приём expand-map)

   ЗАЧЕМ. Шесть кнопок быстрых разделов и три карточки опций - это места,
   где человек ВЫБИРАЕТ. Наклон даёт им вес предмета: плашка поворачивается
   к руке, и та, что выбрана, физически отличается от соседних. На тексте и
   на больших полотнах наклона нет намеренно - там он читался бы трюком.

   Углы приходят из JS переменными, здесь только их применение. Пружину
   считает JS (жёсткость 300, затухание 30 - как в оригинале): переход CSS
   к цели, которая меняется каждый кадр, даёт вязкость, а не пружину.
   ------------------------------------------------------------------------- */
@media (hover:hover) and (pointer:fine){
  .ae4-tilt{
    /* Точку схода держим у самой плашки: общий perspective на родителе дал
       бы карточкам одного ряда разный наклон при одинаковом угле. */
    transition:transform 420ms var(--ae4-ease), box-shadow var(--t-base),
               border-color var(--t-base), background var(--t-base);
  }
  /* Прежний подъём на наведение переписан: два разных сдвига по одной оси
     спорили бы за одно свойство transform. */
  .ae4-tilt:hover{ transform:perspective(760px) translateY(-3px); }
  /* Пока пружина живёт, переход выключен: иначе он сгладил бы её и съел
     ровно тот характер, ради которого пружина и считается. */
  .ae4-tilt.is-tilting{
    transition:box-shadow var(--t-base), border-color var(--t-base),
               background var(--t-base);
    transform:perspective(760px)
              rotateX(var(--ae4-rx,0deg)) rotateY(var(--ae4-ry,0deg))
              translateY(-3px);
  }
}

/* -------------------------------------------------------------------------
   3. РАСКРЫВАЮЩЕЕСЯ ОКНО: FAQ               (приём expand-map)

   Владелец просил «раскрывающихся окон». Тринадцать вопросов - самый длинный
   список страницы, и до правки он открывался рывком: высота менялась
   мгновенно, текст появлялся уже готовым, соседние карточки прыгали.

   🔴 РОСТ ВЫСОТЫ ЗДЕСЬ НЕ ТРОГАЕТСЯ. Он уже сделан в app.js (openItem /
   closeItem, пружина на height + opacity). Свой обработчик я написал, и на
   проверке вопрос открывался и тут же закрывался: два обработчика на одном
   summary отрабатывали один клик подряд. Свой снят, разбор записан в
   effects.js. Здесь остаётся ровно то, чего в app.js не было.

   А не было главного в приёме expand-map: содержимое проявляется ПОЗЖЕ
   коробки, с задержкой (в оригинале duration .4 + delay .1). Без этого текст
   едет вместе со стенками и раскрытие читается как рывок, а не как «окно
   выдвинулось».

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

/* Галочка доворачивалась за 140ms, то есть заметно быстрее, чем открывается
   сам вопрос (420ms в app.js). Знак успевал перевернуться раньше, чем поехала
   коробка, и связь между ними разрывалась. Здесь длительность сведена с
   раскрытием, дуга - общая для блока.
   margin-top в список НЕ входит: это раскладочное свойство, и его отдельная
   анимация ради 4px дала бы пересчёт раскладки на каждый кадр. Оно, как и
   раньше, меняется мгновенно, под прикрытием поворота. */
.faq__item summary::after{
  transition:transform 420ms var(--ae4-ease), border-color var(--t-fast);
}

/* Содержимое въезжает ПОСЛЕ коробки. Задержка 110ms и есть перенесённый
   delay:0.1 из оригинала. */
.faq__body > *{
  opacity:0; transform:translateY(9px);
  transition:opacity 300ms var(--ae4-ease) 110ms,
             transform 400ms var(--ae4-ease) 110ms;
}
.faq__item[open] .faq__body > *{ opacity:1; transform:none; }
/* Гасить текст на ЗАКРЫТИИ здесь нечем и не нужно: app.js в closeItem уже
   уводит прозрачность всего тела с 1 в 0 за 300ms вместе с высотой. */

/* -------------------------------------------------------------------------
   4. СТУПЕНЧАТОЕ ПОЯВЛЕНИЕ                  (приём constellation-grid)

   Ступенька шагом 55ms у части сеток уже была (data-delay в разметке), но
   стояла не везде: FAQ и цифры над сеткой возможностей проявлялись разом,
   вспышкой, и глаз не получал порядка чтения. JS раздаёт задержку по индексу
   всем сеткам, отмеченным .ae4-stagger, потолок 5 шагов - дальше человек
   уже ждёт, а не читает.

   Второго наблюдателя прокрутки не заводим: атрибут data-delay УЖЕ понимает
   наблюдатель в app.js, и лишний обработчик на странице ни к чему.

   Здесь усилен сам ВХОД: было translateY(14px), стало 22px плюс микро-масштаб.
   Плашка не всплывает, а подъезжает.

   🔴 .ae4-stagger НЕ ставится ни на что внутри .hero: там действует правило
   .hero .reveal{opacity:1} с тем же весом, и мой селектор, стоящий в файле
   позже, погасил бы первый экран.
   ------------------------------------------------------------------------- */
.ae4-stagger > .reveal{
  transform:translateY(22px) scale(.985);
  transition:opacity 620ms var(--ae4-ease), transform 620ms var(--ae4-ease);
}
.ae4-stagger > .reveal.is-visible{ transform:none; }

/* -------------------------------------------------------------------------
   5. ЦИФРЫ, ДОЕЗЖАЮЩИЕ ДО ЗНАЧЕНИЯ

   Четыре числа над сеткой возможностей - единственные цифры-утверждения на
   странице. Разгон подчёркивает саму цифру: глаз ловит движение и
   останавливается на числе, а не проскакивает мимо строки.

   Ширину держим табличными цифрами, иначе на разгоне «1 000 000» дёргает
   соседние колонки. Гарнитура здесь уже моноширинная, но флаг ставим явно -
   он переживёт смену гарнитуры.
   ------------------------------------------------------------------------- */
.stats .n{ font-variant-numeric:tabular-nums; }
.ae4-rise{
  opacity:0; transform:translateY(18px);
  transition:opacity 560ms var(--ae4-ease), transform 560ms var(--ae4-ease);
  transition-delay:calc(var(--ae4-i,0) * 70ms);
}
.ae4-rise.is-up{ opacity:1; transform:none; }

/* -------------------------------------------------------------------------
   6. КНОПКИ                                  (приём saa-s-template)

   Приём оригинала: заливка идёт СВЕРХУ ВНИЗ от белого к белому 60%, на
   наведении лёгкое увеличение, на нажатии - уменьшение.

   ПОЧЕМУ У .btn--primary ЗАЛИВКА ОСТАЛАСЬ ГОРИЗОНТАЛЬНОЙ. Серый градиент
   слева направо в чёрный - прямое требование владельца от 19.08 («синюю
   кнопку перевести в серый градиент, справа уходящий в чёрный»), и оно
   старше нынешней правки. Вертикальный свет добавлен ОТДЕЛЬНЫМ слоем
   поверх: направление заливки не тронуто, объём эталона получен.

   ::after выбран потому, что ::before у .btn--primary занят акцентной
   полосой; ::after свободен у всех кнопок сразу.
   z-index:-1 при isolation:isolate кладёт слой НАД собственным фоном кнопки,
   но ПОД её текстом и под акцентной полосой - иначе он затянул бы подпись.
   ------------------------------------------------------------------------- */
.btn{ position:relative; isolation:isolate; }
.btn::after{
  content:""; position:absolute; inset:0; z-index:-1;
  border-radius:inherit; pointer-events:none;
  background:linear-gradient(180deg,
             rgba(255,255,255,.17) 0%, rgba(255,255,255,.06) 46%,
             rgba(255,255,255,0) 74%, rgba(0,0,0,.10) 100%);
  opacity:.9;
  transition:opacity var(--t-fast);
}
.btn:hover::after{ opacity:1; }
/* Нажатие: микро-масштаб вместо прежнего сдвига вниз на 1px. Сдвиг читался
   как «кнопка поехала», масштаб - как «кнопка продавилась». */
.btn:hover{ transform:translateY(-1px); }
.btn:active,
.btn:active:hover{ transform:scale(.97); }

/* Белая кнопка шапки светлая сама по себе; повторный белый поверх белого
   дал бы грязный верх. */
.header__cta.btn--tg::after{
  background:linear-gradient(180deg, rgba(255,255,255,.30) 0%,
             rgba(255,255,255,0) 52%, rgba(0,0,0,.06) 100%);
}

/* ---------- ИЕРАРХИЯ: одна главная кнопка на экран ----------
   На первом экране их было две: белая в шапке и крупная в герое. Белая
   всегда выигрывает по яркости, то есть шапка перебивала главное действие
   ровно там, где оно и так на виду.

   Правило: пока кнопка героя видна, шапочная тихая (стекло); как только
   герой ушёл вверх - шапочная получает белую заливку эталона и становится
   главной. Класс переключает наблюдатель в effects.js, и только он.

   Белые значения повторены ДОСЛОВНО из ЗОНЫ 1, чтобы вид «взведённой»
   кнопки не разошёлся с тем, что там утверждено. */
.header__cta.btn--tg{
  background:rgba(255,255,255,.07);
  color:#E9EEF3; border-color:rgba(255,255,255,.20);
  box-shadow:none;
  transition:background var(--t-base), color var(--t-base),
             border-color var(--t-base), box-shadow var(--t-base),
             transform var(--t-fast);
}
.header__cta.btn--tg .ico-tg{ color:#CFE9F5; transition:color var(--t-base); }
.header__cta.btn--tg:hover{
  background:rgba(255,255,255,.13); border-color:rgba(255,255,255,.34);
  transform:translateY(-1px);
}
.header.is-cta-armed .header__cta.btn--tg{
  background:linear-gradient(180deg,#FFFFFF 0%,rgba(255,255,255,.95) 52%,rgba(255,255,255,.66) 100%);
  color:#0A0B0E; border-color:rgba(255,255,255,.5); font-weight:600;
  box-shadow:0 6px 18px -10px rgba(0,0,0,.9), 0 0 22px -10px rgba(79,196,233,.55);
}
.header.is-cta-armed .header__cta.btn--tg .ico-tg{ color:#0A0B0E; }
.header.is-cta-armed .header__cta.btn--tg:hover{
  background:linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 60%,rgba(255,255,255,.8) 100%);
  border-color:rgba(255,255,255,.7);
  transform:scale(1.04);
}
.header__cta.btn--tg:active{ transform:scale(.97); }

/* -------------------------------------------------------------------------
   7. СВЕЧЕНИЕ ПОД ФИНАЛЬНЫМ БЛОКОМ          (приём saa-s-template)

   В эталоне под дашбордом лежит отдельный слой света - без него панель
   висит в пустоте. У нас такой слой уже есть под калькулятором (ЗОНА 1), а
   финальный блок - второе и последнее место, где человек нажимает кнопку, -
   стоял на голом фоне и терялся между FAQ и футером.

   Свет - радиальные градиенты, а НЕ filter:blur: размытие большой площади и
   было причиной 12-19 кадров 19.08.
   ------------------------------------------------------------------------- */
.final{ position:relative; isolation:isolate; }
.final::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  left:50%; translate:-50% 0; top:-8%;
  /* 🔴 РОВНО 100%, НЕ БОЛЬШЕ. Замер 21.08: при 114% слой вылезал за правый
     край секции на 22px, и на экране 320px раскладочное окно раздувалось до
     342 - появлялась горизонтальная прокрутка на всю страницу. Ширины секции
     хватает и так: .final__inner уже́ её на поля .wrap, поэтому свет всё равно
     выходит за пределы самой плашки, а гаснет он раньше кромки секции. */
  width:min(1120px,100%); height:120%;
  background:
    radial-gradient(58% 62% at 50% 44%, rgba(79,196,233,.14) 0%, rgba(79,196,233,0) 68%),
    radial-gradient(40% 46% at 50% 100%, rgba(255,255,255,.07) 0%, rgba(255,255,255,0) 72%);
}
.final__inner{ position:relative; }

/* -------------------------------------------------------------------------
   8. ПОЛОСА ПРОЧИТАННОГО

   Полотно длиной 12 500px: с середины страницы человек не понимает, сколько
   ещё осталось, а от этого зависит, дочитает он до кнопки или закроет.
   Это прибор, а не украшение.

   Двигаем scaleX, то есть композитный трансформ, без перерасчёта раскладки.
   Полоса лежит в <body>, а не в шапке: у .center стоит container-type, и
   любой position:fixed внутри него считался бы от колонки, а не от окна.
   ------------------------------------------------------------------------- */
.ae4-progress{
  position:fixed; left:0; right:0; top:0; height:2px;
  z-index:61;                         /* шапка 60, шторка 65, модалка 90 */
  pointer-events:none;
  background:rgba(255,255,255,.05);
  opacity:0; transition:opacity 300ms var(--ae4-ease);
}
.ae4-progress.is-on{ opacity:1; }
.ae4-progress > i{
  display:block; height:100%; width:100%;
  transform:scaleX(0); transform-origin:0 50%;
  background:linear-gradient(90deg, rgba(79,196,233,.55) 0%, #4FC4E9 62%, #9BE0F7 100%);
  box-shadow:0 0 10px -1px rgba(79,196,233,.6);
}

/* -------------------------------------------------------------------------
   9. УЗКИЕ ЭКРАНЫ И СЕНСОР

   Наклон и кромка живут на указателе мыши. На телефоне указателя нет, а
   :hover там залипает после тапа, поэтому оба приёма выключены целиком, а
   не «оставлены на всякий случай». Ниже 1200px .qcard перестаёт быть плашкой
   и превращается в кнопку нижней панели навигации - кольцо там лишнее.
   ------------------------------------------------------------------------- */
@media (hover:none), (pointer:coarse){
  .ae4-rim{ display:none; }
  .btn:hover{ transform:none; }
}
@media (max-width:1199px){
  .qcard > .ae4-rim{ display:none; }
}
@media (max-width:520px){
  /* На плотном экране телефона 2px почти не видно, а прибор нужен именно
     там: полотно в одну колонку становится ещё длиннее. */
  .ae4-progress{ height:3px; }
}

/* -------------------------------------------------------------------------
   10. РИТМ ПОЛОСАМИ: СВЕТ ПО ВЕРХНЕЙ КРОМКЕ ЧЕРЕДУЮЩИХСЯ СЕКЦИЙ

   Это прямой ответ на «всё очень темно». Чередование секций в файле есть -
   у .section--alt стоит заливка rgba(255,255,255,.018). Замер: на фоне
   #0C0D11 это даёт #0F1014, разница с соседней секцией меньше одного шага
   восприятия. То есть полосы формально были, а на глаз полотно оставалось
   одним сплошным чёрным на 12 500px, и зацепиться взгляду не за что.

   ПОЧЕМУ НЕ ПОДНЯЛ ЗАЛИВКУ ПОЛОСЫ. Плашки на странице держатся на белом с
   альфой около 4.5%. Подними я полосу до заметных 5%, и карточка стала бы
   ТЕМНЕЕ подложки - ровно то, на что владелец жаловался 17.08 («плашка очень
   сильно затемняет всё»). Уровень поверхностей трогать нельзя.

   Поэтому вместо заливки - СВЕТ ПО ВЕРХНЕЙ КРОМКЕ: полоса выглядит
   освещённой сверху, как все плашки дома с их бликом --rim, только в
   масштабе секции. Уровень поверхности не меняется ни на одну сотую,
   контраст текста и разница «плашка светлее фона» остаются как были.

   🔴 #offline исключён явно: карта - чужая зона.
   Слой статический: ни анимации, ни размытия, ни лишнего узла в разметке.
   ------------------------------------------------------------------------- */
.section--alt:not(#offline){ isolation:isolate; }
/* Гаснет не только вниз, но и к БОКАМ - поэтому эллипс, а не полоса. Секция
   живёт внутри центральной колонки, и линейный градиент во всю её ширину
   обрывался бы по краям колонки двумя вертикальными кромками: на глаз это
   прямоугольная заплатка, а не свет. Эллипс с центром у верхней кромки
   гаснет раньше краёв, и никакого шва не остаётся. */
.section--alt:not(#offline)::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  left:0; right:0; top:0; height:min(300px,48%);
  /* Верхнее значение можно держать выше уровня плашек (около 4.5% белого)
     только потому, что первые 100px каждой такой секции занимает ЗАГОЛОВОК,
     а не карточка: проверено у всех трёх полос (#why, #how, #safety). К тому
     месту, где начинаются плашки, свет уже ниже 1%, и правило «плашка светлее
     подложки» нигде не нарушается. */
  background:radial-gradient(118% 100% at 50% 0%,
             rgba(255,255,255,.072) 0%,
             rgba(255,255,255,.026) 34%,
             rgba(255,255,255,0)    74%);
}
/* Нижняя кромка, наоборот, уходит в тень: так полоса читается плитой с
   толщиной, а не наклейкой поверх фона. Гасим по тому же эллипсу. */
.section--alt:not(#offline)::after{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  left:0; right:0; bottom:0; height:min(190px,30%);
  background:radial-gradient(118% 100% at 50% 100%,
             rgba(0,0,0,.20) 0%, rgba(0,0,0,.07) 42%, rgba(0,0,0,0) 78%);
}

/* -------------------------------------------------------------------------
   11. ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ

   Глобальное правило файла гасит ДЛИТЕЛЬНОСТЬ переходов, но не сами
   значения: без этого блока плашка всё равно стояла бы наклонённой, просто
   мгновенно. Здесь снимается сам эффект, а не его скорость. JS при том же
   запросе не заводит ни одного цикла - проверено на своей стороне.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .ae4-tilt, .ae4-tilt:hover, .ae4-tilt.is-tilting{ transform:none; }
  .ae4-rim{ transition:none; }
  .faq__item summary::after{ transition:none; }
  .faq__body > *{ opacity:1; transform:none; transition:none; }
  .ae4-stagger > .reveal{ opacity:1; transform:none; transition:none; }
  .ae4-rise{ opacity:1; transform:none; transition:none; }
  .btn:hover, .btn:active, .btn:active:hover{ transform:none; }
  .header__cta.btn--tg:hover,
  .header.is-cta-armed .header__cta.btn--tg:hover{ transform:none; }
  .ae4-progress > i{ transition:none; }
}
/* ═══ ЗОНА 4: ОБЩИЕ ЭФФЕКТЫ СТРАНИЦЫ, ПАНЕЛИ И КНОПКИ - КОНЕЦ ═══ */

/* =========================================================================
   ═══ ЗОНА 5A: СОСТОЯНИЯ И ДВИЖЕНИЕ - НАЧАЛО ═══             (22.08.2026)

   Отдельная огороженная зона в конце файла, как зоны 1-4 выше: по сайту
   работают два исполнителя, и правка тела файла в середине столкнулась бы
   с чужими строками. Каскад разруливает сам, !important не нужен нигде,
   кроме одного места (см. пункт 14) - и там он бьёт по чужому !important.

   ЧТО ЭТА ЗОНА ЛЕЧИТ. Не «мало эффектов», а обратное: один дорогой приём
   (синяя полоса) был наложен 31 раз в десяти исполнениях и перестал что-либо
   значить, а на прикосновение поверхность не отвечала вовсе - 30 живых
   элементов имели transition-duration: 0s при живых правилах :hover.

   ЧЕГО ЗДЕСЬ НЕТ НАМЕРЕННО: размеров, полей, кеглей и медиазапросов по
   ширине. Это свойства второго исполнителя (mobile.css). Границу ширины,
   без которой не обойтись (шторка справа), переключает класс из effects.js,
   а не @media - так зоны не пересекаются ни одной строкой.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. СЛОВАРЬ ДВИЖЕНИЯ

   Существующие --t-fast/--t-base/--t-slow НЕ переименованы и НЕ переопределены:
   на них висит вся страница. Здесь дописаны недостающие роли.

   Закон: закрытие всегда --ae5-exit, и оно короче открытия. Человек решает,
   когда открыть, система отвечает, когда закрыть.

   ПОЧЕМУ У ЧАСТИ РОЛЕЙ ПО ДВА ТОКЕНА. Полный токен («90ms кривая») годится
   только для сокращения transition. Свойство transition-duration принимает
   исключительно время, и полный токен там молча отбрасывается парсером -
   правило выглядело бы написанным, а нажатие оставалось бы мгновенным.
   Поэтому рядом лежит скалярный близнец с суффиксом -d.
   ------------------------------------------------------------------------- */
:root{
  --ae5-press:  90ms  cubic-bezier(.22,.61,.36,1);  /* нажатие: короче всего */
  --ae5-press-d: 90ms;
  --ae5-tint:   180ms cubic-bezier(.22,.61,.36,1);  /* цвет, рамка, фон */
  --ae5-lift:   150ms cubic-bezier(.22,.61,.36,1);  /* подъём плашки */
  --ae5-enter:  440ms cubic-bezier(.16,.84,.44,1);  /* приезд при прокрутке */
  --ae5-panel:  260ms cubic-bezier(.22,.61,.36,1);  /* индикатор, раскрытие */
  --ae5-sheet:  380ms cubic-bezier(.32,.72,0,1);    /* вход правой шторки */
  --ae5-exit:   200ms cubic-bezier(.22,.61,.36,1);  /* ЛЮБОЕ закрытие */
  --ae5-exit-d: 200ms;
  --ae5-step:   55ms;                               /* шаг ступеньки */
  /* Авторский момент первого экрана, один на весь сайт. */
  --ae5-hero:   640ms cubic-bezier(.16,1,.3,1);

  /* Канонная полоса важного - дословно из APOLLO-DESIGN-CANON, раздел 2.
     Держим переменными, чтобы второй такой набор нельзя было завести. */
  --ae5-bar-glow: 0 0 26px 3px rgba(79,196,233,.42), 0 0 62px 9px rgba(79,196,233,.16);
  --ae5-bar-r:    6px 0 0 6px;
}

/* -------------------------------------------------------------------------
   2. ПОЛОСА ВАЖНОГО: БЫЛА 31 ШТУКА В ДЕСЯТИ ИСПОЛНЕНИЯХ

   Замер до правки на 1440x900: 31 псевдоэлемент шириной 3px виден
   одновременно, свечений четыре разных (0 0 10px 0 - семь штук,
   0 0 18px 2px + 0 0 46px 9px - семь, вовсе никакого - шестнадцать,
   0 0 10px 1px - одна), радиусов пять (3px, 14px, 6px, 0px, 2px).
   Ни одна из 31 не совпадала с каноном.

   Канон строит важность на РЕДКОСТИ: полоса помечает одно место. Оставляем
   пять смысловых узлов страницы плюс модалку - она отдельная поверхность, и
   когда открыта, важное на ней ровно одно. Всё остальное снимается.
   ------------------------------------------------------------------------- */

/* ---- снять ---- */
.whyus-card::before, .card::before, .guard::before, .svc::before,
.spot::before, .stats::before,
.geo__map::before, .geo__card::before, .geo__rule::before, .geo__live::before,
.vs__col--bad::before,
.btn--primary::before{
  content:none;
}
/* Разница «крупная / средняя / небольшая сумма» держалась цветом полосы.
   Она не пропала: её несёт сам заголовок карточки, он и есть текст правила. */

/* ---- канон: пять узлов страницы плюс модалка ---- */
.rate-strip::before, .calc::before, .honest::before,
.vs__col--good::before, .final__inner::before, .modal__dialog::before{
  content:""; position:absolute; left:0; top:14px; bottom:14px;
  width:3px; border-radius:var(--ae5-bar-r);
  background:#4FC4E9;
  box-shadow:var(--ae5-bar-glow);
  pointer-events:none;
  transform-origin:top;
}
/* Полоса приезжает ПОСЛЕ плашки: сначала встаёт поверхность, потом на ней
   появляется пометка. Двигается только transform, тень статична.

   🔴 ВХОД СДЕЛАН АНИМАЦИЕЙ НА .is-visible, А НЕ СЖАТИЕМ ПО УМОЛЧАНИЮ.
   Разница вся в том, ЧТО ТЕРЯЕТСЯ при отказе. Если по умолчанию держать
   scaleY(0) и разжимать классом, то без скриптов (класс не приходит вовсе)
   и внутри героя (где появление отключено намеренно) полоса пропадала бы
   насовсем - то есть отказ съедал бы саму пометку. Здесь по умолчанию
   полоса НА МЕСТЕ, а класс лишь добавляет ей въезд: отказ стоит эффекта,
   а не содержимого. Задержка 80ms живёт в fill-mode backwards. */
@keyframes ae5BarIn{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
.honest.reveal.is-visible::before,
.vs__col--good.reveal.is-visible::before,
.final__inner.reveal.is-visible::before{
  animation:ae5BarIn var(--ae5-enter) 80ms both;
}

/* ---- исключение: полоса как ИНДИКАТОР СОСТОЯНИЯ, а не украшение ----
   У шага сделки и у вопроса она горит только у раскрытого. Это не
   декорация, а ответ на «где я сейчас», поэтому сценарий сохранён целиком.
   Приведены только числа - радиус и свечение канонные. */
.flow__item::before,
.faq__item[open]::before{
  border-radius:var(--ae5-bar-r);
  background:#4FC4E9;
  box-shadow:var(--ae5-bar-glow);
}

/* -------------------------------------------------------------------------
   3. ОТКЛИК НА НАЖАТИЕ: ГЛАВНЫЙ ДЕФИЦИТ САЙТА

   На 265 КБ файла было СЕМЬ правил :active, все на .btn, .header__cta и
   .pill__link. У плашек, шагов, вопросов, булавок карты и точек карусели -
   ни одного. На телефоне наведения нет вовсе, и нажатие там единственный
   канал обратной связи.

   :active срабатывает по pointerdown, то есть палец получает ответ до того,
   как браузер решит, был это тап или прокрутка. Вешать отклик на click
   означало бы отвечать через 300 мс после прикосновения.
   ------------------------------------------------------------------------- */
.qcard:active, .spot__card:active, .seg__btn:active, .swap:active,
.flow__head:active, .faq__item summary:active, .geo__pin:active,
.geo__close:active, .fcard:active, .flow__all:active,
.modal__close:active, .logo:active, .panel-toggle:active{
  transform:scale(.985);
  transition-duration:var(--ae5-press-d);
}
/* .spot__dot в списке НЕТ намеренно: у него отклик живёт на ::before
   (пункт 9), а два масштаба подряд на одном нажатии дали бы двойной провал.
   .card/.svc/.guard тоже нет: на широком экране их transform занят пружиной
   наклона, и правило всё равно не выиграло бы по весу. */

/* -------------------------------------------------------------------------
   4. ТРИДЦАТЬ МЁРТВЫХ ЭЛЕМЕНТОВ

   Замер до правки: transition-duration 0s при живых правилах :hover у
   13 summary, 6 .flow__head, 4 .geo__pin, 4 .geo__close, 2 .logo и
   1 .panel-toggle. Рамка щёлкала мгновенно тринадцать раз подряд.
   ------------------------------------------------------------------------- */
.faq__item summary, .flow__head, .geo__pin, .geo__close, .logo, .panel-toggle{
  transition:border-color var(--ae5-tint), background var(--ae5-tint),
             color var(--ae5-tint), transform var(--ae5-press);
}
/* У .faq__item переход уже занят появлением (opacity/transform, 620ms).
   Список ДОПИСАН, а не заменён: заменив его, я погасил бы въезд 13 вопросов. */
.faq__item{
  transition:opacity var(--ae5-enter), transform var(--ae5-enter),
             border-color var(--ae5-tint), background var(--ae5-tint);
}

/* -------------------------------------------------------------------------
   5. ПОДЪЁМ, КОТОРЫЙ ВИДНО

   Было -3px за 300-420ms, то есть 7-10 пикселей в секунду: движение
   формально есть, глаз его не ловит. Стало -6px за 150ms. Выше 200ms
   подниматься нельзя - это обратная связь, а не рассказ.

   :hover целиком заперт в @media (hover:hover). На сенсоре наведение
   залипает после тапа, и плашка оставалась бы поднятой навсегда.
   ------------------------------------------------------------------------- */
@media (hover:hover){
  .card:hover, .guard:hover, .svc:hover, .qcard:hover, .fcard:hover{
    transform:translateY(-6px);
  }
  .card, .guard, .svc, .qcard, .fcard{
    transition:transform var(--ae5-lift), border-color var(--ae5-tint),
               background var(--ae5-tint), box-shadow var(--ae5-tint);
  }
  /* У .whyus-card подъём живёт в translate, а не в transform: transform
     занят появлением, и правило появления перебивало бы подъём по весу.
     Это решение зоны 3, оно верное, здесь только глубина. */
  .whyus-card{
    transition:translate var(--ae5-lift), border-color var(--ae5-tint),
               background var(--ae5-tint), box-shadow var(--ae5-tint);
  }
  .whyus-card:hover{ translate:0 -6px; }
  .btn:hover{ transform:translateY(-2px); transition-duration:120ms; }
}
/* Наклон живёт только на точном указателе. Восстанавливаем ему перспективу:
   без этой пары правило подъёма выше (тот же вес, но позже в файле) стёрло бы
   perspective и плашка перестала бы поворачиваться к руке. */
@media (hover:hover) and (pointer:fine){
  .ae4-tilt{ transition:transform var(--ae5-lift), box-shadow var(--ae5-tint),
                        border-color var(--ae5-tint), background var(--ae5-tint); }
  .ae4-tilt:hover{ transform:perspective(760px) translateY(-6px); }
  .ae4-tilt.is-tilting{
    transition:box-shadow var(--ae5-tint), border-color var(--ae5-tint),
               background var(--ae5-tint);
    transform:perspective(760px)
              rotateX(var(--ae4-rx,0deg)) rotateY(var(--ae4-ry,0deg))
              translateY(-6px);
  }
}

/* -------------------------------------------------------------------------
   6. ИЕРАРХИЯ КНОПОК: ЯЗЫК, КОТОРЫЙ В ФАЙЛЕ УЖЕ УТВЕРЖДЁН

   Две кнопки героя были одинаковыми: 239x50 и 206x50, обе тёмные, обе с
   кромкой 1px, разница только в весе шрифта. Ничего изобретать не нужно -
   вид «взведённой» шапочной кнопки (зона 4) уже утверждён и уже серебряный.
   Отдаём ровно эту поверхность главной кнопке.

   ПОЧЕМУ ТОЛЬКО ГЕРОЙ И ФИНАЛ, А НЕ ВСЕ ЧЕТЫРЕ .btn--primary. Их на странице
   четыре: герой, калькулятор, «спросить про свой город», финал. Серебро на
   всех означало бы две громкие кнопки на первом экране (герой и калькулятор
   стоят рядом) и сломало бы ровно то правило, ради которого зона 4 гасит
   шапку. Один экран - одна громкая.
   ------------------------------------------------------------------------- */
.hero__cta .btn--primary,
.final__inner .btn--primary{
  background-image:linear-gradient(180deg,#FFFFFF 0%,rgba(255,255,255,.95) 52%,rgba(255,255,255,.66) 100%);
  color:#0A0B0E;
  border-color:rgba(255,255,255,.5);
  font-weight:600;
  box-shadow:0 6px 18px -10px rgba(0,0,0,.9), 0 0 22px -10px rgba(79,196,233,.55);
}
.hero__cta .btn--primary .ico,
.final__inner .btn--primary .ico{ stroke:#0A0B0E; color:#0A0B0E; }
/* Общий верхний блик кнопок белым по белому дал бы грязный верх - ровно то,
   что зона 4 уже разобрала для шапочной кнопки. Берём её ослабленный слой. */
.hero__cta .btn--primary::after,
.final__inner .btn--primary::after{
  background:linear-gradient(180deg, rgba(255,255,255,.30) 0%,
             rgba(255,255,255,0) 52%, rgba(0,0,0,.06) 100%);
}
@media (hover:hover){
  .hero__cta .btn--primary:hover,
  .final__inner .btn--primary:hover{
    background-image:linear-gradient(180deg,#FFFFFF 0%,#FFFFFF 60%,rgba(255,255,255,.8) 100%);
    border-color:rgba(255,255,255,.7);
  }
}
/* Второстепенная кнопка перестаёт спорить с главной: заливки нет вовсе,
   остаётся кромка и текст на ступень тише. */
.btn--ghost{
  background:none;
  border-color:rgba(255,255,255,.14);
  color:rgb(179,186,197);
  font-weight:500;
}
@media (hover:hover){
  .btn--ghost:hover{ background:rgba(255,255,255,.05); border-color:rgba(255,255,255,.24); color:#EDF1F5; }
}

/* -------------------------------------------------------------------------
   7. ПЕРВЫЙ ЭКРАН

   Третья строка заголовка была залита акцентом на всю ширину, 52px. Канон
   запрещает это прямо: «залить им фон или кнопку целиком - нарушение».
   Плюс она была ещё и приглушена до выцветшего, то есть самая крупная
   надпись страницы читалась как самая тусклая. Отдаём ей серебро строк 1-2.

   И вес: h1 был 500 при 700 у шапок разделов вдвое мельче. Самая крупная
   надпись не может быть самой тонкой.
   ------------------------------------------------------------------------- */
.hero h1{ font-weight:600; }

/* Авторский момент, ОДИН на весь сайт и только на первом экране. Ниже героя
   сцен нет: там движение обязано означать «блок приехал», и не более. */
@keyframes ae5HeroIn{ from{ opacity:0; transform:translateY(14px); } to{ opacity:1; transform:none; } }
@keyframes ae5MarkIn{ from{ transform:scale(.94); }               to{ transform:none; } }
.hero h1{ animation:ae5HeroIn var(--ae5-hero) both; }
/* У знака только масштаб, без opacity: если анимации на машине не пойдут
   вовсе, знак обязан остаться видимым. Потеря эффекта допустима, потеря
   содержимого - нет. */
.logo__mark{ animation:ae5MarkIn var(--ae5-hero) 90ms both; }

/* -------------------------------------------------------------------------
   8. ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ: РАЗВЕСТИ ПО ТИПАМ

   Все 48 блоков ехали одинаково, 14px за 560ms (в сетках 22px за 620ms).
   Одинаковое движение у шапки раздела и у крупной панели стирает разницу
   между ними ровно так же, как одинаковая полоса.

   🔴 КАЖДОЕ ПРАВИЛО СДВИГА ЗАПИСАНО ЧЕРЕЗ :not(.is-visible). Иначе селектор
   вида .geo.reveal (вес 0,2,0), стоящий в файле ПОЗЖЕ .reveal.is-visible
   (тот же вес 0,2,0), выигрывает каскад и блок остаётся сдвинутым навсегда -
   уже приехавший, уже видимый, и на 28px ниже своего места.
   ------------------------------------------------------------------------- */
.reveal{ transition:opacity var(--ae5-enter), transform var(--ae5-enter); }
.reveal:not(.is-visible){ transform:translateY(20px); }
.ae4-stagger > .reveal{ transition:opacity var(--ae5-enter), transform var(--ae5-enter); }
.ae4-stagger > .reveal:not(.is-visible){ transform:translateY(20px) scale(.99); }
/* Шапки разделов только проявляются: заголовок, который подъезжает, читается
   как ещё один блок, а он рамка для блоков. */
.section__head.reveal{ transform:none; }
/* Крупные панели едут дальше - они и весят больше. Калькулятор в этот список
   НЕ входит: он внутри героя, где появление отключено намеренно. */
.geo.reveal:not(.is-visible){ transform:translateY(28px); }

/* -------------------------------------------------------------------------
   9. ТОЧКИ КАРУСЕЛИ УСЛУГ

   Зона нажатия была 6x6px без единого правила :hover, при том что карусель
   листает сама и точки - единственный способ вернуться назад. Геометрия
   здесь принадлежит этой части намеренно: она неотделима от переноса самой
   точки в ::before, отдельно её отдать нельзя.
   ------------------------------------------------------------------------- */
.spot__dot{
  width:28px; height:28px; padding:0; background:none; border:0;
  position:relative; box-shadow:none;
}
/* 🔴 ЗАЛИВКУ АКТИВНОЙ ТОЧКИ СНИМАЕМ С САМОЙ КНОПКИ, А НЕ ЗАБЫВАЕМ ПРО НЕЁ.
   Замер на живой странице сразу после правки: активная точка превратилась в
   синий круг 28px во всю новую зону нажатия. Причина - правило
   .spot__dot.is-on из зоны 3 (вес 0,2,0) красит саму кнопку, а кнопка теперь
   вчетверо больше видимой точки. Одного .spot__dot{background:none} не хватает:
   у него вес 0,1,0, он проигрывает. */
.spot__dot.is-on{
  background:none; box-shadow:none; transform:none;
}
.spot__dot::before{
  content:""; position:absolute; inset:0; margin:auto;
  width:7px; height:7px; border-radius:50%;
  background:rgba(255,255,255,.22);
  transition:transform var(--ae5-tint), background var(--ae5-tint), box-shadow var(--ae5-tint);
}
@media (hover:hover){
  .spot__dot:hover::before{ transform:scale(1.35); background:rgba(255,255,255,.38); }
}
.spot__dot:active::before{ transform:scale(.9); transition-duration:var(--ae5-press-d); }
.spot__dot.is-on::before{
  background:var(--accent); transform:scale(1.25);
  box-shadow:0 0 9px 1px rgba(79,196,233,.55);
}
/* Зоны выросли с 6px до 28px, а ряд обязан выглядеть прежним: зазор уходит
   в минус ровно на прирост, поэтому расстояние между видимыми точками
   осталось тем же. */
.spot__dots{ gap:0; margin-right:-4px; }

/* -------------------------------------------------------------------------
   10. ПЕРЕКЛЮЧАТЕЛЬ НАПРАВЛЕНИЯ ОБМЕНА

   .seg - сетка из двух РАВНЫХ колонок по 226px. Активная кнопка меняла
   background и color двумя независимыми переходами, и в середине было видно
   грязное промежуточное состояние: обе колонки полусветлые.

   Решение - один слой-пилюля, который ЕДЕТ. clip-path и второй слой текста
   не нужны: колонки равные, scaleX не требуется.

   Оба псевдоэлемента .seg свободны (замер: content none у обоих), поэтому
   новый элемент в разметке не нужен - а он и запрещён, разметка не моя.

   ПОЧЕМУ ВСЁ ЗАПЕРТО В @supports selector(:has(*)). Позицию пилюли задаёт
   класс is-active, который ставит app.js на кнопку, а не на .seg. Прочитать
   его с родителя умеет только :has. Там, где :has нет, весь блок отбрасывается
   целиком и остаётся прежняя заливка активной кнопки - переключатель
   продолжает показывать выбранное направление, просто без пилюли.
   ------------------------------------------------------------------------- */
@supports selector(:has(*)){
  .seg{ position:relative; }
  .seg::before{
    content:""; position:absolute; z-index:0;
    left:4px; top:4px; bottom:4px;
    /* Ширина колонки, посчитанная от поля кнопок: минус два поля по 4px и
       минус зазор 4px, пополам. Числа взяты из самой .seg (padding 4, gap 4). */
    width:calc((100% - 12px) / 2);
    border-radius:var(--r-inner, var(--r-sm));
    background:rgba(255,255,255,.13);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.10);
    transform:translateX(0);
    transition:transform var(--ae5-panel);
    pointer-events:none;
  }
  .seg:has(> .seg__btn:nth-child(2).is-active)::before{
    transform:translateX(calc(100% + 4px));
  }
  .seg__btn{ position:relative; z-index:1; }
  /* Заливку с кнопки снимаем: её роль забрала пилюля. Остаётся только цвет. */
  .seg__btn.is-active{ background:none; box-shadow:none; }
  .seg__btn{ transition:color var(--ae5-tint); }
}

/* -------------------------------------------------------------------------
   11. АККОРДЕОН «КАК ПРОХОДИТ СДЕЛКА»: ТОЛЬКО УСИЛЕНИЕ

   Механика не тронута: grid-template-rows 0fr -> 1fr, 520ms, та же кривая
   var(--flow-spring), max-height остаётся none. Правок ровно две.
   ------------------------------------------------------------------------- */
/* Закрытие короче открытия. Сокращение записано на БАЗОВОМ селекторе: при
   закрытии класс is-open уже снят, и действует именно оно. */
.flow__panel{ transition:grid-template-rows var(--ae5-exit); }
.flow__item.is-open .flow__panel{ transition:grid-template-rows 520ms var(--flow-spring); }
/* Содержимое проявляется позже коробки, но 110ms читались паузой между двумя
   отдельными событиями. 60ms читаются продолжением одного. Кривые не тронуты. */
.flow__item.is-open .flow__body{
  transition:opacity 320ms var(--flow-out) 60ms, transform 460ms var(--flow-spring) 60ms;
}
.flow__body{ transition:opacity var(--ae5-exit), transform var(--ae5-exit); }

/* -------------------------------------------------------------------------
   12. ПРАВАЯ ШТОРКА

   Замер в ЗАКРЫТОМ состоянии: transform translateX(336.6px), visibility
   visible, 96 отрисованных узлов, 8 фокусируемых кнопок ловят Tab за краем
   экрана, ни inert, ни aria-hidden, Escape не закрывает, тап мимо не
   закрывает, фон прокручивается под ней.

   Класс .ae5-sheet ставит effects.js по matchMedia, а не @media по ширине:
   выше 1200px .side--right - обычная колонка страницы, и visibility:hidden
   там стёр бы правую панель целиком.
   ------------------------------------------------------------------------- */
.side--right.ae5-sheet{
  visibility:hidden;
  transition:transform var(--ae5-exit), visibility 0s var(--ae5-exit-d);
}
.side--right.ae5-sheet.is-open{
  visibility:visible;
  transition:transform var(--ae5-sheet), visibility 0s 0s;
}
/* Затемнение под шторкой: без него непонятно, что страница ждёт закрытия. */
.ae5-scrim{
  position:fixed; inset:0; z-index:calc(var(--z-sheet) - 1);
  background:rgba(6,7,10,.6);
  opacity:0; pointer-events:none;
  transition:opacity var(--ae5-exit);
}
.ae5-scrim.is-on{ opacity:1; pointer-events:auto; transition:opacity var(--ae5-sheet); }
html.ae5-locked{ overflow:hidden; }

/* -------------------------------------------------------------------------
   13. ЛИПКИЕ ЛОВУШКИ НАВЕДЕНИЯ НА СЕНСОРЕ

   .swap:hover{transform:rotate(180deg)} стоял вне @media (hover:hover). На
   телефоне :hover залипает после тапа, и кнопка направления обмена
   оставалась перевёрнутой - навсегда, до перезагрузки.
   ------------------------------------------------------------------------- */
.swap:hover{ transform:none; }
@media (hover:hover){
  .swap:hover{ transform:rotate(180deg); }
  /* Нажатие поверх наведения: поворот сохраняется, добавляется продавливание.
     Без этой пары общее правило :active стёрло бы поворот на полкадра. */
  .swap:hover:active{ transform:rotate(180deg) scale(.94); }
}
@media (hover:none), (pointer:coarse){
  .swap:hover{ transform:none; }
  .card:hover, .svc:hover, .guard:hover, .qcard:hover, .fcard:hover{ transform:none; }
  .whyus-card:hover{ translate:none; }
  .spot__dot:hover::before{ transform:none; }
  .hero__cta .btn--primary:hover, .final__inner .btn--primary:hover{ transform:none; }
  /* Пересчёт фильтром по всем таблицам 22.08: незащищённых правил :hover со
     сдвигом или прозрачностью нашлось четырнадцать, из них девять закрывает
     список выше и прежнее правило .btn:hover зоны 4. Оставались пять, и
     каждое залипало бы после тапа. Булавки карты живут на планшете (карта
     скрыта только ниже 770px), кнопка шапки - на любом телефоне. */
  .geo__pin:hover .geo__dot{ transform:none; }
  .geo__pin:hover .geo__mark{ transform:none; }
  .hero .pill__link:hover .pill__arr{ transform:none; }
  /* Карусель услуг ниже 1200px скрыта, но на сенсорном ноутбуке она видна,
     и стрелка застревала бы сдвинутой. */
  .spot__card:hover .spot__cta .ico{ transform:none; }
  .header__cta.btn--tg:hover,
  .header.is-cta-armed .header__cta.btn--tg:hover{ transform:none; }
  .btn:hover::after{ opacity:.9; }
}

/* -------------------------------------------------------------------------
   14. ПОДСВЕТКА ТЕКУЩЕГО РАЗДЕЛА И ВОЗВРАТ НАВЕРХ

   Полотно 19526px на ширине 375px - это 24 экрана, и нижняя панель, самый
   быстрый переход, не показывала, где человек сейчас.
   ------------------------------------------------------------------------- */
/* box-shadow в списке обязателен: на широком экране плашка поднимается вместе
   с тенью, и без неё тень щёлкала бы мгновенно, пока плашка едет 150ms. */
.qcard{ transition:transform var(--ae5-lift), border-color var(--ae5-tint),
                   background var(--ae5-tint), box-shadow var(--ae5-tint),
                   color var(--ae5-tint); }
.qcard.is-current{ color:var(--accent-ink); }
.qcard.is-current .qcard__ico{
  color:var(--accent-ink);
  border-color:var(--accent-line);
  background:var(--accent-soft);
}
.qcard.is-current .qcard__t{ color:#EDF1F5; }

.ae5-top{
  position:fixed; right:16px; bottom:24px; z-index:var(--z-toggle);
  display:flex; align-items:center; justify-content:center;
  width:44px; height:44px; padding:0;
  border-radius:var(--r-card, 6px); cursor:pointer;
  background:rgba(12,13,17,.92); border:1px solid var(--line-2);
  color:#E9EEF3;
  opacity:0; transform:translateY(8px); pointer-events:none;
  transition:opacity var(--ae5-panel), transform var(--ae5-panel),
             border-color var(--ae5-tint), background var(--ae5-tint);
}
.ae5-top.is-on{ opacity:1; transform:none; pointer-events:auto; }
.ae5-top:active{ transform:scale(.94); transition-duration:var(--ae5-press-d); }
/* Ниже 1200px внизу стоит панель разделов - кнопка обязана встать НАД ней,
   иначе она закроет её крайнюю ячейку. Класс ставит effects.js по
   matchMedia: @media по ширине в этой зоне не мой инструмент. */
.ae5-top.ae5-narrow{ bottom:calc(96px + env(safe-area-inset-bottom)); }
@media (hover:hover){
  .ae5-top:hover{ background:rgba(20,22,28,.96); border-color:var(--accent-line); }
}

/* -------------------------------------------------------------------------
   15. ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ

   Правило styles.css:1097 гасит transition-duration через !important по
   всему документу. Оно закрывает девять блоков без дыр и остаётся на месте.
   Но вместе с движением оно убивало и ПОДТВЕРЖДЕНИЕ нажатия: человек с
   отключённым движением жал кнопку перехода к боту и не понимал, поехало
   или нет. Движение снимаем, ответ возвращаем - яркостью вместо сдвига.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .btn:active, .qcard:active, .spot__card:active, .seg__btn:active, .swap:active,
  .flow__head:active, .faq__item summary:active, .geo__pin:active, .geo__close:active,
  .fcard:active, .flow__all:active, .modal__close:active, .logo:active,
  .panel-toggle:active, .ae5-top:active{
    transform:none;
    filter:brightness(1.28);
    transition:filter 120ms linear !important;   /* бьёт .001ms из строки 1097 */
  }
  .spot__dot:active::before{ transform:scale(1.25); filter:brightness(1.4); }
  /* Въезд полосы снимается совсем: глобальное правило только ужимает его до
     .001ms, а этого мало - остаётся мигание в один кадр. */
  .honest.reveal.is-visible::before, .vs__col--good.reveal.is-visible::before,
  .final__inner.reveal.is-visible::before{ animation:none; transform:none; }
  .seg::before{ transition:none; }
  .ae5-scrim{ transition:none; }
  .ae5-top{ transform:none; }
  .hero h1, .logo__mark{ animation:none; opacity:1; transform:none; }
}
/* ═══ ЗОНА 5A: СОСТОЯНИЯ И ДВИЖЕНИЕ - КОНЕЦ ═══ */

/* ═══════════════════════════════════════════════════════════════════════════
   ЗОНА 6: ЧИТАЕМОСТЬ И ПАЛЕЦ (полировка 22.08.2026, замер на живом сайте)
   ═══════════════════════════════════════════════════════════════════════════

   🔴 ЧТО ЗАМЕРЕНО, А НЕ ПРЕДПОЛОЖЕНО.
   Дизайн-хук выдал 141 замечание о низком контрасте. Проверил их замером на
   живой странице, с наложением полупрозрачных слоёв по формуле Портера-Даффа:
   настоящих нарушений НОЛЬ. Хук считает по разметке и не знает ни фактического
   фона под элементом, ни того, что серебряные заголовки нарисованы градиентом,
   а белый текст кнопок лежит на синей заливке. Контраст трогать не нужно, и
   трогать его было бы порчей канона.

   А вот эти две вещи замер подтвердил, и они настоящие:

   1. МЕЛКИЙ ТЕКСТ. 30 видов подписей мельче 12px, самая мелкая 9.5px
      (.fcard__kicker, 8 штук на странице; .market__stamp). На телефоне это
      читается с прищуром, а половина этих подписей несёт смысл: валюта, курс,
      координаты города, метка «живое».

   2. ПАЛЕЦ НЕ ПОПАДАЕТ. 10 нажимаемых элементов ниже 44px по высоте, худшие -
      ссылки подвала (22px) и .pill__link в герое (25px). 44px это не выдумка
      стандарта, а размер подушечки пальца взрослого человека.

   Кегли поднимаются ТОЛЬКО у самых мелких, до 11px. Выше не поднимаю намеренно:
   это надписи-ярлыки капсом с широким трекингом, при 13-14px они начнут спорить
   с основным текстом и сломают ту самую иерархию, ради которой их и уменьшали.
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- 6.1 Пол по кеглю: ничего мельче 11px --- */
.fcard__kicker,
.market__stamp,
.geo__plate-t,
.geo__legend-t,
.geo__tag-c,
.geo__live-k,
.fcard__more,
.geo__now,
.mrow__pair {
  font-size: 11px;
}

/* --- 6.2 Палец: минимальная зона нажатия 44px ---
   Растим ЗОНУ, а не саму плашку: вертикальные поля добавляются внутрь ссылки,
   внешний вид капсулы не меняется, а промахов пальцем становится меньше. */
.hero .pill__link {
  padding-top: 10px;
  padding-bottom: 10px;
}

/* Ссылки подвала были 22px высотой - вдвое ниже подушечки пальца. */
.foot a,
.footer a,
.foot__link {
  display: inline-block;
  padding-top: 8px;
  padding-bottom: 8px;
}

/* Переключатель направления обмена и кнопка в шапке: 40px это почти впритык,
   4 недостающих пикселя дают заметную разницу на телефоне. */
.seg__btn,
.btn--sm {
  min-height: 44px;
}

/* --- 6.3 На телефоне читаемость важнее плотности ---
   На узком экране текст держим ещё крупнее: держать в руке дальше от глаз,
   чем монитор, и промахиваться пальцем там дороже. */
@media (max-width: 640px) {
  .fcard__kicker,
  .market__stamp,
  .geo__plate-t,
  .geo__legend-t,
  .geo__tag-c,
  .geo__live-k,
  .fcard__more,
  .geo__now,
  .mrow__pair,
  .flow__chip,
  .spot__cta,
  .card__tag {
    font-size: 12px;
  }
}

/* --- 6.4 Добор по замеру: что осталось после первого прохода ---
   Первый проход поднял кегли по списку, собранному глазами, и промахнулся:
   повторный замер на живой странице нашёл ещё семь видов текста мельче 11px и
   четыре вида зон нажатия ниже 44px. Список ниже собран замером, а не догадкой:
     10.0px  dt в списках определений (8 штук)
     10.5px  .spot__eyebrow, .spot__cta, .flow__chip, .card__tag,
             .geo__status, .geo__rule-k
     35px    .flow__all      37px .pill__link      38px .logo и ссылки подвала */
.spot__eyebrow,
.spot__cta,
.flow__chip,
.card__tag,
.geo__status,
.geo__rule-k,
.geo dl dt,
.spot dl dt,
.fcard dl dt {
  font-size: 11px;
}

.flow__all,
.logo {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* .pill__link уже получил вертикальные поля выше, но капсула считает высоту от
   строки: добавляем нижний предел, иначе на коротком тексте она снова сжимается. */
.hero .pill__link {
  min-height: 44px;
}

/* --- 6.5 Подвал: последние шесть ссылок ---
   Замер показал их в .footer__links, а не в .foot, поэтому селектор из 6.2 мимо.
   Высота была 38px при пороге 44. Ловим по фактическому классу, найденному
   обходом предков на живой странице, а не по предположению об именовании. */
.footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   ЗОНА 7: БОКОВЫЕ КОЛОНКИ ПО КОНЦЕПЦИИ apolloproduction.studio (24.08.2026)
   ═══════════════════════════════════════════════════════════════════════════

   ЖАЛОБА ВЛАДЕЛЬЦА ДОСЛОВНО: «панели слева и справа, они какие-то насранные».

   ЧТО ЗАМЕРЕНО НА ЖИВОМ САЙТЕ (1440x900, до правки). Внутри левой колонки
   19 элементов с замкнутой рамкой на все четыре стороны, внутри правой 4.
   Из них крупных плиток семь слева (спотлайт плюс шесть плашек разделов) и
   две справа (рынок, лента). Сама колонка при этом не существует как форма:
   background у .side прозрачный, border 0px. То есть на полотне просто
   лежат девять отдельных коробок со скруглением 18 и 14 - лоскутное одеяло,
   а не панель.

   ЧЕМ ЭТО РЕШЕНО В ЭТАЛОНЕ (замер apolloproduction.studio, 24.08):
   колонка 320px, фон rgb(9,9,11) - ТЕМНЕЕ полотна #0C0D11, одна линия 1px
   цветом rgb(57,57,65) на границе с центром, никаких скруглений и рамки
   вокруг самой колонки. Разделы внутри отбиты такой же горизонтальной
   линией, заголовок раздела - капс с широким трекингом. Рамка остаётся
   только у того, что обязано быть карточкой.

   ПОЧЕМУ ФОН ТЕМНЕЕ, А НЕ СВЕТЛЕЕ. Светлая плитка на тёмном полотне тянет
   взгляд на себя, и шесть таких плиток соревнуются с калькулятором в
   центре. Тёмная колонка, наоборот, отступает назад: она читается как поле
   страницы, а центр остаётся единственным светлым местом.

   ГРАНИЦЫ ЗОНЫ. Все правила ниже начинаются с .side, то есть не могут
   достать ни до одного блока центра. Ни курс, ни калькулятор, ни аккордеон
   сделки, ни карта городов, ни ссылки на бота не затронуты.
   Селектор с .side весит два класса намеренно: mobile.css подключён ПОСЛЕ
   styles.css и одевает .market/.feed/.spot одним классом, а порядок файлов
   я менять не вправе - вес решает спор без правки чужого файла.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  --ae7-col:   rgb(9,9,11);          /* фон колонки, замер эталона */
  --ae7-line:  rgb(57,57,65);        /* линия-разделитель, замер эталона */
  --ae7-card:  rgba(255,255,255,.24);/* мягкая рамка того, что осталось карточкой */
  --ae7-label: rgba(255,255,255,.62);/* заголовок раздела: 7.7:1 на фоне колонки */
  --ae7-hair:  rgba(255,255,255,.075);/* волосяная линия ВНУТРИ раздела */
}

/* -------------------------------------------------------------------------
   7.1 ШИРИНА КОЛОНОК НЕ ТРОГАЕТСЯ, И ЭТО ЗАМЕР, А НЕ ОСТОРОЖНОСТЬ

   У эталона колонка 320px, здесь 300 слева и 320 справа. Ровнял, замерил,
   откатил: подложка шапки - это псевдоэлемент .header::before с посадкой
   left:-300px; right:-320px, то есть ширины боковых колонок вбиты в него
   числами. Стоит сделать правую колонку 300px, и подложка вылезает на 20px
   за окно: document.scrollWidth 1460 при окне 1440 на КАЖДОЙ ширине от 1400.
   Вторым эффектом на 1400-1439 пропадало меню в шапке: центр падал ниже
   порога @container.

   Правка живёт в .header, а это чужая зона, поэтому ширина остаётся прежней,
   а находка уходит ведущему отдельным пунктом. Разница 20px при собственном
   фоне колонок глазом не ловится - её видно только линейкой.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   7.2 КОЛОНКА КАК ФОРМА: ФОН И ОДНА ЛИНИЯ
   Скругления и рамки по кругу нет намеренно: колонка не коробка, она поле
   страницы. Всю работу делает одна линия на границе с центром.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side{
    background:var(--ae7-col);
    border-radius:0;
    box-shadow:none;
  }
  .side--left{ border-right:1px solid var(--ae7-line); }
  .side--right{ border-left:1px solid var(--ae7-line); }

  /* Разделы идут встык, от края до края: воздух между плитками заменён
     линией, иначе разделитель повисает в воздухе и не примыкает к колонке. */
  .side--left .side__inner,
  .side--right .side__inner{ gap:0; padding:82px 0 28px; }
}

/* -------------------------------------------------------------------------
   7.3 ПЛИТКА ПЕРЕСТАЁТ БЫТЬ КОРОБКОЙ
   Снимаются заливка, рамка, скругление, тень и размытие подложки: за
   разделом теперь не полотно, а фон колонки, размывать нечего.
   ------------------------------------------------------------------------- */
.side .spot,
.side .market,
.side .feed{
  background:none;
  border:0;
  border-radius:0;
  box-shadow:none;
  backdrop-filter:none;
  -webkit-backdrop-filter:none;
}

/* Линия между разделами. Первый раздел её не получает - линия отбивает
   раздел ОТ ПРЕДЫДУЩЕГО, а не рисует ему крышку. */
@media (min-width:1200px){
  .side .side__inner > * + *{ border-top:1px solid var(--ae7-line); }
}
/* В шторке рынка на узком экране разделов тоже два, и отбивка им нужна
   ровно та же. Левая колонка ниже 1200px превращается в нижнюю панель
   навигации - там линия была бы лишней, поэтому правило именное. */
@media (max-width:1199px){
  .side--right .side__inner{ padding:20px 0 96px; }
  .side--right .side__inner > * + *{ border-top:1px solid var(--ae7-line); }
}

/* -------------------------------------------------------------------------
   7.4 ВОЗДУХ ВНУТРИ РАЗДЕЛА
   Поля переехали с .side__inner на сами разделы: только так линия-
   разделитель идёт от края до края колонки, а текст всё равно не липнет к
   краю. Числа те же, что были у плиток, вид плотности не изменился.
   ------------------------------------------------------------------------- */
.side .panel__head{ padding:24px 20px 12px; gap:9px; }
/* Подписи двух колонок обязаны стоять на одной линии: они видны
   одновременно, и разъезд читается как перекос вёрстки. Замер показал
   левую на 111px, правую на 106. Виновата не подпись, а точки карусели:
   у них зона нажатия 28px, и она задирала высоту всей строки, после чего
   подпись центровалась в ней ниже соседней. Высоту строки задаёт подпись,
   зона нажатия точек не трогается - она просто выступает за строку и на
   раскладку не влияет. */
.side .spot__dots{ height:18px; align-items:center; }
/* Штамп времени забирает себе отдельную строку (правка 19.08, замер её
   подтвердил), поэтому нижнее поле шапки рынка остаётся поджатым. */
.side .market .panel__head{ padding-bottom:6px; }
.side .market__list{ padding:2px 12px 20px; }
.side .feed__list{ padding:2px 14px 22px; gap:10px; }
.side .spot{ padding:24px 20px 26px; }

/* -------------------------------------------------------------------------
   7.5 ЗАГОЛОВОК РАЗДЕЛА
   Капс, широкий трекинг, приглушённый цвет - ровно как «THEMES» и
   «TOP OFFERS IN HIGH DEMAND» у эталона. Кегль 11px: ниже планки
   читаемости сайта не опускаемся, она выставлена зоной 6.

   Интерлиньяж НЕ прижимаю к единице намеренно: подпись стоит в строке с
   значком и точками карусели, и сжатая строка центрируется в ней иначе,
   чем соседняя - подписи двух колонок разъезжались по вертикали.
   ------------------------------------------------------------------------- */
.side .panel__title,
.side .spot__eyebrow{
  font-family:var(--font-mono);
  font-size:11px; font-weight:600;
  letter-spacing:.24em; text-transform:uppercase;
  color:var(--ae7-label);
}
/* Значок раздела теряет плитку-подложку: у эталона заголовок раздела - это
   текст, и шесть маленьких коробочек вокруг значков были частью той самой
   лоскутности. Сам значок остаётся, он держит узнаваемость раздела. */
.side .panel__ico{
  width:auto; height:auto; padding:0;
  background:none; border:0; border-radius:0;
  color:var(--ae7-label);
}
.side .panel__ico .ico{ width:15px; height:15px; }

/* -------------------------------------------------------------------------
   7.6 БЫСТРЫЕ РАЗДЕЛЫ: СПИСОК, А НЕ СЕТКА ПЛИТОК
   Шесть плашек 128x96 в две колонки - половина всей лоскутности левой
   панели. У эталона это простой список строк под заголовком раздела.
   Только на широком экране: ниже 1200px .qcard - кнопка нижней панели
   навигации, и она не трогается вообще.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side .qnav{
    display:grid; grid-template-columns:1fr; gap:2px;
    padding:22px 12px 26px;
  }
  /* Заголовка у этого раздела нет в разметке, а по эталону он обязан быть.
     Ставлю его псевдоэлементом: разметку index.html параллельно правят
     другие исполнители, и лезть туда ради одной подписи - лишний риск
     столкновения. Смысл подписи уже продублирован в aria-label самого
     <nav>, поэтому читалка ничего не теряет. */
  .side .qnav::before{
    content:"Разделы";
    padding:0 8px 12px;
    font-family:var(--font-mono);
    font-size:11px; font-weight:600; line-height:1;
    letter-spacing:.24em; text-transform:uppercase;
    color:var(--ae7-label);
    pointer-events:none;
  }

  /* Поле слева 8px, а не 14: значок строки встаёт ровно под первую букву
     заголовка раздела (обе точки на 20px от края колонки). Разъезд в 6px
     между подписью и списком под ней виден глазом сразу. */
  .side .qcard{
    position:relative;
    flex-direction:row; align-items:center; gap:12px;
    min-height:44px;                    /* планка пальца, зона 6 */
    padding:11px 10px 11px 8px;
    background:none; border:0; border-radius:6px; box-shadow:none;
    transition:background var(--ae5-tint), color var(--ae5-tint);
  }
  .side .qcard__ico{
    width:auto; height:auto;
    background:none; border:0; border-radius:0;
  }
  .side .qcard__ico .ico{ width:17px; height:17px; }
  .side .qcard__t{ font-size:13px; font-weight:500; color:#D7DDE5; }

  /* Наведение - только подсветка строки. Подъём плашки и пружинный наклон
     сняты намеренно: они были ответом плитки, а строка списка, которая
     отрывается от колонки и поворачивается к курсору, читается игрушкой.
     Нажатие остаётся, оно единственный отклик на сенсорном ноутбуке. */
  .side .qcard:hover{
    background:rgba(255,255,255,.055);
    box-shadow:none; transform:none;
  }
  .side .qcard:hover .qcard__t{ color:#FFFFFF; }
  .side .qcard.ae4-tilt.is-tilting{ transform:none; }
  .side .qcard:active{ transform:scale(.985); transition-duration:var(--ae5-press-d); }
  /* Светящееся кольцо по кромке ставил JS зоны 4 - у плитки оно вело руку.
     У строки кольцо нарисовало бы ровно ту коробку, которую мы убираем. */
  .side .qcard > .ae4-rim{ display:none; }

  /* «Вы здесь» - единственный акцент колонки. Числа канонные: 3px,
     скругление 6px 0 0 6px, свечение то же, что у пяти узлов страницы.
     Горит ровно одна строка из шести, то есть акцент остаётся редким. */
  .side .qcard::before{
    content:""; position:absolute; left:0; top:9px; bottom:9px;
    width:3px; border-radius:var(--ae5-bar-r);
    background:#4FC4E9; box-shadow:var(--ae5-bar-glow);
    opacity:0; transition:opacity var(--ae5-tint);
    pointer-events:none;
  }
  .side .qcard.is-current::before{ opacity:1; }
  .side .qcard.is-current .qcard__t{ color:#FFFFFF; }
  /* Плитка-подложка значка снята, поэтому прежняя метка текущего раздела
     (заливка и рамка значка) больше не существует - её роль забрали полоса
     и цвет строки. */
  .side .qcard.is-current .qcard__ico{
    background:none; border:0; color:var(--accent-ink);
  }
}

/* -------------------------------------------------------------------------
   7.7 ЧТО ОБЯЗАНО ОСТАТЬСЯ КАРТОЧКОЙ
   Карточка новости - самостоятельный объект: её открывают, у неё своя
   рубрика и своё «читать». Она и получает мягкую рамку эталона. Колонка
   вокруг неё рамки не имеет, поэтому рамок в колонке остаётся ровно
   столько, сколько в ней настоящих карточек.
   ------------------------------------------------------------------------- */
.side .fcard{
  border:1px solid var(--ae7-card);
  background:rgba(255,255,255,.028);
}
.side .fcard:hover{
  background:rgba(255,255,255,.055);
  border-color:rgba(255,255,255,.34);
}

/* Котировки - это таблица, а не набор карточек: строки разделены волосяной
   линией. На потемневшем фоне колонки прежние 5,5% белого почти пропали,
   поэтому линия чуть плотнее. */
.side .mrow + .mrow::before{ background:var(--ae7-hair); }

/* -------------------------------------------------------------------------
   7.8 ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ
   Единственное новое движение зоны - проявление полосы «вы здесь».
   Глобальное правило ужимает переход до .001ms, здесь он снимается совсем:
   один кадр мигания на метке положения хуже, чем её мгновенная смена.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .side .qcard::before{ transition:none; }
  .side .qcard:hover{ transform:none; }
}
/* ═══ ЗОНА 7 - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 8: ПЛОТНОСТЬ И ТИПОГРАФИКА ЦЕНТРАЛЬНОЙ КОЛОНКИ     (24.08.2026)

   ЖАЛОБА ВЛАДЕЛЬЦА, ДОСЛОВНО: «всё очень грустно и очень вяло, очень
   непрофессионально... чтобы он выглядел дороже». Дорогое ощущение даёт
   ИЕРАРХИЯ, а не количество эффектов, поэтому НИ ОДНОГО нового эффекта,
   градиента, тени или анимации зона не вводит. Она только расставляет ранг
   там, где до неё всё весило одинаково.

   ЗАМЕР ДО (живой сайт, окно 1440, центр 820px):
     - h1 52.48px весом 600, а шапки разделов 34.44px весом 700. Самая
       крупная надпись страницы была САМОЙ ТОНКОЙ.
     - в шкале кеглей провал: 73 элемента на 14.5px, 205 на 17px, дальше
       сразу 34.44px. В полосе 25-32px НОЛЬ элементов.
     - 13 разных радиусов скругления при каноне 6px.
     - «Чем мы отличаемся»: обе колонки совпадают по фону, рамке, кеглю и
       цвету заголовка, то есть наша сторона и сторона биржи - близнецы.

   ЗАМЕР ПОСЛЕ (тем же прибором, там же):
     - h1 52.48/700 против шапок 600: заголовок тяжелее и крупнее всех.
     - три ранга шапок 37.72 / 30.34 / 26.24, в полосе 25-32px теперь 7
       элементов вместо нуля, добавлена ступень 20px у заголовков карточек.
     - радиусов стало заметно меньше, 6px у 145 элементов (142 после зоны 8
       плюс три, добранные зоной 9).

   🔴 ПОПРАВКА СКЕПТИКА 24.08: строка выше раньше утверждала «радиусов 4
   вместо 13, остальные три - линейка 1px, круги 50% и пилюли 999px».
   Пересчёт на живой странице этого НЕ подтвердил: в центре осталось восемь
   разных значений, а не четыре. Сверх формообразующих (6px, 1px, 50%, 999px)
   висели ещё 18px, 16px, 14px, 10px и 8px. Причина промаха - в том, что
   список селекторов 8.5 перечисляет потомков .hero и .section, а .stats и
   .final__inner лежат вне обоих и берут радиус из своего --r-panel (18px).
   Эти два добраны в ЗОНЕ 9 ниже. Оставшиеся 16/14/10/8px - шапка, подвал и
   их кнопки; это открытый вопрос к ведущему, а не забытый селектор.

   🔴 ГРАНИЦА ОТВЕТСТВЕННОСТИ, ВАЖНО ДЛЯ СЛЕДУЮЩЕГО.
   Кегль шапок #how, #safety, #services, #reviews и скрытие их линейки
   объявлены НЕ ЗДЕСЬ, а в mobile.css (блок Б3), причём вне медиазапроса,
   то есть на всех ширинах. mobile.css подключён ПОСЛЕ styles.css, поэтому
   при равном весе селектора он побеждает. Эта зона сознательно НЕ
   переобъявляет те же свойства у тех же элементов: два файла, пишущие один
   кегль, - это будущая гонка правок. Здесь задан ранг для разделов, которых
   в mobile.css нет (#why, #diff, #options, #offline, #faq), и те измерения
   ранга, которых там нет вовсе (воздух, линейка, вес). Свести обе половины
   в один файл - отдельная задача, она передана ведущему.

   ЧЕГО ЗОНА НЕ КАСАЕТСЯ: боковых колонок (.side и всё внутри, включая
   .spot - он лежит в aside#sideLeft, а не в центре), текстов условий, курса
   91 ₽ и 566 ₸, ссылок на бота, логики калькулятора, аккордеона, карты и
   переключателя. Проверено вживую: 100 000 ₽ по-прежнему дают 1 098,90 USDT.
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   8.1 ТОКЕНЫ РАНГА И РАДИУСА, ОБЪЯВЛЕНЫ НА КОНТЕЙНЕРЕ ЦЕНТРА

   Единица cqi выбрана не для красоты: у .center стоит container-type, и
   базовое правило .section__head h2 уже считает кегль от ширины ЦЕНТРА, а
   не окна. Держим одну шкалу, иначе на странице появятся две параллельные.

   Радиусы переопределены ИМЕННО на #center, а не в :root. Те же четыре
   токена ЗОНЫ 3 обслуживают боковые плитки (.spot, .qcard, .mrow, .fcard),
   и правка в :root молча переписала бы чужую свежую работу в колонках.
   Наследование от #center отсекает боковины по построению, а не по
   договорённости.
   ------------------------------------------------------------------------- */
#center{
  --r8-mid:   clamp(24px, 3.70cqi, 34px);   /* опорные разделы: 30.34 при центре 820 */
  --r8-minor: clamp(22px, 3.20cqi, 28px);   /* служебные: 26.24, число взято из mobile.css Б3 */
  --r8-sub:   clamp(18px, 2.44cqi, 20px);   /* ступень заголовка карточки: ровно 20px */

  /* Канон агентства: «Скругление плашек: 6px». Одно место на весь центр. */
  --z3-r-panel: 6px;
  --z3-r-card:  6px;
  --z3-r-inner: 6px;
  --z3-r-ico:   6px;
}

/* -------------------------------------------------------------------------
   8.2 ВЕС: САМАЯ КРУПНАЯ НАДПИСЬ ОБЯЗАНА БЫТЬ САМОЙ ТЯЖЁЛОЙ

   ЗОНА 5A уже поднимала h1 с 500 до 600 с верной мыслью «h1 не может быть
   тоньше шапок», но остановилась на полпути: шапки-то весят 700. Довожу
   до конца с двух сторон - h1 на 700, шапки на 600. Заодно уходит главная
   причина серости: девять жирных плит подряд перестают быть жирными.
   700 - предельное начертание из подключённых (Poppins 400/500/600/700),
   выше браузер начал бы подделывать жир синтетически.
   ------------------------------------------------------------------------- */
.hero h1{ font-weight:700; }
#center .section__head h2{ font-weight:600; }

/* -------------------------------------------------------------------------
   8.3 ТРИ РАНГА РАЗДЕЛОВ

   Ранг 1, узловые (#how, #safety) - сердце предложения: как проходит сделка
   и что защищает. Кегль им задаёт mobile.css, здесь им достаётся воздух и
   полная линейка канона 220x3.
   Ранг 2, опорные (#why, #diff, #options, #offline) - объясняют и доказывают.
   Ранг 3, служебные (#services, #reviews, #faq) - довесок, оговорка и
   справка. #faq попал сюда по прямому указанию: «вопросы» названы
   второстепенными. Линейка у них снята: в каноне она помечает важное, и на
   служебном разделе она врёт о ранге.
   ------------------------------------------------------------------------- */
#why     .section__head h2,
#diff    .section__head h2,
#options .section__head h2,
#offline .section__head h2{ font-size:var(--r8-mid); }

#faq     .section__head h2{ font-size:var(--r8-minor); }

#why     .section__head .rule,
#diff    .section__head .rule,
#options .section__head .rule,
#offline .section__head .rule{ width:140px; }

#faq     .section__head .rule{ display:none; }

/* Ранг воздухом - ТОЛЬКО там, где воздух есть.
   🔴 Первая редакция ставила 104px безусловно, и замер на 375px показал
   брак: узкий экран уже сжат правилом .section{padding:56px} на 900px, а
   селектор с id перебивал его по весу и раздувал два раздела до 208px
   пустоты на экран высотой 812. Ниже 901px ранг несёт один кегль (28/24/22),
   и этого там достаточно. */
@media (min-width:901px){
  #how.section,
  #safety.section{ padding-top:104px; padding-bottom:104px; }
  #how .section__head,
  #safety .section__head{ margin-bottom:48px; }

  #services.section,
  #reviews.section,
  #faq.section{ padding-top:56px; padding-bottom:56px; }
  #services .section__head,
  #reviews .section__head,
  #faq .section__head{ margin-bottom:26px; }
}

/* -------------------------------------------------------------------------
   8.4 НЕДОСТАЮЩАЯ СТУПЕНЬ ШКАЛЫ: ЗАГОЛОВОК КАРТОЧКИ

   Заголовки карточек стояли на 17.28-19.44px при теле 16-17px. Разница в
   один-два пикселя не читается как разница, и пятнадцать карточек - основной
   объём страницы - выглядели сплошным серым полотном. Один общий шаг на 20px
   отделяет заголовок от тела и закрывает провал шкалы снизу, ровно там же,
   где ранг разделов закрыл его сверху.
   ------------------------------------------------------------------------- */
#center .whyus-card__t,
#center .guard h3,
#center .card h3,
#center .vs__col h3,
#center .flow__title{ font-size:var(--r8-sub); }

/* -------------------------------------------------------------------------
   8.5 РАДИУСЫ, КОТОРЫЕ НЕ ПРИВЯЗАНЫ К ТОКЕНАМ

   Первый экран и карта собирались раньше системы токенов и держат числа
   в себе: 18 у панели калькулятора, 14 у кнопок и полей, 10 у чипов, 8 и
   11 и 15 и 16 у карты. Это остаток, который токен из 8.1 не достаёт.
   Круги (50%), пилюли (999px) и волосяная линейка (1px) сюда НЕ входят:
   у них скругление задаёт форму, а не отделку, и канон их не касается.
   ------------------------------------------------------------------------- */
.hero .btn,      .section .btn,
.hero .calc,     .hero .seg,          .hero .seg__btn,
.hero .field__box, .hero .field__cur, .hero .field__input,
.hero .calc__rate, .hero .calc__badge, .hero .swap,
.hero .trust li, .hero .rate-strip,
.section .geo__map,   .section .geo__stage,  .section .geo__plate,
.section .geo__now,   .section .geo__legend, .section .geo__tag,
.section .geo__card,  .section code,
#center .flow__chip{ border-radius:6px; }

/* -------------------------------------------------------------------------
   8.6 ДВЕ СТОРОНЫ В «ЧЕМ МЫ ОТЛИЧАЕМСЯ»

   Синяя полоса у нашей колонки была и раньше, и это единственное, чем
   стороны различались; сами плоскости совпадали до значения - тот же фон
   .03, та же рамка .086, тот же белый заголовок весом 500. Раздел про
   разницу не показывал разницы.
   Приём тот же, что во всём каноне: важное ВЫСТУПАЕТ, неважное УТОПЛЕНО.
   Наша сторона приподнята планом и весом заголовка, сторона биржи опущена
   в фон и уведена в серебро.

   🔴 Цвет ТЕЛА списков не тронут намеренно. Контраст на этой странице уже
   мерили с наложением слоёв, нарушений там ноль, и приглушение пунктов ради
   выразительности - это порча канона, а не дизайн. Разницу держат план,
   рамка и заголовок; они контраст текста не меняют.
   ------------------------------------------------------------------------- */
#center .vs__col--good{
  background:rgba(255,255,255,.05);
  border-color:rgba(255,255,255,.14);
}
#center .vs__col--good h3{ font-weight:600; }

#center .vs__col--bad{
  background:rgba(255,255,255,.012);
  border-color:rgba(255,255,255,.06);
}
/* Серебро середины канонного градиента заголовка. На фоне полотна это
   около 11:1, то есть заголовок остаётся заголовком, а не подписью. */
#center .vs__col--bad h3{ color:#C3CBD5; }

/* -------------------------------------------------------------------------
   8.7 ДВИЖЕНИЕ
   Отдельного блока prefers-reduced-motion у зоны нет, и это не упущение:
   зона не объявляет ни одной анимации и ни одного перехода. Гасить нечего.
   ------------------------------------------------------------------------- */
/* ═══ ЗОНА 8 - КОНЕЦ ═══ */

/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 9: ДОБОР СКРУГЛЕНИЙ, ПРОПУЩЕННЫХ ЗОНОЙ 8        (24.08.2026, скептик)

   ЧТО НАШЛА ПРОВЕРКА. Зона 8 объявила канонные 6px четырьмя токенами на
   #center и отдельным списком селекторов в 8.5. Пересчёт скруглений на живой
   странице показал, что два блока центра мимо обоих механизмов:

     .stats        - строка цифр под первым экраном, 18px
     .final__inner - плашка финального призыва, 18px

   ПОЧЕМУ ИХ НЕ ВЗЯЛО. Токены зоны 8 (--z3-r-*) до них не доходят: радиус этим
   двум назначает ДРУГОЕ правило, `border-radius:var(--r-panel)`, а --r-panel
   переобъявлен на 18px и в зоне 8 не трогался. Список 8.5 их тоже не ловит -
   он перечисляет потомков .hero и .section, а .stats лежит в .proof и
   .final__inner в .final, то есть вне обеих веток.

   ПОЧЕМУ ЧЕРЕЗ ТОТ ЖЕ ТОКЕН, А НЕ ЧИСЛОМ 6px. --z3-r-panel уже переопределён
   зоной 8 на #center. Взяв его же, добор остаётся одной правкой с остальным
   центром: поменяет ведущий значение токена - эти два блока поедут вместе со
   всеми, а не останутся забытым числом в конце файла.

   ПОЧЕМУ СЕЛЕКТОР НАЧИНАЕТСЯ С #center. Ровно по той же причине, по которой
   зона 8 переопределяла токены на #center, а не на :root: .stats и .final у
   боковых колонок свои соседи по правилу (.spot, .market, .feed), и правка
   без привязки к центру переписала бы свежую работу зоны 7. Проверено
   замером: боковины после этой зоны не меняются ни одним свойством.

   ЧЕГО ЗОНА НЕ ТРОГАЕТ. Скругления шапки и подвала (16/14/10/8px у .logo__mark,
   .btn--lg, .btn--sm и ссылок футера) остаются как были: распространять ли
   канон на header и footer - вопрос ведущему, он уже поставлен. Сам ведущий
   решает и правку сводит, скептик за него это не выбирает.
   Круги 50%, пилюли 999px и волосяная линейка 1px не входят сюда никогда:
   там скругление задаёт форму, а не отделку, и канон их не касается.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ, поэтому блока prefers-reduced-motion у неё нет -
   гасить нечего. Ни одного нового эффекта, тени или градиента тоже нет.
   ═════════════════════════════════════════════════════════════════════════ */
#center .stats,
#center .final__inner{ border-radius:var(--z3-r-panel); }
/* ═══ ЗОНА 9 - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 11: ЛИНИИ И СВЕЧЕНИЯ - ТОРЕЦ РАСТВОРЯЕТСЯ, А НЕ ОБРУБАЕТСЯ
   ═════════════════════════════════════════════════════════════════════════
                                                              (24.08.2026)

   ЖАЛОБА ВЛАДЕЛЬЦА ДОСЛОВНО: «Синюю линию, там где калькулятор обмена, нужно
   чтобы она постепенно расплывалась сверху и снизу, а то она чётко
   обрывается, просто некрасиво. И так каждую линию где-то везде, чтобы она
   больше была такая расфокусенная.»

   ЗАМЕР ДО ПРАВКИ. Прибор свой: headless-Chrome по CDP на локальной копии
   сайта, три контроля выполняются ДО того, как напечатана хоть одна цифра.
     К1 - ширина окна ровно та, что просили. Иначе меряется чужой медиазапрос:
          навигация уже сбрасывала вьюпорт на 1440 и портила замеры.
     К2 - страница живая: есть .calc, полотно тёмное. Иначе меряется пустота.
     К3 - ТЕСТ НА ОТКАЗЕ. В страницу подсаживаются четыре зонда: сплошная
          полоса, полоса с гаснущей заливкой, обычная граница и граница с
          гаснущим border-image. Прибор обязан разложить их резкий / мягкий /
          резкий / мягкий. Не разложил - сломан прибор, а не сайт, замер
          останавливается. Без К3 ответ «резких линий ноль» ничего не стоит:
          ноль одинаково выдаёт и вылеченный сайт, и ослепший прибор.
   Результат замера:
     1440x900 - 74 линии с открытыми торцами, ВСЕ 74 обрублены, 0 растворены;
     375x812  - 68 линий с открытыми торцами, ВСЕ 68 обрублены, 0 растворены.

   ЗАМКНУТЫЕ РАМКИ В ПЕРЕПИСЬ НЕ ВОШЛИ НАМЕРЕННО. У рамки по четырём сторонам
   торца нет: она замыкается сама на себя, обрубать нечего. Владелец жалуется
   на линию, которая КОНЧАЕТСЯ ножом, а не на прямоугольник.

   -------------------------------------------------------------------------
   ПОЧЕМУ НЕ МАСКА, ХОТЯ МАСКА НАПРАШИВАЕТСЯ ПЕРВОЙ

   mask-image гасит торец идеально, но маска режет ВСЁ, что рисует элемент,
   а область маски по умолчанию - его border-box. Свечение канонной полосы
   живёт box-shadow'ом СНАРУЖИ этой коробки, поэтому маска стирает свечение
   целиком. Снято на зондах и видно глазом: полоса становится плоской ниткой,
   а канон говорит прямо - «свечение обязательно: без него полоса выглядит
   дёшево». Спасает mask-clip:no-clip, но замер поддержки на этой же машине:
     mask-clip:no-clip .............. есть
     -webkit-mask-clip:no-clip ...... НЕТ
   То есть на webkit без нового синтаксиса объявление отбрасывается, маска
   возвращается к border-box и свечение умирает уже у живого посетителя с
   айфона. Ставить приём, который у части людей отнимает канонный элемент,
   нельзя.

   ВЗЯТО ДРУГОЕ: гаснет САМА ЗАЛИВКА полосы. Ядро уходит в прозрачность на
   концах, а box-shadow остаётся нетронутым и работает везде. Свечение при
   этом и так размыто на 26 и 62 пикселя, поэтому его собственный торец мягкий
   от рождения - ножом резало именно сплошное ядро.

   ГРАНИЦЫ (border) заливкой не лечатся, а маску на них ставить нельзя по той
   же причине - вместе с кромкой замаскируется содержимое блока. Для них взят
   border-image с градиентом: он красит ТОЛЬКО кромку, содержимого не касается
   и отказывает безопасно - если движок не понял значение, кромка просто
   рисуется прежним border-color, то есть теряется улучшение, а не линия.
   Проверено, что border-image здесь применим: он отменяет border-radius, и
   поэтому замером подтверждено, что у ВСЕХ пролеченных элементов радиус 0px
   на обеих ширинах (1440 и 375). Ни у одного скруглённого блока границы не
   трогаются.

   ЧЕГО ЗОНА НЕ ТРОГАЕТ И ПОЧЕМУ:
     - кнопки, движение и правая колонка - по ним работают другие исполнители;
     - .header - его перебирает исполнитель по шапке (кнопки «курс», «отличия»);
     - .mrow (строки котировок) - внутренности правой колонки, чужая зона;
     - две границы у .flow__all-ico 12.7x12.7 - это НЕ линия, это уголок-шеврон,
       нарисованный двумя border. Растворить его торцы значит сломать значок;
     - li::before 14x2 - маркеры-тире у списков. Тире длиной 14px, растворённое
       с двух сторон, превращается в пыль: это метка, а не линия.
   Все четыре исключения найдены прибором и отброшены осознанно, а не пропущены.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ НИ ОДНОГО - ни transform, ни opacity, ни keyframes.
   Поэтому блок prefers-reduced-motion у неё пустой по существу: гасить нечего.
   Вместо него стоит блок prefers-contrast, и он важнее: человеку, который
   просит максимум контраста, размытый торец мешает - он ищет границу, а она
   нарочно неопределённая. Ему линии возвращаются ножевыми.
   ═════════════════════════════════════════════════════════════════════════ */

:root{
  /* Доля торца, которая гаснет у ГРАНИЦ. 11% от 820px секции = 90px, от 900px
     колонки = 99px, от 313px плашки = 34px. Пропорция выбрана долей, а не
     числом, потому что границы тут разной длины на порядок, и фиксированные
     пиксели на короткой плашке съели бы её целиком. */
  --ae11-edge: 11%;

  /* Цвет линии подставляется НА МЕСТЕ каждым правилом ниже. Приём с косвенной
     переменной: градиент описан один раз, а var(--ae11-hair) внутри него
     разрешается уже на том элементе, где градиент применён. Иначе пришлось бы
     писать четыре одинаковых градиента ради четырёх оттенков волоса. */
  --ae11-hair: rgba(255,255,255,.10);

  --ae11-fade-x: linear-gradient(90deg,
                   transparent 0,
                   var(--ae11-hair) var(--ae11-edge),
                   var(--ae11-hair) calc(100% - var(--ae11-edge)),
                   transparent 100%);
  --ae11-fade-y: linear-gradient(180deg,
                   transparent 0,
                   var(--ae11-hair) var(--ae11-edge),
                   var(--ae11-hair) calc(100% - var(--ae11-edge)),
                   transparent 100%);
}

/* -------------------------------------------------------------------------
   10.1 ГЛАВНАЯ ПРЕТЕНЗИЯ: СИНЯЯ ПОЛОСА У КАЛЬКУЛЯТОРА И ЕЁ РОДНЯ

   Один и тот же приём на все девять мест, где дом-стиль ставит вертикальную
   полосу 3px: пять смысловых узлов страницы, модалка, шаг сделки, раскрытый
   вопрос и метка «вы здесь» в колонке разделов.

   box-shadow здесь НЕ ПЕРЕОПРЕДЕЛЯЕТСЯ ни одной строкой - канонное свечение
   0 0 26px 3px + 0 0 62px 9px остаётся ровно тем, что записано в каноне.
   Меняется только заливка ядра.

   ДЛИНА ТОРЦА - min(56px, 30%), и это не украшательство. Полосы отличаются в
   27 раз: у калькулятора 714px, у метки «вы здесь» 26px. Фиксированные 56px
   съели бы метку целиком, а голые 30% дали бы калькулятору 214px киселя
   вместо линии. min() берёт по месту: длинной полосе - ровные 56px мягкого
   схода, короткой - её собственные 30%.
   ------------------------------------------------------------------------- */
.rate-strip::before,
.calc::before,
.honest::before,
.vs__col--good::before,
.final__inner::before,
.modal__dialog::before,
.flow__item::before,
.faq__item[open]::before,
.side .qcard::before{
  /* 🔴 ЗАПАСНАЯ СТРОКА ИДЁТ ПЕРВОЙ, И ЭТО ГЛАВНОЕ В ЭТОМ ПРАВИЛЕ.
     Здесь нарочно НЕ используется var(--токен). Разница в том, что ТЕРЯЕТСЯ
     при отказе. Подстановка переменной ломается на этапе вычисленного
     значения, а такое свойство НЕ откатывается на предыдущую строку - оно
     обнуляется, и полоса пропадает совсем, то есть отказ съедает саму
     пометку канона. Две литеральные строки ведут себя иначе: движок, который
     не знает min(), отбрасывает вторую ещё при разборе, и остаётся первая -
     полоса всё равно гаснет, просто торец меряется долей, а не пикселями. */
  background:linear-gradient(180deg,
              rgba(79,196,233,0) 0%,
              #4FC4E9 11%,
              #4FC4E9 89%,
              rgba(79,196,233,0) 100%);
  background:linear-gradient(180deg,
              rgba(79,196,233,0) 0,
              #4FC4E9 min(56px, 30%),
              #4FC4E9 calc(100% - min(56px, 30%)),
              rgba(79,196,233,0) 100%);
}

/* -------------------------------------------------------------------------
   10.2 ГРАНИЦЫ СЕКЦИЙ И ПЛАШЕК

   Всё это горизонтальные волосяные линии во всю ширину блока, обрубленные
   ножом слева и справа. Красятся гаснущим border-image; собственный
   border-color остаётся на месте как страховка на случай отказа.
   Оттенок волоса у каждой группы свой - он замерен на живом сайте, а не
   придуман, поэтому линии не меняют яркость, меняют только торцы.
   ------------------------------------------------------------------------- */
.section--alt,
.footer,
.footer__bottom{
  --ae11-hair:rgba(255,255,255,.10);
  border-image:var(--ae11-fade-x) 1;
}
.whyus-live{
  --ae11-hair:rgba(255,255,255,.08);
  border-image:var(--ae11-fade-x) 1;
}
.card__for,
.flow__row{
  --ae11-hair:rgba(255,255,255,.07);
  border-image:var(--ae11-fade-x) 1;
}

/* -------------------------------------------------------------------------
   10.3 РАЗДЕЛИТЕЛИ БОКОВЫХ КОЛОНОК

   🔴 ПОПРАВКА ПОСЛЕ ПОВТОРНОГО ЗАМЕРА (см. зону 11Б внизу файла). Здесь
   сначала было написано «самые заметные ножи на странице». Это НЕВЕРНО, и
   прибор это показал: .side--left и .side--right сидят на position:sticky
   высотой ровно в окно (замер: 300x900 и 320x900 при окне 900), их торцы
   лежат на 0 и 900, то есть ЗА краем экрана на любом скролле. Ножа там никто
   никогда не видел.
   Приём всё равно оставлен, но ради другого и названного вслух: владелец
   просил линии «более расфокусенные», а вертикальный градиент на липкой
   колонке держит линию плотной в середине экрана и приглушает у шапки и у
   низа - на каждом кадре одинаково, потому что бокс к экрану приколот.
   Устройство зоны 7 не ломается: линия та же, тот же цвет --ae7-line, та же
   одна штука на колонку. Меняется только плотность к краям кадра.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side--left,
  .side--right{
    --ae11-hair:var(--ae7-line);
    border-image:var(--ae11-fade-y) 1;   /* вертикальная линия - градиент 180deg */
  }
  /* Горизонтальные отбивки между разделами внутри колонки. */
  .side .side__inner > * + *{
    --ae11-hair:var(--ae7-line);
    border-image:var(--ae11-fade-x) 1;
  }
}
@media (max-width:1199px){
  /* Шторка рынка: те же отбивки разделов. */
  .side--right .side__inner > * + *{
    --ae11-hair:var(--ae7-line);
    border-image:var(--ae11-fade-x) 1;
  }
  /* Нижняя панель навигации. Её волос светлее колоночного - замер показал
     rgba(255,255,255,.145), и он сохранён без изменения яркости. */
  .side--left .qnav{
    --ae11-hair:rgba(255,255,255,.145);
    border-image:var(--ae11-fade-x) 1;
  }
}

/* -------------------------------------------------------------------------
   10.4 ЛИНЕЙКА ПОД ЭЙБРАУ

   Канон описывает её как «белый градиент, гаснет слева направо» - и правый
   конец у неё действительно уже мягкий. А левый начинается сразу с .92, то
   есть режет ножом. Правится ОДИН токен --rule: направление канона
   сохранено полностью, добавлен только короткий разгон в первые 8% (около
   11px из 140). Линейка остаётся той же самой, у неё просто перестаёт быть
   квадратным начало.
   ------------------------------------------------------------------------- */
:root{
  --rule: linear-gradient(90deg,
            rgba(255,255,255,0)   0%,
            rgba(255,255,255,.92) 8%,
            rgba(255,255,255,.78) 46%,
            rgba(255,255,255,0)   100%);
}

/* -------------------------------------------------------------------------
   10.5 СТЕКЛО В ДУХЕ TELEGRAM: КРОМКА, А НЕ НОВОЕ РАЗМЫТИЕ

   🔴 НОВЫХ ПОВЕРХНОСТЕЙ РАЗМЫТИЯ ЗДЕСЬ НЕТ НИ ОДНОЙ, И ЭТО ОСОЗНАННО.
   В зоне 4 записан замер 19.08: 34 элемента с backdrop-filter давали 12-19
   кадров, сайт грел ноутбук. Размытие под панелями на сайте уже есть - оно
   живёт токеном --z3-blur и накрывает десяток классов зоны 3. Добавить туда
   ещё поверхностей значит повторить чужую аварию ради вида.

   Что делает стекло стеклом на самом деле - это КРОМКА. У Telegram светлая
   волосяная линия по верху панели и тёмная по низу: одна показывает, что
   свет падает сверху, вторая даёт стеклу толщину. Правится один токен
   --z3-rim, поэтому все панели меняются согласованно и ни одно чужое
   правило не переписывается.

   Верх поднят с .06 всего до .085. Зона 3 специально опускала его с .16,
   потому что сильный блик на плоской поверхности снова читался градиентом,
   и это ограничение уважается: .085 - середина между «не видно» и «каша».
   Тёмная нижняя кромка добавлена не ради красоты, а ради того же контраста:
   она делает край определённее, то есть работает против каши, а не за неё.

   Насыщенность подложки поднята с 118% до 134%, радиус размытия почти не
   тронут (12 -> 13). Так и задумано: дорогая часть фильтра - именно радиус,
   а насыщенность бесплатна, и оживляет она как раз то, ради чего размытие
   ставили - синие точки фона-созвездия под панелью.
   ------------------------------------------------------------------------- */
:root{
  --z3-rim:  inset 0 1px 0 rgba(255,255,255,.085),
             inset 0 -1px 0 rgba(0,0,0,.30);
  --z3-blur: blur(13px) saturate(134%);
}

/* -------------------------------------------------------------------------
   10.6 КОМУ РАСТВОРЁННЫЕ ТОРЦЫ МЕШАЮТ

   Человек, включивший в системе повышенный контраст, просит не «красивее», а
   «чётче видно границу». Расфокусенный торец - ровно то, что ему мешает.
   Возвращаем ножевую линию: это его выбор, а не наш вкус.
   ------------------------------------------------------------------------- */
@media (prefers-contrast: more){
  :root{
    --ae11-edge: 0%;                       /* градиент схлопывается в сплошной */
    --rule: linear-gradient(90deg,
              rgba(255,255,255,.92) 0%,
              rgba(255,255,255,.78) 46%,
              rgba(255,255,255,0)   100%);
  }
  .rate-strip::before,
  .calc::before,
  .honest::before,
  .vs__col--good::before,
  .final__inner::before,
  .modal__dialog::before,
  .flow__item::before,
  .faq__item[open]::before,
  .side .qcard::before{ background:#4FC4E9; }
}

/* -------------------------------------------------------------------------
   10.7 ДВИЖЕНИЕ

   Зона не добавила ни одной анимации и ни одного перехода, поэтому гасить
   нечего. Блок оставлен пустым намеренно и с подписью: пустой блок читается
   как «проверено, движения нет», а его отсутствие - как «забыли посмотреть».
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  /* пусто: зона 10 не вводит движения */
}
/* ═══ ЗОНА 11 - КОНЕЦ ═══ */

/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 10R: ПРАВАЯ КОЛОНКА - КУРСЫ ЧИТАЮТСЯ, ЛЕНТА ПЕРЕСТАЁТ БЫТЬ СЕРОЙ
                                                            (24.08.2026)

   🔴 ПОЧЕМУ «10R», А НЕ ПРОСТО «10». Над сайтом одновременно работают
   несколько исполнителей, и номер 10 в этот же файл дописала соседняя зона
   про кнопки и навигацию. Два блока с одинаковым номером ломают поиск по
   файлу, поэтому свой я развожу буквой: R - правая колонка. Приём не
   выдуман, он уже есть в этом файле у ЗОНЫ 5A. Чужие строки при этом не
   тронуты ни одной: переименован только собственный блок.

   ЖАЛОБА ВЛАДЕЛЬЦА ДОСЛОВНО: «Ленту новостей надо сделать более ярче.
   Крипторынок справа тоже, типа курсы под ключи, а то там биткоин и прочее,
   нету никакого курса. Не видно.»

   🔴 СНАЧАЛА ДИАГНОЗ, ПОТОМ КРАСКА. Замер живого сайта 1440x900 (контроль
   прибора сошёлся: окно 1440, белый на полотне 19.42, строк 4, карточек 8):

     USDT 91 ₽ · BTC $79,834 +3.4% · ETH $2,526 +3.7% · TON $1.49 −1.9%
     штамп «обновлено 18:28», data-placeholder снят у всех четырёх строк.

   КУРСЫ ЕСТЬ И ОНИ ЖИВЫЕ. Фид CoinGecko доезжает, данные не пустые, чинить
   в app.js нечего. Значит случай «а»: цифры теряются в вёрстке. Почему
   именно теряются - видно в том же замере:

     тикер  BTC      13.0px  вес 600  #FFFFFF          контраст 19.90
     ЦЕНА   $79,834  13.5px  вес 600  rgb(237,241,245) контраст 17.53
     имя    Bitcoin  11.5px  вес 400  rgb(156,163,175) контраст  7.84

   Цена крупнее названия монеты всего в 1.17 раза и ТУСКЛЕЕ собственного
   тикера. То есть самое яркое пятно строки - слово «BTC», а не число. Глаз
   читает список названий, а курса не находит: он ровно там же по весу, где
   служебная подпись. Это перевёрнутая иерархия, а не нехватка данных.
   Плюс font-variant-numeric было normal - цифры не табличные.

   ЛЕНТА, тот же замер. Все три уровня карточки оказались ОДНОГО цвета
   rgb(156,163,175) с одним и тем же контрастом 7.51:

     .fcard__kicker  11.0px  вес 500  контраст 7.51
     .fcard__title   12.5px  вес 400  контраст 7.51
     .fcard__more    11.0px  вес 400  контраст 7.51

   По краске различимый уровень РОВНО ОДИН. Заголовок новости подан ровно
   тем же серым, что и служебное слово «ЧИТАТЬ». Отсюда «серые и одинаковые».
   Виноват не автор карточки: строка 3573 зоны 3 сгребла .fcard__title в
   общий список вторичного текста вместе с .mrow__name, и заголовок потерял
   свой цвет #DDE3EA.

   🔴 ЧЕГО ЗДЕСЬ НЕТ И ПОЧЕМУ. Ведущий просил «различимость между свежим и
   старым». В данных ленты ВРЕМЕНИ НЕТ: NEWS в app.js - это восемь заметок
   с полями kicker/title/body, при NEWS_IS_PLACEHOLDER = true. Ни даты, ни
   отметки времени, ни источника. Проставить их - выдумать факт, поэтому
   шкалы времени здесь не будет. Вместо неё поставлена шкала, которая
   опирается на настоящее событие: карточка, которую в этом сеансе уже
   открывали, гаснет на ступень (.fcard.is-read, класс вешает app.js).
   «Старое» тут значит «ты это уже читал», и это правда.

   ГРАНИЦЫ ЗОНЫ. Каждый селектор начинается с .side, дальше .market/.feed
   или их потомки. До центра колонки не достаёт ни одно правило: ни курс
   91 ₽ и 566 ₸, ни калькулятор, ни аккордеон сделки, ни карта городов, ни
   ссылки на бота. Ширины колонок, линии-разделители, кнопки и вся моторика
   зоны 5A не трогаются - это чужие зоны ответственности.
   Два класса в селекторе намеренно: mobile.css подключён ПОСЛЕ styles.css
   и одевает .fcard__title/.mrow__* одним классом. Вес спорит за меня, и
   чужой файл править не приходится.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ НИ ОДНОГО: ни keyframes, ни transform, ни новых
   transition. Меняются только краска, кегль, вес и отделка. Поэтому блока
   @media (prefers-reduced-motion: reduce) у зоны нет - гасить нечего.
   Переходы цвета на :hover уже описаны зоной 3 и зоной 5A и там же гасятся.

   ПЛАНКА ЧИТАЕМОСТИ СОХРАНЕНА: ни одного кегля мельче 11px не появляется,
   все значения ниже только растут. Зон нажатия зона не создаёт: «ЧИТАТЬ» -
   это оформление ВНУТРИ кнопки .fcard (её высота 128px), а не отдельная
   цель, поэтому правило 44px к нему не относится и не нарушается.
   ═════════════════════════════════════════════════════════════════════════ */

:root{
  /* Лестница краски правой колонки. Значения посчитаны против фона колонки
     rgb(9,9,11), а не против полотна: колонка зоной 7 сделана темнее, и
     контраст на ней выше, чем на #0C0D11. */
  --ae10-val:   #FFFFFF;                 /* цифра курса: 19.4:1 - главное в блоке */
  --ae10-tick:  rgba(255,255,255,.72);   /* тикер монеты: 10.7:1 - подпись к цифре */
  --ae10-title: #EDF1F5;                 /* заголовок новости: 17.5:1 */
  --ae10-read:  rgba(255,255,255,.74);   /* слово «ЧИТАТЬ»: 10.7:1 */
  --ae10-kick:  rgba(255,255,255,.56);   /* рубрика: 6.4:1 - тише заголовка */
  --ae10-old:   rgba(255,255,255,.58);   /* уже открывали: 6.7:1 */
  --ae10-chip:  rgba(255,255,255,.16);   /* рамка чипа «ЧИТАТЬ» */
}

/* -------------------------------------------------------------------------
   10.1 КУРС - ГЛАВНОЕ ЧИСЛО СТРОКИ, А НЕ ПОДПИСЬ К НЕЙ

   Кегль 20 против 11.5 у названия монеты - отношение 1.74 вместо прежних
   1.17. Вес 700 и чистый белый ставят цену выше тикера по обоим приборам
   сразу, кеглю и контрасту, иначе перевёрнутая иерархия не чинится:
   поднять только размер мало, пока тикер остаётся самым белым пятном.

   line-height:1.05 намеренно: строка - grid с выравниванием по базовой
   линии, и крупная цифра со штатным интерлиньяжем растянула бы всю строку
   вниз, оторвав тикер от имени монеты.
   ------------------------------------------------------------------------- */
.side .mrow__price{
  font-size:20px;
  font-weight:700;
  color:var(--ae10-val);
  line-height:1.05;
  letter-spacing:-.005em;
  /* Табличные цифры: при обновлении фида «1» перестаёт быть уже «8», и
     число не дёргается по ширине. Моно-стек это уже делает, но если он
     не подхватится, свойство удержит выравнивание само. */
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}
/* Прочерк на неудавшемся фиде не должен кричать двадцатым кеглем: провал
   загрузки - не новость, о которой сообщают крупно. Возврат к прежнему
   виду плейсхолдера, честность зоны 3 сохраняется. */
.side .mrow__price[data-placeholder]{
  font-size:13.5px;
  font-weight:500;
  color:var(--z3-mut);
}

/* Тикер уходит на ступень вниз: он был единственным чисто белым элементом
   строки и перетягивал внимание с числа. Кегль не тронут - падает только
   яркость, поэтому строка не теряет опознавательный знак. */
.side .mrow__sym{ color:var(--ae10-tick); }

/* -------------------------------------------------------------------------
   10.2 ИЗМЕНЕНИЕ ЗА СУТКИ - РАЗЛИЧИМО ЦВЕТОМ И ФОРМОЙ

   Цвета роста и падения на сайте уже были (--up/--down), но подавались
   самым мелким кеглем строки, 11px, обычным весом, без подложки - то есть
   цвет приходилось искать. Чип возвращает знаку вес: подложка своего цвета
   даёт «зелёное/красное» ещё до того, как прочитано число.

   ПОЧЕМУ ЭТО НЕ НАРУШАЕТ КАНОН АКЦЕНТА. Канон ограничивает синий #4FC4E9.
   Зелёный и красный - не акцент, а значение данных, ими помечается рост и
   падение, а не «важность». Синего в чипах нет ни пикселя.

   Строка сервиса под чип не попадает намеренно: у неё в этой ячейке текст
   «курс сервиса», а не процент, и подложка соврала бы про направление.
   Правило именное - только .is-up и .is-down.
   ------------------------------------------------------------------------- */
.side .mrow__chg{
  font-size:12px;
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}
.side .mrow__chg.is-up,
.side .mrow__chg.is-down{
  display:inline-flex; align-items:center;
  padding:3px 8px;
  font-weight:600;
  /* 999px - это форма, а не отделка: канон скруглений плашек к пилюлям не
     применяется (оговорено зоной 9). */
  border-radius:999px;
  border:1px solid transparent;
}
.side .mrow__chg.is-up{
  background:rgba(99,198,162,.12);
  border-color:rgba(99,198,162,.24);
}
.side .mrow__chg.is-down{
  background:rgba(229,147,138,.12);
  border-color:rgba(229,147,138,.24);
}
/* Крупная цифра и чип рядом требуют чуть больше воздуха между строками
   ячеек, иначе процент липнет к цене. Горизонтальный зазор не тронут. */
.side .mrow{ gap:5px 10px; }

/* -------------------------------------------------------------------------
   10.3 ШТАМП ЖИВЫХ КОТИРОВОК

   Единственное место правой колонки, где канонный синий уместен: он метит
   ВАЖНОЕ - что показанные числа настоящие и когда они получены. Точка
   ставится только при снятом data-placeholder, то есть по факту удачного
   фида, а не всегда. Свечение по канону, пропорционально уменьшенное с
   3px-полосы до 5px-точки.

   Площадь акцента: 25px² точки на 288000px² колонки - три сотых процента.
   Замер до правки показал долю акцентных заливок в колонке 0.00%.
   ------------------------------------------------------------------------- */
.side .market__stamp{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}
.side .market__stamp:not([data-placeholder]){
  display:flex; align-items:center; justify-content:flex-end; gap:7px;
}
.side .market__stamp:not([data-placeholder])::before{
  content:"";
  width:5px; height:5px; border-radius:50%;
  background:#4FC4E9;
  box-shadow:0 0 10px 1px rgba(79,196,233,.55), 0 0 22px 4px rgba(79,196,233,.16);
  flex:0 0 auto;
}

/* -------------------------------------------------------------------------
   10.4 ЛЕНТА: ТРИ УРОВНЯ КРАСКИ ВМЕСТО ОДНОГО

   Было: заголовок, рубрика и «ЧИТАТЬ» - один цвет, контраст 7.51 у всех
   троих. Стало: 17.5 / 6.4 / 10.7. Различие теперь читается с расстояния,
   на котором буквы ещё не разбираются - а именно так карточку и оценивают
   боковым зрением, прокручивая страницу.

   Заголовку возвращён вес: 600 вместо 400. Это ЕДИНСТВЕННЫЙ носитель
   смысла в карточке, остальное - служебная обвязка, и она должна отойти.
   ------------------------------------------------------------------------- */
.side .fcard__title{
  font-size:13.5px;
  font-weight:600;
  line-height:1.45;
  color:var(--ae10-title);
  letter-spacing:-.002em;
}
/* Рубрика тише заголовка, но своего характера не теряет: капс и широкий
   трекинг остаются от зоны 3, меняется только яркость. Акцентной она НЕ
   становится - зона 3 сознательно убрала отсюда синий, чтобы восемь
   голубых надписей подряд не рябили в узкой колонке. Это решение в силе. */
.side .fcard__kicker{ color:var(--ae10-kick); }

/* -------------------------------------------------------------------------
   10.5 «ЧИТАТЬ» ВЫГЛЯДИТ НАЖИМАЕМЫМ

   Было слово того же серого, что и весь остальной текст карточки: ничем не
   отличается от подписи и не обещает действия. Стало - чип с рамкой и
   собственным полем: замкнутый контур человек читает как цель ещё до того,
   как навёл курсор.

   Отдельной цели нажатия при этом не появляется: кнопка - вся карточка
   .fcard высотой 128px, чип лежит внутри неё и события не перехватывает.
   Планка 44px относится к цели, а не к её оформлению, и не нарушается.
   Движения не добавлено: переход цвета уже описан зонами 3 и 5A.
   ------------------------------------------------------------------------- */
.side .fcard__more{
  align-self:flex-start;
  padding:6px 11px;
  border:1px solid var(--ae10-chip);
  border-radius:999px;
  background:rgba(255,255,255,.035);
  color:var(--ae10-read);
  font-weight:600;
}
.side .fcard:hover .fcard__more{
  border-color:rgba(79,196,233,.42);
  background:rgba(79,196,233,.10);
  color:#9BE0F7;
}

/* -------------------------------------------------------------------------
   10.6 УЖЕ ОТКРЫВАЛИ - ЧЕСТНАЯ ЗАМЕНА ШКАЛЕ ВРЕМЕНИ

   Класс is-read вешает app.js по факту клика (см. блок в конце app.js).
   Никакой даты, никакого «2 часа назад» - только то, что действительно
   произошло на глазах у человека. Гаснет заголовок и чип, рубрика остаётся:
   по ней карточку и находят повторно.
   ------------------------------------------------------------------------- */
.side .fcard.is-read .fcard__title{ color:var(--ae10-old); font-weight:500; }
.side .fcard.is-read .fcard__more{
  color:rgba(255,255,255,.52);
  border-color:rgba(255,255,255,.10);
  background:transparent;
}
/* Наведение снимает приглушение целиком: карточка снова обещает открыться. */
.side .fcard.is-read:hover .fcard__title{ color:var(--ae10-title); }
/* ═══ ЗОНА 10R - КОНЕЦ ═══ */

/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 10: МЕТАЛЛ НА КНОПКАХ И ВЕС НАВИГАЦИИ                (24.08.2026)

   ТРЕБОВАНИЕ ВЛАДЕЛЬЦА ДОСЛОВНО: «Кнопки наверху, типа курс, отличия и так
   далее, и слева где разделы, сделай чуть побольше и как-то их чуть выделить...
   кнопки, чтобы они не были такими тупорылыми: чуть закруглённые и тоже с
   градиентом, допустим, от металлического к тёмному, слева направо все кнопки.
   Чтобы было эстетично.»

   ЧТО ЗАМЕРЕНО НА ЖИВОЙ СТРАНИЦЕ ДО ПРАВКИ (локальный сервер, окно 1440x900,
   контроль прибора сошёлся: innerWidth 1440, 6 пунктов меню, 6 строк разделов,
   таблицы стилей читаются из CSSOM, scrollWidth 1440):

     пункт меню      35.5px высотой, кегль 12.5, вес 400, цвет белый 58%,
                     подложки нет вовсе - шесть серых слов в пустоте;
     строка разделов 44.36px, кегль 13, подложки нет;
     кнопок видно    12 (10 штук .btn + 2 половины переключателя);
     из них с горизонтальным градиентом  2  (только .btn--primary в центре);
     скругление      6px у десяти из двенадцати - это и есть «тупорылые»;
     правил :active  14.

   🔴 РАСХОЖДЕНИЕ С КАНОНОМ ОСОЗНАННОЕ, А НЕ НЕБРЕЖНОСТЬ. Канон агентства
   задаёт скругление 6px, и зона 8 честно свела к нему весь центр. Владелец
   24.08 прямо просит «более закруглённый», и его свежее слово старше канона.
   Расхождение ограничено КНОПКАМИ и рамкой переключателя: карточки, плашки и
   мелкие ярлыки зона не трогает, у них 6px остаются. То есть канон не отменён,
   у него сделано одно названное исключение.

   ГРАНИЦЫ ЗОНЫ. Линии, движение страницы, правая колонка, тексты условий,
   курс, ссылки на бота, работа калькулятора, аккордеона, карты и переключателя
   направления не затронуты ни одним селектором ниже. Меняются только заливка,
   скругление, кегль, цвет и отклик на нажатие.
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   10.1 СЕМЬЯ МЕТАЛЛА: РАМПЫ, ВСЕ СЛЕВА НАПРАВО

   Просьба звучит как «от металлического к тёмному, слева направо». Рампа
   ровно такая уже утверждена владельцем 19.08 и живёт на .btn--primary
   (#4A4E56 -> #0B0C10). Я её не переписываю, а поднимаю в токен и раздаю
   остальным кнопкам - тогда у страницы один материал, а не пять похожих.

   Ступеней несколько, чтобы кнопки не слились в одну массу: громкая, плотная,
   тихая и стеклянная различаются СВЕТЛОТОЙ металла, а направление у всех одно -
   слева направо в тёмное. У каждой ступени три состояния: покой, наведение
   (светлее), нажатие (темнее). Темнее именно на нажатии, потому что вдавленная
   поверхность уходит в тень - это единственный физически честный вариант.

   ПОЧЕМУ СЕРЕБРО ИМЕННО ТАКИМИ ЧИСЛАМИ. #FFFFFF -> #F4F7FA 26% -> #C3CBD5 63%
   -> #98A2AE - это дословный серебряный градиент канона, только развёрнутый
   по горизонтали. Тёмный текст #0A0B0E даже на самом тёмном его конце даёт
   7.6:1, а на вдавленном состоянии 6.0:1, то есть просьба «к тёмному»
   выполнена без потери читаемости.
   ------------------------------------------------------------------------- */
:root{
  /* сталь: утверждённая рампа главной кнопки, поднятая в токен */
  --z10-steel:     linear-gradient(90deg,#4A4E56 0%,#33363D 38%,#1B1D22 72%,#0B0C10 100%);
  --z10-steel-hi:  linear-gradient(90deg,#52565F 0%,#3B3F47 38%,#212429 72%,#0E0F14 100%);
  --z10-steel-lo:  linear-gradient(90deg,#3B3F46 0%,#2A2D33 38%,#141619 72%,#08090C 100%);
  /* серебро канона, развёрнутое слева направо - только для громкой кнопки */
  --z10-silver:    linear-gradient(90deg,#FFFFFF 0%,#F4F7FA 26%,#C3CBD5 63%,#98A2AE 100%);
  --z10-silver-hi: linear-gradient(90deg,#FFFFFF 0%,#FBFDFE 30%,#D3DAE3 66%,#AAB3BE 100%);
  --z10-silver-lo: linear-gradient(90deg,#E8ECF1 0%,#DCE2E9 26%,#AEB7C2 63%,#87909C 100%);
  /* плотное стекло: вторичное действие внутри карточек */
  --z10-plate:     linear-gradient(90deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,.145) 42%,
                                        rgba(255,255,255,.075) 76%,rgba(0,0,0,.06) 100%);
  --z10-plate-hi:  linear-gradient(90deg,rgba(255,255,255,.30) 0%,rgba(255,255,255,.21) 42%,
                                        rgba(255,255,255,.12) 76%,rgba(0,0,0,.04) 100%);
  --z10-plate-lo:  linear-gradient(90deg,rgba(255,255,255,.13) 0%,rgba(255,255,255,.08) 42%,
                                        rgba(255,255,255,.04) 76%,rgba(0,0,0,.14) 100%);
  /* тихое стекло: призрачная кнопка, плашка-ссылка, спящая кнопка шапки */
  --z10-glass:     linear-gradient(90deg,rgba(255,255,255,.13) 0%,rgba(255,255,255,.07) 42%,
                                        rgba(255,255,255,.02) 76%,rgba(0,0,0,.10) 100%);
  --z10-glass-hi:  linear-gradient(90deg,rgba(255,255,255,.20) 0%,rgba(255,255,255,.11) 42%,
                                        rgba(255,255,255,.04) 76%,rgba(0,0,0,.08) 100%);
  --z10-glass-lo:  linear-gradient(90deg,rgba(255,255,255,.07) 0%,rgba(255,255,255,.035) 42%,
                                        rgba(255,255,255,.012) 76%,rgba(0,0,0,.16) 100%);

  /* Скругления кнопок. Ступени различимы глазом: 10 < 12 < 14. */
  --z10-r:     12px;
  --z10-r-sm:  10px;
  --z10-r-lg:  14px;
}

/* -------------------------------------------------------------------------
   10.2 СКРУГЛЕНИЕ

   Селектор повторяет .hero .btn и .section .btn намеренно: зона 8 свела их к
   6px правилом в два класса, и одиночный .btn его бы не перебил. Вес тот же,
   моё правило стоит позже - спор решается порядком, без !important и без
   правки чужих строк.

   Акцентная полоса .btn--primary::before поджимается РОВНО НА РАДИУС - это
   уже разобранный урок файла: при меньшем поджиме прямой торец полосы 2px
   вылезает слева от скругления отдельным синим язычком.
   ------------------------------------------------------------------------- */
.btn,     .hero .btn,     .section .btn,     .final .btn{ border-radius:var(--z10-r); }
.btn--sm, .hero .btn--sm, .section .btn--sm, .final .btn--sm{ border-radius:var(--z10-r-sm); }
.btn--lg, .hero .btn--lg, .section .btn--lg, .final .btn--lg{ border-radius:var(--z10-r-lg); }
.btn--primary::before{ top:var(--z10-r); bottom:var(--z10-r); }
.btn--sm.btn--primary::before{ top:var(--z10-r-sm); bottom:var(--z10-r-sm); }
.btn--lg.btn--primary::before{ top:var(--z10-r-lg); bottom:var(--z10-r-lg); }

/* Рамка переключателя направления и его половины: 14 снаружи, 10 внутри.
   Числа не выбраны на глаз - у .seg поле 4px, и 14 - 4 = 10 даёт ТОЧНО
   концентричные скругления. Раньше рамка была 6px, а пилюля внутри 10px:
   внутренний радиус больше внешнего читается как брак вёрстки.
   Работа переключателя не тронута: ни ширина пилюли, ни её сдвиг, ни классы. */
.seg,      .hero .seg{      border-radius:var(--z10-r-lg); }
.seg__btn, .hero .seg__btn{ border-radius:var(--z10-r-sm); }

/* -------------------------------------------------------------------------
   10.3 ЗАЛИВКА ПО ВИДАМ КНОПОК

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

   ПОЧЕМУ ВЕЗДЕ background-image, А НЕ background. Сокращённое свойство
   обнуляет цвет фона, а у половины кнопок он несёт свою работу (кромка
   стекла, подложка шапки). Ставим только слой краски.

   🔴 ПОЧЕМУ ЗДЕСЬ ЕСТЬ ОТДЕЛЬНОЕ ПРАВИЛО ДЛЯ .svc И .honest. Первая редакция
   этой зоны красила .btn--tg одним классом - и три кнопки из четырёх остались
   без металла. Замер показал причину: внутри карточек услуг и честной оговорки
   живёт ЧУЖОЕ правило в два класса с сокращённым background, оно и весом, и
   свойством било мою краску. Плотность .14 против .045 у призрака там выбрана
   осознанно (иначе главное действие карточки сравнивается с второстепенным),
   поэтому я не сравниваю их обратно, а ПОВТОРЯЮ ступень: плотное стекло у
   действия, тихое у призрака. Ладонь иерархии остаётся у прежнего автора.
   ------------------------------------------------------------------------- */

/* Громкая кнопка первого экрана и финала: серебро канона по горизонтали. */
.hero__cta .btn--primary,
.final__inner .btn--primary{ background-image:var(--z10-silver); }

/* Кнопка в Telegram вне карточек: плотное стекло, акцентная кромка остаётся
   её приметой - по ней кнопку бота узнают среди серых. */
.btn--tg{
  background-image:var(--z10-plate);
  color:#FFFFFF;
  border-color:rgba(79,196,233,.42);
}
/* Те же кнопки внутри карточек: плотность и белая кромка чужого правила
   сохранены, добавлена только рампа. Цвет фона снижен до .05 намеренно -
   рампа сама несёт до .22 белого, и без снижения кнопка ушла бы в белое
   пятно, то есть ровно в то, что канон запрещает. */
.svc .btn--tg, .honest .btn--tg{
  background-color:rgba(255,255,255,.05);
  background-image:var(--z10-plate);
}

/* Второстепенная кнопка: самое тихое стекло той же семьи. Заливки как таковой
   у неё не было вовсе (зона 5A сняла её, чтобы не спорила с главной) - рампа
   возвращает материал, оставаясь полупрозрачной и тише плотного стекла. */
.btn--ghost{
  background-image:var(--z10-glass);
  border-color:rgba(255,255,255,.16);
}

/* Кнопка шапки, спящее состояние: то же тихое стекло. Белой она становится
   только когда наблюдатель в effects.js ставит .is-cta-armed - правило ниже. */
.header__cta.btn--tg{
  background-image:var(--z10-glass);
  border-color:rgba(255,255,255,.22);
}
/* Взведённое состояние: серебро вместо белой заливки сверху вниз. Селектор
   повторяет чужой ДОСЛОВНО (четыре класса), иначе он не перебьётся. */
.header.is-cta-armed .header__cta.btn--tg{ background-image:var(--z10-silver); }

/* ---- НАВЕДЕНИЕ. Заперто в @media (hover:hover): на сенсоре наведения нет,
   и без запора палец оставлял бы на кнопке «залипшую» подсветку. ---- */
@media (hover:hover){
  .hero__cta .btn--primary:hover,
  .final__inner .btn--primary:hover{ background-image:var(--z10-silver-hi); }
  .btn--tg:hover{
    background-image:var(--z10-plate-hi);
    border-color:rgba(79,196,233,.72);
  }
  .svc .btn--tg:hover, .honest .btn--tg:hover{
    background-color:rgba(255,255,255,.09);
    background-image:var(--z10-plate-hi);
  }
  .btn--ghost:hover{
    background-color:transparent;
    background-image:var(--z10-glass-hi);
    border-color:rgba(255,255,255,.28);
    color:#EDF1F5;
  }
  .header__cta.btn--tg:hover{
    background-image:var(--z10-glass-hi);
    border-color:rgba(255,255,255,.36);
  }
  .header.is-cta-armed .header__cta.btn--tg:hover{ background-image:var(--z10-silver-hi); }
}

/* -------------------------------------------------------------------------
   10.4 ОТКЛИК НА НАЖАТИЕ

   Зона 5A уже развела масштаб .97 по кнопкам, и он остаётся. Здесь ДОБАВЛЕН
   второй канал ответа - материал: на нажатии рампа уходит в тёмное. Масштаба
   на телефоне мало: палец закрывает собой половину кнопки, и единственное, что
   человек видит, это край. Край и меняется.

   🔴 ПОЧЕМУ ЭТОТ БЛОК СТОИТ ПОСЛЕ БЛОКА НАВЕДЕНИЯ, А НЕ ДО. На мыши нажатие
   всегда происходит ПОВЕРХ наведения: активны оба состояния сразу. Первая
   редакция зоны ставила :active выше по файлу при равном весе - и на десктопе
   нажатие не показывалось вовсе, его перекрывал :hover. Проверено щелчком на
   живой странице, а не рассуждением.

   Градиент между собой не интерполируется, поэтому смена мгновенная - это не
   анимация и в бюджет движения не входит. Ни одного перехода по
   width/height/top/left зона не вводит.
   ------------------------------------------------------------------------- */
.btn--primary:active{ background-image:var(--z10-steel-lo); }
.hero__cta .btn--primary:active,
.final__inner .btn--primary:active{ background-image:var(--z10-silver-lo); }
/* 🔴 Цвет фона на нажатии тоже сбрасывается вниз, и это не украшательство.
   Замер форсированным состоянием показал: правило наведения ставит фон
   СОКРАЩЁННЫМ свойством, и без своего цвета нажатие выходило СВЕТЛЕЕ покоя -
   палец получал ответ «кнопка загорелась» вместо «кнопка продавилась». */
.btn--tg:active{ background-color:rgba(79,196,233,.06); background-image:var(--z10-plate-lo); }
.svc .btn--tg:active, .honest .btn--tg:active{
  background-color:rgba(255,255,255,.03);
  background-image:var(--z10-plate-lo);
}
.btn--ghost:active{ background-image:var(--z10-glass-lo); }
.header__cta.btn--tg:active{ background-color:rgba(255,255,255,.04); background-image:var(--z10-glass-lo); }
.header.is-cta-armed .header__cta.btn--tg:active{ background-image:var(--z10-silver-lo); }

/* -------------------------------------------------------------------------
   10.5 МЕНЮ В ШАПКЕ: ПОБОЛЬШЕ И ВЫДЕЛИТЬ

   ЧТО БЫЛО: шесть слов кеглем 12.5 весом 400 цветом белый 58% высотой 35.5px,
   без подложки. Промах пальцем на сенсорном ноутбуке гарантирован (порог 44),
   и на фоне белой кнопки справа меню читается как служебная сноска.

   ЧТО СТАЛО: единый стеклянный трек с шестью строками внутри - приём
   сегментного переключателя. Одна подложка на все шесть спокойнее, чем шесть
   отдельных плашек: выделение получено, лоскутности не прибавилось.

   🔴 ОТКУДА ВЗЯЛОСЬ МЕСТО ПОД БОЛЕЕ КРУПНЫЙ КЕГЛЬ. Замер до правки: просвет
   слева до логотипа 17.89px, справа до кнопки 66.17px. Меню центровано по
   ШАПКЕ, а логотип (174px) шире кнопки (126px), поэтому меню и стоит вплотную
   к логотипу - перекос в 48px виден глазом. Сдвиг ровно на половину разницы,
   24px, уравнивает просветы и отдаёт под меню те 48px, что до этого пустовали
   справа. Ширины логотипа и кнопки от ширины окна не зависят, поэтому и
   поправка постоянная.

   ПОЧЕМУ ПОРОГ 813px И ПОЧЕМУ ОН НЕ ВЫДУМАН. Ровно на этом пороге чужое
   правило прячет меню, и ровно под полосу 780-812 в файле уже выкроена
   отдельная сборка ужатых пунктов (она чинит провал меню на окнах 1400-1432).
   Мой блок начинается с 813 и в ту полосу не заходит: ужатая сборка остаётся
   работать как была.

   ЗАМЕР ПОСЛЕ ПРАВКИ (числа, а не расчёт): пункт 44px высотой при кегле 13.5,
   меню 424.4px, просветы 21.4 слева и 21.7 справа на окне 1440.
   ------------------------------------------------------------------------- */
@container center (min-width:813px){
  .nav{
    gap:2px; padding:3px;
    border-radius:var(--z10-r-lg);
    background:rgba(255,255,255,.045);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.055);
    /* Сдвиг на половину разницы «логотип минус кнопка». Трансформ, а не
       отступ: раскладку не пересчитывает и в кадр не попадает. */
    transform:translate(calc(-50% + 24px),-50%);
  }
  .nav a{
    display:inline-flex; align-items:center; justify-content:center;
    min-height:44px;                    /* планка пальца, зона 6 */
    padding:0 8px;
    border-radius:var(--z10-r-sm);
    font-size:13.5px; font-weight:500; letter-spacing:-.004em;
    color:rgba(255,255,255,.74);        /* было 58%: слово в шапке было тише подписи */
  }
}
@media (hover:hover){
  @container center (min-width:813px){
    .nav a:hover{ color:#FFFFFF; background:rgba(255,255,255,.10); }
  }
}
/* Нажатие - ПОСЛЕ наведения, по той же причине, что и у кнопок. */
@container center (min-width:813px){
  .nav a:active{
    transform:scale(.96);
    background:rgba(255,255,255,.15);
    color:#FFFFFF;
    transition-duration:var(--ae5-press-d);
  }
}

/* -------------------------------------------------------------------------
   10.6 «РАЗДЕЛЫ» СЛЕВА: ПОБОЛЬШЕ И ВЫДЕЛИТЬ

   Зона 7 сняла с этих строк плитки, и это верно: шесть коробок 128x96 были
   половиной той самой лоскутности, на которую жаловался владелец. Но вместе с
   коробкой ушла и всякая подложка, и список стал шестью серыми строчками.
   Просьба «чуть выделить» закрывается не возвратом коробок, а самой тихой
   заливкой: 3.5% белого читаются как строка списка, а не как плитка - рамки
   нет, тени нет, скругление мягкое.

   Кегль 13 -> 14 и высота 44 -> 48: это единственная навигация по странице
   длиной 19 500 пикселей, она обязана быть крупнее подписи под картинкой.

   Полоса «вы здесь» поджата на 10px - ровно на новый радиус строки, по тому
   же правилу, что и у кнопок.

   Только широкий экран: ниже 1200px эти же строки - ячейки нижней панели
   навигации, у них своя сборка в mobile.css, и она не трогается.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side .qnav{ gap:4px; }
  .side .qcard{
    min-height:48px;
    padding:12px 10px 12px 8px;
    border-radius:var(--z10-r-sm);
    background:rgba(255,255,255,.035);
  }
  .side .qcard__t{ font-size:14px; font-weight:500; color:#E7ECF3; }
  .side .qcard__ico .ico{ width:18px; height:18px; }
  .side .qcard::before{ top:10px; bottom:10px; }
  /* Текущий раздел светлее соседей даже без синей полосы - на случай, когда
     полоса ещё не доехала или движение выключено. */
  .side .qcard.is-current{ background:rgba(255,255,255,.075); }
  /* Подпись раздела чуть ярче: она подписывает теперь заметный блок, а не
     шесть серых строк. Кегль 11px канонный и не меняется. */
  .side .qnav::before{ color:rgba(255,255,255,.72); }
}
@media (hover:hover){
  @media (min-width:1200px){
    .side .qcard:hover{ background:rgba(255,255,255,.085); }
  }
}
@media (min-width:1200px){
  .side .qcard:active{ background:rgba(255,255,255,.11); }
}

/* -------------------------------------------------------------------------
   10.7 ПЛАШКА-ССЫЛКА В ГЕРОЕ
   Тот же материал, что у кнопок, но форма не трогается: 999px здесь задаёт
   ФОРМУ капсулы, а не отделку, и канон скруглений её не касается.
   ------------------------------------------------------------------------- */
.hero .pill__link{ background-image:var(--z10-glass); }
@media (hover:hover){
  .hero .pill__link:hover{
    background-color:rgba(255,255,255,.10);
    background-image:var(--z10-glass-hi);
    color:#FFFFFF;
  }
}
.hero .pill__link:active{ background-image:var(--z10-glass-lo); }

/* -------------------------------------------------------------------------
   10.8 ЧЕГО ЗОНА НАМЕРЕННО НЕ ДЕЛАЕТ

   ПЕРЕКЛЮЧАТЕЛЬ НАПРАВЛЕНИЯ НЕ ПОЛУЧАЕТ ГРАДИЕНТА. Его выбранная половина -
   это не заливка кнопки, а отдельная пилюля .seg::before, которая ЕЗДИТ между
   половинами. Дай я половинам собственный металл, на переключателе оказалось
   бы два указателя выбора сразу, и приехавшая пилюля спорила бы с залитой
   кнопкой. Поэтому здесь только скругление и отклик, работа не тронута.

   ЦВЕТ ТЕЛА КНОПОК НЕ ПРИГЛУШАЕТСЯ. Контраст на странице уже мерили с
   наложением слоёв, нарушений ноль; приглушать текст ради красоты металла -
   порча, а не дизайн. Самый тёмный конец серебра под чёрным текстом даёт
   7.6:1 в покое и 6.0:1 на вдавленном состоянии.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   10.9 ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ

   Новое движение у зоны ровно одно: масштаб .96 на нажатом пункте меню.
   Гасим его и возвращаем ответ яркостью - тем же приёмом, что зона 5A, иначе
   человек с отключённым движением жмёт пункт и не понимает, попал ли.
   Смена градиента на нажатии остаётся: она мгновенная и движением не является.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .nav a:active{
    transform:none;
    filter:brightness(1.28);
    transition:filter 120ms linear !important;  /* бьёт глобальные .001ms */
  }
}
/* ═══ ЗОНА 10 (КНОПКИ И НАВИГАЦИЯ) - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 12: ДВИЖЕНИЕ И ПЕРЕЛИВАНИЕ ЗНАКА                     (24.08.2026)

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

   НОМЕР 12, А НЕ 11. На момент дописки в файле уже лежали ДВЕ разные зоны с
   номером 10 (правая колонка и металл на кнопках) - по файлу одновременно
   работают соседние исполнители. Номер 11 оставлен им про запас, чтобы
   столкновения не вышло второй раз. Свой префикс ae12 выбран по той же
   причине: ae10 уже занят токенами правой колонки.

   ГРАНИЦЫ ЗОНЫ. Только знак в шапке и появление блоков при прокрутке. Линии,
   кнопки, правая колонка, калькулятор, карта городов, аккордеон - не здесь.
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   12.1 ПЕРЕЛИВАНИЕ ЗНАКА «Apollo Exchange»

   ЗАМЕР ДО ПРАВКИ: у .header .logo__text animation none, background-clip
   border-box, color rgb(255,255,255). Никакого движения на знаке не было
   вовсе - только у рамки .logo__mark разовый ae5MarkIn при загрузке.

   ПРИЁМ. Два слоя фона под одним background-clip:text. Нижний - канонное
   серебро агентства дословно (#FFFFFF -> #F4F7FA 26% -> #C3CBD5 63% ->
   #98A2AE). Верхний - светлая полоса, которая едет по буквам слева направо.
   Двигается background-position, то есть краска внутри уже размеченной
   коробки: раскладка не пересчитывается, соседи не двигаются, ширина знака
   остаётся теми же 125px.

   🔴 ПОЧЕМУ ПОЗИЦИЯ УМЕНЬШАЕТСЯ, А НЕ РАСТЁТ. Ловушка процентов в
   background-position: при картинке ШИРЕ коробки смещение считается как
   (ширина коробки - ширина картинки) * доля, а эта разность отрицательная.
   Значит больший процент двигает картинку ВЛЕВО. Чтобы блик шёл слева
   направо, процент обязан падать: 150% (полоса за левым краем) -> 0%
   (полоса ушла за правый край). Написанное «от 0% к 150%» дало бы блик,
   ползущий в обратную сторону.

   ПОЧЕМУ РАЗ В 5.2 СЕКУНДЫ. Сам проезд занимает 24% цикла, это около 1.25с,
   остальные 4 секунды знак стоит спокойно. Просили 4-6 секунд; чаще - и
   шапка превращается в мигающую рекламу, а знак обязан оставаться знаком.

   🔴 ПРОЗРАЧНЫЙ ЦВЕТ ТЕКСТА ЗАПЕРТ В @supports, И ЭТО ГЛАВНОЕ ЗДЕСЬ.
   Приём держится на background-clip:text. Где его нет, color:transparent
   означает НЕВИДИМОЕ НАЗВАНИЕ КОМПАНИИ в шапке - потеря содержимого, а не
   потеря эффекта. Поэтому внутри @supports лежит ВСЁ: и заливка, и
   прозрачный цвет, и сама анимация. Не поддержал браузер - знак остаётся
   ровно таким, каким был до правки: белый текст, приглушённое второе слово.

   ПОЧЕМУ ВТОРОЕ СЛОВО НЕ ПОТЕРЯЛО ТИШИНУ. До правки .logo__text em гасился
   цветом rgba(255,255,255,.55). Под background-clip краска у обоих слов
   общая, поэтому em тоже делается прозрачным - иначе он закрасил бы себя
   поверх градиента и блик обрывался бы на слове «Exchange». Разницу держит
   сам канонный градиент: он идёт от белого к #98A2AE, и «Exchange» попадает
   в его тёмную половину. Контраст этой половины на полотне #0C0D11 - 7.5:1
   при пороге 4.5, то есть читаемость не просела, а выросла (было около 6.5).

   ПОДВАЛ НЕ ТРОГАЕМ: селектор начинается с .header, второй такой же знак
   внизу страницы остаётся как был. Просили именно верхнюю надпись.
   ------------------------------------------------------------------------- */
@supports ((-webkit-background-clip: text) or (background-clip: text)){
  .header .logo__text{
    background-image:
      /* блик - слоем ВЫШЕ, поэтому идёт первым в списке.

         🔴 У ПОЛОСЫ ЕСТЬ ТЁМНЫЕ ПЛЕЧИ, И ЭТО РАЗБОР ПИКСЕЛЬНОГО ЗАМЕРА,
         А НЕ УКРАШЕНИЕ. Прошлая редакция была из одного белого ядра, и я
         записал её в исправные по снимкам фаз - на глаз казалось, что
         переливание есть. Настоящий замер яркости (снимок области знака,
         разбор по пикселям букв, фаза выбиралась паузой анимации, а не
         «снял когда успел») показал другое:

               слово        покой   пик    размах
               «Apollo»     214.1   226.9   12.8   ← 5% от 255, не видно
               «Exchange»   170.0   208.1   38.1   ← видно

         Причина арифметическая, а не вкусовая: буквы «Apollo» лежат в
         светлом конце серебра (#F4F7FA), это почти потолок яркости, и
         белому блику подниматься там просто некуда. Ярче белого не бывает.
         Итог - переливалась треть надписи, а просили всю.

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

         РЕЗУЛЬТАТ, СНЯТЫЙ ТЕМ ЖЕ ПРИБОРОМ, что и жалоба выше (размах яркости
         буквенных штрихов, медиана по столбцам пикселей):

               слово        было   стало
               «Apollo»      23     58     ← втрое заметнее
               «Exchange»    61     85

         🔴 ЧТО ЭТО СТОИЛО, А НЕ ТОЛЬКО ЧТО ДАЛО. Плечо опускает буквы, и за
         это надо платить контрастом. Самый тёмный штрих за весь проезд: было
         156 единиц яркости (7.07:1 на полотне), стало 134 (5.33:1). Порог для
         15.5px/600 - это 4.5:1, то есть запас остался, но он сократился.
         Именно поэтому плечо .20, а не глубже: расчёт по худшему случаю (плечо
         над самой тёмной ступенью серебра #98A2AE) даёт при .30 уже 4.19:1 -
         ниже порога. Взято .20 с запасом, и проверено пикселями, а не формулой.

         ПОЧЕМУ ЦВЕТ ПЛЕЧА #0C0D11, А НЕ ЧЁРНЫЙ: это цвет полотна страницы,
         буквы уходят в тон фона, а не в посторонний чёрный.

         ШИРИНА ПОЛОСЫ. Плечи разведены на 18% картинки, а картинка шире
         коробки в 2.8 раза - значит рабочая часть полосы укладывается ровно в
         половину ширины знака. Шире было нельзя: полоса накрывала бы обе
         буквенные группы разом, и средняя яркость надписи почти не менялась
         бы - блик стал бы общим подмигиванием, а не проездом слева направо. */
      linear-gradient(100deg,
        rgba(12,13,17,0)    36%,
        rgba(12,13,17,.20)  41%,
        rgba(255,255,255,1) 50%,
        rgba(12,13,17,.20)  59%,
        rgba(12,13,17,0)    64%),
      /* 🔴 БЕЛЫЙ ОТДАН БЛИКУ, А НЕ ПРИБИТ К ЛЕВОМУ КРАЮ - ЭТО РАЗБОР ЗАМЕРА.
         Первая редакция брала канонную лесенку дословно, вместе с #FFFFFF на
         отметке 0%. Снимки семи фаз показали, что блеска на слове «Apollo»
         при этом НЕТ вообще: буквы там уже белые, ярче белого не бывает, и
         полоса проходила по ним вхолостую. Переливание читалось только на
         втором слове, то есть на трети надписи.
         Палитра канона сохранена дословно и целиком - те же четыре цвета
         #FFFFFF, #F4F7FA, #C3CBD5, #98A2AE. Изменилось одно: чистый белый
         больше не лежит неподвижно в начале строки, он ЕДЕТ вместе с бликом.
         Покой держат три остальные ступени, и самая тёмная из них, #98A2AE,
         даёт на полотне #0C0D11 контраст 7.5:1 при пороге 4.5 - читаемость
         не просела. */
      linear-gradient(90deg, #F4F7FA 0%, #DDE3EA 30%, #C3CBD5 63%, #98A2AE 100%);
    background-size: 280% 100%, 100% 100%;
    background-position: 150% 0, 0 0;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    /* 🔴 ОТСРОЧКА 5s - ЭТО ЗАМЕР, А НЕ ВКУС. Первую редакцию я поставил на 2s
       и на снимках увидел чёрный кадр вместо знака. Разбор: страницу до
       4497ms (замер наблюдателем с первого кадра загрузки) закрывает собой
       заставка .intro - fixed, во весь экран. То есть первый проезд блика
       целиком проходил ЗА заставкой, человек его не видел ни разу, а первый
       ВИДИМЫЙ приходился только на 7.5с. Отсрочка 5s ставит первый проезд
       через полсекунды после снятия заставки: знак успевает появиться, и
       сразу по нему проходит блик. Дальше цикл ровный, раз в 5.2с. */
    animation: ae12Sheen 5.2s cubic-bezier(.45,0,.25,1) 5s infinite;
  }
  /* Второе слово отдаёт краску родителю, иначе блик по нему не пройдёт. */
  .header .logo__text em{
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

@keyframes ae12Sheen{
  0%,   6%  { background-position: 150% 0, 0 0; }   /* полоса ждёт за левым краем */
  30%, 100% { background-position:   0% 0, 0 0; }   /* ушла за правый и стоит      */
}

/* -------------------------------------------------------------------------
   12.2 ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ: РАЗНЫМ БЛОКАМ РАЗНАЯ АМПЛИТУДА

   ЗАМЕР ДО ПРАВКИ (перепись всех 50 блоков): на всю страницу три значения
   сдвига - 0 у шапок разделов, 20px у всего остального, 28px у карты
   городов. То есть двенадцать вопросов, шесть гарантий и три карточки
   опций ехали ровно тем же движением, что и крупная плашка финала.

   ЗАМЫСЕЛ. Вес движения обязан совпадать с весом блока:
     - мелкое и повторяющееся (вопрос, гарантия, карточка, шаг, услуга)
       едет коротко: их много, и длинный ход у каждого читается как рябь;
     - крупная одиночная плашка (карта, финал, честный блок, строка цифр)
       едет дальше: она тяжелее и приезжает одна.

   🔴 КАЖДОЕ ПРАВИЛО ЧЕРЕЗ :not(.is-visible) - ЭТО НЕ УКРАШЕНИЕ.
   Ловушка разобрана соседней зоной на живом сайте: селектор вида
   .geo.reveal имеет тот же вес (0,3,0), что и .reveal.is-visible, и стоя в
   файле ПОЗЖЕ выигрывает каскад. Блок, который уже приехал и уже виден,
   остался бы сдвинутым вниз навсегда. Условие :not снимает правило ровно в
   тот момент, когда блок помечен приехавшим.

   ПОЧЕМУ scale ПОВТОРЁН, А НЕ ОПУЩЕН. Правило .ae4-stagger > .reveal
   :not(.is-visible) даёт translateY(20px) scale(.99) и имеет тот же вес
   (0,3,0), что и мои селекторы. Мои стоят позже и выигрывают, то есть
   ЗАМЕНЯЮТ весь transform целиком. Не повторив scale, я бы молча отменил
   чужую находку внутри сеток.

   Двигаются только transform и opacity. Ни width, ни height, ни top/left.
   ------------------------------------------------------------------------- */

/* Мелкое и повторяющееся: короткий ход. */
.faq__item.reveal:not(.is-visible),
.guard.reveal:not(.is-visible),
.card.reveal:not(.is-visible),
.svc.reveal:not(.is-visible),
.flow__item.reveal:not(.is-visible),
.vs__col.reveal:not(.is-visible){
  transform: translateY(12px) scale(.995);
}

/* Крупное и одиночное: ход длиннее, масштаб не трогаем - на широкой плашке
   он заметен как дрожание кромки. */
.stats.reveal:not(.is-visible),
.honest.reveal:not(.is-visible),
.final__inner.reveal:not(.is-visible),
.faq__foot.reveal:not(.is-visible){
  transform: translateY(30px);
}

/* Шапка раздела приходит первой и только проявляется: заголовок, который
   ещё и подъезжает, читается как очередной блок, а он рамка для блоков.
   Правило уже есть выше по файлу; здесь оно закреплено вместе с остальным
   разбором по типам, чтобы порядок появления был описан в одном месте. */
.section__head.reveal{ transform: none; }

/* -------------------------------------------------------------------------
   🔴 ВЛОЖЕННОЕ ПОЯВЛЕНИЕ: ДВА СДВИГА СКЛАДЫВАЛИСЬ В ОДИН ДЛИННЫЙ

   ЗАМЕР. Перепись всех 50 блоков появления по родителям дала ровно два
   вложенных случая, и оба - колонки сравнения «Обычная биржа» / «Apollo
   Exchange»:

     .vs__col--bad   внутри .vs.reveal   свой сдвиг 12px, родителя 20px
     .vs__col--good  внутри .vs.reveal   свой сдвиг 12px, родителя 20px

   Трансформации родителя и ребёнка перемножаются, то есть колонка на самом
   деле проезжала 32px - больше всех остальных блоков страницы, включая
   крупные одиночные плашки с их 30px. Непрозрачность тоже перемножалась:
   ноль родителя на ноль ребёнка. Задержки при этом почти совпадают (родитель
   1, колонки 1 и 2, то есть 55 и 110ms), поэтому оба движения шли внахлёст и
   читались как одно вязкое.

   РЕШЕНИЕ: движение отдано ОДНОМУ участнику, и это колонки, а не обёртка.
   Обёртка - это просто рамка вокруг двух колонок, у неё нет своего вида;
   двигать её значит двигать пустоту. Колонки же и есть содержание раздела
   «Чем мы отличаемся»: их две, они приезжают по очереди, и ступенька между
   ними наконец видна, потому что её больше не забивает общий проезд рамки.

   Обёртка при этом остаётся блоком появления и по-прежнему проявляется -
   снят только сдвиг. Правило весит три класса против двух у .reveal
   :not(.is-visible) выше по файлу и стоит позже, поэтому выигрывает.
   ------------------------------------------------------------------------- */
.vs.reveal:not(.is-visible){ transform: none; }

/* -------------------------------------------------------------------------
   12.3 УВАЖЕНИЕ К НАСТРОЙКЕ ДВИЖЕНИЯ

   Общий блок доступности выше по файлу гасит длительности через
   animation-duration:.001ms !important. Для бесконечной анимации это не
   остановка, а бесконечный повтор нулевой длины. Поэтому блик снимается
   здесь ЯВНО - вместе с ним снимается и весь сдвиг блоков.

   Знак при этом остаётся в канонном серебре, только неподвижном: заливка и
   background-clip не отменяются, отменяется движение.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .header .logo__text{
    animation: none;
    background-position: 0% 0, 0 0;   /* блик припаркован за правым краем */
  }
  .faq__item.reveal:not(.is-visible),
  .guard.reveal:not(.is-visible),
  .card.reveal:not(.is-visible),
  .svc.reveal:not(.is-visible),
  .flow__item.reveal:not(.is-visible),
  .vs__col.reveal:not(.is-visible),
  .stats.reveal:not(.is-visible),
  .honest.reveal:not(.is-visible),
  .final__inner.reveal:not(.is-visible),
  .faq__foot.reveal:not(.is-visible){
    transform: none;
    opacity: 1;
  }
}

/* -------------------------------------------------------------------------
   12.4 АВАРИЙНЫЙ ПОКАЗ, ЕСЛИ СКРИПТЫ НЕ ДОЕХАЛИ ВОВСЕ

   🔴 ЗАМЕР, РАДИ КОТОРОГО ЭТО НАПИСАНО. Три отказа проверены блокировкой
   файлов на уровне сети. Скрипты при этом ВКЛЮЧЕНЫ, поэтому аварийный стиль
   внутри <noscript> не применяется - он спасает только выключенные скрипты:

     не доехал app.js .......... было потеряно 46 блоков из 50
     не доехали оба файла ...... было потеряно 46 блоков из 50

   Первый случай закрыт сторожем в effects.js. Второй закрыть оттуда нельзя:
   упавший файл сам себя не спасёт. Значит спасать обязаны стили - они лежат
   в <head> и приезжают раньше любого скрипта.

   КАК ЭТО РАБОТАЕТ. effects.js при разборе ставит на <html> метку ae12-live.
   Пока метки нет, правило ниже через 8 секунд показывает всё содержимое.
   Метка появилась - правило отключается и показом занимается наблюдатель.

   ПОЧЕМУ ЗДЕСЬ НЕТ МОРГАНИЯ. Исходное состояние блоков не меняется вовсе:
   они как были скрытыми, так и остаются. Правило умеет только ПОКАЗАТЬ, и
   только по истечении отсрочки. На живой странице метка встаёт за доли
   секунды, то есть за восемь секунд до срабатывания, и правило не успевает
   сделать ничего.

   ПОЧЕМУ 8 СЕКУНД, А НЕ 2. Отсрочка обязана быть заведомо больше времени
   разбора страницы на медленном канале: сработать раньше метки значит
   показать блоки на исправной странице и убить эффект. Восемь секунд человек
   без содержимого не просидит - он к этому моменту ещё читает первый экран,
   который виден всегда.

   ДЛИТЕЛЬНОСТЬ 1ms, А НЕ 0s: нулевая длительность у части движков даёт
   неопределённое поведение заливки forwards, миллисекунда ведёт себя
   одинаково везде и глазом всё равно неотличима от мгновенной.
   ------------------------------------------------------------------------- */
html:not(.ae12-live) .reveal:not(.is-visible){
  animation: ae12Rescue 1ms linear 8s forwards;
}
@keyframes ae12Rescue{ to{ opacity:1; transform:none; } }
/* ═══ ЗОНА 12 - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 11Б: ДОБОР ЛИНИЙ ПО ПОВТОРНОЙ ПЕРЕПИСИ
   ═════════════════════════════════════════════════════════════════════════
                                                              (24.08.2026)

   ПОЧЕМУ ОТДЕЛЬНАЯ ЗОНА, А НЕ ДОПИСКА В ЗОНУ 11.
   Две причины, обе техничные.
     1. Зона 11 больше НЕ последняя в файле: после неё дописались зоны 10R,
        10 и 12. Правило, дописанное внутрь зоны 11, встало бы в каскаде перед
        ними.
     2. Правило ниже спорит по специфичности с чужим живым правилом зоны 3
        (.mrow:hover + .mrow::before). Специфичности равны, поэтому решает
        порядок, и моё обязано стоять ПОЗЖЕ - иначе оно молча отнимет у чужого
        приёма его работу. Подробности прямо в правиле.

   -------------------------------------------------------------------------
   ПЕРЕПИСЬ ПРИБОРОМ scripts/line-edges-check.mjs, ЗАМЕР НА ДВУХ СТЕНДАХ

   Стенды подняты рядом: 4180 - файл как есть, 4181 - тот же сайт, из которого
   вырезаны ровно 295 строк зоны 11. Разница между колонками - это и есть
   работа зоны, а не «стало лучше по ощущению».

     ширина     линий   без зоны 11        с зоной 11
     1440x900     68    7 мягких / 61 нож  36 мягких / 32 ножа
     375x812      61    7 мягких / 54 ножа 32 мягких / 29 ножей

   Семь исходных мягких - это канонная линейка .rule под эйбрау: она и до
   правки гасла справа. Зона 11 добавила ей гашение слева, но прибор обе
   версии зовёт мягкими, поэтому в цифрах прибавки по ней не видно. Это
   ограничение прибора, названное вслух, а не скрытая победа.

   -------------------------------------------------------------------------
   ЧТО ОСТАЛОСЬ «НОЖОМ» И ПОЧЕМУ ЭТО НЕ ЛИНИИ

   Прибор ловит линию по геометрии - тонкая закрашенная полоса или закрашенные
   1-3 стороны границы. Под это описание попадают вещи, которые линиями не
   являются. Разбор всех 32 штук с ширины 1440:

     13x summary::after 11x11 [правая+нижняя]  - ШЕВРОН аккордеона «Как
         проходит сделка». Уголок из двух border, повёрнутый на 45°. Растворить
         его торцы - размыть стрелку в кляксу;
      6x .flow__chev::before 9x9 [правая+нижняя] - тот же уголок в шагах сделки;
      1x .flow__all-ico 12.7x12.7 [правая+нижняя] - он же в строке «всё сразу»;
      6x li::before 14x2 - маркер-тире у списков. Тире длиной 14px, гаснущее с
         обоих концов, превращается в пыль: это метка, а не линия;
      2x .logo__mark::before 2x8 - деталь ЗНАКА агентства. Знаком занимается
         зона 12, и трогать его отсюда нельзя;
      1x .header::before [нижняя] 1440x70 - вот это разобрано отдельно ниже;
      3x .mrow + .mrow::before 271x1 - ЕДИНСТВЕННАЯ настоящая линия в остатке.
         Её и лечим правилом ниже.

   ШАПКА: НОЖА НЕТ, ХОТЯ ПРИБОР ЕГО ЗАСЧИТАЛ.
   Замер торцов (scrollY 0 и 1600, окно 1440x900): подложка шапки .header
   ::before идёт от 0 до 1440 при ширине окна 1440, то есть оба её конца лежат
   ЗА краем экрана и на любом скролле остаются там (элемент sticky). Обрубать
   нечего: линия уходит за кадр, а не кончается на виду. На 375 то же самое -
   375 из 375. Поэтому шапка не правится, и причина здесь замер, а не «чужая
   зона». Тем же замером снят и вопрос по колонкам - поправка вписана в
   комментарий 10.3 зоны 11.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ: ни transform, ни opacity, ни keyframes, ни
   перехода. Блок prefers-reduced-motion внизу пустой по существу и оставлен
   подписью «проверено, гасить нечего».
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   11Б.1 РАЗДЕЛИТЕЛИ СТРОК КОТИРОВОК

   Что это. В колонке рынка строки идут таблицей и разделены волосом 271x1.
   Замер живого стиля: background-color rgba(255,255,255,.075),
   background-image none - то есть сплошная заливка, оба конца ножевые, и оба
   конца НА ВИДУ (торцы на 1145 и 1416 при окне 1440). Три штуки в кадре
   одновременно, и это единственные оставшиеся настоящие ножи.

   Почему это моя линия, хотя колонка рынка чужая. Исполнитель правой колонки
   (зона 10R) занимается ЧТЕНИЕМ курсов: .mrow__price, .mrow__sym, .mrow__chg
   и зазор в .mrow. Самого разделителя он не касается ни одной строкой -
   проверено поиском по зоне. Пересечения писателей нет.

   Яркость НЕ МЕНЯЕТСЯ: берётся тот же самый var(--ae7-hair) из зоны 7, что
   красит линию сейчас. Меняются только 9% с каждого конца - около 24px из 271.

   🔴 ГЛАВНОЕ В ЭТОМ ПРАВИЛЕ - ВТОРОЙ СЕЛЕКТОР, А НЕ ПЕРВЫЙ.
   В зоне 3 живёт приём: при наведении на строку разделители над ней и под ней
   ГАСНУТ, чтобы подсветка строки читалась цельным блоком. Сделано это строкой
   .mrow:hover + .mrow::before{ background:transparent }, а сокращение
   background обнуляет и картинку тоже. Специфичность там (0,3,1) - ровно как
   у моего первого селектора. Мой стоит в файле позже, значит выиграл бы он, и
   на hover вместо чистого блока осталась бы висеть моя картинка-градиент.
   Приём умер бы молча: разделитель на наведении просто перестал бы исчезать.
   Поэтому гашение переобъявлено здесь с весом (0,4,1) - чужое поведение
   сохранено ровно таким, каким оно было.
   ------------------------------------------------------------------------- */
.side .mrow + .mrow::before{
  /* Цвет уезжает в картинку целиком, поэтому собственная заливка снимается -
     иначе сплошной цвет проступил бы под прозрачными концами градиента. */
  background-color:transparent;
  background-image:linear-gradient(90deg,
                     transparent 0,
                     var(--ae7-hair) 9%,
                     var(--ae7-hair) 91%,
                     transparent 100%);
}
.side .mrow:hover + .mrow::before,
.side .mrow:hover::before{
  background-image:none;      /* возвращаем зоне 3 её чистый блок на наведении */
}

/* -------------------------------------------------------------------------
   11Б.2 КОМУ РАСТВОРЁННЫЙ ТОРЕЦ МЕШАЕТ

   Человек с включённым повышенным контрастом просит не «красивее», а «чётче
   видно границу». Расфокусенный конец - ровно то, что ему мешает: он ищет
   край таблицы, а край нарочно неопределённый. Возвращаем сплошную линию.
   ------------------------------------------------------------------------- */
@media (prefers-contrast: more){
  .side .mrow + .mrow::before{
    background-color:var(--ae7-hair);
    background-image:none;
  }
}

/* -------------------------------------------------------------------------
   11Б.3 ДВИЖЕНИЕ
   Зона не ввела ни анимации, ни перехода. Пусто намеренно: пустой блок с
   подписью читается как «проверено», отсутствие блока - как «забыли».
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  /* пусто: зона 11Б движения не вводит */
}
/* ═══ ЗОНА 11Б - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 13R: КОТИРОВКИ НЕ ВРУТ О СВОЁМ ВОЗРАСТЕ                (24.08.2026)

   НОМЕР 13R, А НЕ 12 И НЕ 11В. На момент дописки в файле уже жили зоны с
   номерами 9, 10 (дважды - правая колонка и кнопки), 11, 11Б и 12: по файлу
   работают соседние исполнители. Свой номер взят заведомо свободным, свой
   префикс - ae13, потому что ae10 занят токенами зоны 10R.

   ЧТО ЭТА ЗОНА ПРОДОЛЖАЕТ. Зона 10R выше разобрала половину жалобы «нету
   никакого курса, не видно» - ту, где курсы приходили, но терялись в
   вёрстке: цена была всего в 1.17 раза крупнее названия монеты и тусклее
   собственного тикера. Замер после неё: цена 20px вес 700 контраст 19.90,
   название 11.5px вес 400 контраст 7.84, отношение кеглей 1.74. Это готово
   и переделке здесь не подлежит.

   🔴 ВТОРАЯ ПОЛОВИНА ЖАЛОБЫ ОКАЗАЛАСЬ НЕ ПРО КРАСКУ. Пять загрузок подряд:
   в трёх из пяти в колонке НЕ БЫЛО НИ ОДНОГО КУРСА, только прочерки, а
   штамп при этом вечно обещал «котировки подгружаются». Источник отбивает
   частые обращения, и единственная попытка блока 4 в app.js молча падала.
   Чинится это данными, а не цветом - блоком 7 в app.js: цепочка из двух
   источников, повторы, обновление раз в 90 секунд.

   ЗДЕСЬ - ТОЛЬКО ВИД ТЕХ СОСТОЯНИЙ, КОТОРЫЕ БЛОК 7 ТЕПЕРЬ РАЗЛИЧАЕТ.
   Раньше состояние было одно на всё: «прочерк». Теперь их три, и разница
   между ними - разница между правдой и неправдой:
     живое     - числа свежие, у штампа горит синяя точка (зона 10R);
     is-stale  - числа настоящие, но старые: связь пропала после удачи;
     is-offline- чисел нет вовсе и попытки исчерпаны.
   Синяя точка «в эфире» гаснет в обоих несчастных случаях сама: блок 7
   возвращает штампу data-placeholder, а правило точки в зоне 10R стоит на
   :not([data-placeholder]). Отдельного правила на это писать не надо, и
   его здесь намеренно нет - дублирующая страховка разошлась бы с оригиналом
   при первой же правке соседа.

   ГРАНИЦЫ ЗОНЫ. Все селекторы начинаются с .side .market и живут внутри
   правой колонки. Курс сделки 91 ₽ и 566 ₸, калькулятор, аккордеон, карта
   городов, ссылки на бота, линии, кнопки и любое движение страницы не
   затронуты ни одним правилом. Лента (.feed) тоже не трогается: её разобрала
   зона 10R, и трогать чужую готовую работу ради присутствия здесь незачем.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ НИ ОДНОГО - только краска. Переход цвета на
   .mrow__price уже описан и погашен зоной 3, поэтому блок
   prefers-reduced-motion внизу пустой и стоит подписью «гасить нечего»:
   отсутствие блока читалось бы как «забыли».

   ПЛАНКА ЧИТАЕМОСТИ. Ни один кегль не меняется вовсе, меняется только
   яркость, и самое тусклое значение зоны даёт 7.7:1 на фоне колонки
   rgb(9,9,11) при норме 4.5 для тела. Зон нажатия зона не создаёт.
   ═════════════════════════════════════════════════════════════════════════ */

:root{
  /* Старое, но настоящее число: гасим на ступень от белого. 7.74:1 против
     фона колонки - выше нормы тела вдвое, то есть число остаётся читаемым,
     оно просто перестаёт быть самым ярким пятном строки. Так и должно
     выглядеть значение, за свежесть которого сервис больше не ручается. */
  --ae13-stale: rgba(255,255,255,.62);
}

/* -------------------------------------------------------------------------
   13R.1 УСТАРЕВШИЕ ЧИСЛА ГАСНУТ, НО ОСТАЮТСЯ ЧИТАЕМЫМИ

   Прочерка это не касается намеренно: у него уже свой приглушённый вид от
   зоны 10R, и гасить пустоту второй раз нечего. Отсюда :not([data-placeholder]).
   ------------------------------------------------------------------------- */
.side .market.is-stale .mrow__price:not([data-placeholder]){
  color:var(--ae13-stale);
}

/* -------------------------------------------------------------------------
   13R.2 ЧИП РОСТА И ПАДЕНИЯ ТЕРЯЕТ ЦВЕТ ВМЕСТЕ С АКТУАЛЬНОСТЬЮ

   🔴 ПОЧЕМУ ИМЕННО ОБЕСЦВЕЧИВАНИЕ, А НЕ ПРОСТО ПРИГЛУШЕНИЕ. Зелёный чип
   заявляет «монета растёт ПРЯМО СЕЙЧАС». Если связь потеряна десять минут
   назад, это утверждение уже не подтверждено ничем, а цвет продолжает его
   выкрикивать - и выкрикивает громче всего в строке, потому что он
   единственное цветное пятно. Тусклый зелёный остался бы тем же неверным
   утверждением, сказанным тише. Поэтому знак направления уходит в
   нейтральный серый целиком: заливка, рамка и текст. Само число со знаком
   плюс или минус остаётся на месте - это факт на момент последнего ответа,
   его никто не отменял.

   Строку сервиса правило не задевает: у неё в этой ячейке слово «курс
   сервиса», а не процент, классов is-up и is-down на ней нет никогда.
   ------------------------------------------------------------------------- */
.side .market.is-stale .mrow__chg.is-up,
.side .market.is-stale .mrow__chg.is-down{
  color:var(--ae13-stale);
  background:rgba(255,255,255,.05);
  border-color:rgba(255,255,255,.12);
}

/* -------------------------------------------------------------------------
   13R.3 ШТАМП В НЕСЧАСТНОМ СЛУЧАЕ

   Текст штампа пишет блок 7 («котировки не обновляются» / «котировки
   недоступны»), здесь только его вид. Курсив не берём и в красный не
   красим: обрыв внешнего справочного фида - не авария сервиса и пугать им
   человека, пришедшего менять деньги, незачем. Тон служебный.

   Табличные цифры от зоны 10R остаются: в этих двух надписях цифр нет, но
   штамп переключается между тремя текстами на живой странице, и правило,
   действующее через раз, - это будущая находка на ровном месте.
   ------------------------------------------------------------------------- */
.side .market.is-stale .market__stamp,
.side .market.is-offline .market__stamp{
  color:var(--ae13-stale);
  letter-spacing:.06em;
}

@media (prefers-reduced-motion: reduce){
  /* пусто: зона 13R движения не вводит, гасить нечего */
}
/* ═══ ЗОНА 13R - КОНЕЦ ═══ */


/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 10B: ДОЛГ ЗОНЫ 10, НАЙДЕННЫЙ ЗАМЕРОМ ПОСЛЕ ПРАВКИ    (24.08.2026)

   Отдельной зоной, а не правкой строк зоны 10, по двум причинам: по файлу
   одновременно работают соседние исполнители, и правка в середину чужого
   потока чтения дороже дописки; плюс так в файле остаётся видно, ЧТО именно
   сломала первая редакция и чем это лечится.

   🔴 ЧТО ИМЕННО СЛОМАЛА ЗОНА 10 И КАК ЭТО ВСКРЫЛОСЬ.
   Общий замерщик контраста scripts/contrast-check.mjs по построению ПРОПУСКАЕТ
   текст на градиентном фоне - иначе он мерил бы белую надпись кнопки против
   чёрного полотна страницы и врал бы. В его выводе это видно строкой
   «пропущено: на градиентном фоне 75». Зона 10 подложила градиент под
   одиннадцать кнопок - то есть перевела ровно свои изменения в слепую зону
   прибора, и его «нарушений НЕТ» перестало что-либо доказывать.
   Пришлось написать адресный замер, который берёт ВСЕ стопы градиента, каждый
   композитит на фактическую подложку и берёт ХУДШИЙ: буква стоит на всей
   ленте, а не на её середине. Он и показал одно настоящее нарушение.
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   10B.1 ПЛАШКА-ССЫЛКА В ГЕРОЕ: КОНТРАСТ УПАЛ С ПРОХОДНОГО ДО 3.8

   ЗАМЕР. До зоны 10: подложка сплошная rgba(255,255,255,.06), нарушений нет.
   После: тот же .06 плюс поверх ЛЕВЫЙ конец рампы rgba(255,255,255,.13) -
   composite около .18 белого, и серый текст #9CA3AF даёт 3.8 при норме 4.5.
   Нарушение появилось у моего селектора и от моей краски.

   КОРЕНЬ, А НЕ СИМПТОМ. Ошибка не в том, что «мало контраста», а в том, что
   единая ступень металла была выдана поверхности, у которой УЖЕ есть своя
   подсветка. Остальные десять кнопок стоят на голом полотне, а эта - на
   светлой капсуле, и одна и та же рампа даёт на ней другой результат.
   Поэтому лечится не осветлением текста «на глазок», а собственной, самой
   тихой ступенью того же материала: направление слева направо сохранено,
   семья та же, светлота посажена под уже подсвеченную капсулу.
   Текст поднят до #B7BFCA - это ступень призрачной кнопки, не ярче: плашка
   обязана остаться тише главной кнопки экрана.
   ------------------------------------------------------------------------- */
:root{
  --z10-pill:    linear-gradient(90deg,rgba(255,255,255,.055) 0%,rgba(255,255,255,.028) 42%,
                                       rgba(255,255,255,.008) 76%,rgba(0,0,0,.13) 100%);
  --z10-pill-hi: linear-gradient(90deg,rgba(255,255,255,.10) 0%,rgba(255,255,255,.055) 42%,
                                       rgba(255,255,255,.02) 76%,rgba(0,0,0,.10) 100%);
  --z10-pill-lo: linear-gradient(90deg,rgba(255,255,255,.03) 0%,rgba(255,255,255,.015) 42%,
                                       rgba(255,255,255,.004) 76%,rgba(0,0,0,.18) 100%);
}
.hero .pill__link{ background-image:var(--z10-pill); color:#B7BFCA; }
@media (hover:hover){
  /* Наведение перебивает правило зоны 10 порядком, а не !important: селектор
     тот же, вес тот же, моя строка ниже по файлу. */
  .hero .pill__link:hover{ background-image:var(--z10-pill-hi); color:#FFFFFF; }
}
.hero .pill__link:active{ background-image:var(--z10-pill-lo); }

/* -------------------------------------------------------------------------
   10B.2 ТЕКУЩИЙ РАЗДЕЛ СЛЕВА: НАВЕДЕНИЕ БЫЛО НЕРАЗЛИЧИМО

   Замер форсированным состоянием: у строки «вы здесь» покой .075, наведение
   .086 - разница одиннадцать тысячных, глазом это ноль. Причина механическая:
   зона 10 подняла покой текущей строки, а общее правило наведения осталось
   рассчитанным на покой .035. У остальных пяти строк разница .035 -> .085
   видна, у шестой пропала.

   Требование владельца «чуть выделить» относится ко ВСЕМ строкам списка, и
   строка, на которой человек стоит, не может быть единственной без ответа на
   курсор. Поднимаю наведение именно для неё, сохраняя порядок ступеней:
   покой .075 < наведение .115 < нажатие .14.
   ------------------------------------------------------------------------- */
@media (hover:hover){
  @media (min-width:1200px){
    .side .qcard.is-current:hover{ background:rgba(255,255,255,.115); }
  }
}
@media (min-width:1200px){
  .side .qcard.is-current:active{ background:rgba(255,255,255,.14); }
}

/* -------------------------------------------------------------------------
   10B.3 ДВИЖЕНИЕ
   Зона не вводит ни одного нового движения: только цвет и краска фона, оба
   мгновенные либо на уже существующих переходах. Гасить нечего, поэтому блок
   prefers-reduced-motion пуст по существу, а не забыт.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  /* пусто намеренно: новых transform и keyframes в зоне 10B нет */
}
/* ═══ ЗОНА 10B - КОНЕЦ ═══ */

/* --- Заставка: кнопка «Пропустить» держит планку пальца ---
   Замер после переделки кнопок показал единственную просевшую зону нажатия на
   всём сайте: .intro__skip была 38px при пороге 44. Это первая кнопка, которую
   человек видит на сайте, и промах по ней особенно обиден.
   Растим ЗОНУ вертикальными полями, вид кнопки не меняется. */
.intro__skip {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* --- Карточка города: кнопка «Свернуть» держит планку пальца ---
   Замер показал 14px высоты при пороге 44. Это кнопка внутри раскрытой карточки
   города, по ней промахиваются чаще всего: она мелкая и стоит рядом с текстом.
   Растим зону полями, вид не меняем. */
.geo__close {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding-top: 8px;
  padding-bottom: 8px;
}

/* --- Метки городов на карте: палец должен попадать ---
   Замер: .geo__pin 38px при пороге 44. Метка это капля с названием города,
   и по ней нажимают, чтобы раскрыть условия. Растим ЗОНУ, а не саму каплю:
   вид карты не меняется, промахов меньше. */
.geo__pin {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* --- «Свернуть» в карточках городов: кегль до планки ---
   На узких экранах кнопка стояла на 10.5px при нашем полу в 11px. Она
   появляется по одной в каждой раскрытой карточке города, то есть на телефоне
   их сразу четыре, и все мелкие. Планку не опускаем нигде, включая карту. */
.geo__close {
  font-size: 11px;
}
@media (max-width: 640px) {
  .geo__close { font-size: 12px; }
}

/* ═════════════════════════════════════════════════════════════════════════
   ЗОНА 14L: ВЕРХНЯЯ КРОМКА, ВЕС РАЗДЕЛИТЕЛЕЙ, РАНГ РАЗДЕЛОВ
   ═════════════════════════════════════════════════════════════════════════
                                                              (25.08.2026)

   🔴 БУКВА L В НОМЕРЕ - НЕ УКРАШЕНИЕ. Пока я писал, второй исполнитель дописал
   в тот же файл свою зону и тоже назвал её 14 («ПОМОЩНИК APOLLO AI»). Два
   одинаковых номера в файле на 8466 строк - это ловушка для того, кто будет
   искать зону по номеру. Переименовываю СВОЮ (она в файле выше, значит правка
   короче и чужие строки не трогаются), суффикс взят по образцу уже живущих в
   файле 10R, 10B и 11Б. Пересечения селекторов с той зоной проверено нет:
   поиск по её 477 строкам не нашёл ни body::before, ни .side--left/right, ни
   .section--alt, ни .section__head, ни .rule.

   ЖАЛОБА ВЛАДЕЛЬЦА ДОСЛОВНО: «как-то не знаю, чего-то не хватает как будто.
   Возможно, какой-то цветной линии, то есть вот сверху линия тоже какая-нибудь
   такая сине-серебряная и по бокам вот где крипторынок справа и услуги слева,
   они же разделяются сверху вниз линией. И разделы как-то больше выделить.
   Чуть как-то живее, да, сделать.»
   Образец он назвал отдельно, на примере OnlyHub: «если свернуть панель
   правую, от этой кнопки, когда я нажимаю свернуть, исходит типа линия
   серебристая вверх и вниз... И именно вот это вот я примерно у тебя и просил
   сделать с Apollo Exchange... Тоже такие разделения сделать весомые.»
   Ключевые слова разобраны по одному: «сверху линия» - её нет вообще;
   «сине-серебряная» - синий И серебро в одной линии; «исходит вверх и вниз» -
   линия ярче в одном месте и гаснет к обоим концам, а не ровная нитка;
   «весомые» - разделитель обязан ЧИТАТЬСЯ, а не угадываться.

   -------------------------------------------------------------------------
   🔴 ЗАМЕР ДО ПРАВКИ, И ГЛАВНАЯ НАХОДКА В НЁМ

   Прибор свой: scripts/zone14-lines-check.mjs, headless-Chrome по CDP на
   локальной копии (python3 -m http.server 4190). Три контроля выполняются ДО
   того, как напечатана хоть одна цифра:
     К1 - ширина окна ровно та, что просили. Page.navigate сбрасывает вьюпорт
          на 1440, и «мобильный» замер молча меряет десктоп.
     К2 - страница живая: есть .calc с ненулевой коробкой, полотно тёмное.
     К3 - ТЕСТ НА ОТКАЗЕ, три части. (а) реальная верхняя линия временно
          гасится - прибор ОБЯЗАН вернуть «нет»; (б) подсаживается подложный
          двойник - прибор ОБЯЗАН его найти; (в) два зонда-разделителя,
          сплошной и гаснущий, обязаны разложиться резкий/мягкий. Провал
          любого = выход без печати результата.

   Что показал замер 1440x900 до правки:
     верхняя линия ......... НЕТ НИ ОДНОЙ (подтверждено и пикселем: столбец
                             y=0..11 в центре кадра даёт rgb(9,11,15), то есть
                             голое полотно);
     разделители колонок ... 2 шт, оба уже с растворёнными торцами (зона 11).

   🔴 А ВОТ ЧТО НАШЛОСЬ СВЕРХ ЖАЛОБЫ, И ЭТО НЕ ВКУСОВЩИНА, А ДЕФЕКТ.
   Зона 7 объявила разделителю канонный цвет эталона rgb(57,57,65). Зона 11
   поверх поставила border-image с косвенной переменной, рассчитывая, что
   var(--ae11-hair) разрешится НА ЭЛЕМЕНТЕ. Так подстановка не работает:
   значение --ae11-fade-y вычисляется там, где ОБЪЯВЛЕНО, то есть на :root, и
   вниз наследуется уже подставленным. Переопределение --ae11-hair на .side
   опаздывает и не действует.
   Замер вычисленного стиля:  rgba(255,255,255,.10) вместо rgb(57,57,65).
   Замер ПИКСЕЛЯ (px-probe.py по снимку, столбец файла x=276):
     y=420..3220 ровно rgb(34,34,36) на всём протяжении.
   Считаем честно: rgba(255,255,255,.10) поверх фона колонки rgb(9,9,11) даёт
   9 + .10*246 = 34. Сходится до единицы, то есть прибор не врёт.
   ИТОГ: линия жила на rgb(34,34,36) при канонных rgb(57,57,65) - она была
   тише канона почти вдвое. «Чего-то не хватает» у владельца - это ровно оно.
   Ниже градиент выписан ЛИТЕРАЛЬНО, без косвенной переменной, поэтому та же
   ловушка не повторяется.

   -------------------------------------------------------------------------
   ПОЧЕМУ ПРИЁМ ТОТ ЖЕ, ЧТО В ЗОНЕ 11, А НЕ МАСКА

   Зона 11 разобрала это на зондах: mask-image режет по border-box, свечение
   живёт box-shadow'ом СНАРУЖИ коробки, а -webkit-mask-clip:no-clip на этой
   машине не поддержан - значит у части людей маска отняла бы канонное
   свечение. Поэтому гаснет САМА КРАСКА: заливка у полос, border-image у
   границ. Продолжаю в том же ключе, новых приёмов не ввожу.

   ЧЕГО ЗОНА НЕ ТРОГАЕТ (чужие исполнители, названо поимённо):
     - шрифты панелей, кнопка «Обменять», блок Apollo AI - прямой запрет;
     - .btn и навигация - зона 10; знак - зона 12; строки котировок .mrow -
       зоны 10R и 11Б; кегли и веса заголовков - зона 8 (её шкалу 37.7/30.3/
       26.2 и вес 600 я не переопределяю ни одной строкой);
     - .footer и .footer__bottom - подвал не раздел, их кромки остаются на
       зоне 11;
     - нотки зелёного и жёлтого из расширенной палитры - они по решению
       владельца идут «на статусах и акцентах». В линиях и границах разделов
       статуса нет, и красить ими разделитель значит делать светофор из
       конструкции. Пункт осознанно отдан исполнителю по статусам.

   ДВИЖЕНИЯ ЗОНА НЕ ВВОДИТ НИ ОДНОГО: ни transform, ни opacity, ни keyframes,
   ни перехода. «Живее» здесь сделано краской, а не движением, и это осознанно:
   бегущий блик по верхней кромке человек видит при КАЖДОМ заходе на сайт, то
   есть 100+ раз, а канон такую частоту прямо запрещает анимировать.
   ═════════════════════════════════════════════════════════════════════════ */

:root{
  /* Серебро канона (#FFFFFF -> #F4F7FA -> #C3CBD5 -> #98A2AE) в виде КРАСКИ
     для линий. Держим три ступени: пик отлива, плечо и подошва. Значения
     подобраны не на глаз - они пересчитаны в конечный пиксель поверх фона
     колонки rgb(9,9,11), см. цифры у каждого правила. */
  --z14-silver-hi:  rgba(214,224,238,.30);
  --z14-silver-mid: rgba(198,208,222,.20);
  --z14-silver-lo:  rgba(160,172,188,.07);

  /* Отступ канонной метки раздела влево от текста. Меньше, чем поле .wrap на
     той же ширине (28 / 20 / 14), иначе метка вылезет за полотно и родит
     горизонтальную прокрутку. Запас держим не меньше 4px. */
  --z14-mark-x: 18px;
}
@media (max-width:900px){ :root{ --z14-mark-x:13px; } }
@media (max-width:400px){ :root{ --z14-mark-x:9px;  } }

/* -------------------------------------------------------------------------
   14.1 ВЕРХНЯЯ КРОМКА СТРАНИЦЫ: СИНЕ-СЕРЕБРЯНАЯ ЛИНИЯ

   Толщина 2px, и это не «побольше для заметности». 1px на экране с DPR 2
   уходит в полпикселя и на части устройств бледнеет до невидимости, 3px уже
   плашка - а владелец сказал «линия», и канон говорит «акцент, не заливка».
   2px читается на любом DPR и остаётся линией: 2 * 1440 = 2880 пикселей из
   1 296 000 в кадре, это 0.22% площади.

   СИНЕГО В НЕЙ РОВНО 16% ДЛИНЫ (42%..58%), то есть около 230px из 1440.
   Канон разрешает акцент на «меньше десятой части площади»; здесь синего
   460 пикселей из миллиона с четвертью - две сотых процента. Стоит он ровно
   над центральной колонкой, то есть помечает главное на странице, а не красит
   кромку ради цвета. Остальная длина - серебро, гаснущее к обоим краям окна.

   ПОЧЕМУ ЛИНИЯ И СВЕЧЕНИЕ - ДВА РАЗНЫХ ЭЛЕМЕНТА. box-shadow у полосы
   размывается одинаково по всей длине, и синее свечение расползлось бы под
   серебряными участками - вышла бы синяя кромка целиком, чего канон не
   разрешает. Поэтому сияние вынесено в отдельный слой ::after с РАДИАЛЬНЫМ
   градиентом: оно рождается только там, где линия синяя, и гаснет вместе с
   ней. Это краска, а не фильтр - размытия не добавляется ни одного, замер
   зоны 4 (34 элемента с backdrop-filter давали 12-19 кадров) не ухудшается.
   ------------------------------------------------------------------------- */
body::before{
  content:"";
  position:fixed; top:0; left:0; right:0; height:2px;
  z-index:calc(var(--z-header) + 2);
  pointer-events:none;                 /* линия не должна перехватывать нажатия */
  background:linear-gradient(90deg,
    rgba(152,162,174,0)    0%,
    rgba(152,162,174,.30)  4%,
    rgba(195,203,213,.58) 17%,
    rgba(228,236,245,.78) 31%,
    #4FC4E9               42%,
    #4FC4E9               58%,
    rgba(228,236,245,.78) 69%,
    rgba(195,203,213,.58) 83%,
    rgba(152,162,174,.30) 96%,
    rgba(152,162,174,0)  100%);
}
body::after{
  content:"";
  position:fixed; top:0; left:0; right:0; height:16px;
  z-index:calc(var(--z-header) + 1);   /* под самой линией, над шапкой */
  pointer-events:none;
  /* Купол свечения ровно по синему отрезку: 34% ширины с центром в 50%.
     Значения взяты из канонной пары 26px/.42 и 62px/.16, пересчитанной из
     тени в радиальный градиент - отсюда две остановки, а не одна. */
  background:radial-gradient(34% 100% at 50% 0%,
              rgba(79,196,233,.20)  0%,
              rgba(79,196,233,.075) 46%,
              rgba(79,196,233,0)    100%);
}

/* -------------------------------------------------------------------------
   14.2 РАЗДЕЛИТЕЛИ КОЛОНОК: СЕРЕБРЯНЫЙ ОТЛИВ И ВЕС

   Три слоя, и каждый отвечает за своё слово из жалобы.

   СЛОЙ 1 - ЯДРО ЛИНИИ, «весомые». border-image с литеральным градиентом.
   Пик .30 поверх фона колонки rgb(9,9,11) даёт 9 + .30*205 = rgb(71,75,83):
   это вдвое ярче нынешних rgb(34,34,36) и на четверть ярче канонных
   rgb(57,57,65) - ровно в середине кадра, где на линию и смотрят.
   Плечи .20 дают 9 + .20*198 = rgb(50,53,58), то есть у краёв кадра линия
   ТИШЕ канона. Средняя по всей высоте остаётся канонной, громкость добавлена
   только там, где человек её видит.

   СЛОЙ 2 - ОТЛИВ, «серебристая... исходит вверх и вниз». Радиальное пятно у
   самой кромки внутри колонки, с центром на 46% высоты кадра. Оно и делает
   образец OnlyHub: линия не ровная нитка, у неё есть место рождения, и от
   него свет расходится к верху и к низу. Пятно живёт в background-image
   колонки, а не в тени, поэтому ничего не размывается и не стоит кадров.
   background-attachment остаётся scroll: у прокручиваемого блока это значит
   «не едет с содержимым», то есть пятно приколото к кадру, а не к ленте.

   СЛОЙ 3 - ВЫНОС В ЦЕНТР, тоже «весомые». Направленная тень, уводящая мягкий
   свет на 13px в центральную колонку. Смещение 12px и поджим -14px выбраны
   так, что видимой остаётся ТОЛЬКО эта полоска: всё остальное тело тени
   уходит под непрозрачный фон колонки. В центре на этих 13px нет содержимого
   (поле .wrap 28px), то есть свет ложится на пустое поле, а не на текст.

   ТОРЦЫ. Все три слоя гаснут к верху и к низу кадра: у ядра прозрачные
   крайние остановки, у пятна - край радиуса, тень же тянется на всю высоту
   липкой колонки, а её торцы лежат на 0 и 900 при окне 900, то есть ЗА краем
   экрана на любом скролле (замер зоны 11Б, повторён здесь: бокс 300x900,
   top 0, bottom 900). Обрубать там нечего.

   ТОЛЬКО ОТ 1200px: ниже этой ширины левая колонка становится нижней панелью
   навигации, правая - шторкой, и разделителя не существует. Медиазапрос тот
   же, что у зоны 7, поэтому правило не может подать голос там, где линии нет.
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side--left,
  .side--right{
    /* 🔴 ГРАДИЕНТ ВЫПИСАН ЦЕЛИКОМ И БЕЗ var() ВНУТРИ. Причина - замер выше:
       косвенная переменная разрешается на :root, а не на элементе, и молча
       подставляет чужой цвет. Литерал отказывает честно: не понял движок
       border-image - остаётся собственный border-color, то есть теряется
       отлив, а не линия. */
    border-image:linear-gradient(180deg,
      rgba(160,172,188,0)     0%,
      rgba(160,172,188,.07)   7%,
      rgba(198,208,222,.20)  22%,
      rgba(214,224,238,.30)  47%,
      rgba(198,208,222,.20)  72%,
      rgba(160,172,188,.07)  93%,
      rgba(160,172,188,0)   100%) 1;
    /* Страховка на случай отказа border-image: канонный цвет эталона, тот
       самый, который зона 7 объявляла и который замер не нашёл на экране. */
    border-color:var(--ae7-line);
  }
  .side--left{
    background-color:var(--ae7-col);
    background-image:radial-gradient(140px 44% at 100% 46%,
      rgba(178,192,212,.075) 0%,
      rgba(178,192,212,.028) 42%,
      rgba(178,192,212,0)    76%);
    box-shadow:12px 0 30px -14px rgba(150,170,195,.30);
  }
  .side--right{
    background-color:var(--ae7-col);
    background-image:radial-gradient(140px 44% at 0% 46%,
      rgba(178,192,212,.075) 0%,
      rgba(178,192,212,.028) 42%,
      rgba(178,192,212,0)    76%);
    box-shadow:-12px 0 30px -14px rgba(150,170,195,.30);
  }
}

/* -------------------------------------------------------------------------
   14.3 ГРАНИЦЫ СЕКЦИЙ: ГРАНИЦА ЧИТАЕТСЯ, А НЕ УГАДЫВАЕТСЯ

   Секций с кромкой на странице три: #how, #safety, #offline. Их волос стоял
   на --line = rgba(255,255,255,.10), это 12 + .10*243 = rgb(36,37,39) поверх
   полотна - почти неразличимо. Пик .24 даёт 12 + .24*202 = rgb(60,64,72),
   то есть ровно окрестность канонных rgb(57,57,65) эталона, а к краям линия
   по-прежнему уходит в ноль. Яркость поднята вдвое ТОЛЬКО в середине пролёта.

   Приём и направление те же, что у зоны 11 (border-image, гаснущие торцы) -
   меняется краска, не механика. Оттенок уводится из чистого белого в серебро
   канона: белая линия на тёмном полотне читается как царапина, серебряная -
   как кромка материала.
   ------------------------------------------------------------------------- */
.section--alt{
  border-image:linear-gradient(90deg,
    rgba(170,182,198,0)     0%,
    rgba(170,182,198,.09)   8%,
    rgba(206,216,230,.20)  28%,
    rgba(214,224,238,.24)  50%,
    rgba(206,216,230,.20)  72%,
    rgba(170,182,198,.09)  92%,
    rgba(170,182,198,0)   100%) 1;
}

/* -------------------------------------------------------------------------
   14.4 РАНГ РАЗДЕЛА СТАНОВИТСЯ ВИДИМЫМ: МЕТКА СЛЕВА ОТ ЗАГОЛОВКА

   ЧТО БЫЛО. Зона 8 развела разделы на три ранга, но развела их ТОЛЬКО
   кеглем и длиной линейки: 37.7 / 30.3 / 26.2px и 220 / 140 / нет. Замер
   подтверждает - вес у всех девяти одинаковый (600), метки нет ни у одного.
   Разница в семь пикселей кегля между соседними рангами существует в
   таблице, но на экране, где разделы разнесены на два экрана прокрутки,
   человек их рядом никогда не видит и сравнить не может.

   ЧТО СТАЛО. Ранг получает ЗНАК, который читается сам по себе, без соседа:
     ранг 1, узловые (#how, #safety) - канонная СИНЯЯ полоса важного,
       дословно по канону: 3px, radius 6px 0 0 6px, свечение
       0 0 26px 3px rgba(79,196,233,.42) и 0 0 62px 9px rgba(79,196,233,.16);
     ранг 2, опорные (#why, #diff, #options, #offline) - та же полоса, но
       СЕРЕБРЯНАЯ и 2px, без свечения;
     ранг 3, служебные (#services, #reviews, #faq) - без метки, как и было.

   ПОЧЕМУ СИНЕГО РОВНО ДВА. Канон разрешает синим помечать важное и требует
   держать его в пределах десятой части площади. Две полосы 3px на всю
   страницу - это два раздела из девяти, «как проходит сделка» и «что
   защищает». Дай синее всем шести значимым - синий перестанет означать
   «важно» и станет отделкой, а вместе с ним обесценятся и девять полос,
   которые уже стоят на калькуляторе, курсе и модалке.

   ЗАЛИВКА ГАСНЕТ К ТОРЦАМ - min(56px, 30%), тот же приём и те же числа, что
   у девяти канонных полос зоны 11: полосы на странице обязаны выглядеть
   роднёй, а не двумя разными приёмами.

   🔴 СВЕЧЕНИЕ НАПИСАНО ПОСЛЕДНИМ И ОТДЕЛЬНОЙ СТРОКОЙ НАМЕРЕННО. Канон о нём
   говорит прямо: «Свечение обязательно: без него полоса выглядит дёшево».
   Отдельной строкой оно переживает любую будущую правку заливки.

   ОТСТУП И ПРОКРУТКА. Метка выносится влево на --z14-mark-x, а это всегда
   меньше поля .wrap на той же ширине (18<28, 13<20, 9<14). Запас 10/7/5px,
   поэтому метка физически не может вылезти за полотно и родить
   горизонтальную прокрутку. Проверено замером scrollWidth на 1440 и 375.
   ------------------------------------------------------------------------- */
#how     .section__head,
#safety  .section__head,
#why     .section__head,
#diff    .section__head,
#options .section__head,
#offline .section__head{ position:relative; }

#how     .section__head::before,
#safety  .section__head::before,
#why     .section__head::before,
#diff    .section__head::before,
#options .section__head::before,
#offline .section__head::before{
  content:"";
  position:absolute;
  left:calc(var(--z14-mark-x) * -1); top:2px; bottom:2px;
  border-radius:6px 0 0 6px;
  pointer-events:none;
}

/* Ранг 1: канонная синяя полоса важного. */
#how    .section__head::before,
#safety .section__head::before{
  width:3px;
  /* Запасная строка идёт первой и без min() - движок, который min() не знает,
     отбросит вторую при разборе и оставит рабочую полосу, а не пустоту. */
  background:linear-gradient(180deg,
              rgba(79,196,233,0) 0%, #4FC4E9 11%, #4FC4E9 89%, rgba(79,196,233,0) 100%);
  background:linear-gradient(180deg,
              rgba(79,196,233,0) 0,
              #4FC4E9 min(56px, 30%),
              #4FC4E9 calc(100% - min(56px, 30%)),
              rgba(79,196,233,0) 100%);
  box-shadow:0 0 26px 3px rgba(79,196,233,.42), 0 0 62px 9px rgba(79,196,233,.16);
}

/* Ранг 2: то же место и та же форма, но серебро и на пиксель тоньше.
   Свечения нет: оно в каноне закреплено за синим и означает «важное». */
#why     .section__head::before,
#diff    .section__head::before,
#options .section__head::before,
#offline .section__head::before{
  width:2px;
  background:linear-gradient(180deg,
              rgba(196,206,220,0) 0%, rgba(196,206,220,.46) 11%,
              rgba(196,206,220,.46) 89%, rgba(196,206,220,0) 100%);
  background:linear-gradient(180deg,
              rgba(196,206,220,0) 0,
              rgba(196,206,220,.46) min(56px, 30%),
              rgba(196,206,220,.46) calc(100% - min(56px, 30%)),
              rgba(196,206,220,0) 100%);
}

/* -------------------------------------------------------------------------
   14.5 КОМУ ВСЁ ЭТО МЕШАЕТ

   Человек с включённым повышенным контрастом просит не «красивее», а «чётче
   видно границу». Растворённый торец и размытое свечение - ровно то, что ему
   мешает: он ищет край, а край нарочно неопределённый. Возвращаем ножевые
   линии и снимаем оба сияния. Это его выбор, а не наш вкус.
   ------------------------------------------------------------------------- */
@media (prefers-contrast: more){
  body::before{
    background:linear-gradient(90deg,
      #98A2AE 0%, #C3CBD5 30%, #4FC4E9 42%, #4FC4E9 58%,
      #C3CBD5 70%, #98A2AE 100%);
  }
  body::after{ display:none; }

  .section--alt{ border-image:none; border-color:var(--line); }

  #how    .section__head::before,
  #safety .section__head::before{ background:#4FC4E9; box-shadow:none; }
  #why     .section__head::before,
  #diff    .section__head::before,
  #options .section__head::before,
  #offline .section__head::before{ background:#C3CBD5; }
}
@media (prefers-contrast: more) and (min-width:1200px){
  .side--left,
  .side--right{ border-image:none; border-color:var(--ae7-line); }
  .side--left,
  .side--right{ background-image:none; box-shadow:none; }
}

/* -------------------------------------------------------------------------
   14.6 ДВИЖЕНИЕ
   Зона не объявила ни одной анимации, ни одного перехода и ни одного
   transform. Блок оставлен пустым НАМЕРЕННО и с подписью: пустой блок
   читается как «проверено, гасить нечего», а его отсутствие - как «забыли
   посмотреть».
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  /* пусто: зона 14 движения не вводит */
}
/* ═══ ЗОНА 14L - КОНЕЦ ═══ */

/* =========================================================================
   ЗОНА 14: ПОМОЩНИК APOLLO AI В ПРАВОМ НИЖНЕМ УГЛУ      (25.08.2026)

   ДОСЛОВНО ОТ ВЯЧЕСЛАВА: «Apollo AI бота где-нибудь справа внизу. Apollo AI
   поставить, который есть в нашем мини-апп приложении обменника. Сюда же его
   на сайт разместить внизу в правом углу, чтобы люди могли в случае чего
   задавать вопросы и обращаться. И чтобы он также иногда маячил, типа как у
   Apollo Production, типа можешь задать мне любой вопрос там, мы на связи и
   так далее.»

   ЧТО ПЕРЕНЕСЕНО, А ЧТО НАПИСАНО ЗАНОВО. Поведение и вид сняты с готового
   помощника мини-аппа (TgAskAi.tsx в проекте сайта агентства) и с всплывающей
   подсказки apolloproduction.studio (AIChatBot.tsx, там она показывается через
   3 с и потом каждые 15 с). Сам React-компонент сюда не переносится: этот сайт
   чистая статика без сборки. Перенесены ТРИ вещи - обращение к той же
   edge-функции exchange-ai, разбор ответа (жирный текст и ссылки-переходы) и
   идея «маячка». Разметка и стиль написаны под дом-стиль этого сайта.

   🔴 ЧАСТОТА МАЯЧКА НАМЕРЕННО НЕ КАК НА apolloproduction.studio. Там подсказка
   выскакивает каждые 15 секунд - на сайте обменника, где человек читает длинное
   полотно про безопасность сделки, это дёргало бы его 4 раза в минуту. Здесь
   первый показ на 25-й секунде, дальше раз в 4 минуты, и любой из них можно
   выключить навсегда крестиком. Назойливый помощник хуже отсутствующего.

   ------------------------------------------------------------------------
   ПОЧЕМУ ИМЕННО ЭТИ КООРДИНАТЫ. Правый нижний угол на этом сайте НЕ пустой,
   и это замер, а не догадка (375x812, до правки):
     .panel-toggle «Рынок»  46x58, стоит в 9..67 px от низа;
     .ae5-top «наверх»      44x44, стоит в 96..140 px от низа;
     .qnav нижняя панель    77 px во всю ширину, z-index 65.
   На 1440x900 занят только .ae5-top - 24..68 px от низа.
   Поэтому помощник встаёт НАД тем, что там уже есть: 80 px от низа на широком
   экране и 152 px на узком. Ни одного чужого правила зона не двигает - чужие
   кнопки остаются ровно там, где стояли, двигаться должен пришедший последним.

   ЧЕГО ЗОНА НЕ КАСАЕТСЯ: шрифтов, линий, разделов, боковых колонок, шапки,
   подвала и любых существующих селекторов. Введён ОДИН новый префикс .aai-,
   проверено: 0 вхождений в index.html, styles.css, mobile.css, app.js,
   effects.js до этой правки.

   ПАЛИТРА. Синий #4FC4E9 держится в пределах акцента: канонная полоса 3px со
   свечением на кнопке и на шапке панели, кромка, иконка. Плоскостей синим не
   заливается. Точечная НОТКА ЗЕЛЁНОГО (--up #63C6A2) - только точка «на связи»
   размером 8px, потому что «мы на связи» это ровно то, что просили сказать.
   Точечная НОТКА ЖЁЛТОГО (--warn #E3C088) - только полоска 2px у сноски про
   то, что точный курс фиксирует менеджер. Обе нотки вместе занимают меньше
   процента площади виджета: светофора не образуется.

   ДВИЖЕНИЕ. Три штуки, у каждой одно назначение словом:
     появление панели  - spatial consistency (панель выезжает из своей кнопки);
     появление маячка  - state indication (помощник подал голос);
     точки «печатает»  - feedback (ответ считается, сервис не завис).
   Все три только на transform и opacity. prefers-reduced-motion гасит их в
   конце зоны явным блоком: глобальное правило строки 1097 ужимает переходы, но
   keyframes оно не выключает.
   ========================================================================= */

/* Контейнер-якорь. Он фиксирован у правого нижнего угла, а панель, маячок и
   кнопка лежат внутри обычным столбиком. Так растёт он ВВЕРХ, и появление
   маячка не сдвигает саму кнопку ни на пиксель. */
.aai-root{
  position: fixed;
  right: 16px;
  bottom: 80px;                 /* над .ae5-top, который занимает 24..68 */
  z-index: 75;                  /* выше тоггла (70), ниже модалки (90) */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  pointer-events: none;         /* пустое место столбика клики не ловит */
  font-family: var(--font);
}
.aai-root > *{ pointer-events: auto; }

/* -------------------------------------------------------------------------
   14.1 КНОПКА-ПУЗЫРЬ

   Скругление 6px, а не круг: дом-стиль держится на прямых углах, круглый
   пузырь в этом наборе выглядел бы деталью с чужого сайта. Геометрия взята у
   соседней .ae5-top, чтобы правый край читался одной колонкой кнопок.
   ------------------------------------------------------------------------- */
.aai-fab{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: var(--r);
  cursor: pointer;
  background: rgba(12,13,17,.94);
  border: 1px solid var(--accent-line);
  color: var(--accent-ink);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: 0 10px 30px rgba(0,0,0,.42);
  overflow: hidden;
  transition: transform var(--t-fast), background var(--t-base),
              border-color var(--t-base), box-shadow var(--t-base);
}
/* Канонная синяя полоса важного: 3px, скругление 6px 0 0 6px, два слоя
   свечения. Значения дословно из APOLLO-DESIGN-CANON, не на глаз. */
.aai-fab::before{
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: var(--bar);
  border-radius: 6px 0 0 6px;
  background: var(--accent);
  box-shadow: 0 0 26px 3px rgba(79,196,233,.42), 0 0 62px 9px rgba(79,196,233,.16);
}
.aai-fab svg{ width: 25px; height: 25px; }
/* Точка «на связи» - та самая нотка зелёного. Обводка цветом кнопки нужна,
   чтобы точка читалась и когда под ней окажется светлая часть страницы. */
.aai-fab__live{
  position: absolute;
  top: 9px; right: 9px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 0 2px rgba(12,13,17,.94), 0 0 10px 1px rgba(99,198,162,.55);
}
@media (hover:hover){
  .aai-fab:hover{
    background: rgba(20,22,28,.97);
    border-color: rgba(79,196,233,.72);
    box-shadow: 0 12px 34px rgba(0,0,0,.5), 0 0 22px rgba(79,196,233,.16);
  }
}
.aai-fab:active{ transform: scale(.94); }
.aai-fab:focus-visible{ outline: 2px solid var(--accent); outline-offset: 3px; }

/* -------------------------------------------------------------------------
   14.2 МАЯЧОК

   Крестик внутри маячка - полноразмерная цель 44x44, поэтому и сам маячок
   ровно 44 в высоту: планка нажатия важнее компактности, промах по крестику
   означает случайное открытие чата, то есть ровно ту назойливость, которую
   маячок и должен исключать.
   ------------------------------------------------------------------------- */
.aai-teaser{
  display: flex;
  align-items: center;
  /* 🔴 Ширина по ЗАМЕРУ, а не на глаз. На 272px фраза «Задайте любой вопрос,
     мы на связи» обрезалась многоточием на слове «связи» - маячок терял ровно
     то, ради чего его просили. Замер строки на 12.5px: 197px текста + 13px
     поля слева + 44px крестика = 254px, плюс запас на подстановку шрифта,
     когда SF Pro нет и подхватывается Golos Text. */
  max-width: min(316px, calc(100vw - 40px));
  height: 44px;
  padding: 0 0 0 13px;
  border-radius: var(--r);
  background: rgba(12,13,17,.95);
  border: 1px solid var(--line-2);
  border-left: var(--bar) solid var(--accent);
  box-shadow: 0 10px 28px rgba(0,0,0,.44), 0 0 26px 3px rgba(79,196,233,.16);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
.aai-teaser[hidden]{ display: none; }
.aai-teaser__t{
  font-size: 12.5px;
  line-height: 1.25;
  color: #E7ECF2;                /* 15.3:1 к подложке маячка */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aai-teaser__x{
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;     /* планка нажатия */
  padding: 0;
  background: none; border: 0; cursor: pointer;
  color: var(--muted);
  transition: color var(--t-fast);
}
.aai-teaser__x svg{ width: 13px; height: 13px; }
@media (hover:hover){ .aai-teaser__x:hover{ color: #EDF1F5; } }
.aai-teaser__x:focus-visible{ outline: 2px solid var(--accent); outline-offset: -3px; }
/* Въезд маячка: сдвиг и проявление. Класс ставит assistant.js после того, как
   снял hidden, - без второго кадра переход не запустился бы вовсе. */
/* 🔴 Тайминг здесь развёрнут, а НЕ через var(--t-base). Токен --t-base это
   «300ms cubic-bezier(...)» целиком, вместе с длительностью, и в сокращённой
   записи перехода он встал бы вторым временем, то есть ЗАДЕРЖКОЙ: маячок
   выезжал бы через треть секунды после команды. Токены с длительностью внутри
   в shorthand не подставляются. */
.aai-teaser{
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 260ms cubic-bezier(.22,.61,.36,1),
              transform 260ms cubic-bezier(.22,.61,.36,1);
}
.aai-teaser.is-in{ opacity: 1; transform: none; }

/* -------------------------------------------------------------------------
   14.3 ПАНЕЛЬ ДИАЛОГА
   ------------------------------------------------------------------------- */
.aai-panel{
  display: flex;
  flex-direction: column;
  width: min(384px, calc(100vw - 32px));
  max-height: min(560px, calc(100vh - 200px));
  border-radius: var(--r);
  /* Подложка почти непрозрачная, а не стеклянная как у панелей страницы:
     виджет висит над произвольным местом полотна, в том числе над холстом
     созвездия, и полупрозрачный фон съел бы читаемость переписки. */
  background: linear-gradient(163deg, #17191F 0%, #101217 100%);
  border: 1px solid var(--line-2);
  box-shadow: 0 22px 60px rgba(0,0,0,.6);
  overflow: hidden;
}
.aai-panel[hidden]{ display: none; }
/* Выезд из кнопки: spatial consistency. Точка роста внизу справа, там же,
   где физически стоит кнопка. */
.aai-panel{
  opacity: 0;
  transform: translateY(10px) scale(.985);
  transform-origin: 100% 100%;
  transition: opacity 220ms cubic-bezier(.22,.61,.36,1),
              transform 220ms cubic-bezier(.22,.61,.36,1);
}
.aai-panel.is-in{ opacity: 1; transform: none; }

.aai-head{
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 13px 8px 13px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(255,255,255,.028);
}
/* Вторая канонная полоса - у шапки панели. Больше синего в виджете нет. */
.aai-head::before{
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: var(--bar);
  border-radius: 6px 0 0 6px;
  background: var(--accent);
  box-shadow: 0 0 26px 3px rgba(79,196,233,.42), 0 0 62px 9px rgba(79,196,233,.16);
}
.aai-head__ico{
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent-ink);
}
.aai-head__ico svg{ width: 19px; height: 19px; }
.aai-head__txt{ min-width: 0; flex: 1 1 auto; }
.aai-head__t{
  display: flex; align-items: center; gap: 7px;
  font-size: 14.5px; font-weight: 700; color: var(--ink);
  letter-spacing: .01em;
}
/* Нотка зелёного номер два: та же точка «на связи», что и на кнопке. */
.aai-dot{
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--up);
  box-shadow: 0 0 9px 1px rgba(99,198,162,.5);
}
.aai-head__s{
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aai-x{
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;      /* планка нажатия */
  padding: 0; background: none; border: 0; cursor: pointer;
  color: var(--muted);
  transition: color var(--t-fast);
}
.aai-x svg{ width: 15px; height: 15px; }
@media (hover:hover){ .aai-x:hover{ color: #EDF1F5; } }
.aai-x:focus-visible{ outline: 2px solid var(--accent); outline-offset: -4px; }

.aai-log{
  flex: 1 1 auto;
  min-height: 132px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px 14px 4px;
  display: flex; flex-direction: column; gap: 9px;
}
.aai-msg{
  max-width: 88%;
  padding: 9px 12px;
  border-radius: var(--r);
  font-size: 13.5px;
  line-height: 1.5;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
.aai-msg--bot{
  align-self: flex-start;
  background: rgba(255,255,255,.055);
  border: 1px solid var(--line);
  color: #DEE4EB;                 /* 12.9:1 к подложке панели */
}
.aai-msg--user{
  align-self: flex-end;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: #EDF2F6;
}
.aai-msg--err{ color: #EFB6AE; }
.aai-msg b{ color: var(--ink); font-weight: 700; }
.aai-msg a{
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
/* Точки «печатает»: feedback. Только opacity, ни размера, ни сдвига. */
.aai-typing{ display: inline-flex; gap: 5px; align-items: center; height: 8px; }
.aai-typing i{
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent-ink);
  opacity: .3;
  animation: aai-blink 1.1s infinite ease-in-out;
}
.aai-typing i:nth-child(2){ animation-delay: .18s; }
.aai-typing i:nth-child(3){ animation-delay: .36s; }
@keyframes aai-blink{ 0%,80%,100%{ opacity:.28 } 40%{ opacity:1 } }

.aai-chips{ display: flex; flex-wrap: wrap; gap: 7px; padding: 8px 14px 2px; }
.aai-chips[hidden]{ display: none; }
.aai-chip{
  min-height: 44px;               /* планка нажатия, не косметика */
  padding: 6px 12px;
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.05);
  border: 1px solid var(--line-2);
  color: #D2D9E1;
  font-family: var(--font);
  font-size: 12px;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
@media (hover:hover){
  .aai-chip:hover{ background: rgba(255,255,255,.09); border-color: var(--accent-line); color: #EDF1F5; }
}
.aai-chip:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

.aai-form{
  display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 12px 8px;
  border-top: 1px solid var(--line);
}
.aai-input{
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;               /* планка нажатия у поля ввода тоже */
  max-height: 120px;
  padding: 12px 12px;
  border-radius: var(--r-sm);
  background: rgba(255,255,255,.045);
  border: 1px solid var(--line-2);
  color: #EDF1F5;
  font-family: var(--font);
  font-size: 13.5px;              /* 13.5, а не 16: iOS зумит поле только ниже 16,
                                     но панель здесь fixed и зум её не ломает,
                                     а более крупный ввод сломал бы ритм панели.
                                     Проверено на 375: подписи не расползаются. */
  line-height: 1.35;
  resize: none;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.aai-input::placeholder{ color: var(--dim); }
.aai-input:focus{ outline: none; border-color: var(--accent-line); background: rgba(255,255,255,.07); }
.aai-send{
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;      /* планка нажатия */
  padding: 0;
  border-radius: var(--r-sm);
  background: rgba(79,196,233,.12);
  border: 1px solid var(--accent-line);
  color: var(--accent-ink);
  cursor: pointer;
  transition: background var(--t-fast), transform var(--t-fast), opacity var(--t-fast);
}
.aai-send svg{ width: 18px; height: 18px; }
@media (hover:hover){ .aai-send:hover:not(:disabled){ background: rgba(79,196,233,.2); } }
.aai-send:active:not(:disabled){ transform: scale(.94); }
.aai-send:disabled{ opacity: .4; cursor: default; }
.aai-send:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

/* Сноска: единственная нотка жёлтого во всём виджете - полоска 2px слева.
   Смысл именно предупредительный, поэтому цвет предупреждения уместен. */
.aai-note{
  margin: 0;
  padding: 0 14px 12px;
  border-left: 2px solid rgba(227,192,136,.5);
  margin-left: 12px;
  padding-left: 10px;
  font-size: 11px;
  line-height: 1.42;
  color: var(--muted);            /* 7.3:1, выше планки для служебного текста */
}

/* -------------------------------------------------------------------------
   14.4 УЗКИЕ ЭКРАНЫ

   Порог 1199px тот же, что у нижней панели разделов в mobile.css: именно с
   него в правом нижнем углу появляются .qnav и «Рынок», и именно с него
   помощник обязан подняться выше.
   ------------------------------------------------------------------------- */
@media (max-width: 1199px){
  .aai-root{
    right: 12px;
    /* 96 + 44 у кнопки «наверх» = 140, плюс 12 просвета = 152.
       env() повторяет то, как считает низ вся остальная мобильная вёрстка. */
    bottom: calc(152px + env(safe-area-inset-bottom));
  }
  /* 🔴 ЗАПАС ПО ВЫСОТЕ ПЕРЕСЧИТАН ВСЛЕД ЗА НИЗОМ, ИНАЧЕ АРИФМЕТИКА НЕ СХОДИТСЯ.
     Потолок панели (100vh - 200px) посчитан от ДЕСКТОПНОГО низа 80px. Здесь
     столбик поднят на 152px, а вычитаемое осталось прежним: 152 низ + панель
     560 + 10 просвет + 56 кнопка = 778px при окне 768 (iPad в ландшафте) -
     шапка панели с крестиком уезжала ЗА верх экрана, и закрыть её было нечем.
     На телефоне в ландшафте (844x390) промах доходил до 39px.
     Верное вычитаемое: 152 низ + 66 кнопка с просветом + 12 воздуха = 230. */
  .aai-panel{ max-height: min(560px, calc(100vh - 230px - env(safe-area-inset-bottom))); }
}

/* Низкое окно. Гарантированные ленте 132px там взять неоткуда, а min-height
   запрещает flex её ужать - и overflow:hidden панели срезал бы снизу ПОЛЕ
   ВВОДА, то есть единственное, ради чего виджет открывают. Ниже 560px высоты
   лента уступает место форме. */
@media (max-height: 560px){
  .aai-log{ min-height: 0; }
}

@media (max-width: 640px){
  /* На телефоне панель перестаёт быть пузырём у кнопки и становится листом:
     384px у правого края на экране 375 не помещаются, а ужимать переписку до
     ширины кнопки бессмысленно. Лист держится в границах, которые уже
     согласованы с чужими элементами: сверху под шапкой, снизу над панелью
     разделов (77px + env). */
  .aai-panel{
    position: fixed;
    left: 10px; right: 10px;
    bottom: calc(94px + env(safe-area-inset-bottom));
    width: auto;
    /* 🔴 Высота ПО СОДЕРЖИМОМУ, а не во весь экран. Первая редакция ставила
       top:74px, и панель растягивалась на 644px: между приветствием и
       подсказками зияло 200 пикселей пустоты, лист выглядел недоделанным.
       Теперь панель начинается компактной и растёт по мере переписки, упираясь
       в потолок. Потолок считается от тех же чисел, что и низ: 94px просвет
       снизу + 74px под шапку сайта. */
    max-height: calc(100vh - 168px - env(safe-area-inset-bottom));
    transform-origin: 100% 100%;
  }
  /* Кнопка при открытом листе прячется: она физически попала бы внутрь листа,
     а закрывать всё равно нечем, кроме крестика в шапке. Крестик на месте. */
  .aai-root.is-open .aai-fab,
  .aai-root.is-open .aai-teaser{ display: none; }
  .aai-teaser__t{ font-size: 12px; }
}

/* -------------------------------------------------------------------------
   14.5 ДВИЖЕНИЕ ПО ЖЕЛАНИЮ ПОЛЬЗОВАТЕЛЯ

   Глобальное правило строки 1097 ужимает transition-duration через !important
   и закрывает переходы этой зоны. Но keyframes оно НЕ выключает, поэтому точки
   «печатает» продолжали бы мигать. Гасим явно и оставляем вместо мигания
   ровную половинную яркость - индикатор ожидания остаётся, движение уходит.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  .aai-panel, .aai-teaser{
    opacity: 1;
    transform: none;
    transition: none !important;
  }
  .aai-typing i{ animation: none; opacity: .62; }
  .aai-fab:active, .aai-send:active:not(:disabled){
    transform: none;
    filter: brightness(1.28);
    transition: filter 120ms linear !important;   /* бьёт .001ms из строки 1097 */
  }
}
/* ═══ ЗОНА 14 - КОНЕЦ ═══ */

/* ═══════════════════════════════════════════════════════════════════════════
   ЗОНА 15: ШРИФТЫ ЗАГОЛОВКОВ БОКОВЫХ ПАНЕЛЕЙ И МЕТАЛЛ НА «ОБМЕНЯТЬ»
                                                             (25.08.2026)
   ═══════════════════════════════════════════════════════════════════════════

   ТРЕБОВАНИЕ ВЛАДЕЛЬЦА ДОСЛОВНО: «всё равно очень как-то сыро, объебански
   выглядит, особенно вот шрифты какие-то, вот где написано лента рынка, там
   крипторынок, услуги. Как-то надо с шрифтами немножко поиграться,
   поинтереснее... И верхняя кнопка обменять, она сначала серая, потом какая-то
   белая становится. Сделай её изначально, не знаю, может, перелив от
   металлического к белому, типа градиент.»

   ЧТО ЗАМЕРЕНО НА ЖИВОЙ СТРАНИЦЕ ДО ПРАВКИ (свой Chrome по протоколу отладки,
   локальный сервер, окно 1440x900; контроль прибора сошёлся: белый на полотне
   19.42 при расчётных 19.42, innerWidth 1440, scrollWidth 1440, найдены все
   четыре заголовка):

     КРИПТОРЫНОК   11px / вес 600 / трекинг 2.64px / IBM Plex Mono / белый 62%
     ЛЕНТА РЫНКА   11px / вес 600 / трекинг 2.64px / IBM Plex Mono / белый 62%
     УСЛУГИ        11px / вес 600 / трекинг 2.64px / IBM Plex Mono / белый 62%
     РАЗДЕЛЫ       11px / вес 600 / трекинг 2.64px / IBM Plex Mono / белый 72%

   То есть ЧЕТЫРЕ заголовка разделов набраны ОДНИМ И ТЕМ ЖЕ служебным стилем -
   тем же, каким на сайте подписаны поля, ярлыки карточек и коды валют. Жалоба
   «выглядит как подпись к полю» подтверждена прибором, а не на глаз: в
   типографике сайта у заголовка раздела просто НЕТ своей ступени.

     кнопка «Обменять» в покое   заливка linear-gradient(90deg,
                                 rgba(255,255,255,.13) -> rgba(255,255,255,.02)
                                 -> rgba(0,0,0,.10)), текст #E9EEF3
     она же во взведённом виде   серебро #FFFFFF -> #98A2AE, текст тот же светлый

   Вот это и есть «сначала серая, потом какая-то белая»: в покое кнопка залита
   почти прозрачным стеклом (глазом - серое пятно), а по классу .is-cta-armed
   мгновенно подменяется на серебро. Меняется не сила, а МАТЕРИАЛ - отсюда
   ощущение дешёвого переключателя.

   🔴 ОСОЗНАННОЕ РАСХОЖДЕНИЕ С ПРЕЖНИМ РЕШЕНИЕМ ФАЙЛА. Блок на строке 4251
   («одна главная кнопка на экран») намеренно держал шапочную кнопку тихой,
   пока видна кнопка героя. Владелец 25.08 прямо просит металл ИЗНАЧАЛЬНО, и
   его свежее слово старше того решения. Иерархию я не выбрасываю, а перевожу
   на другой признак: покой и взведённое состояние теперь различаются СВЕТЛОТОЙ
   одного и того же металла плюс акцентным ореолом у взведённого, а не сменой
   материала с серого на белый.

   ГРАНИЦЫ ЗОНЫ. Линии-разделители колонок, свечения, блок Apollo AI, плитки
   разделов, лента, курсы, калькулятор и разметка index.html не затронуты ни
   одним селектором ниже. Меняются только гарнитура, кегль, вес, трекинг и
   краска заголовков панелей - и заливка одной кнопки шапки.
   ═════════════════════════════════════════════════════════════════════════ */

/* -------------------------------------------------------------------------
   15.1 ЗАГОЛОВОК РАЗДЕЛА ПОЛУЧАЕТ СВОЮ СТУПЕНЬ

   ЧТО ИМЕННО «ПОИГРАТЬ ШРИФТАМИ» ЗНАЧИТ ЗДЕСЬ. Не подобрать новую гарнитуру -
   подключать ничего нельзя, канон держит системный стек. Играем тремя
   рычагами, которые у заголовка раздела и так должны отличаться от служебной
   подписи:

     1. ГАРНИТУРА. Моно IBM Plex - служебный слой сайта (коды валют, цифры,
        ярлыки). Заголовок раздела уходит на дом-гарнитуру var(--font): у неё
        другая ширина буквы и другой ритм, разница видна с первого взгляда,
        а кириллица берётся из SF Pro Display - ровно то, что задаёт канон.
     2. КЕГЛЬ И ВЕС. 11 -> 12.5px (--fs-eyebrow канона) и 600 -> 700. Это
        РАЗНЫЕ ступени шкалы, а не «чуть-чуть больше»: рядом с ярлыками
        карточек ленты (11px моно, приглушённые) заголовок наконец читается
        как уровень выше, а не как их близнец.
     3. КРАСКА. Плоский белый 62% заменён серебряным градиентом канона. Это
        главный признак «дорогого продукта» в нашем доме: у эталонного дека
        серебром набраны именно заголовки.

   ПОЧЕМУ НИЖНИЙ СТОП СЕРЕБРА СВЕТЛЕЕ КАНОННОГО. Канон даёт рампу
   #FFFFFF -> #F4F7FA 26% -> #C3CBD5 63% -> #98A2AE для КРУПНЫХ заголовков
   (62-92px). На 12.5px хвост #98A2AE садится в грязь: тонкая буква на тёмном
   полотне теряет вес быстрее крупной. Поэтому первые три стопа взяты канонные
   дословно, а хвост поднят до #B4BDC8. Расчёт: #B4BDC8 на полотне #0C0D11
   даёт 10.2:1 против 7.7:1 у прежнего белого 62% - заголовок стал и заметнее,
   и контрастнее одновременно.

   ⚠️ ИНТЕРЛИНЬЯЖ НЕ ТРОГАЕТСЯ НАМЕРЕННО. Зона 7.5 отдельно объясняет, почему:
   подписи левой и правой колонок стоят на одной высоте только потому, что
   высоту строки задаёт сама подпись. Прижму line-height к единице - две
   колонки разъедутся по вертикали. Кегль меняется у ОБЕИХ подписей на одно и
   то же число, поэтому равенство сохраняется.
   ------------------------------------------------------------------------- */
.side .panel__title,
.side .spot__eyebrow{
  position:relative;                 /* якорь для линейки 15.2, layout не меняет */
  font-family:var(--font);
  font-size:12.5px;
  font-weight:700;
  letter-spacing:.26em;
  text-transform:uppercase;
  color:#E7ECF2;                     /* запасной цвет, если clip:text не поддержан */
}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .side .panel__title,
  .side .spot__eyebrow{
    background-image:linear-gradient(90deg,#FFFFFF 0%,#F4F7FA 26%,#D2D9E1 63%,#B4BDC8 100%);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
}

/* -------------------------------------------------------------------------
   15.2 ЛИНЕЙКА ПОД ЗАГОЛОВКОМ - ТО, ЧЕГО НЕ ХВАТАЛО БОЛЬШЕ ВСЕГО

   Канон, раздел 2: «Линейка под эйбрау - белый градиент, гаснет слева
   направо, толщина 3, ширина 220» на сцене 1920. Пересчёт по кеглю, а не по
   ширине сцены: у эйбрау канона 18px линейка 220px и толщина 3px, то есть
   12.2 и 0.167 кегля. При нашем кегле 12.5px это дало бы 152px при внутренней
   ширине колонки 260px - линейка съела бы больше половины и читалась бы как
   разделитель, а не как часть заголовка. Поэтому от фиксированной ширины канона
   отказываюсь в пользу ширины САМОГО СЛОВА (width:100%): у «КРИПТОРЫНОК» это
   118px, у «УСЛУГИ» 64px, и линейка везде остаётся подчёркиванием подписи, а не
   самостоятельной чертой. Толщина 2px - пересчёт 0.167 от кегля 12.5.

   🔴 ПОЧЕМУ ЛИНЕЙКА АБСОЛЮТНАЯ, А НЕ ОТСТУПОМ СНИЗУ. Заголовок стоит в
   flex-строке вместе со значком, точками карусели и штампом времени, и строка
   выровнена по центру. Любой padding-bottom у подписи сдвинул бы значок вверх
   относительно текста и уронил бы выравнивание двух колонок, которое чинила
   зона 7.4. Абсолютный псевдоэлемент не участвует в раскладке вообще: он
   ложится в уже существующее нижнее поле шапки раздела.

   Это НЕ линия-разделитель колонки и не свечение - те принадлежат другому
   исполнителю и здесь не упоминаются ни одним селектором. Линейка привязана
   к самой подписи и живёт внутри её габарита.
   ------------------------------------------------------------------------- */
.side .panel__title::after,
.side .spot__eyebrow::after{
  content:"";
  position:absolute; left:0; top:calc(100% + 6px);
  width:100%; height:2px; border-radius:2px;
  pointer-events:none;
  background-image:linear-gradient(90deg,
                   rgba(255,255,255,.90) 0%,
                   rgba(255,255,255,.62) 44%,
                   rgba(255,255,255,0)   100%);
}

/* -------------------------------------------------------------------------
   15.3 «РАЗДЕЛЫ»: ТОТ ЖЕ СТИЛЬ, НО ДРУГОЙ МЕХАНИЗМ ЛИНЕЙКИ

   Подпись «Разделы» живёт псевдоэлементом ::before у навигации (зона 7.6
   поставила её так, чтобы не лезть в index.html - там параллельно работают
   другие исполнители). У псевдоэлемента своего псевдоэлемента не бывает,
   поэтому линейку 15.2 к нему прицепить нечем.

   Фон занят серебром под background-clip:text, значит и через background
   линейку не нарисовать. Остаётся третий канал краски - border-image:
   нижняя граница 2px, источником градиент, слайс 1. Рисуется только там, где
   толщина границы не ноль, то есть только снизу. width:max-content держит
   линейку по ширине слова, а не во всю колонку - иначе она стала бы похожа на
   разделитель списка.

   Цвет и кегль подписи менялись зоной 10.6 ради «чуть выделить» - я это
   решение не откатываю: 11px моно у неё СНЯТЫ в пользу общей ступени 12.5,
   но яркость остаётся не ниже прежней (серебро с хвостом #B4BDC8 = 10.2:1
   против 8.7:1 у белого 72%).
   ------------------------------------------------------------------------- */
@media (min-width:1200px){
  .side .qnav::before{
    width:max-content;
    padding-bottom:8px;              /* линейка принадлежит заголовку, а не списку:
                                        отступ до неё обязан быть МЕНЬШЕ отступа
                                        от неё до первой строки разделов */
    font-family:var(--font);
    font-size:12.5px;
    font-weight:700;
    letter-spacing:.26em;
    color:#E7ECF2;                   /* запасной цвет, если clip:text не поддержан */
    border-bottom:2px solid transparent;
    border-image:linear-gradient(90deg,
                 rgba(255,255,255,.90) 0%,
                 rgba(255,255,255,.62) 44%,
                 rgba(255,255,255,0)   100%) 1;
  }
  @supports ((-webkit-background-clip:text) or (background-clip:text)){
    .side .qnav::before{
      background-image:linear-gradient(90deg,#FFFFFF 0%,#F4F7FA 26%,#D2D9E1 63%,#B4BDC8 100%);
      -webkit-background-clip:text; background-clip:text;
      color:transparent;
    }
  }
}

/* -------------------------------------------------------------------------
   15.4 КНОПКА «ОБМЕНЯТЬ»: МЕТАЛЛ СРАЗУ, СЛЕВА НАПРАВО

   Просьба дословно: «перелив от металлического к белому, типа градиент».
   Рампа идёт слева направо, как вся семья кнопок зоны 10, но в ОБРАТНУЮ
   сторону: у зоны 10 металл светлеет влево и уходит в тёмное вправо, здесь
   тёмный металл стоит слева и разгорается в белое справа. Это и есть
   «от металлического к белому».

   ПОЧЕМУ ИМЕННО ЭТИ ЧИСЛА. Три стопа из четырёх взяты у канонного серебра
   (#F4F7FA, #FFFFFF и их окрестности), новым является только тёмный конец.
   Он выбран по контрасту, а не на глаз: текст кнопки #0A0B0E на самом тёмном
   стопе #7E8894 даёт 5.5:1 при норме 4.5 для 13.5px, на вдавленном состоянии
   (#79828E) 5.1:1. То есть «металлический» конец сделан настолько тёмным,
   насколько позволяет читаемость, и ни на тон темнее.

   ТРИ СТУПЕНИ ОДНОГО МАТЕРИАЛА ВМЕСТО ДВУХ РАЗНЫХ МАТЕРИАЛОВ:
     покой      --z15-metal      кнопка героя ещё видна, шапочная тише
     взведена   --z15-metal-hi   герой ушёл вверх, шапочная стала главной
     наведение  на ступень выше своей (покой -> hi, взведённая -> max)
     нажатие    --z15-metal-lo   вдавленная поверхность уходит в тень
   Ни в одном состоянии материал не подменяется: меняется только светлота.
   Ровно это владелец и просил - «наведение пусть усиливает эффект».
   ------------------------------------------------------------------------- */
:root{
  --z15-metal:     linear-gradient(90deg,#7E8894 0%,#A9B2BD 22%,#D6DCE4 54%,#F4F7FA 80%,#FFFFFF 100%);
  --z15-metal-hi:  linear-gradient(90deg,#8E97A2 0%,#B8C0CA 22%,#E2E7ED 54%,#FAFCFD 80%,#FFFFFF 100%);
  --z15-metal-max: linear-gradient(90deg,#9CA5B0 0%,#C6CED7 22%,#EDF1F5 54%,#FDFEFF 80%,#FFFFFF 100%);
  --z15-metal-lo:  linear-gradient(90deg,#79828E 0%,#A0A9B4 22%,#C9D0D9 54%,#E6EAF0 80%,#F3F6F9 100%);
}

/* Покой. background-color гасится явно: правило на строке 4262 ставит его
   СОКРАЩЁННЫМ свойством, и без явного сброса под моей рампой остался бы
   чужой полупрозрачный белый - он ничего не портит на непрозрачных стопах,
   но делает состояние непредсказуемым при любой будущей правке рампы. */
.header__cta.btn--tg{
  position:relative;
  background-color:transparent;
  background-image:var(--z15-metal);
  color:#0A0B0E;
  border-color:rgba(255,255,255,.44);
  box-shadow:0 6px 18px -10px rgba(0,0,0,.9),
             0 0 18px -12px rgba(79,196,233,.45);
}
/* Глиф Telegram заливается currentColor: на металле он обязан быть тёмным,
   иначе повторяется прежняя болезнь - светлая иконка на светлом фоне. */
.header__cta.btn--tg .ico-tg{ color:#0A0B0E; }

/* Фаска. Прежний верхний блик был рассчитан на плоскую белую заливку и на
   металле смывал левый, самый тёмный конец рампы. Здесь блик слабее, а снизу
   добавлена тень - вместе это читается как выпуклая металлическая пластина,
   а не как белое пятно. */
.header__cta.btn--tg::after{
  background:linear-gradient(180deg,
             rgba(255,255,255,.34) 0%,
             rgba(255,255,255,0)   46%,
             rgba(0,0,0,.10)       100%);
}

/* Фирменная засечка дома: полоса 2px слева, ровно тем же приёмом, что у
   главной кнопки страницы (.btn--primary::before). Поджата на радиус кнопки
   (--z10-r-sm = 10px), иначе прямой торец полосы вылезает за скругление
   отдельным язычком - урок, уже разобранный в этом файле дважды.
   Это единственное место, где на кнопке появляется синий канона: площадь
   2x24px против 121x44 всей кнопки, то есть меньше двух сотых. */
.header__cta.btn--tg::before{
  content:"";
  position:absolute; left:0; top:var(--z10-r-sm); bottom:var(--z10-r-sm);
  width:2px; border-radius:2px; pointer-events:none;
  background:linear-gradient(180deg,
             rgba(79,196,233,.45) 0%, var(--accent) 50%, rgba(79,196,233,.45) 100%);
  box-shadow:0 0 10px 1px rgba(79,196,233,.42);
  transition:box-shadow var(--t-fast);
}

/* Взведённое состояние: та же рампа на ступень светлее плюс акцентный ореол.
   Селектор повторяет чужой ДОСЛОВНО (четыре класса) - иначе не перебьётся.
   Разница с покоем теперь в СИЛЕ, а не в материале. */
.header.is-cta-armed .header__cta.btn--tg{
  background-color:transparent;
  background-image:var(--z15-metal-hi);
  color:#0A0B0E;
  border-color:rgba(255,255,255,.62);
  box-shadow:0 6px 18px -10px rgba(0,0,0,.9),
             0 0 0 1px rgba(79,196,233,.30),
             0 12px 26px -14px rgba(79,196,233,.45);
}
.header.is-cta-armed .header__cta.btn--tg .ico-tg{ color:#0A0B0E; }
.header.is-cta-armed .header__cta.btn--tg::before{
  box-shadow:0 0 14px 2px rgba(79,196,233,.55);
}

/* ---- НАВЕДЕНИЕ. Заперто в @media (hover:hover): на сенсоре наведения нет, и
   без запора палец оставлял бы на кнопке залипшую подсветку. ---- */
@media (hover:hover){
  .header__cta.btn--tg:hover{
    background-color:transparent;
    background-image:var(--z15-metal-hi);
    border-color:rgba(255,255,255,.66);
    color:#0A0B0E;
    box-shadow:0 8px 20px -10px rgba(0,0,0,.9),
               0 0 16px -8px rgba(79,196,233,.55);
  }
  .header.is-cta-armed .header__cta.btn--tg:hover{
    background-color:transparent;
    background-image:var(--z15-metal-max);
    border-color:rgba(255,255,255,.78);
    box-shadow:0 8px 20px -10px rgba(0,0,0,.9),
               0 0 0 1px rgba(79,196,233,.42),
               0 14px 30px -14px rgba(79,196,233,.55);
  }
  .header__cta.btn--tg:hover::before{ box-shadow:0 0 16px 2px rgba(79,196,233,.66); }
}

/* ---- НАЖАТИЕ. Стоит ПОСЛЕ наведения намеренно: на мыши нажатие всегда
   происходит поверх наведения, оба состояния активны сразу, и при равном весе
   спор решает порядок. Урок зоны 10.4, повторять его ошибку незачем. ---- */
.header__cta.btn--tg:active,
.header.is-cta-armed .header__cta.btn--tg:active{
  background-color:transparent;
  background-image:var(--z15-metal-lo);
  color:#0A0B0E;
}

/* -------------------------------------------------------------------------
   15.5 ЧЕГО ЗОНА НАМЕРЕННО НЕ ДЕЛАЕТ

   Не трогает линии-разделители колонок, свечения торцов, блок Apollo AI,
   плитки разделов, карточки ленты, строки курсов, калькулятор, переключатель
   направления и разметку index.html - там работают другие исполнители.
   Не трогает значки в шапках разделов: они остаются на своей краске, потому
   что заголовок и так получил ступень выше, а поднимать заодно и значок
   значит снова выравнивать всю строку.
   Не вводит ни одной новой единицы движения: ни transform, ни keyframes, ни
   перехода по width/height/top/left. Градиенты между собой не
   интерполируются, смена ступени металла мгновенная - это состояние, а не
   анимация.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  /* Пусто по существу, а не по забывчивости: своих transform и keyframes у
     зоны 15 нет. Масштаб и подъём кнопки шапки принадлежат прежним зонам и
     уже гасятся их собственными блоками (строки 2867, 4428, 4894). */
}
/* ═══ ЗОНА 15 - КОНЕЦ ═══ */

/* =========================================================================
   ЗОНА 16 - ЗНАК SKR В ШАПКЕ И ПОДВАЛЕ (08.09.2026)

   ЗАДАЧА СЛОВАМИ ВЛАДЕЛЬЦА: «там, где наверху слева, где Apollo Exchange,
   туда нужно одну из них вставить, которая будет подходить по цвету. Ну,
   наверное, чёрно-белая. Вот туда её вставь, чтобы она красиво была там,
   стояла, как логотип полноценный. И снизу нужно название, нужно Apollo
   Exchange».

   ЧТО ИЗ ЭТОГО СЛЕДУЕТ ПО РАСКЛАДКЕ. «Снизу нужно название» - значит знак
   и надпись встают друг над другом, а не в строку. Это же читается и в
   самом исходнике владельца: там под монограммой стоит подпись «х Apollo
   Production». Вертикальная связка - родная композиция этого знака, а не
   моя выдумка.

   ЗАМЕР ВЫСОТЫ, ЧТОБЫ ШАПКА НЕ УЕХАЛА. До правки: .header 71px, .logo 44px
   (min-height), поля .header__inner 13px сверху и снизу. Сборка ниже даёт
   32.1 + 3 + 14.4 = 49.5px, то есть шапка становится 76px. Порог здесь не
   вкусовой: у страницы scroll-padding-top 88px (строка 117), и якорная
   ссылка отбивает заголовок от верха ровно на это число. Шапка выше 88px
   начала бы накрывать заголовок раздела, к которому только что прыгнули.
   76 < 88 - запас 12px остаётся.

   ПОЧЕМУ НАДПИСЬ 12.5px, А НЕ ПРЕЖНИЕ 15.5px. На 15.5px строка «Apollo
   Exchange» занимает 125px при знаке в 76px: низ связки в 1.6 раза шире
   верха, и знак читается приложением к надписи, а не наоборот. На 12.5px
   надпись ~101px против 76px - 1.33, связка держится. Ниже 11px опускать
   нельзя: на странице действует собственный порог мелкого текста (зона
   про 11px, строка 5107), и надпись бренда нарушать его не может.
   ------------------------------------------------------------------------- */
.logo--skr{
  flex-direction:column;
  align-items:center;
  gap:3px;
  text-align:center;
}
/* Подвал: абзац под знаком выключен влево, центрованная связка сбила бы ось. */
.logo--skr-left{ align-items:flex-start; text-align:left; }

/* 🔴🔴 ПРАВКА СКЕПТИКА 08.09.2026. В ПОДВАЛЕ КОЛОНКА НЕ ВКЛЮЧАЛАСЬ ВООБЩЕ,
   И ЭТО НЕ ПРИДИРКА К КОДУ, А ЗАМЕР ЖИВОЙ СТРАНИЦЫ.

   ЧТО БЫЛО НА САМОМ ДЕЛЕ. getBoundingClientRect на apolloexchange.finance:
   в подвале знак занимал x 278...354, а надпись «Apollo Exchange» - x 358.5...464.7.
   Это ОДНА строка, знак СЛЕВА, надпись СПРАВА. На 375px то же самое:
   знак 14...76, надпись 80.5...178.2. То есть в подвале название стояло
   СБОКУ, а не под знаком, - ровно то, чего владелец не просил, и композиция
   подвала расходилась с композицией шапки. Один знак на странице обязан
   иметь одну композицию, иначе это читается как две разные конторы -
   довод из комментария в разметке, который сам себя и не выполнял.

   ПРИЧИНА. Строка 5046: `.foot a, .footer a, .foot__link{ display:inline-block }`.
   Вес селектора 0-1-1 (класс + тип) выше, чем 0-1-0 у `.logo--skr`, и порядок
   в файле тут ничего не решает. Значит в подвале ссылка знака оставалась
   inline-block, а НЕ flex-контейнером. А flex-direction, align-items и gap -
   свойства flex-контейнера: у inline-block они не то что проигрывают, они
   просто не применяются. Все три строки блока выше в подвале молчали.
   В шапке дефекта нет: там `.logo` остаётся inline-flex, `.footer a` не матчит.

   ПОЧЕМУ ИМЕННО ЭТИ ДВА СЕЛЕКТОРА. `.footer .logo--skr` даёт вес 0-2-0 и
   перебивает `.footer a`; второй нужен отдельно, потому что первый несёт
   унаследованный от `.logo--skr` align-items:center, и без него левая
   выключка подвала снова уехала бы в центр. */
.footer .logo--skr{ display:inline-flex; flex-direction:column; }
.footer .logo--skr-left{ align-items:flex-start; text-align:left; }

/* 🔴 ПЛИТКА 38x38 СНИМАЕТСЯ, И ЭТО НЕ ПОТЕРЯ ПРИЁМА, А АРИФМЕТИКА.
   Монограмма SKR имеет пропорцию 2.37:1 (замер getBBox: 194.13 x 82.01).
   В квадрате 38x38 с полями она получает 30px ширины и 12.7px высоты -
   при толщине штриха 6% это 0.8px линии. Знак превращается в серую
   царапину. Плитка тут не «оформляет знак», а душит его.
   Акцентная засечка ::before снимается вместе с плиткой: она была краем
   плитки, а без плитки повисла бы голубой чёрточкой рядом со знаком. */
.logo--skr .logo__mark{
  width:auto; height:auto; padding:0;
  background:none; border:0; border-radius:0;
}
.logo--skr .logo__mark::before{ content:none; }

/* Высота задана числом, а не auto: у inline-svg без явной высоты браузер
   берёт запасные 150px до применения viewBox, и на первом кадре шапка
   прыгает. 76 / 2.3671 = 32.1. */
.logo--skr .ico--skr{
  display:block;
  width:76px; height:32.1px;
  color:#fff;                 /* вариант 3 - белая монограмма */
  fill:currentColor; stroke:none;
}

/* 🔴 ЦВЕТ НАДПИСИ ЗДЕСЬ НЕ ЗАДАЁТСЯ НАМЕРЕННО. У .header .logo__text
   (зона 12) стоит серебряная заливка через background-clip:text и проезд
   блика ae12Sheen. Любое объявление color или -webkit-text-fill-color с
   этим же весом, но ниже по файлу, погасило бы и заливку, и блик. Меняем
   только кегль, трекинг и интерлиньяж - ровно то, что нужно связке. */
.logo--skr .logo__text{
  font-size:12.5px;
  letter-spacing:.012em;
  line-height:1.15;           /* было наследуемые 1.72 - 26.7px пустоты в связке */
}

/* 🔴 ПОРОГ 1199px ВЗЯТ НЕ С ПОТОЛКА, А ИЗ mobile.css СТРОКА 369: именно там
   у .logo появляется padding:4px 0, то есть связка становится на 8px выше.
   Поставь я привычные 640px - в промежутке 641...1199px знак остался бы
   крупным поверх этих 8px, и шапка вышла бы 83.5px при пороге 88px. Запас
   в 4.5px до накрытия якорных заголовков - это не запас. */
@media (max-width:1199px){
  .logo--skr .ico--skr{ width:62px; height:26.2px; }
  .logo--skr .logo__text{ font-size:11.5px; }
}
/* ═══ ЗОНА 16 - КОНЕЦ ═══ */

/* =========================================================================
   ЗОНА 17 - ЖИВЫЕ СТАТУСЫ И ХОД ЧАСОВ (08.09.2026)

   ЗАДАЧА СЛОВАМИ ВЛАДЕЛЬЦА: «кнопка зелёная, то, что новая заявка. Сделай
   её какой-нибудь анимированной, а не простой. <...> Так же, как и жёлтую,
   и красную кнопки, где заявка в работе, или где отказ. <...> Там часики,
   они не анимированные».

   🔴 ЧЕСТНАЯ ГРАНИЦА. Карточки заявок («🟢 НОВАЯ ЗАЯВКА #», «🕒 16:43 МСК»)
   на этом сайте НЕ ЖИВУТ. Это сообщения телеграм-бота, файл
   supabase/functions/exchange-bot-webhook/index.ts, строки 1096, 1101 и
   1604. Здесь я их не рисую и не подделываю.
   Что на сайте ЕСТЬ и что оживлено этой зоной - индикаторы статуса точек
   выдачи в блоке городов (.geo__status) и циферблат «Курс» в левой панели.

   ПОЧЕМУ ИНДИКАТОР «ЖИВАЯ ТОЧКА» ГОЛУБОЙ, А НЕ ЗЕЛЁНЫЙ. Владелец просил
   зелёный - но зелёного в палитре сайта нет вовсе, акцент один: #4FC4E9.
   Зелёная точка рядом с голубой полосой была бы третьим цветом на пустом
   месте. Оживлена та краска, что уже стоит.

   ПОЧЕМУ ДЫШИТ ОРЕОЛ, А НЕ САМА ТОЧКА. Точка 8px. Масштаб такой точки даже
   на 1.15 гуляет по пиксельной сетке: край то попадает в пиксель, то нет,
   и вместо пульсации виден дребезг. Поэтому сама точка стоит намертво, а
   дышит отдельный ореол под ней - он размытый, сетки не замечает.
   ------------------------------------------------------------------------- */

/* --- ЗЕЛЁНЫЙ/АКЦЕНТНЫЙ «НОВАЯ, ЖИВАЯ»: лёгкая пульсация ореола ---
   3.4s: полный вдох-выдох дольше трёх секунд читается как дыхание, короче -
   как мигание индикатора неисправности. */
@keyframes aeStatusHalo{
  0%,100%{ transform:scale(.72); opacity:.30; }
  50%    { transform:scale(1.26); opacity:.85; }
}
.geo__status--live i{ position:relative; }
.geo__status--live i::after{
  content:""; position:absolute; inset:-4px; border-radius:50%;
  background:radial-gradient(circle, rgba(79,196,233,.55), rgba(79,196,233,0) 70%);
  animation:aeStatusHalo 3.4s ease-in-out infinite;
  pointer-events:none;
}

/* --- ЖЁЛТЫЙ «В РАБОТЕ, ЖДЁТ»: медленное дыхание, 4.6s ---
   Ожидание обязано быть медленнее готовности, иначе жёлтый перетягивает
   внимание с рабочего статуса. Диапазон 1 -> .55, не до нуля: статус,
   который пропадает, читается как сбой отрисовки. */
@keyframes aeStatusBreath{
  0%,100%{ opacity:1; }
  50%    { opacity:.55; }
}
.geo__status--soon i{ animation:aeStatusBreath 4.6s ease-in-out infinite; }

/* --- КРАСНЫЙ «ОТКАЗ»: почти статичен ---
   Отказ - конечное состояние, ему двигаться незачем; едва заметное 1 -> .8
   за 6s оставлено только чтобы точка не выглядела выключенной.
   Ни одна карточка городов сейчас класс --off не носит: правило стоит про
   запас, чтобы красный статус при появлении не выпал из общей системы. */
@keyframes aeStatusFaint{
  0%,100%{ opacity:1; }
  50%    { opacity:.80; }
}
.geo__status--off i{ animation:aeStatusFaint 6s ease-in-out infinite; }

/* --- СЕРЫЙ «ПО ЗАПРОСУ»: движения нет вовсе.
   Это не забывчивость. Если задвигаются все четыре статуса, разницы между
   ними снова не будет - а разница и есть смысл индикатора. --- */

/* --- ЧАСЫ: плавный ход ---
   Стрелки в символе #i-clock нарисованы одним path с изломом в точке
   (12,12) - это центр viewBox 24x24, то есть ровно 50% 50% элемента.
   Крутится весь значок: циферблат у него - окружность, при повороте она
   неотличима от себя же, видно только ход стрелок.
   90s на оборот: за три секунды взгляда стрелка проходит 12 градусов -
   заметно, если смотреть, и не мельтешит, если не смотреть. */
@keyframes aeClockSweep{
  from{ transform:rotate(0deg); }
  to  { transform:rotate(360deg); }
}
.qcard__ico .ico--clock{
  transform-origin:50% 50%;
  animation:aeClockSweep 90s linear infinite;
}

/* --- УВАЖЕНИЕ К ОТКЛЮЧЁННОМУ ДВИЖЕНИЮ ---
   Гасим движение, а не сами индикаторы: точки и стрелки обязаны остаться
   на экране, статус - это содержимое, а не эффект. */
@media (prefers-reduced-motion:reduce){
  .geo__status--live i::after,
  .geo__status--soon i,
  .geo__status--off i,
  .qcard__ico .ico--clock{
    animation:none;
  }
  .geo__status--live i::after{ transform:scale(1); opacity:.5; }
  .geo__status--soon i,
  .geo__status--off i{ opacity:1; }
}
/* ═══ ЗОНА 17 - КОНЕЦ ═══ */
