/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   LANDING.CSS — стили девяти страниц Vantage. Подключается ТОЛЬКО на лендинге (App.razor).

   ⚠ ТОКЕНЫ ЖИВУТ ЗДЕСЬ, app.css НЕ ТРОГАЕМ (решение Emil). Часть значений дублирует литералы
     экрана логина. Это ПРИНЯТЫЙ ХВОСТ, а не недосмотр: поднять девять переменных в app.css
     значит тронуть стили 31 страницы, при этом сам логин остался бы на литералах — токены
     объявлены и не используются. Половина рефакторинга хуже его отсутствия.

   ⚠ ПРАВИЛО TEAL — ОДНО НА ВСЕ ДЕВЯТЬ СТРАНИЦ (утверждено Emil 18.08):
       ЗАЛИВКА  --teal-soft  = СТАТУС   (утверждение про элемент)
       ГРАДИЕНТ 135deg       = ДЕЙСТВИЕ (призыв нажать)
     Проверочный вопрос: заливка что-то УТВЕРЖДАЕТ про элемент или ЗОВЁТ нажать?
     Если второе — это кнопка, и у неё градиент.
     Законные заливки: .mod.base («входит всегда»), .src (чипы источников),
     .build-col.on («наш вариант» в сравнении двух), .cap-ic/.branch-ic/.axis-ic (иконки).

   ⚠ ФИЗИЧЕСКИХ left/right НЕТ НИ ОДНОГО — только логические свойства: страницы идут
     и в RTL (he), и в LTR (en, ru), и зеркалиться должны сами.

   ⚠ ШКАЛА ТИПОГРАФИКИ — СЕМЬ СТУПЕНЕЙ. Ничего мимо --fs-*.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  /* из живого app.css, дословно */
  /* ⚠⚠ ЧЕТЫРЕ ТОКЕНА ПОДНЯТЫ ДО КОНТРАСТА AA (правка Emil 20.08 — подпись в подвале терялась
     на фоне). Замерено на --bg #f7f8fa, норма WCAG AA для мелкого текста 4.5:1:
       --sub         #8a8ea3 → #6b6f8a   3.05 → 4.63   (12 правил, почти весь мелкий текст)
       --muted       #6b6f8a → #5f6480   4.63 → 5.46   (сдвинут на ступень, чтобы не слиться с sub)
       --teal-dk     #17898c → #137276   3.96 → 5.35   (18 правил: метки секций, ссылки, чипы)
       --placeholder #b8bccd → #8a8ea3   1.83 → 3.14   (плейсхолдер полей ввода)
     ⚠ --teal НЕ ТРОНУТ: он нигде не цвет текста, только border-color и фон — требования
       контраста к нему не предъявляются, а сдвиг испортил бы фирменный цвет ни за чем.
     ⚠ Про «Google забанит»: банят СКРЫТЫЙ текст (цвет в цвет с фоном, off-screen, display:none)
       под набивку ключевыми словами. Здесь текст видимый, просто плохо читаемый — домену
       ничего не грозило. Чинить всё равно надо: это провал доступности и минус в Lighthouse,
       а он уже влияет на оценку страницы. */
  --navy:#161848; --navy-lt:#383a63; --navy-soft:#ececf0;
  --teal:#1ca2a5; --teal-dk:#137276; --teal-soft:#dcf1f1;
  --ink:#161848; --muted:#5f6480; --line:#e4e5ec; --bg:#f7f8fa; --panel:#fff;
  --heebo:"Heebo","Segoe UI","Arial","Rubik",sans-serif;

  /* литералы экрана логина, поднятые в токены */
  --brand-deep:#141640; --teal-glow:#54d6d9; --sub:#6b6f8a;
  --field-line:#e6e8f0; --field-bg:#fbfbfe; --brand-p:#b9bde0;
  --label:#3a3d5c; --placeholder:#8a8ea3;

  /* текст на тёмном: три ступени вместо шести случайных */
  --on-navy-1:#dfe2f5; --on-navy-2:#aeb4e0; --on-navy-3:#9098c9;
  --teal-ink:#17575a;

  --fs-1:44px; --fs-2:30px; --fs-3:20px; --fs-4:17px;
  --fs-5:15px; --fs-6:13px; --fs-7:11.5px;

  --r:11px;
  --shadow-cta:0 8px 20px rgba(28,162,165,.26);
  --shadow-cta-hi:0 12px 26px rgba(28,162,165,.34);
  --focus:0 0 0 4px rgba(28,162,165,.14);
  --hair:rgba(255,255,255,.10);
}
@media (max-width:980px){
  :root{ --fs-1:31px; --fs-2:24px; --fs-3:18px; --fs-4:16px; }
}

/* ⚠⚠ БЕЗ ЭТОЙ СТРОКИ ПОЛЯ ФОРМЫ ВЫЛЕЗАЛИ ЗА КАРТОЧКУ. Измерено на живой странице:
   карточка 470px, паддинг 30+30, содержимое 410 — заголовок, подпись, кнопка и примечание
   ровно 410, а input и textarea 442, то есть на 32px шире и на 2px за краем карточки.
   Причина: у <button> браузер сам ставит border-box, а у input/textarea — content-box,
   и width:100% складывается с паддингом 15+15 и рамкой 1.5+1.5.
   ⚠ Правило ГЛОБАЛЬНОЕ, а не на два селектора: следующий элемент с width и паддингом
   наступил бы на те же грабли, и заметили бы это опять по фотографии, а не по коду. */
*,*::before,*::after{box-sizing:border-box}

/* ⚠ И ТОТ ЖЕ ПРИЁМ ДЛЯ ССЫЛОК — механизмом, а не по одной. У <a> собственный цвет
   в таблице браузера, поэтому цвет, объявленный на родителе, до него НЕ доходит:
   так подвал и карточки развилки оказались браузерно-синими при живом --muted рядом.
   Базовое «наследуй» снимает весь класс ошибки; ссылке, которой нужен свой цвет,
   он задаётся явно ниже. landing.css грузится только на девяти страницах — за их
   пределы это правило не выходит. */
a{color:inherit;text-decoration:none}

body{font-family:var(--heebo);background:var(--panel);color:var(--ink);
     font-size:var(--fs-5);line-height:1.7;-webkit-font-smoothing:antialiased;margin:0}
.wrap{max-width:1120px;margin:0 auto;padding-inline:40px}
/* ⚠⚠ .narrow БОЛЬШЕ НЕ ПРИМЕНЯЕТСЯ НА ЛЕНДИНГЕ (разбор Emil 20.08: «блоки идут один за другим
   разной ширины — не ровно, не симметрично и очень бросается в глаза»). Он был прав, и вот
   в чём была ошибка.
   .wrap центрируется (margin:0 auto). Значит .narrow сдвигал ОБА края внутрь на 120px —
   вместе с заголовком и меткой секции. Читатель видел, как вся колонка прыгает туда-сюда
   по странице: def(880) → logos(1120) → … → demo(880) → diff(1120) → faq(880).
   ⚠ Ограничение длины строки при этом НУЖНО и никуда не делось — оно просто переехало
   с КОНТЕЙНЕРА на ТЕКСТ и задаётся в ch (.sec-p 62ch, .def 74ch, .faq 76ch, пузыри чата).
   Так делают и остальные двенадцать секций, и там никогда не было претензий: кромка чтения
   у всех одна, а короче меры оказывается только сам абзац — это обычная типографика,
   а не сбитое поле.
   Правило одной фразой: КОНТЕЙНЕР У ВСЕХ ОДИН, УЗКИМ БЫВАЕТ ТОЛЬКО ТЕКСТ, И ВЫРАВНЕН ОН
   ПО НАЧАЛУ СТРОКИ ЧТЕНИЯ, А НЕ ПО ЦЕНТРУ.
   Класс оставлен ради VantageThanks — отдельной странице результата, у которой соседей нет. */
.narrow{max-width:880px}

/* ─── Шапка ──────────────────────────────────────────────────────────────────────────────── */
.top{position:relative;z-index:3;display:flex;align-items:center;justify-content:space-between;
     padding-block:18px;gap:20px}
/* ⚠ ЛОК-АП, А НЕ ДВА СЛОВА РЯДОМ. Имя «Vantage» в B2B SaaS занято (Vantage.sh, Vantage
   Circle, VantageScore, Vantage Data Centers), поэтому продукт нигде не называется одним
   словом: сущность — «SLAtech Vantage». В шапке первую половину имени несёт логотип,
   вторую — марка, и между ними стоит волосяная линия: она читается как связка внутри
   одного знака, а не как подпись рядом с картинкой. Отступы вокруг линии разные
   намеренно (6px до неё, 9px после) — оптическая, а не арифметическая центровка. */
.top-logo{display:flex;align-items:center;gap:0;text-decoration:none}
/* ⚠⚠ ЛОГОТИП ПЕРЕКРАШИВАЕТСЯ В БЕЛЫЙ ФИЛЬТРОМ. В /logo.png слово «SLA» набрано цветом
   --navy (#161848), а шапка лендинга стоит на --brand-deep (#141640) — почти том же самом.
   На проде было видно только бирюзовое «tech», а половина знака проваливалась в фон.
   brightness(0) валит все каналы в чёрный (включая бирюзовую половину), invert(1) делает
   его белым: знак становится одноцветным и читается целиком.
   ⚠ Второго файла (logo-white.png) не заводим намеренно — два файла одного знака
   расходятся при первой же смене логотипа, и заметно это будет только на тёмном фоне. */
.top-logo img{height:28px;width:auto;display:block;margin-inline-end:12px;
              filter:brightness(0) invert(1)}
.top-logo .mark{position:relative;padding-inline-start:15px;
  font-size:var(--fs-6);font-weight:700;letter-spacing:.16em;color:var(--teal-glow)}
.top-logo .mark::before{content:"";position:absolute;inset-inline-start:0;top:50%;
  transform:translateY(-50%);width:1px;height:15px;background:rgba(255,255,255,.26)}
.top-nav{display:flex;align-items:center;gap:8px;font-size:var(--fs-6);font-weight:600}
/* ⚠ min-height:24px — та же норма WCAG 2.2 (2.5.8), что и у ссылок подвала: крошка
   «на главную» стоит отдельным пунктом шапки, а не внутри предложения. */
.crumb{font-size:var(--fs-6);font-weight:600;color:var(--on-navy-2);padding-inline-end:6px;
       min-height:24px;display:inline-flex;align-items:center;text-decoration:none}
.crumb:hover{color:#fff}
/* ⚠ Стрелка у «на главную» УБРАНА (решение Emil: стрелок в интерфейсе минимум, только там,
   где без них нельзя). Слово уже говорит направление, стрелка его лишь повторяла.
   Механизм зеркалирования, если стрелка когда-нибудь вернётся, — в истории этого файла:
   content задаётся от dir документа, а не пишется в текст. */
/* ⚠ Активный язык опознаётся ПО aria-current, а не по служебному классу. Так состояние
   объявлено один раз и для глаза, и для скринридера: рассинхронизировать их нечем.
   Прежняя подсветка (заливка .16 на тёмном) была почти неразличима — на трёхъязычном
   сайте это первое, что замечают. Теперь активный язык несёт и заливку, и цвет,
   и подчёркивающую линию снизу. */
.lang{display:flex;border:1px solid rgba(255,255,255,.18);border-radius:9px;overflow:hidden}
.lang a{position:relative;padding:6px 12px;color:var(--brand-p);font-size:var(--fs-7);font-weight:700;
        letter-spacing:.04em;text-decoration:none;transition:background .15s,color .15s}
.lang a[aria-current]{background:rgba(84,214,217,.28);color:#fff}
.lang a[aria-current]::after{content:"";position:absolute;inset-inline:6px;bottom:3px;height:2px;
        border-radius:2px;background:var(--teal-glow)}
.lang a:hover{color:#fff}
.top-login{padding:8px 16px;border:1px solid rgba(255,255,255,.22);border-radius:9px;
           color:var(--on-navy-1);text-decoration:none;transition:border-color .15s,color .15s}
.top-login:hover{border-color:var(--teal-glow);color:#fff}

/* ─── Герой ──────────────────────────────────────────────────────────────────────────────── */
.hero{position:relative;overflow:hidden;background:var(--brand-deep);color:#fff}
.hero::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:46px 46px;
  -webkit-mask-image:linear-gradient(120deg,#000,transparent 70%);
          mask-image:linear-gradient(120deg,#000,transparent 70%);}
/* ⚠ логическое свойство: в LTR полоса переезжает сама */
.hero-bar{position:absolute;top:0;inset-inline-start:0;width:5px;height:100%;background:var(--teal)}
.hero-in{position:relative;z-index:2;padding-block:28px 0}
.eyebrow{font-size:var(--fs-6);font-weight:700;letter-spacing:.2em;color:var(--teal-glow);
         margin-bottom:14px}
.hero-in h1,.hero-in .hero-h{font-size:var(--fs-1);font-weight:700;line-height:1.16;margin:0 0 16px;
   letter-spacing:-.018em;text-wrap:balance}
.rule{width:54px;height:3px;background:var(--teal);border-radius:2px;margin-bottom:18px}
.hero-p{font-size:var(--fs-4);line-height:1.6;color:var(--brand-p);margin:0 0 24px;max-width:56ch;text-wrap:balance}
.cta-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.cta{display:inline-flex;align-items:center;gap:10px;padding:13px 26px;border-radius:var(--r);
  font-size:var(--fs-5);font-weight:700;color:#fff;text-decoration:none;
  background:linear-gradient(135deg,var(--teal),var(--teal-dk));box-shadow:var(--shadow-cta);
  transition:transform .12s,box-shadow .12s}
.cta:hover{transform:translateY(-1px);box-shadow:var(--shadow-cta-hi)}
.cta svg{width:15px;height:15px;flex:none}
/* ⚠ на мобильном НЕ прячем: обещание «три поля» там нужнее всего */
.cta-side{display:inline-flex;align-items:center;gap:8px;font-size:var(--fs-6);
          font-weight:600;color:var(--on-navy-2)}
.cta-side svg{width:14px;height:14px;color:var(--teal-glow);flex:none}

/* оси в герое (хаб) — компактные, НЕ заголовки */
.axes{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:24px}
.axis{padding:16px 18px;border-radius:14px;background:rgba(255,255,255,.045);
      border:1px solid var(--hair);transition:background .18s,border-color .18s,transform .18s}
.axis:hover{background:rgba(255,255,255,.075);border-color:rgba(84,214,217,.42);transform:translateY(-2px)}
.axis-top{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.axis-ic{width:30px;height:30px;border-radius:9px;background:rgba(84,214,217,.14);
  display:flex;align-items:center;justify-content:center;flex:none}
.axis-ic svg{width:16px;height:16px;color:var(--teal-glow)}
.axis-name{font-size:var(--fs-3);font-weight:700;line-height:1.2}
.axis p{font-size:var(--fs-6);color:var(--on-navy-2);margin:0;line-height:1.55}

/* ─── Доказательства ─────────────────────────────────────────────────────────────────────── */
.proof{position:relative;z-index:2;display:grid;grid-template-columns:auto 1fr 1fr;
  gap:1px;margin-top:24px;background:var(--hair);border-block:1px solid var(--hair)}
/* studios — три утверждения без числа-акцента, значит равные колонки */
.proof.even{grid-template-columns:repeat(3,1fr)}
.proof > div{background:var(--brand-deep);padding:15px 26px;display:flex;
  flex-direction:column;justify-content:center}
.proof .n{font-size:var(--fs-2);font-weight:700;line-height:1.05;color:#fff;letter-spacing:-.02em}
.proof .l{font-size:var(--fs-7);color:var(--on-navy-3);margin-top:6px;letter-spacing:.02em}
/* ⚠ Тезис и механизм — БЛОКИ, а не строка с выделением внутри. Тезис читается первым и один,
   механизм отвечает на «почему это правда». В строку они снова слились бы в абзац — ровно то,
   от чего уходили: три абзаца в три колонки читаются как заполнитель, а не как довод.
   ⚠ .claim b здесь по-прежнему нужен: форма studios приходит одной строкой с <b> из ресурса. */
.proof .claim{font-size:var(--fs-6);color:var(--on-navy-1);line-height:1.6;font-weight:600;
              display:flex;flex-direction:column;gap:5px}
.proof .claim b{color:#fff;font-weight:700}
.proof .claim-t{font-size:var(--fs-5);font-weight:700;color:#fff;line-height:1.3;
                letter-spacing:-.01em}
.proof .claim-d{font-size:var(--fs-7);font-weight:400;color:var(--on-navy-2);line-height:1.55}

/* ⚠ Доводы hub/clients — те же карточки .axis, что у осей (разметка в ProofSection).
   Здесь ТОЛЬКО отступы: вид карточки описан один раз, выше, и второго описания у неё нет.
   Полоса с волосяными линиями осталась ветке agencies — там довод одной фразой,
   заголовка у него нет, и карточка была бы пустой сверху. */
.proof-axes{margin-top:22px;margin-bottom:34px}
/* На экране входа отступ уже задан обёрткой .signin-proof — второй не нужен. */
.signin-proof .proof-axes{margin-top:0;margin-bottom:0}

/* ─── Секции ─────────────────────────────────────────────────────────────────────────────── */
section{padding-block:70px}
section.alt{background:var(--bg);border-block:1px solid var(--line)}
.sec-label{font-size:var(--fs-6);font-weight:700;letter-spacing:.18em;color:var(--teal-dk);
           margin-bottom:10px}
/* ⚠⚠ text-wrap:balance — ОТВЕТ НА «ЗАЧЕМ 62ch» (вопрос Emil 20.08), а не отмена ограничения.
   Ограничение по мере нужно и остаётся: строка длиннее ~75 знаков читается плохо, глаз
   теряет начало следующей. Некрасив был не сам предел, а РАЗБИЕНИЕ по нему: лид из двух
   строк выходил «длинная + короткий хвост» («...נבנה כדי שלא / תצטרכו לקבל אף אחת מהן»).
   balance просит браузер разложить строки поровну — перенос садится по смыслу фразы,
   а не по случайному месту, где кончилась мера. Работает до ~6 строк, то есть ровно
   на заголовках и лидах; в старом браузере просто игнорируется и всё как было. */
.sec-h{font-size:var(--fs-2);font-weight:700;margin:0 0 10px;letter-spacing:-.01em;line-height:1.3;
       text-wrap:balance}
.sec-p{font-size:var(--fs-5);color:var(--sub);margin:0 0 34px;max-width:62ch;line-height:1.7;
       text-wrap:balance}

/* развилка (только хаб) */
.fork{padding-block:34px 76px}
.fork-grid{display:grid;grid-template-columns:1fr 1fr;gap:26px}
/* ⚠ color ОБЯЗАТЕЛЕН: карточка — это <a>, и без него заголовок внутри наследовал
   браузерный синий (измерено: rgb(0,0,238)). Карточка-ссылка выглядела как
   несверстанный список ссылок из девяностых. */
.branch{position:relative;display:flex;flex-direction:column;background:var(--panel);
  border:1.5px solid var(--field-line);border-radius:18px;padding:24px 28px 24px;
  color:var(--ink);
  text-decoration:none;transition:border-color .18s,box-shadow .18s,transform .18s}
.branch:hover{border-color:var(--teal);box-shadow:0 14px 34px rgba(22,24,72,.09);transform:translateY(-2px)}
.branch-ic{width:38px;height:38px;border-radius:11px;background:var(--teal-soft);
  display:flex;align-items:center;justify-content:center;margin-bottom:13px}
.branch-ic svg{width:21px;height:21px;color:var(--teal-dk)}
.branch h3{font-size:var(--fs-3);font-weight:700;margin:0 0 6px;letter-spacing:-.01em}
/* ⚠ Списков в карточках развилки НЕТ намеренно: три буллета превращали перекрёсток
   в мини-лендинг и дублировали страницу ветки, до которой один клик. */
.branch-lead{font-size:var(--fs-5);color:var(--muted);margin:0 0 22px;line-height:1.6;flex:1}
.branch-go{display:inline-flex;align-items:center;gap:9px;align-self:flex-start;
  padding:12px 24px;border-radius:var(--r);font-size:var(--fs-5);font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--teal),var(--teal-dk));box-shadow:var(--shadow-cta);
  transition:transform .12s,box-shadow .12s}
.branch-go:hover{transform:translateY(-1px);box-shadow:var(--shadow-cta-hi)}
.branch-go svg{width:15px;height:15px;flex:none}

/* боли */
.pains{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.pain{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:26px 24px}
/* ⚠ КАВЫЧКИ ЗАДАЁТ CSS, А НЕ ТЕКСТ. В json реплика лежит голой («Мы этим занимаемся» →
   «Мы этим занимаемся» без обрамления), а пару подставляет `quotes` по языку документа.
   Иначе обрамление приходится дублировать в трёх файлах и оно неизбежно расходится:
   так в английском оказались ёлочки («just trust us»), которых в английском не бывает,
   а в иврите — тоже ёлочки вместо принятых там прямых. Правило `quotes:none`,
   стоявшее здесь раньше, глушило механизм целиком вместо того, чтобы им пользоваться. */
.pain q{display:block;font-size:var(--fs-4);font-weight:600;line-height:1.6;margin-bottom:10px;
        quotes:"\201C" "\201D" "\2018" "\2019"}
:lang(ru) .pain q{quotes:"\00AB" "\00BB" "\201E" "\201C"}
:lang(he) .pain q{quotes:"\0022" "\0022" "\0027" "\0027"}
.pain p{font-size:var(--fs-6);color:var(--muted);margin:0;line-height:1.65}

/* три оси крупно (clients) — отдельный класс, чтобы не конфликтовать с осями героя */
.axes-lg{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;margin-top:34px}
.axis-lg{padding:28px 26px 26px;border:1.5px solid var(--field-line);border-radius:18px;
         background:var(--panel);transition:border-color .18s,box-shadow .18s}
.axis-lg:hover{border-color:var(--teal);box-shadow:0 12px 30px rgba(22,24,72,.07)}
.axis-lg .axis-ic{width:42px;height:42px;border-radius:12px;background:var(--teal-soft);margin-bottom:16px}
.axis-lg .axis-ic svg{width:20px;height:20px;color:var(--teal-dk)}
.axis-lg h3{font-size:var(--fs-3);font-weight:700;margin:0 0 8px}
.axis-lg p{font-size:var(--fs-5);color:var(--muted);margin:0;line-height:1.7}

/* шесть возможностей (studios) */
.caps{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:32px}
.cap{position:relative;padding:26px 24px 24px;border:1.5px solid var(--field-line);
     border-radius:18px;background:var(--panel);transition:border-color .18s,box-shadow .18s}
.cap:hover{border-color:var(--teal);box-shadow:0 12px 30px rgba(22,24,72,.07)}
.cap-ic{width:40px;height:40px;border-radius:11px;background:var(--teal-soft);
  display:flex;align-items:center;justify-content:center;margin-bottom:15px}
.cap-ic svg{width:19px;height:19px;color:var(--teal-dk)}
.cap h3{font-size:var(--fs-4);font-weight:700;margin:0 0 7px}
.cap p{font-size:var(--fs-6);color:var(--muted);margin:0;line-height:1.65}
/* ⚠ ОФОРМЛЕНИЯ «НАПРАВЛЕНИЕ» (.cap.direction — пунктир, контурная иконка, приглушённый
   текст) ЗДЕСЬ БОЛЬШЕ НЕТ: решением Emil 19.08 плитка «оценка и предложение» показывается
   как остальные. Правила удалены, а не оставлены мёртвыми — CSS без разметки, которая его
   вызывает, читается следующим как «где-то это ещё используется». Понадобится вернуть —
   стоит в истории этого файла. */

/* повторный CTA */
.midcta{display:flex;align-items:center;justify-content:space-between;gap:26px;flex-wrap:wrap;
  margin-top:42px;padding:24px 28px;border-radius:18px;
  background:var(--teal-soft);border:1px solid rgba(28,162,165,.28)}
.midcta p{margin:0;font-size:var(--fs-4);font-weight:600;color:var(--teal-ink);line-height:1.5}

/* демо-диалог */
.demo{border:1.5px solid var(--field-line);border-radius:20px;background:var(--panel);
      overflow:hidden;margin-top:30px}
.demo-bar{display:flex;align-items:center;gap:10px;padding:13px 20px;background:var(--navy);color:#fff}
.demo-bar .dot{width:9px;height:9px;border-radius:50%;background:var(--teal-glow);flex:none}
.demo-bar .t{font-size:var(--fs-6);font-weight:700;letter-spacing:.02em}
.demo-bar .tag{margin-inline-start:auto;font-size:var(--fs-7);font-weight:700;letter-spacing:.1em;
  color:var(--on-navy-3);border:1px solid rgba(255,255,255,.16);border-radius:6px;padding:3px 9px}
.chat{padding:24px 22px 22px;display:flex;flex-direction:column;gap:13px}
/* ⚠ Мера пузыря — в ch, а не в процентах от карточки. Карточка расширилась до общих 1120
   (см. .narrow), и 84% от неё дали бы строку почти в тысячу пикселей: такую не читают,
   её сканируют. Процент оставлен вторым ограничителем — на узком экране он строже. */
.bubble{padding:14px 18px;border-radius:16px;font-size:var(--fs-5);line-height:1.65;
        max-width:min(62ch,84%)}
.bubble.q{align-self:flex-start;background:var(--navy);color:#fff;border-end-start-radius:5px;
          max-width:min(52ch,70%)}
.bubble.a{align-self:flex-end;background:var(--bg);border:1px solid var(--line);
          border-end-end-radius:5px;color:var(--ink)}
.bubble.a b{font-weight:700}
.srcs{display:flex;flex-wrap:wrap;gap:7px;margin-top:11px;padding-top:11px;border-top:1px solid var(--line)}
.srcs:empty{display:none;margin:0;padding:0;border:0}
.src{font-size:var(--fs-7);font-weight:600;color:var(--teal-dk);background:var(--teal-soft);
     border-radius:6px;padding:3px 9px}
.demo-foot{padding:14px 22px 18px;border-top:1px solid var(--line);
  font-size:var(--fs-6);color:var(--muted);line-height:1.65}

/* «чем это отличается» (clients) */
.claims{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:30px}
.claim-card{position:relative;padding:24px 26px 22px;border:1px solid var(--line);
            border-radius:16px;background:var(--panel)}
.claim-card::before{content:"";position:absolute;top:24px;inset-inline-start:0;width:3px;height:24px;
  background:var(--teal);border-radius:0 2px 2px 0}
.claim-card h3{font-size:var(--fs-4);font-weight:700;margin:0 0 7px;padding-inline-start:18px}
.claim-card p{font-size:var(--fs-5);color:var(--muted);margin:0;padding-inline-start:18px;line-height:1.7}

/* «почему не строить самим» (studios) */
.build{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:30px}
.build-col{border:1px solid var(--line);border-radius:18px;padding:26px 26px 24px;background:var(--panel)}
/* ⚠ Заливка ЗАКОННА: помечает «наш вариант» в сравнении двух — утверждение, не призыв. */
.build-col.on{border-color:var(--teal);background:var(--teal-soft)}
.build-col h3{font-size:var(--fs-4);font-weight:700;margin:0 0 14px}
.build-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.build-col li{position:relative;padding-inline-start:24px;font-size:var(--fs-5);
              color:var(--muted);line-height:1.6}
.build-col li::before{content:"";position:absolute;inset-inline-start:0;top:8px;width:8px;height:8px;
  border-radius:50%;background:var(--line)}
.build-col.on li{color:var(--teal-ink)}
.build-col.on li::before{background:var(--teal)}

/* ⚠ «Состав и цена» ВМЕСТО ЯРУСОВ: ярусов нет, конфигурация индивидуальная.
   Три яруса без цен читаются как «цену скрыли» — хуже, чем сказать «собирается под проект».
   ⚠ Каталог на ВСЮ ширину, факторы цены — блоком под ним. Двухколоночная раскладка жила,
   пока плиток было десять: семь групп вчетверо выше соседней колонки, и рядом с ними
   справа висела бы пустота на пол-экрана. Порядок «состав → цена» сохранён. */
.compose-h{font-size:var(--fs-3);font-weight:700;margin:32px 0 6px}
.compose-sub{font-size:var(--fs-6);color:var(--muted);margin:0 0 18px;line-height:1.6}

/* ⚠ ПОЛОСА БАЗОВЫХ — отдельное сообщение «эти три получаете всегда», НАД группами.
   Внутри групп метка разъезжалась: первая бирюзовая плитка встречалась в группе 5 из 7,
   а «портал клиента» вообще лежал за строкой «и ещё N». Заливка = СТАТУС, и подзаголовок
   прямо над полосой объясняет её словами («первые три входят в любой состав»). */
.base-strip{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:18px}
.base-label{font-size:var(--fs-7);font-weight:700;letter-spacing:.08em;color:var(--teal-dk)}

/* Семь групп: карточки в резиновой сетке. */
.mods-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:16px}
.mgroup{border:1.5px solid var(--field-line);border-radius:16px;padding:18px 18px 14px;
        background:var(--panel)}
/* Иконка группы: та же плашка, что у карточек развилки и осей — один язык на всех страницах. */
.mgroup-ic{width:34px;height:34px;border-radius:10px;background:var(--teal-soft);
  display:flex;align-items:center;justify-content:center;margin-bottom:12px}
.mgroup-ic svg{width:19px;height:19px;color:var(--teal-dk)}
/* ⚠ Группа стала <details>, и её шапка — <summary>. На широком экране она НЕ должна выглядеть
   нажимаемой: там группы всегда раскрыты, и курсор-палец обещал бы действие, которого нет.
   Стрелка и cursor:pointer появляются только на узком экране, где скрипт включает аккордеон. */
.mgroup > summary{list-style:none;display:block;cursor:default}
.mgroup > summary::-webkit-details-marker{display:none}
.mgroup h4{margin:0 0 12px;font-size:var(--fs-5);font-weight:700;line-height:1.35}
.mgroup ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.mgroup li{font-size:var(--fs-6);color:var(--ink);display:flex;align-items:center;gap:8px;line-height:1.4}
.mgroup li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--teal);flex:none}
.mgroup .more{margin-top:11px;font-size:var(--fs-7);color:var(--sub)}

.mod{display:inline-flex;align-items:center;gap:8px;font-size:var(--fs-6);font-weight:600;
     color:var(--ink);background:var(--bg);border:1px solid var(--line);border-radius:10px;padding:9px 13px}
.mod svg{width:14px;height:14px;color:var(--teal-dk);flex:none}
/* ⚠ Заливка ЗАКОННА: «входит всегда» — статус элемента. */
.mod.base{background:var(--teal-soft);border-color:rgba(28,162,165,.32);color:var(--teal-ink)}
.mods-note{margin-top:16px;font-size:var(--fs-7);color:var(--sub);line-height:1.6}

/* Факторы цены — блок под каталогом, отделён линией. */
.factors-block{border-top:1px solid var(--line);margin-top:30px;padding-top:26px}
.factors-block h3{font-size:var(--fs-3);font-weight:700;margin:0 0 6px}
.factors-block .sub{font-size:var(--fs-6);color:var(--muted);margin:0 0 18px;line-height:1.6}
/* В полную ширину факторы стоят сеткой, а не столбиком: столбик на 1120px — четыре
   коротких строки с пустотой справа. */
.factors-block .factors{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px}
/* ⚠ .mod-soon (пунктирная строка «дорожная карта» под каталогом) удалён вместе с ключом
   studios.compose.soon.text — см. пояснение в ComposeSection. */
.factors{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px;counter-reset:f}
.factors li{position:relative;padding-inline-start:34px;font-size:var(--fs-5);
            color:var(--muted);line-height:1.6}
.factors li b{display:block;font-weight:700;color:var(--ink)}
.factors li::before{content:counter(f);counter-increment:f;position:absolute;inset-inline-start:0;top:1px;
  width:23px;height:23px;border-radius:7px;background:var(--teal);color:#fff;
  font-size:var(--fs-7);font-weight:700;display:flex;align-items:center;justify-content:center}
.compose-foot{margin-top:22px;padding:18px 22px;border-radius:14px;background:var(--navy);color:#fff;
  font-size:var(--fs-5);line-height:1.6}
.compose-foot b{color:var(--teal-glow);font-weight:700}

/* приватность */
.privacy{display:flex;gap:18px;align-items:flex-start;margin-top:32px;padding:24px 28px;
  background:var(--panel);border:1px solid var(--line);border-radius:16px}
.privacy svg{width:21px;height:21px;color:var(--teal-dk);flex:none;margin-top:3px}
.privacy h3{font-size:var(--fs-4);font-weight:700;margin:0 0 5px}
.privacy p{font-size:var(--fs-5);color:var(--muted);margin:0;line-height:1.7;max-width:72ch}

/* ─── Форма ──────────────────────────────────────────────────────────────────────────────── */
.join{position:relative;overflow:hidden;background:var(--brand-deep);color:#fff}
.join::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:46px 46px;
  -webkit-mask-image:linear-gradient(300deg,#000,transparent 72%);
          mask-image:linear-gradient(300deg,#000,transparent 72%);}
.join-grid{position:relative;z-index:2;display:grid;grid-template-columns:1fr 470px;gap:60px;
           align-items:start;padding-block:68px}
.join-h{font-size:var(--fs-2);font-weight:700;line-height:1.3;margin:0 0 16px;text-wrap:balance}
.join-p{font-size:var(--fs-4);line-height:1.7;color:var(--brand-p);margin:0 0 24px;max-width:44ch;text-wrap:balance}
.join-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.join-list li{position:relative;padding-inline-start:26px;font-size:var(--fs-5);
              color:var(--on-navy-2);line-height:1.6}
.join-list li::before{content:"";position:absolute;inset-inline-start:0;top:7px;width:9px;height:9px;
  border-radius:3px;background:var(--teal-glow)}
.card{background:var(--panel);border-radius:20px;padding:32px 30px;box-shadow:0 22px 60px rgba(0,0,0,.28)}
.card h3{font-size:var(--fs-3);font-weight:700;margin:0 0 6px;color:var(--ink)}
.card-sub{font-size:var(--fs-6);color:var(--sub);margin:0 0 22px;line-height:1.6}
/* ⚠ ПОЛЯ ФОРМЫ. Правило собрано КОНСТРУКТИВНО, а не подгонкой чисел:
     - box-sizing:border-box приходит из глобального сброса вверху файла, поэтому
       padding и рамка входят В ширину, а не прибавляются к ней;
     - width:100% + max-width:100% - второй рубеж: даже если предок окажется уже,
       поле не вылезет за него;
     - min-width:0 - без него flex-элемент отказывается сжиматься ниже своего
       содержимого, и длинный плейсхолдер распирает карточку;
     - фиксированных width / inset у полей нет ни одного (проверено поиском);
     - padding у input и textarea ОДИН И ТОТ ЖЕ, одним объявлением: разъехаться нечему.
   ⚠ resize:vertical, а не both: горизонтальное растягивание вытаскивало ручку и само
     поле за карточку - именно это видно на присланной фотографии. */
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:15px;min-width:0}
.field label{font-size:var(--fs-6);font-weight:600;color:var(--label)}
.field input,.field textarea{display:block;width:100%;max-width:100%;min-width:0;
  padding:13px 15px;border:1.5px solid var(--field-line);
  border-radius:var(--r);font-size:var(--fs-5);font-family:inherit;background:var(--field-bg);
  color:var(--ink);transition:border-color .15s,box-shadow .15s,background .15s}
.field textarea{min-height:100px;max-height:340px;resize:vertical;line-height:1.6}
.field input::placeholder,.field textarea::placeholder{color:var(--placeholder)}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--teal);
  background:var(--panel);box-shadow:var(--focus)}
.btn{width:100%;margin-top:6px;padding:14px;border:none;border-radius:var(--r);cursor:pointer;
  font-family:inherit;font-size:var(--fs-5);font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--teal),var(--teal-dk));box-shadow:var(--shadow-cta);
  transition:transform .12s,box-shadow .12s}
.btn:hover{transform:translateY(-1px);box-shadow:var(--shadow-cta-hi)}
.card-note{display:flex;align-items:flex-start;gap:8px;margin-top:16px;
           font-size:var(--fs-7);color:var(--sub);line-height:1.55}
.card-note svg{width:15px;height:15px;color:var(--teal-dk);flex:none;margin-top:1px}

/* ─── Подвал ─────────────────────────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--line);background:var(--bg)}
/* ⚠ Приватность на хабе живёт ЗДЕСЬ: после развилки она размывала единственное действие. */
.foot-privacy{display:flex;gap:14px;align-items:flex-start;padding-block:26px 22px;
  border-bottom:1px solid var(--line)}
.foot-privacy svg{width:19px;height:19px;color:var(--teal-dk);flex:none;margin-top:2px}
.foot-privacy b{display:block;font-size:var(--fs-6);font-weight:700;margin-bottom:3px}
.foot-privacy p{font-size:var(--fs-6);color:var(--muted);margin:0;line-height:1.65;max-width:78ch}
.foot-row{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;
          padding-block:22px 34px}
/* ⚠⚠ ЦВЕТ ЗАДАЁТСЯ НА САМОЙ ССЫЛКЕ, НЕ НА ОБЁРТКЕ. У <a> в таблице браузера свой
   color (-webkit-link), и он ПОБЕЖДАЕТ наследование от родителя. Измерено на живой
   странице: ссылки подвала отдавались как rgb(0,0,238) — дефолтный синий браузера,
   при том что .foot-links честно объявлял --muted. Так и выглядели «неоформленные
   стандартные ссылки»: правило было, до ссылки оно не доходило. */
/* ─── Определение продукта ────────────────────────────────────────────────────────────────
   ⚠ Оформление намеренно сдержанное: это справка, а не продающий блок. Если сделать её
   ярче соседних секций, она перетянет внимание с того, ради чего человек пришёл. */
.def{max-width:74ch}
.def-h{font-size:var(--fs-3);font-weight:700;margin:0 0 10px;color:var(--ink)}
.def-p{font-size:var(--fs-5);line-height:1.75;color:var(--muted);margin:0}

/* ─── Страница результата отправки заявки ────────────────────────────────────────────────── */
/* ⚠ Honeypot: уводим за пределы экрана, а НЕ display:none - часть ботов узнаёт именно
   display:none и такое поле пропускает. Для человека оно недостижимо: вне вьюпорта,
   tabindex=-1, aria-hidden. */
.hp{position:absolute;inset-inline-start:-9999px;width:1px;height:1px;overflow:hidden}

.result-page{display:flex;flex-direction:column;min-height:100vh;background:var(--navy)}
.result-page > section{flex:0 0 auto;padding-block:56px 40px}
.result{display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px}
.result-ic{width:56px;height:56px;border-radius:16px;display:flex;align-items:center;justify-content:center}
.result-ic.ok{background:rgba(84,214,217,.16)}
.result-ic.warn{background:rgba(255,255,255,.08)}
.result-ic svg{width:26px;height:26px;color:var(--teal-glow)}
.result-h{font-size:var(--fs-2);font-weight:700;color:#fff;margin:0;line-height:1.25}
.result-p{font-size:var(--fs-4);color:var(--on-navy-2);margin:0;max-width:52ch;line-height:1.7;text-wrap:balance}
/* Список незаполненного: слева от текста маркер, сам список выровнен по началу строки,
   потому что читать перечисление по центру неудобно. */
.result-errs{list-style:none;margin:6px 0 0;padding:14px 18px;text-align:start;
  border:1px solid rgba(255,255,255,.14);border-radius:12px;background:rgba(255,255,255,.04);
  display:flex;flex-direction:column;gap:8px;font-size:var(--fs-6);color:var(--on-navy-1)}
.result-errs li{position:relative;padding-inline-start:18px}
.result-errs li::before{content:"";position:absolute;inset-inline-start:0;top:8px;
  width:6px;height:6px;border-radius:50%;background:var(--teal-glow)}
.result .cta{margin-top:8px}

/* Нав-строка подвала: единый кегль, приглушённый цвет, разделители между пунктами.
   ⚠ Разделитель — ::before у соседа, а не символ в разметке: тогда он не может
   остаться висеть у первого пункта и не попадает в текст, который читает скринридер. */
.foot-links{display:flex;align-items:center;flex-wrap:wrap;gap:0;
            font-size:var(--fs-6);font-weight:600;line-height:1.4}
/* ⚠ min-height:24px — норма WCAG 2.2 (2.5.8) на размер цели нажатия. Замерено на 390px:
   было 22px, то есть на два пикселя ниже. Ссылки подвала стоят отдельными пунктами,
   а не внутри фразы, поэтому исключение «inline-ссылка в тексте» к ним не относится. */
.foot-links a{color:var(--muted);text-decoration:none;padding-block:2px;padding-inline:14px;
              min-height:24px;display:inline-flex;align-items:center;
              transition:color .15s}
.foot-links a:first-child{padding-inline-start:0}
.foot-links a:last-child{padding-inline-end:0}
.foot-links a + a{position:relative}
.foot-links a + a::before{content:"";position:absolute;inset-block:3px;inset-inline-start:0;
  width:1px;background:var(--line)}
.foot-links a:hover{color:var(--teal-dk)}
/* Главный пункт подвала. ⚠ Без градиента — см. пояснение в разметке. */
.foot-links a.is-key{color:var(--ink);font-weight:700}
.foot-links a.is-key:hover{color:var(--teal-dk)}
/* ⚠⚠ ЭТО ТА САМАЯ СТРОКА, КОТОРУЮ EMIL ОБВЁЛ 20.08, и первый заход её НЕ ПОЧИНИЛ.
   Она красилась токеном --foot (#c2c6d6) и давала на подвале #f7f8fa ровно 1.60:1 —
   худший контраст на сайте при норме 4.5. Я его пропустил, потому что в аудите разложил
   токены по ИМЕНАМ: «foot» отнёс к тёмным фонам вместе с --on-navy-*, а подвал светлый.
   ⚠ УРОК: контраст проверяется по фактическим парам «цвет текста / вычисленный фон»
     на живой странице, а не по тому, как назван токен. Гадание по имени пропустило
     единственный дефект, на который и указали.
   ⚠ Токен --foot удалён, а не подкручен: ниже --sub (4.63:1) на этом фоне нет ни одного
     значения, которое проходит AA, — значит отдельная «ещё более тихая» ступень здесь
     существовать не может, и держать её значит приглашать следующий такой промах. */
.foot-c{font-size:var(--fs-7);color:var(--sub)}
/* ⚠ Марка в подвале — ссылка наружу. Цвет НАСЛЕДУЕТСЯ: у .foot-c он уже поднят до
   проходящего по AA, и свой цвет ссылке дал бы второй тон, который придётся мерить заново.
   Отличается подчёркиванием. Правило 24×24 сюда не относится — это ссылка внутри строки. */
.foot-c a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.foot-c a:hover{color:var(--teal-dk)}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ПОЛОСА ИНТЕГРАЦИЙ

   ⚠ ЗНАКИ ПЕРЕКРАШЕНЫ МЕХАНИЗМОМ mask, А НЕ ПОДОБРАНЫ ПО ЦВЕТУ. Файл в /landing/logos даёт
     форму (альфу), краску даёт background: одна на всех. Дюжина фирменных палитр в одной
     полосе — дюжина конкурирующих акцентов, полоса перестаёт быть нашим утверждением
     и становится чужой рекламой.
   ⚠ Знаки из simple-icons приходят БЕЗ атрибута fill (у части ранних он есть). Это ничего не
     меняет: маска работает по альфе, а не по цвету, и путь без заливки всё равно непрозрачен. Побочно снимается вечная беда таких полос: логотипы разной
     светлоты, где половина проваливается в фон.
   ⚠ -webkit-mask ДУБЛИРУЕТ mask НАМЕРЕННО: без префикса знаки не появляются в Safari
     до 15.4, а это ещё живой парк.
   ⚠ Полоса СВЕТЛЕЕ текста (--sub, не --ink): она подтверждает, а не заявляет. Знак, набранный
     в полную силу основного цвета, начинает спорить с заголовком секции над ним.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.logos-band{padding-block:44px}
.logos-head{text-align:center}
.logos-h{font-size:var(--fs-4);font-weight:600;color:var(--muted);margin:0 0 26px;line-height:1.5}
/* ⚠⚠ FLEX С ЦЕНТРИРОВАНИЕМ, А НЕ СЕТКА — И ЭТО ВТОРОЙ ЗАХОД НА ОДНУ И ТУ ЖЕ ЗАДАЧУ.
   Сначала здесь был flex без фиксированной ширины: на 1440px десять слотов не помещались
   в 1040px обёртки и переносились как 9 + 1. Тогда поставили сетку auto-fit — она уложила
   все десять в строку на десктопе, но перенесла проблему на узкий экран: на 390px выходило
   3 + 3 + 3 + 1, и Qdrant стоял один, ПРИЖАТЫЙ К НАЧАЛУ строки (justify-items центрирует
   слот в ячейке, а не ячейку в ряду). Сетка не умеет центрировать неполный последний ряд.
   Умеет flex — но только если ширина слота задана явно, иначе он растягивается.
   ⚠ 90px и промежуток 14px посчитаны под ДЕСЯТЬ в строку: 10×90 + 9×14 = 1026 при 1040
   доступных. Меняешь одно — пересчитай остальное, иначе десятка снова разъедется на 9 + 1.
   ⚠⚠ ЗНАКОВ СЕЙЧАС ДВЕНАДЦАТЬ, И ПОЛОСА НАМЕРЕННО СВЁРНУТА В ДВА РЯДА ПО ШЕСТЬ (26.08).
   В строку они не влезают никак (12×90 + 11×14 = 1234 при 1040), а ужимать слот нельзя:
   «Azure DevOps» в подписи стоит с nowrap и при 72px вылезет за слот, разъехав всю раскладку.
   Само по себе это дало бы 10 + 2 — длинный ряд и обрубок под ним. Поэтому ширина списка
   ограничена под ШЕСТЬ слотов (6×90 + 5×14 = 610), и ряды выходят ровными.
   ⚠ Побочно ряды легли ПО СМЫСЛУ: сверху трекеры, снизу код, мониторинг и переписка.
   ⚠ На телефоне 12 раскладываются как 3+3+3+3 — без «сироты» в конце, которая была при
   десяти знаках (3+3+3+1) и ради которой здесь и появился разбор про flex.
   Меняешь число знаков — проверь ОБА случая живьём, десктоп и 390px.
   ⚠ align-items:center: слоты одинаковой высоты, но выравнивание оставлено явным —
   при разной длине названий строки иначе разъезжаются по базовой линии. */
.logos{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;
       align-items:center;justify-content:center;gap:26px 14px;
       /* ⚠ 610 = 6×90 + 5×14. Это НЕ косметика: без ограничения двенадцать знаков дают
          10 + 2, то есть длинный ряд и обрубок под ним. */
       max-width:610px;margin-inline:auto}
.logo{flex:0 0 auto;width:90px;
      display:flex;flex-direction:column;align-items:center;gap:8px;
      opacity:.78;transition:opacity .18s}
.logo:hover{opacity:1}
.logo-mark{width:26px;height:26px;background:var(--ink);
  mask:var(--logo) center/contain no-repeat;
  -webkit-mask:var(--logo) center/contain no-repeat}
.logo-name{font-size:var(--fs-7);font-weight:600;color:var(--muted);letter-spacing:.02em;
           white-space:nowrap}
.logos-note{margin:26px auto 0;max-width:64ch;text-align:center;
            font-size:var(--fs-7);color:var(--sub);line-height:1.6}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ЭКРАНЫ ПРОДУКТА

   ⚠ СЕТКА 2×2, А НЕ ЛЕНТА В ОДНУ КОЛОНКУ. Четыре экрана в столбик — это четыре экрана
     прокрутки на десктопе, и до подписи четвёртого не доходит никто. Парами они ещё
     и сравниваются глазом, чего лента не даёт.
   ⚠ У РАМКИ overflow:hidden И РАДИУС НА НЕЙ, А НЕ НА <img>: радиус на самой картинке
     в Safari не срезает её углы при масштабировании, и в углах остаются светлые заусенцы.
   ⚠ aspect-ratio ДЕРЖИТ МЕСТО ДО ЗАГРУЗКИ. Секция ниже фолда и грузится лениво;
     без зарезервированной высоты страница прыгает под курсором ровно тогда,
     когда человек начал читать подпись.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
/* Видео-обход: та же рамка, что у снимков, но во всю ширину и первым в секции. */
.shots-video{margin-top:34px;border:1px solid var(--line);border-radius:16px;overflow:hidden;
  background:var(--navy);box-shadow:0 18px 44px rgba(22,24,72,.13);line-height:0}
/* ⚠ 16/10 и contain, а НЕ 16/9 и cover: у ролика снизу полоса подписи высотой 140 из 800,
   и при 16/9 с обрезкой по краям браузер срезал бы ровно её — то есть единственное, что
   в ролике объясняет происходящее. */
.shots-vid{display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:contain}

/* ⚠ Правило на случай НЕЧЁТНОГО числа снимков: последний остался бы один в ряду половиной
   ширины рядом с пустотой. Сейчас снимков четыре и оно не срабатывает — оно и нужно затем,
   чтобы уронить один кадр можно было, не трогая CSS. */
.shots{display:grid;grid-template-columns:repeat(2,1fr);gap:30px;margin-top:30px}
.shot:nth-child(odd):last-child{grid-column:1 / -1}
.shot:nth-child(odd):last-child .shot-frame{aspect-ratio:16/9}
.shot{margin:0;display:flex;flex-direction:column;gap:16px}
/* ⚠⚠ СНИМОК БОЛЬШЕ НЕ РЕЖЕТСЯ ПОД РАМКУ (правка Emil 20.08: «обрезаны впритык под размер
   блока, хочется отступы»). Было: жёсткий 16/10 + object-fit:cover + object-position:top —
   и `feed` (940×1201, то есть 0.78) терял почти сорок процентов высоты, а остальные три
   срезались по низу. Показывать обрезок экрана в секции, которая называется «вот что вы
   увидите», — обещать не то.
   Стало: рамка 4/3 как общий знаменатель четырёх разных пропорций, `contain` вместо `cover`
   и поле в 18px. Снимок виден ЦЕЛИКОМ и лежит НА поверхности, а не заполняет её от края
   до края; неиспользованные поля по бокам — это и есть «воздух», а не пустота. */
.shot-frame{position:relative;border:1px solid var(--line);border-radius:16px;overflow:hidden;
  background:var(--bg);box-shadow:0 14px 34px rgba(22,24,72,.09);aspect-ratio:4/3;padding:18px}
.shot-frame img{display:block;width:100%;height:100%;object-fit:contain;object-position:center;
  border-radius:8px}
.shot figcaption h3{font-size:var(--fs-4);font-weight:700;margin:0 0 6px;line-height:1.4}
.shot figcaption p{font-size:var(--fs-6);color:var(--muted);margin:0;line-height:1.65}
/* ⚠ .shots-note удалён вместе с абзацем под сеткой (решение Emil 21.08, см. ShotsSection).
   Правило снято сразу: осиротевший стиль возвращается копипастой — кто-нибудь увидит готовый
   класс и подпишет им новый абзац, не зная, что подпись убрали намеренно. */

/* ── Снимок открывается крупно. Ни строки JS: показ по :target ────────────────────────────
   ⚠ ПОЧЕМУ НЕ ДИАЛОГ С КНОПКОЙ. На landing-путях App.razor не подключает blazor.web.js —
     обработчику здесь взяться неоткуда. Ссылка-фрагмент делает то же самое и вдобавок
     работает с клавиатуры, попадает в историю и переживает выключенный JS.
   ⚠ Намерение должно читаться ДО нажатия, иначе «нажимаемость» снимка приходится угадывать:
     курсор zoom-in и значок в углу. */
.shot-frame{cursor:zoom-in;display:block;text-decoration:none}
.shot-zoom{position:absolute;inset-block-start:10px;inset-inline-end:10px;z-index:2;
  width:32px;height:32px;border-radius:9px;display:flex;align-items:center;
  justify-content:center;background:rgba(22,24,72,.62);color:#fff;
  opacity:0;transform:scale(.9);transition:opacity .16s,transform .16s;
  backdrop-filter:blur(3px)}
.shot-zoom svg{width:15px;height:15px}
.shot-frame:hover .shot-zoom,.shot-frame:focus-visible .shot-zoom{opacity:1;transform:none}
/* На сенсорном экране наведения нет вовсе — значок виден всегда, иначе он не появится
   никогда и намерение прочитать будет нечем. */
@media (hover:none){.shot-zoom{opacity:1;transform:none}}
.shot-frame:focus-visible{outline:none;box-shadow:var(--focus)}

.shotbox{display:none;position:fixed;inset:0;z-index:60;padding:32px;
  align-items:center;justify-content:center}
.shotbox:target{display:flex}
.shotbox-bg{position:absolute;inset:0;background:rgba(11,16,48,.86);backdrop-filter:blur(4px)}
.shotbox-in{position:relative;z-index:2;margin:0;max-width:min(1320px,100%);
  max-height:100%;display:flex;flex-direction:column;gap:14px}
/* ⚠ ПОЛЕ ВОКРУГ СНИМКА, А НЕ КАРТИНКА ВСТЫК (правка Emil 20.08). Снимок лежит на белой
   подложке с отступом — так он читается как экран на столе, а не как кусок страницы,
   упёршийся в собственные края.
   ⚠ max-height через vh, а не 100%: без него высокий снимок (feed — 1201px) вылезал бы
   за экран, а прокрутки у fixed-слоя нет. Из vh вычитается всё, что занимает высоту:
   поля слоя (32×2), подпись с промежутком (~46) и поля подложки (14×2). */
.shotbox-surface{background:var(--panel);border-radius:16px;padding:14px;
  box-shadow:0 24px 70px rgba(0,0,0,.5);display:flex}
.shotbox-in img{display:block;max-width:100%;max-height:calc(100vh - 138px);
  width:auto;height:auto;object-fit:contain;border-radius:8px;border:1px solid var(--line)}
.shotbox-in figcaption{color:#fff;font-size:var(--fs-6);font-weight:600;text-align:center}
.shotbox-x{position:absolute;inset-block-start:-8px;inset-inline-end:-8px;
  width:36px;height:36px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-size:22px;line-height:1;color:var(--ink);background:#fff;
  text-decoration:none;box-shadow:0 6px 18px rgba(0,0,0,.35)}
.shotbox-x:focus-visible{outline:none;box-shadow:var(--focus)}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   КТО ЧТО ВИДИТ

   ⚠ ДВЕ КОЛОНКИ РАЗНОГО ВЕСА, И ЭТО ГЛАВНОЕ В БЛОКЕ. «Видно» — на белой панели с teal-заливкой
     иконки (заливка ЗАКОННА: статус элемента, а не призыв нажать). «Скрыто» — на приглушённом
     фоне, с замком и без единой капли teal. Читатель должен увидеть границу раньше, чем прочтёт
     хоть одну строку: именно граница, а не списки, отвечает на вопрос про маржу.
   ⚠ ПОСЛЕДНЯЯ СТРОКА ВНЕ КОЛОНОК и набрана крупнее пунктов: списки говорят «что», а решает
     вопрос «кто настраивает». Внутри колонки эта мысль стала бы пятым пунктом и потерялась.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.visib{display:grid;grid-template-columns:repeat(2,1fr);gap:22px;margin-top:34px}
.visib-col{border:1.5px solid var(--field-line);border-radius:18px;padding:24px 24px 22px;
           background:var(--panel)}
.visib-col.closed{background:var(--bg);border-color:var(--line)}
.visib-head{display:flex;align-items:center;gap:11px;margin-bottom:16px}
.visib-ic{width:36px;height:36px;border-radius:10px;flex:none;
  display:flex;align-items:center;justify-content:center;background:var(--teal-soft)}
.visib-ic svg{width:18px;height:18px;color:var(--teal-dk)}
.visib-col.closed .visib-ic{background:var(--navy-soft)}
.visib-col.closed .visib-ic svg{color:var(--muted)}
.visib-head h3{font-size:var(--fs-4);font-weight:700;margin:0;line-height:1.35}
.visib-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
.visib-col li{position:relative;padding-inline-start:20px;font-size:var(--fs-6);
              color:var(--ink);line-height:1.55}
.visib-col li::before{content:"";position:absolute;inset-inline-start:0;top:7px;
  width:8px;height:8px;border-radius:50%;background:var(--teal)}
.visib-col.closed li{color:var(--muted)}
/* У закрытой колонки маркер — не точка, а перечёркивающая линия: тот же ритм, другой смысл. */
.visib-col.closed li::before{top:10px;width:9px;height:2px;border-radius:2px;background:var(--sub)}
.visib-note{margin:22px 0 0;padding:18px 22px;border-radius:14px;background:var(--navy);color:#fff;
            font-size:var(--fs-5);line-height:1.65}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   FAQ

   ⚠ НАТИВНЫЙ <details>, БЕЗ ЕДИНОЙ СТРОКИ JS. Лендинг — static SSR, blazor.web.js здесь
     не подключается; аккордеон на скриптах просто не раскрылся бы. Нативный элемент даёт
     клавиатуру, объявление скринридером и — главное — весь текст в HTML даже закрытым.
   ⚠ list-style:none И ::-webkit-details-marker ВМЕСТЕ: WebKit до сих пор рисует свой
     треугольник вторым правилом, и без него он остаётся торчать рядом с нашей стрелкой.
   ⚠ Стрелка через inline-свойства и rotate — в RTL она обязана смотреть в другую сторону,
     и делает это сама, без второго правила под he.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
/* ⚠ Мера теперь на самом списке, а не на контейнере секции (см. .narrow выше). Выровнен он
   по НАЧАЛУ строки чтения: тогда кромка вопросов совпадает с меткой и заголовком секции,
   а короче оказывается только дальний край — там текст и так рваный, и это не читается
   как сбитое поле. Без ограничения вопрос растянулся бы на 1120, и стрелка-шеврон
   (margin-inline-start:auto) улетала бы от него метров на пять. */
.faq{margin-top:30px;border-top:1px solid var(--line);max-width:76ch}
.faq-item{border-bottom:1px solid var(--line)}
.faq-item summary{list-style:none;cursor:pointer;display:flex;align-items:flex-start;gap:14px;
  padding-block:18px;font-size:var(--fs-4);font-weight:600;line-height:1.5;color:var(--ink);
  transition:color .15s}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary:hover{color:var(--teal-dk)}
.faq-item summary:focus-visible{outline:none;box-shadow:var(--focus);border-radius:8px}
/* ⚠⚠ ЗДЕСЬ border-right/border-bottom — ФИЗИЧЕСКИЕ, И ЭТО ЕДИНСТВЕННОЕ МЕСТО В ФАЙЛЕ,
   ГДЕ ТАК НАДО. Стрелка «раскрыть» смотрит ВНИЗ, а не по направлению чтения: вниз — это
   вниз и в иврите тоже. С логическими свойствами border-inline-end в RTL превращается
   в левую границу, уголок собирается зеркально, и после поворота на 45° шеврон показывал
   ВЛЕВО — проверено на живой ивритской странице. Из двух физических границ, повёрнутых
   на 45°, получается «галочка», симметричная относительно вертикали, поэтому она одинаково
   верна в обоих направлениях. Место стрелки в строке при этом задано логически
   (margin-inline-start:auto) и зеркалится как положено. */
.faq-item summary::after{content:"";flex:none;margin-inline-start:auto;margin-top:7px;
  width:9px;height:9px;border-right:2px solid var(--sub);border-bottom:2px solid var(--sub);
  transform:rotate(45deg);transition:transform .18s,border-color .18s}
.faq-item[open] summary::after{transform:rotate(225deg);margin-top:11px;border-color:var(--teal-dk)}
.faq-a{padding-block:0 20px;padding-inline-end:34px;max-width:74ch;
       font-size:var(--fs-5);color:var(--muted);line-height:1.75}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ЛИПКИЙ CTA — ТОЛЬКО НА УЗКОМ ЭКРАНЕ И ТОЛЬКО НА ВЕТКАХ

   ⚠ ЗАЧЕМ. /studios — самая длинная страница сайта: семь групп модулей, четыре фактора цены,
     сравнение двух колонок. На телефоне это метры прокрутки, и до формы внизу доходит не тот,
     кто решился, а тот, кто дотерпел. Липкая полоса возвращает форму на расстояние одного
     нажатия из любой точки страницы.
   ⚠ ПОЧЕМУ НЕ НА ДЕСКТОПЕ. Там форма достижима прокруткой за секунду, а полоса поверх контента
     съедает высоту у страницы, которую и так решили сокращать.
   ⚠ padding-bottom У body ОБЯЗАТЕЛЕН: без него полоса накрывает подвал, и последняя строка
     сайта живёт под кнопкой.
   ⚠ safe-area-inset-bottom — под домашнюю полосу iPhone. Без него кнопка стоит ровно под ней,
     и половина нажатий уходит системе, а не нам.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ЭКРАНЫ ВХОДА

   ⚠ ПЕРЕЕХАЛИ СЮДА ИЗ app.css 20.08 вместе с самими экранами: /login и /login/code объявлены
     landing-путями, а на них app.css не подключается вовсе. Перенесены ТОЛЬКО правила самой
     карточки и её содержимого; правила старой двухпанельной раскладки (.auth-wrap, .auth-panel,
     .auth-brand*, .auth-seam, .auth-axes, .auth-ax*) удалены вместе с раскладкой, которой
     больше нет.
   ⚠ Литералы цветов и кеглей заменены на токены: файл живёт по своей шкале --fs-* и своей
     палитре, и оставить здесь #161848 значило бы завести второй источник тех же значений.

   ⚠⚠ СПЛИТ, А НЕ КАРТОЧКА НА ТЁМНОМ ФОНЕ. Промежуточная редакция клала белую карточку
     на сплошной герой — обычный лендинговый приём, и он дешевле смотрится: карточка
     «лежит» на фоне, границы между смыслами нет. Экран делится честно, во всю высоту:
     одна панель — система, другая — тот, кто входит, между ними жёсткий шов.
     Так было изначально; возвращено правкой Emil 20.08.

   ⚠⚠ ФОРМА — ПЕРВАЯ КОЛОНКА, значит в иврите она СПРАВА, в ru/en слева. Позиция
     логическая, а не выбранная. Промежуточная редакция ставила её второй и меняла порядок
     через order — это молча перевернуло ивритский экран, где форма исторически была первой
     колонкой. Заодно первая колонка даёт верный порядок на узком экране без единого
     дополнительного правила: колонки складываются как написано, и вход оказывается первым.

   ⚠ Ширина колонки формы фиксирована (468px): длина поля — обещание длины ввода, а адрес
     почты короткий. Растянутое на пол-экрана поле обещает не то.

   ⚠⚠ min-height ЗДЕСЬ БОЛЬШЕ НЕТ. Прежние 90vh стояли ради «выглядывающего края» полосы
     доказательств: полоса шла ОТДЕЛЬНЫМ блоком под сплитом, во всю ширину, и высоту сплита
     приходилось подрезать, чтобы она показалась снизу. Теперь полоса живёт ВНУТРИ тёмной
     колонки, а высоту задаёт содержимое.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.signin{display:grid;grid-template-columns:468px minmax(0,1fr);background:var(--panel)}

.signin-form{display:flex;align-items:center;justify-content:center;padding:48px 46px}
.signin-form-in{width:100%;max-width:346px}
/* ⚠ На широком экране знак даёт шапка в тёмной панели — второй здесь удваивал бы вывеску.
   Появляется он только когда колонки складываются и шапка уезжает под фолд (см. ниже). */
.signin-logo{display:none;height:32px;width:auto;margin-bottom:28px}

/* ⚠⚠ ВСЯ ТЁМНАЯ ПОЛОВИНА — ОДИН ЭЛЕМЕНТ, включая доказательства. Отсюда ровно то, ради чего
   это и сделано: шов идёт во всю высоту тёмной области, а белая колонка сетки растягивается
   на ту же высоту и упирается прямо в белую секцию ниже — границы между ними не видно,
   потому что и body, и section белые (--panel).
   ⚠ Альтернатива «сетка 2×2, шов отдельным абсолютным элементом» отвергнута: шов пришлось бы
   прибить к координате 468px, то есть повторить ширину колонки формы во втором месте. */
.signin-dark{position:relative;overflow:hidden;background:var(--brand-deep);color:#fff;
             display:flex;flex-direction:column;padding:0 0 34px}
/* Техническая сетка на фоне: crisp-линии с маской по диагонали, а не размытое пятно.
   ⚠ Тот же приём и те же значения, что у .hero на лендинге — панели обязаны выглядеть
   одной поверхностью, а не двумя похожими. */
.signin-dark::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.55;
  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:46px 46px;
  -webkit-mask-image:linear-gradient(120deg,#000,transparent 70%);
          mask-image:linear-gradient(120deg,#000,transparent 70%)}

/* ⚠ Отступ тот же, что у содержимого панели: шапка стоит НЕ в .wrap (та центрировала бы её
   по всей странице, а панель — только часть ширины), поэтому поля задаются здесь. Без них
   логотип упирался прямо в шов — замерено, начинался в 4px от него. */
.signin-brand-top{position:relative;z-index:2;padding-inline:48px}
/* Содержимое панели: колонка, центрированная по вертикали в остатке под шапкой.
   ⚠⚠ align-items:center — ИСПРАВЛЕНИЕ ПОТЕРЯННОГО МЕСТА (правка Emil 20.08, фото со стрелкой).
   Колонка содержимого ограничена по ширине, а flex-column по умолчанию прижимает детей
   к началу строки чтения — то есть в иврите к ПРАВОМУ краю, вплотную к шву. Замерено
   на 1440: панель 957, поля 48+48, содержимое 560 → 301px пустоты, вся одним куском слева.
   Центрирование делит остаток пополам, а расширение колонки ниже забирает его большую часть. */
.signin-brand-in{position:relative;z-index:2;flex:1;display:flex;flex-direction:column;
                 justify-content:center;align-items:center;padding:26px 48px 0}
/* Доказательства внутри панели: свои поля вместо .wrap — тот центрировал бы содержимое
   по всей ширине страницы, а панель занимает только её часть. */
.signin-proof{position:relative;z-index:2;padding:0 48px;margin-top:30px}
.signin-proof .wrap{padding-inline:0;max-width:none}

/* ── Живой шов между панелями ─────────────────────────────────────────────────────────────
   Единственное движение на экране. Граница между «системой» и «тем, кто входит» существует
   и так; теперь по ней раз в несколько секунд проходит свет. Ничего не обещает и не
   показывает выдуманных чисел — опровергнуть нечего.
   ⚠ inset-inline-start: шов на том краю бренд-панели, который граничит с формой, и
   зеркалится вместе с направлением письма. */
.signin-seam{position:absolute;inset-block:0;inset-inline-start:0;width:3px;z-index:3;display:block;
  background:linear-gradient(180deg,var(--teal-dk),var(--teal) 50%,var(--teal-dk))}
.signin-seam i{position:absolute;inset-inline:0;height:26%;display:block;
  background:linear-gradient(180deg,transparent,var(--teal-glow),transparent);
  filter:blur(1px);animation:signinTravel 7s cubic-bezier(.45,0,.55,1) infinite}
@keyframes signinTravel{0%{top:-30%;opacity:0}12%{opacity:1}88%{opacity:1}100%{top:104%;opacity:0}}
/* Тот же свет, но вдоль горизонтального шва (узкий экран). ⚠ left, а не inset-inline-start:
   ключевые кадры анимации не понимают логических свойств, а направление здесь и не нужно —
   свет проходит полосу насквозь в обе стороны одинаково. */
@keyframes signinTravelX{0%{left:-30%;opacity:0}12%{opacity:1}88%{opacity:1}100%{left:104%;opacity:0}}
/* ⚠ Движение — не для всех. На премиум-экране это не мелочь, а признак того, что делали
   не на глаз: свет останавливается, а не исчезает. */
@media (prefers-reduced-motion:reduce){
  .signin-seam i{animation:none;top:37%;opacity:.9}
}

/* Герой внутри панели: своя ширина колонки и без верхнего отступа — его задаёт панель.
   ⚠ Ширина распространяется на ВСЁ содержимое панели, а не только на герой: артефакт,
   строка происхождения и ряд осей обязаны стоять по той же кромке.
   ⚠ 720, а не 560: на 560 панель шириной 957 отдавала под содержимое меньше двух третей,
   и треть ширины уходила в пустоту. 720 + центрирование оставляет по ~70px воздуха с обеих
   сторон — поле, а не дыра. */
.signin-brand-in .hero-in,
.signin-origin,.signin-brand-in .artifact,.signin-brand-in .axes-row{width:100%;max-width:720px}
.signin-brand-in .hero-in{padding-block:0}
/* ⚠ У ЗАГОЛОВКА СВОЯ, БОЛЕЕ ТЕСНАЯ МЕРА — 560, а не общие 720. На 720 ивритский h1 влезал
   в ОДНУ строку и терял силу удара: «הפרויקט שלכם / מסביר את עצמו» в два ряда читается как
   утверждение, в один — как подпись. Заголовку тесная мера нужна по той же причине, по
   которой она не нужна артефакту: его читают взглядом целиком, а не построчно. */
.signin-brand-in .hero-in h1,
.signin-brand-in .hero-in .hero-h{max-width:560px}
/* Лид героя в панели короче, чем на лендинге: под ним сразу идёт строка происхождения. */
.signin-brand-in .hero-p{margin-bottom:14px}

/* Строка происхождения — тихая, не заголовок: это подпись под лидом, а не второе обещание.
   Выделение внутри приходит из ресурса (<b> вокруг «построен внутри студии»). */
.signin-origin{font-size:var(--fs-7);color:var(--on-navy-3);line-height:1.55;
               margin:0 0 20px}
.signin-origin b{color:var(--on-navy-1);font-weight:700}

/* ── Артефакт: ответ портала внутри тёмной панели ─────────────────────────────────────────
   ⚠ Границы светом, а не линией: --line на navy читается как царапина. Поверхность
   полупрозрачная — панель просвечивает, и артефакт лежит НА ней, а не поверх неё. */
.artifact{border:1px solid rgba(255,255,255,.11);border-radius:16px;overflow:hidden;
  background:rgba(255,255,255,.045)}
.artifact-bar{display:flex;align-items:center;gap:9px;padding:10px 16px;
  background:rgba(255,255,255,.06);border-bottom:1px solid rgba(255,255,255,.09)}
.artifact-bar .dot{width:8px;height:8px;border-radius:50%;background:var(--teal-glow);flex:none}
.artifact-bar .t{font-size:var(--fs-7);font-weight:700;color:var(--on-navy-1);
  letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠ Метка «пример» — не украшение, а обязательство: без неё числа в артефакте читались бы
   как настоящие данные настоящего клиента. Та же метка стоит на демо-диалоге лендинга. */
.artifact-bar .tag{margin-inline-start:auto;flex:none;font-size:10px;font-weight:700;
  letter-spacing:.1em;color:var(--teal-glow);border:1px solid rgba(84,214,217,.4);
  border-radius:6px;padding:2px 7px;white-space:nowrap}
.artifact-in{padding:16px 18px 15px}
/* Вопрос — то, что человек напечатал. Кавычек нет (их на сайте нет нигде), вместо них
   полоска на кромке строки: она же зеркалится вместе с направлением письма. */
.artifact-q{font-size:var(--fs-6);font-weight:700;color:#fff;line-height:1.45;
  padding-inline-start:12px;border-inline-start:2px solid var(--teal);margin-bottom:12px}
.artifact-a{font-size:var(--fs-6);color:var(--on-navy-2);line-height:1.7}
.artifact-a b{color:#fff;font-weight:700}
.artifact-srcs{display:flex;flex-wrap:wrap;gap:7px;margin-top:13px;padding-top:12px;
  border-top:1px solid rgba(255,255,255,.09)}
.artifact-srcs .src{font-size:var(--fs-7);font-weight:600;color:var(--teal-glow);
  background:rgba(84,214,217,.11);border:1px solid rgba(84,214,217,.22);
  border-radius:7px;padding:4px 9px}

/* ── Оси одной строкой ───────────────────────────────────────────────────────────────────
   ⚠ Это ЗАМЕНА карточкам .axis на этом экране, а не добавка к ним: описания осей взял
   на себя артефакт выше. Названия остались, потому что они — оглавление продукта. */
.axes-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}
.axis-chip{display:inline-flex;align-items:center;gap:7px;font-size:var(--fs-7);
  font-weight:600;color:var(--on-navy-2);background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.09);border-radius:9px;padding:6px 11px}
.axis-chip .axis-ic{width:20px;height:20px;border-radius:6px;background:rgba(84,214,217,.14);
  display:inline-flex;align-items:center;justify-content:center;flex:none}
.axis-chip .axis-ic svg{width:12px;height:12px;color:var(--teal-glow)}

.auth-card{width:100%}
.auth-title{font-size:var(--fs-2);font-weight:700;margin:0 0 8px;color:var(--ink);
            line-height:1.2;letter-spacing:-.01em}
.auth-sub{font-size:var(--fs-6);color:var(--sub);line-height:1.6;margin:0 0 24px}
.auth-lbl{display:block;font-size:var(--fs-6);font-weight:600;color:var(--label);margin-bottom:8px}
.auth-field{display:flex;flex-direction:column;gap:7px;margin-bottom:6px}
.auth-field label{font-size:var(--fs-6);font-weight:600;color:var(--label)}
.auth-field input{width:100%;padding:13px 15px;border:1.5px solid var(--field-line);border-radius:11px;
  font-size:var(--fs-5);font-family:inherit;background:var(--field-bg);
  transition:border-color .15s,box-shadow .15s,background .15s}
.auth-field input::placeholder{color:var(--placeholder)}
.auth-field input:focus{outline:none;border-color:var(--teal);background:var(--panel);box-shadow:var(--focus)}
/* ⚠ Заливка градиентом ЗАКОННА по правилу teal: это единственное действие экрана. */
.auth-btn{width:100%;margin-top:18px;padding:13px;border:none;border-radius:11px;cursor:pointer;
  font-family:inherit;font-size:var(--fs-5);font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--teal),var(--teal-dk));box-shadow:var(--shadow-cta);
  transition:transform .12s,box-shadow .12s}
.auth-btn:hover{transform:translateY(-1px);box-shadow:var(--shadow-cta-hi)}
.auth-err{display:block;color:#dc2626;font-size:var(--fs-6);margin-top:6px}
.auth-note{display:flex;align-items:flex-start;gap:8px;margin-top:20px;
           font-size:var(--fs-7);color:var(--sub);line-height:1.5}
.auth-note svg{width:15px;height:15px;color:var(--teal-dk);flex:none;margin-top:1px}
.auth-back{margin-top:18px;text-align:center}
/* ⚠ min-height:24px — норма WCAG 2.2 (2.5.8). Замерено: было 19px, и это единственная
   дорога назад с экрана кода, промахнуться по ней на телефоне дороже всего. */
.auth-back a{font-size:var(--fs-6);color:var(--teal-dk);text-decoration:none;font-weight:600;
             min-height:24px;display:inline-flex;align-items:center;justify-content:center}
/* ⚠ direction:ltr на ряду цифр ОБЯЗАТЕЛЕН и в иврите: код читается слева направо всегда,
   и в RTL без этого первая введённая цифра оказывалась бы справа. */
.otp-row{display:flex;gap:9px;direction:ltr;margin:2px 0 4px}
.otp-box{flex:1;min-width:0;aspect-ratio:1;text-align:center;font-size:var(--fs-2);font-weight:700;
  font-family:inherit;color:var(--ink);background:var(--field-bg);border:1.5px solid var(--field-line);
  border-radius:12px;transition:border-color .15s,box-shadow .15s,background .15s}
.otp-box:focus{outline:none;border-color:var(--teal);background:var(--panel);box-shadow:var(--focus)}

.sticky-cta{display:none}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   ⚠⚠ ШАПКА НА УЗКОМ ЭКРАНЕ ПЕРЕНОСИТСЯ НА ДВЕ СТРОКИ — ЭТО ИСПРАВЛЕНИЕ ЖИВОЙ ПОЛОМКИ.

   Замерено на проде при окне 390px: лок-ап логотипа занимает 231px, навигация — 271px
   (крошка 61 + переключатель 94 + кнопка входа 100 и промежутки). В строку это 502px при
   342px доступных, а `.top` — обычный flex БЕЗ переноса. Итог: переключатель языков стоял
   на 344…438, кнопка «вход в портал» на 446…546 — то есть ОБА за краем экрана. С телефона
   нельзя было ни сменить язык на трёхъязычном сайте, ни попасть в портал с лендинга.

   ⚠ ПОЧЕМУ ЭТО НЕ ЗАМЕТИЛИ ГОДАМИ (и почему не заметил бы никакой автотест на переполнение):
     улику съел `.hero{overflow:hidden}` — он обрезал вылезающее, и горизонтальной прокрутки
     не появлялось. `document.documentElement.scrollWidth` честно показывал 390 при двух
     недоступных элементах управления. Ловится только замером положения самих элементов.

   ⚠ ПОРОГ 700px, А НЕ 980px И НЕ 600px. Общий мобильный медиазапрос лендинга шире, и
     переносить шапку вместе с остальным значило бы чинить то, что не сломано. Но и 600px
     оказалось мало: замер на 601px показал, что за экран уже ничего не уезжает, зато пункты
     СЖИМАЮТСЯ и ломают текст внутри себя — «Вход в портал» становится двухэтажной кнопкой
     высотой 62px. Считаем по худшему случаю (русская кнопка — самая длинная из трёх языков):
     логотип 231 + промежуток 20 + навигация 297 = 548, плюс поля обёртки 48 = 596.
     Порог 700px даёт запас на разницу длины слов в he/en/ru, а не подгоняет под одну.

   ⚠ ПЕРЕНОС, А НЕ СКРЫТИЕ. Спрятать крошку или марку «VANTAGE» было бы короче, но это
     решение «пусть на телефоне будет меньше сайта». Вторая строка ничего не убирает.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width:700px){
  .top{flex-wrap:wrap;row-gap:12px;padding-block:16px 14px}
  /* Навигация занимает всю ширину второй строки и прижимается к концу строки —
     в RTL это левый край, в LTR правый; логическое свойство зеркалит само. */
  .top-nav{width:100%;justify-content:flex-end;flex-wrap:wrap;row-gap:10px}
  /* ⚠ nowrap на самих пунктах, а wrap — на их контейнере. Без первого «На главную»
     и «Вход в портал» ломались ПОСРЕДИ ФРАЗЫ на две строки (замерено на 390px);
     без второго на 360px они бы вместо переноса снова полезли за край.
     Вместе: пункт остаётся целым, а не поместившийся уходит на следующую строку. */
  .crumb,.top-login{white-space:nowrap}
  /* Немного тесноты переключателю: три ячейки по 12px паддинга съедали 24px строки,
     которых на 360px как раз не хватало. */
  .lang a{padding-inline:10px}
}

@media (max-width:980px){
  .wrap{padding-inline:24px}
  /* ⚠ Сплит складывается в одну колонку В ПОРЯДКЕ ДОКУМЕНТА, а он уже верный: форма первая.
     Свой не ищет поле каждый день; гость прокручивает один экран и попадает в доводы.
     ⚠ Про min-height здесь больше нечего снимать: его нет и в базовом правиле — см. пояснение
     там же. */
  /* ⚠⚠ minmax(0,1fr), А НЕ 1fr — ИСПРАВЛЕНИЕ ЖИВОЙ ПОЛОМКИ (QA 20.08).
     На /login/code при 390px была ГОРИЗОНТАЛЬНАЯ ПРОКРУТКА: документ 398 при экране 375,
     обе половины сплита стояли на left = −23. Механизм: `1fr` это `minmax(auto,1fr)`,
     и `auto` не даёт треку стать уже min-content своего содержимого. Давил ряд OTP —
     у .otp-box стоит aspect-ratio:1, поэтому минимальная ШИРИНА выводится из минимальной
     ВЫСОТЫ, а её задаёт кегль: шесть боксов + пять зазоров = ровно 398.
     minmax(0,…) снимает этот минимум, а ряд ужат ниже, чтобы ему хватало места и по факту. */
  .signin{grid-template-columns:minmax(0,1fr)}
  /* Ряд из шести цифр на телефоне: кегль на ступень мельче и зазор уже.
     Считаем от РЕАЛЬНО доступного: 375 − поля формы 52 = 323; 6×46 + 5×7 = 311. */
  .otp-row{gap:7px}
  .otp-box{font-size:var(--fs-3)}
  .signin-form{padding:34px 26px 40px}
  /* Знак возвращается: форма идёт первой, а шапка с лок-апом ушла под фолд вместе
     с тёмной панелью — без него человек видит поле на белом листе и не понимает, куда попал. */
  .signin-logo{display:block}
  .signin-dark{padding-bottom:34px}
  .signin-brand-in{padding:22px 24px 0}
  .signin-proof{padding-inline:24px;margin-top:24px}
  /* Шов на узком экране идёт ПОПЕРЁК, по верхней кромке бренд-панели: вертикальная полоска
     в три пикселя у края телефона читалась бы как артефакт рендера, а не как граница. */
  .signin-seam{inset-block:0 auto;inset-inline:0;width:auto;height:3px;
    background:linear-gradient(90deg,var(--teal-dk),var(--teal) 50%,var(--teal-dk))}
  .signin-seam i{inset-block:0;inset-inline:auto;width:26%;height:auto;
    background:linear-gradient(90deg,transparent,var(--teal-glow),transparent);
    animation-name:signinTravelX}
  .shots,.visib{grid-template-columns:1fr}
  .shots{gap:26px}
  /* Лайтбокс на телефоне: поля меньше, крестик ближе к углу, картинке отдана вся высота. */
  .shotbox{padding:16px}
  .shotbox-in img{max-height:calc(100vh - 96px)}
  .shotbox-x{inset-block-start:-6px;inset-inline-end:-6px;width:32px;height:32px}
  /* ⚠ Слот ужат так, чтобы на телефоне вставало ЧЕТЫРЕ в ряд (4+4+2), а не три с одиноким
     хвостом. Считать надо от РЕАЛЬНО доступного, а не от ширины окна: на 390px полоса
     прокрутки съедает 15px, поля обёртки ещё 48 — остаётся 327. Отсюда 4×74 + 3×8 = 320.
     ⚠ 74px выбрано с запасом в 6px над самым длинным названием («Freshservice» ~68px при
     кегле --fs-7): у названий стоит nowrap, и при нехватке они не переносятся, а вылезают. */
  .logos{gap:22px 8px}
  .logo{width:74px}
  .logos-band{padding-block:34px}

  /* Каталог модулей превращается в аккордеон: шапка становится нажимаемой строкой
     со стрелкой, иконка и заголовок встают в ряд, отступ снизу у заголовка снимается —
     у закрытой группы он висел бы пустотой под последней видимой строкой. */
  .mgroup > summary{cursor:pointer;display:flex;align-items:center;gap:11px}
  .mgroup > summary:focus-visible{outline:none;box-shadow:var(--focus);border-radius:8px}
  .mgroup .mgroup-ic{margin-bottom:0;flex:none}
  .mgroup h4{margin:0}
  /* ⚠ Физические границы по той же причине, что у стрелки FAQ, — см. пояснение там. */
  .mgroup > summary::after{content:"";flex:none;margin-inline-start:auto;
    width:8px;height:8px;border-right:2px solid var(--sub);border-bottom:2px solid var(--sub);
    transform:rotate(45deg);transition:transform .18s}
  .mgroup[open] > summary::after{transform:rotate(225deg)}
  .mgroup[open] > ul{margin-top:14px}

  .sticky-cta{display:flex;position:fixed;inset-inline:0;bottom:0;z-index:40;
    align-items:center;gap:12px;
    padding:10px 16px calc(10px + env(safe-area-inset-bottom,0px));
    background:rgba(255,255,255,.94);backdrop-filter:blur(10px);
    border-top:1px solid var(--line);box-shadow:0 -6px 20px rgba(22,24,72,.08)}
  .sticky-cta .sticky-txt{flex:1;min-width:0;font-size:var(--fs-7);color:var(--muted);
    line-height:1.35;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
  .sticky-cta .cta{flex:none;padding:11px 18px;font-size:var(--fs-6)}
  body:has(.sticky-cta){padding-bottom:74px}
  .axes,.pains,.axes-lg,.caps,.claims,.build,.mods-groups,.fork-grid{grid-template-columns:1fr}
  .axes{gap:10px;margin-top:26px}
  .proof,.proof.even{grid-template-columns:1fr;margin-top:28px}
  .join-grid{grid-template-columns:1fr;gap:34px;padding-block:50px}
  section{padding-block:52px}
  .bubble{max-width:92%}
  .bubble.q{max-width:86%}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   СТРАНИЦА ПОДТВЕРЖДЕНИЯ ПРИГЛАШЕНИЯ (/invite/{token}).

   ⚠ Живёт ЗДЕСЬ, а не в app.css: путь объявлен auth-путём, а им App.razor подключает только
     landing.css. Правило то же, что у экранов входа.
   ⚠ Направление письма страница не задаёт сама — его ставит App.razor на <html> из того же
     языка, что и тексты. Отступы поэтому логические (inline-start/end), а не левые и правые.
   ⚠ Вес шрифта не выше 700: на иврите Heebo выше 700 ломает форму букв.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */
.inv-page{max-width:560px;margin:0 auto;padding:52px 22px 60px}
/* ⚠ Лок-ап тот же, что в шапке лендинга (.top-logo): знак из /logo.png плюс словесная часть
   ВПЛОТНУЮ к нему, через тонкий разделитель. Отдельного «S»-квадрата у бренда не существует.
   ⚠ Фильтра brightness(0) invert(1) здесь НЕТ: он нужен шапке, потому что там знак стоит на
   тёмном --brand-deep. Эта страница светлая, и знак читается как есть. */
.inv-brand{display:flex;align-items:center;justify-content:center;margin-bottom:26px}
.inv-brand img{height:28px;width:auto;display:block;margin-inline-end:12px}
.inv-word{position:relative;padding-inline-start:15px;
  font-size:13px;font-weight:700;letter-spacing:.16em;color:var(--teal-dk)}
.inv-word::before{content:"";position:absolute;inset-inline-start:0;top:50%;
  transform:translateY(-50%);width:1px;height:15px;background:rgba(22,24,72,.18)}

.inv-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;
  padding:30px 30px 26px;box-shadow:0 10px 34px -14px rgba(22,24,72,.18)}

.inv-head{margin:0 0 6px;font-size:var(--fs-3);font-weight:700;line-height:1.35;color:var(--ink)}
.inv-role{margin:0 0 20px;color:var(--sub);font-size:var(--fs-5)}

.inv-sees{padding:15px 17px;background:var(--teal-soft);border-radius:13px;
  font-size:var(--fs-6);color:var(--teal-ink);line-height:1.6}
.inv-sees b{display:block;color:var(--ink);font-weight:600;margin-bottom:7px}
.inv-sees ul{margin:0;padding-inline-start:18px}
.inv-sees li{margin-bottom:5px}
.inv-sees li:last-child{margin-bottom:0}

.inv-expires{margin:16px 0 0;color:var(--sub);font-size:var(--fs-7)}
.inv-gap{margin-top:16px}

.inv-acts{display:flex;gap:9px;align-items:center;margin-top:22px;flex-wrap:wrap}
/* ⚠ Кнопка и ссылка выглядят одинаково намеренно: «войти» это переход, «принять» это форма,
   но для человека это один ряд действий, и разнобой читался бы как разная важность. */
.inv-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:11px 22px;border:1px solid var(--line);border-radius:11px;cursor:pointer;
  font-family:inherit;font-size:var(--fs-5);font-weight:600;color:var(--ink);background:var(--panel);
  text-decoration:none;transition:transform .12s,box-shadow .12s,border-color .14s,color .14s}
.inv-btn:hover{border-color:var(--teal);color:var(--teal-dk)}
.inv-btn-main{border:none;color:#fff;background:linear-gradient(135deg,var(--teal),var(--teal-dk));
  box-shadow:var(--shadow-cta)}
.inv-btn-main:hover{color:#fff;transform:translateY(-1px);box-shadow:var(--shadow-cta-hi)}
.inv-btn-ghost{border-color:transparent;color:var(--sub);margin-inline-start:auto}
.inv-btn-ghost:hover{border-color:var(--line);color:var(--ink)}

.inv-addr{margin:16px 0 0;padding-top:14px;border-top:1px solid var(--line);
  color:var(--sub);font-size:var(--fs-7);line-height:1.55}
.inv-addr + .inv-addr{margin-top:6px;padding-top:0;border-top:none}

.inv-icon{width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  font-size:19px;margin-bottom:16px}
.inv-warn{background:#fdf6e3;color:#a16207}
.inv-dead{background:var(--bg);color:var(--sub)}
.inv-good{background:#e8f5ec;color:#15803d}
.inv-lead{margin:0 0 8px;font-size:var(--fs-4);font-weight:700;color:var(--ink)}
.inv-body{margin:0;color:var(--sub);font-size:var(--fs-6);line-height:1.65}

.inv-foot{margin-top:26px;text-align:center;color:var(--sub);font-size:var(--fs-7)}

@media (max-width:520px){
  .inv-page{padding:32px 16px 44px}
  .inv-card{padding:24px 20px 20px;border-radius:15px}
  .inv-acts{gap:8px}
  .inv-btn{flex:1;min-width:0}
  .inv-btn-ghost{margin-inline-start:0}
}

/* Поля экрана регистрации бизнес-аккаунта (/business/new). Карточка, кнопки и знак — те же
   .inv-*, что у страницы подтверждения: это один и тот же вход, разрывать его оформлением нечем. */
.biz-field{margin-bottom:16px}
.biz-field label{display:block;font-size:12.5px;font-weight:600;color:var(--sub);margin-bottom:7px}
.biz-field input,.biz-field select{width:100%;border:1.5px solid var(--line);border-radius:11px;
  padding:12px 14px;font:inherit;font-size:var(--fs-5);background:var(--field-bg);color:var(--ink);
  transition:border-color .15s,box-shadow .15s,background .15s}
.biz-field input:focus,.biz-field select:focus{outline:none;border-color:var(--teal);
  background:var(--panel);box-shadow:var(--focus)}
/* ⚠ Номер всегда слева направо, даже в RTL: девять цифр читаются как число, а не как текст. */
.biz-field input.num{direction:ltr;text-align:left;letter-spacing:.08em}
.biz-field.bad input{border-color:#dc2626}
.biz-hint{font-size:var(--fs-7);color:var(--sub);margin-top:7px;line-height:1.55}
.biz-err{font-size:var(--fs-7);color:#dc2626;margin-top:7px;line-height:1.55}
.biz-err-block{margin-top:14px;padding:10px 13px;background:#fdecea;border-radius:10px}

/* Сообщение шага входа на странице приглашения (код отправлен / уже отправлен / не тот). */
.inv-note{margin:16px 0 0;padding:11px 14px;background:var(--teal-soft);border-radius:11px;
  color:var(--teal-ink);font-size:var(--fs-6);line-height:1.55}
.inv-note.bad{background:#fdecea;color:#b91c1c}
/* Граница раскрытия под списком «что станет видно»: не пункт, а вывод — потому и выделена. */
.inv-only{margin:9px 0 0;font-weight:600;color:var(--ink)}

/* Разделы страницы подтверждения — те же, что в письме: «что откроется», «что не откроется»,
   «что вы получаете», «о чём знать заранее», «управление». ⚠ Второй блок оформлен отдельно:
   он про то, чего НЕ будет, и путать его с первым нельзя. */
.inv-before{margin:18px 0 12px;font-weight:600;color:var(--ink)}
.inv-sec{margin:22px 0 8px;font-size:var(--fs-4);font-weight:700;color:var(--ink)}
.inv-list{margin:0 0 10px;padding-inline-start:18px;color:var(--sub);font-size:var(--fs-6);line-height:1.65}
.inv-list li{margin-bottom:5px}
.inv-sees + .inv-sees{margin-top:12px}
.inv-not{background:#fdf6e3;color:#7a4b06}
.inv-not b{color:var(--ink)}
