/* ==========================================================================
   Экран 15 — модальная форма заявки.

   Материалы те же, что у всей страницы: панель — это карточка сайта
   (--surface, --r-xl, --sh-lift), главная кнопка — .btn.btn--primary
   с фирменной тенью, кегли только из --fz-*, отступы только из --s-*.
   Своих цветов и своих размеров окно не заводит.

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

   1. <dialog> растянут на весь экран и прозрачен, а видимая коробка —
      это .lead-form__panel внутри него. Так сделано ради закрытия
      по клику мимо окна: у dialog размером с панель промахнуться некуда,
      и «клик по фону» пришлось бы ловить по координатам. Здесь фон —
      это сам элемент dialog, и проверка сводится к e.target === dialog.
      Затемнение при этом даёт ::backdrop, а не заливка dialog.

   2. Центрирование — margin: auto на панели, а не align-items: center
      на контейнере. У флекса с центровкой длинная панель обрезается
      СВЕРХУ и до её верха нельзя доскроллить; auto-поля флекс-элемента
      от этого свободны.

   3. Высота окна на телефоне берётся из visualViewport (переменные
      --lead-vh / --lead-vtop ставит скрипт), а не из 100vh и не из 100dvh.
      Причина в клавиатуре: с Chrome 108 она по умолчанию НЕ сжимает
      layout viewport, поэтому 100vh — это высота вместе с областью
      под клавиатурой, и нижние поля формы оказываются под ней навсегда.
      На iOS атрибута interactive-widget нет вовсе, и visualViewport —
      единственный общий путь. Значения приходят только на телефоне,
      на десктопе работает запасное 100%.
   ========================================================================== */

/* Браузер, который не знает <dialog>, отрисовал бы его обычным блоком —
   форма встала бы куском страницы над подвалом. Скрипт в таком браузере
   тоже не включается (проверяет showModal), и кнопки остаются ссылками
   на #price, как сейчас. */
.lead-form:not([open]) { display: none; }

.lead-form {
  position: fixed;
  inset: 0;
  top: var(--lead-vtop, 0px);
  width: 100%;
  height: var(--lead-vh, 100%);
  max-width: none;
  max-height: none;
  margin: 0;
  padding: var(--s-5);
  border: 0;
  background: transparent;
  overflow: auto;
  /* Прокрутка внутри окна не пробивается на страницу за ним. */
  overscroll-behavior: contain;
}

.lead-form[open] { display: flex; }

.lead-form::backdrop {
  /* Тон затемнения — основной текст сайта, а не чёрный: чёрный слой поверх
     цветного фона обесцвечивает его (docs/premium-web.md, «Тени»). */
  background: rgba(27, 22, 51, .62);
}

/* Появление: 220 мс, ease-out — вторая ступень движения из tokens.css,
   ровно та, что свод отводит существенной смене состояния. Уход мгновенный:
   анимация закрытия требует transition-behavior: allow-discrete, а это
   пока не везде, и третьей длительности проект не заводит. */
.lead-form[open]           { animation: lead-form-in var(--t-base); }
.lead-form[open]::backdrop { animation: lead-form-fade var(--t-base); }

@keyframes lead-form-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

@keyframes lead-form-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .lead-form[open]           { animation: none; }
  .lead-form[open]::backdrop { animation: none; }
}

/* Страница за окном не прокручивается. Класс ставит скрипт; он же кладёт
   в --lead-sbw ширину исчезнувшей полосы прокрутки, иначе на десктопе
   содержимое страницы прыгает вправо в момент открытия. */
html.has-lead-modal {
  overflow: hidden;
  padding-right: var(--lead-sbw, 0px);
}

/* ---------- Панель ---------- */

.lead-form__panel {
  display: flex;
  flex-direction: column;
  margin: auto;
  width: 100%;
  max-width: 520px;
  padding: var(--s-7);
  background: var(--surface);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lift);
}

/* Панель получает фокус после открытия и обводки не показывает: рамка
   вокруг всего окна ничего не сообщает, а сам факт «фокус внутри модалки»
   виден по самому окну. Клавиатурный обход начинается с крестика следующим
   Tab, и у него обводка на месте. */
.lead-form__panel:focus { outline: none; }
.lead-form__panel:focus-visible { outline: none; }

/* ---------- Крестик ---------- */

/* Обычный поток, а не absolute: на телефоне он становится липким и остаётся
   доступным при прокрутке формы, а липким может быть только элемент в потоке.
   44×44 — зона нажатия из свода, значок внутри 20. */
.lead-form__close {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: calc(var(--s-5) * -1) calc(var(--s-5) * -1) var(--s-2) 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--bg-tint);
  color: var(--muted);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}

.lead-form__close .icon { width: 20px; height: 20px; }

@media (hover: hover) {
  .lead-form__close:hover { background: var(--brand-soft); color: var(--brand); }
}

.lead-form__close:active { background: var(--brand-soft); color: var(--brand); }

/* ---------- Шапка окна ---------- */

.lead-form__head { margin-bottom: var(--s-6); }

.lead-form__title { margin: 0 0 var(--s-3); }

.lead-form__lead {
  margin: 0;
  font-size: var(--fz-small);
  line-height: var(--lh-body);
  color: var(--muted);
}

/* ---------- Поля ---------- */

/* Переносов по слогам в служебных строках формы нет.
   Правило то же, по которому в base.css не переносятся кнопки, бейджи
   и метки: это не абзацы, а короткие подписи в 2-6 слов, и дефис посреди
   «персональ-ных» или «обра-ботку» читается сломанной вёрсткой, а не
   заботой о правом крае. Замер на 393: без этого правила переносились
   подпись согласия и два сообщения об ошибке из четырёх. */
.lead-form__label,
.lead-form__optional,
.lead-form__err,
.lead-form__consent,
.lead-form__alert {
  -webkit-hyphens: none;
  hyphens: none;
}

/* Пространство вокруг группы больше, чем внутри неё: между полями 24,
   внутри поля (подпись → рамка) 8, ошибка липнет к своему полю на 8.
   Группа полей отбивается от согласия и кнопки на 32. */
.lead-form__fields {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  margin-bottom: var(--s-6);
}

.lead-form__label {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin-bottom: var(--s-2);
  font-size: var(--fz-small);
  font-weight: 600;
  color: var(--ink);
}

.lead-form__optional {
  font-size: var(--fz-caption);
  font-weight: 400;
  color: var(--muted-2);
}

/* РАМКА ПОЛЯ — --muted-2, а не --line, и это не вкус.

   Поле лежит на белой панели и само белое: заливкой оно от фона
   не отличается, значит опознать его можно только по рамке, а на такую
   рамку распространяется SC 1.4.11 с порогом 3:1 (уровень AA).
   --line #EEEBF4 на белом даёт 1.09:1 — поля не существует.
   --muted-2 #726C87 даёт 4.99:1 (пересчёт по формуле WCAG). Свод про этот
   случай пишет прямо:
   если рамка еле видна, её не утоньшают, а усиливают цветом.

   Кегль --fz-body: его нижняя граница 16px, и это порог, ниже которого
   iOS Safari зумит вьюпорт при фокусе — после чего липкая панель и шапка
   уезжают за край. */
.lead-form__input,
.lead-form__code {
  width: 100%;
  min-height: 56px;
  padding: 0 var(--s-4);
  border: 1.5px solid var(--muted-2);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fz-body);
  line-height: var(--lh-body);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}

.lead-form__input::placeholder { color: var(--muted-2); }

/* Фокус: кромка уходит в бренд и получает мягкое свечение — тот же приём,
   что у акцентных элементов страницы. Обводка :focus-visible из base.css
   при этом остаётся: она и есть обязательный индикатор, свечение — добавка. */
.lead-form__input:focus,
.lead-form__code:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(124, 59, 246, .14);
}

/* Ошибка показывается не только цветом: рядом с текстом стоит знак,
   а у самого поля меняется кромка. */
.lead-form__input[aria-invalid="true"] { border-color: var(--bad-ink); }

.lead-form__input[aria-invalid="true"]:focus {
  border-color: var(--bad-ink);
  box-shadow: 0 0 0 3px rgba(176, 58, 80, .16);
}

/* Строка «код страны + номер» */
.lead-form__row {
  display: flex;
  gap: var(--s-2);
}

.lead-form__code {
  flex: 0 0 116px;
  width: 116px;
  padding-right: var(--s-6);
  cursor: pointer;
  /* Своя стрелка вместо системной: системная у select на iOS и на Windows
     рисуется по-разному и ломает общую кромку. Значок — data-URI, то есть
     ни одного лишнего запроса. */
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%235D5773' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
}

.lead-form__input--phone {
  /* Цифры табличные — иначе строка пляшет по ширине, пока набирают номер. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ---------- Ошибка поля ---------- */

.lead-form__err {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  margin: var(--s-2) 0 0;
  font-size: var(--fz-small);
  line-height: var(--lh-heading);
  color: var(--bad-ink);
}

.lead-form__err[hidden] { display: none; }

.lead-form__err-icon {
  flex: none;
  width: 20px;
  height: 20px;
  /* Оптическая подгонка, а не отступ из шкалы: круг 20px рядом со строкой
     высотой 19px стоит на пиксель выше, чем нужно глазу. Свод про этот
     случай говорит прямо — числовых допусков не бывает, правится на глаз
     и в токены не кодируется. */
  margin-top: 1px;
}

/* ---------- Согласие ---------- */

.lead-form__field--consent { margin-bottom: var(--s-6); }

/* Кликается вся строка, а не квадратик 24×24: подпись — часть <label>,
   и попасть пальцем можно куда угодно в ней. */
.lead-form__consent {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  font-size: var(--fz-small);
  line-height: var(--lh-body);
  color: var(--muted);
  cursor: pointer;
}

.lead-form__consent input {
  flex: none;
  width: 24px;
  height: 24px;
  margin: 0;
  accent-color: var(--brand);
  cursor: pointer;
}

.lead-form__consent a { color: var(--brand); }

/* Незаполненная галочка отмечается не только цветом текста ошибки:
   у самого квадратика появляется обводка. */
.lead-form__consent input[aria-invalid="true"] {
  outline: 2px solid var(--bad-ink);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ---------- Кнопка и общая ошибка ---------- */

.lead-form__submit { width: 100%; }

/* Ожидание: кнопка выключена, надпись меняется, форма не очищается. */
.lead-form__submit[disabled] { cursor: progress; }

.lead-form__alert {
  display: flex;
  margin: var(--s-4) 0 0;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  background: var(--bad-bg);
  color: var(--bad-ink);
  font-size: var(--fz-small);
  line-height: var(--lh-body);
}

.lead-form__alert[hidden] { display: none; }

/* ---------- Состояние после отправки ---------- */

.lead-form__done { text-align: center; }

.lead-form__done[hidden] { display: none; }

.lead-form__done:focus,
.lead-form__done:focus-visible { outline: none; }

.lead-form__done-mark {
  display: inline-flex;
  vertical-align: top;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin-bottom: var(--s-5);
  border-radius: var(--r-pill);
  background: var(--grad-brand);
  color: #fff;
  box-shadow: var(--glow-brand);
}

.lead-form__done-mark .icon { width: 28px; height: 28px; }

/* Заявка не ушла — знак об этом и говорит. Материал взят у блоков
   «было / стало»: та же пара --bad-bg / --bad-ink, что на всей странице. */
.lead-form__done-mark--warn {
  background: var(--bad-bg);
  background-image: none;
  color: var(--bad-ink);
  box-shadow: none;
}

.lead-form__done-mark--warn .lead-form__err-icon { width: 28px; height: 28px; margin: 0; }

.lead-form__done .lead-form__title { margin-bottom: var(--s-3); }

.lead-form__done .lead-form__lead {
  margin-inline: auto;
  margin-bottom: var(--s-6);
  max-width: 42ch;
  /* Абзац короткий и стоит по центру: рваная последняя строка на центрованном
     тексте видна сильнее всего. Больше шести перенесённых строк здесь не бывает,
     то есть balance отработает и в Chromium, и в Firefox. */
  text-wrap: balance;
}

.lead-form__done-btn { width: 100%; }
.lead-form__done-close { width: 100%; margin-top: var(--s-3); }

/* ---------- Ловушка для ботов ---------- */

.lead-form__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   ТЕЛЕФОН: ОКНО ВО ВЕСЬ ЭКРАН
   --------------------------------------------------------------------------
   640 — та же граница, на которой в base.css главная кнопка становится
   во всю ширину. Новых границ проект не заводит.

   Панель занимает экран целиком и прокручивается сама; кнопка отправки
   едет вместе с содержимым и липкой НЕ становится — свод называет
   «форму в модалке высотой 100vh с фиксированной кнопкой внизу»
   антипаттерном ровно потому, что клавиатура эту кнопку и накрывает.
   Всегда доступным остаётся один элемент — крестик, и он липкий.
   ========================================================================== */
@media (max-width: 640px) {

  .lead-form { padding: 0; }
  .lead-form[open] { display: block; }

  .lead-form__panel {
    margin: 0;
    max-width: none;
    min-height: 100%;
    border-radius: 0;
    box-shadow: none;
    /* Поля панели равны полям страницы и уважают вырез устройства:
       max(), а не сложение, — на телефоне без выреза инсета равна нулю. */
    padding: max(var(--s-5), env(safe-area-inset-top))
             max(var(--s-5), env(safe-area-inset-right))
             max(var(--s-6), env(safe-area-inset-bottom))
             max(var(--s-5), env(safe-area-inset-left));
  }

  .lead-form__close {
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 0 var(--s-3) auto;
  }

  .lead-form__head { margin-bottom: var(--s-5); }
}

/* Узкий телефон: на 320 после селектора кода на номер оставалось 148px
   при нужных 157 — «(916) 123-45-67» не помещалось. Поля панели там
   и так меньше (--container-pad на этой ступени 16), селектор ужимается
   до 104: маска влезает с запасом. Граница 359 — та же, что у полей
   контейнера в tokens.css. */
@media (max-width: 359px) {
  .lead-form__panel {
    padding-inline: max(var(--s-4), env(safe-area-inset-left))
                    max(var(--s-4), env(safe-area-inset-right));
  }

  .lead-form__code {
    flex-basis: 104px;
    width: 104px;
    padding-inline: var(--s-3) var(--s-5);
    background-position: right var(--s-3) center;
  }

  .lead-form__input { padding-inline: var(--s-3); }
}

/* Ландшафт телефона: экран высотой 393, и шапка окна в нём — роскошь.
   Условие то же, что у остальных ландшафтных ступеней проекта,
   вместе с обязательным (pointer: coarse): без него в запрос попадает
   десктоп с низким окном, а десктоп принят заказчиком. */
@media (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
  /* 852×393 шире 640, поэтому мобильная ветка сюда не попадает и окно
     остаётся карточкой. Поле вокруг неё ужимается, чтобы карточка начиналась
     у самой кромки: полностью в 393 форма не помещается ни при каких
     отступах, и каждый лишний пиксель поля — это лишняя прокрутка. */
  .lead-form { padding: var(--s-3); }
  .lead-form__panel { padding: var(--s-5) var(--s-6); }
  .lead-form__close { margin: calc(var(--s-3) * -1) calc(var(--s-4) * -1) 0 0; }
  .lead-form__head { margin-bottom: var(--s-4); }
  .lead-form__fields { gap: var(--s-4); margin-bottom: var(--s-4); }
  .lead-form__field--consent { margin-bottom: var(--s-4); }
  .lead-form__done-mark { display: none; }
}

/* ==========================================================================
   Страница «спасибо» (thanks.html)
   --------------------------------------------------------------------------
   Живёт в файле формы намеренно: это её продолжение, человек попадает сюда
   сразу после отправки. Своего файла стилей у страницы нет — в dist и главная,
   и она ссылаются на один собранный файл, который к этому моменту уже лежит
   в кэше, поэтому «спасибо» открывается мгновенно.
   ========================================================================== */

/* Экран целиком, без прокрутки: сообщать здесь больше нечего.
   svh, а не vh: на телефоне адресная строка съедает часть высоты,
   и на vh страница получала бы прокрутку в несколько пикселей. */
.thanks {
  display: flex;
  align-items: center;
  min-height: 100svh;
  padding-block: var(--s-8);
}

.thanks__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-5);
  text-align: center;
}

.thanks__title { margin: 0; }

.thanks__lead { max-width: 34ch; margin: 0; }

/* Даты — не украшение: человек только что оставил заявку и в этот момент
   прикидывает, успевает ли он. Материал тот же, что у надзаголовков. */
.thanks__dates {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-md);
  background: var(--grad-soft);
  border: 1px solid rgba(124, 59, 246, .16);
  color: var(--brand);
  font-weight: 600;
}

.thanks__dates .icon { width: 20px; height: 20px; }

.thanks__actions { margin-top: var(--s-2); }

.thanks__note { margin: 0; }

.thanks__note a { text-decoration: underline; text-underline-offset: .2em; }

@media (max-width: 640px) {
  .thanks__lead { max-width: none; }
  /* Кнопка на телефоне во всю ширину — правило .btn из base.css,
     здесь только выравнивание блока под неё. */
  .thanks__actions { width: 100%; }
}

/* На самом тесном экране страница переставала помещаться целиком: 611px
   содержимого при окне 568. Прокрутка на «спасибо» — мелочь, но она
   обещает, что ниже что-то есть, а там ничего нет. Забираем запас
   у полей: их тут двойные, а сообщать больше нечего. */
@media (max-width: 360px) {
  .thanks { padding-block: var(--s-6); }
  .thanks__inner { gap: var(--s-4); }
}
