/* Базовый слой: сброс, типографика, колонка, повторяющиеся элементы.
   Размеры и цвета — только через переменные из tokens.css.
   Макет: Figma «cursovaya.ru», мобильная 390, десктопная 1440. */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 26px;
  color: var(--color-text-primary);
  background: var(--color-bg-page);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }

img, svg { display: block; max-width: 100%; }
img { height: auto; }

a {
  color: inherit;
  text-decoration: none;
}

button {
  padding: 0;
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

input, select {
  font: inherit;
  color: inherit;
}

/* Фокус виден всегда — обводка не снимается, только приводится к палитре. */
:focus-visible {
  outline: 2px solid var(--color-border-accent);
  outline-offset: 2px;
}

/* --- Колонка ------------------------------------------------------------
   Весь контент живёт в 1200 по центру. На широком мониторе колонка не
   растягивается: это решение владельца, менять нельзя. */
.column {
  width: min(100% - var(--page-gutter) * 2, var(--page-max));
  margin-inline: auto;
}

/* --- Текстовые стили из Figma ------------------------------------------- */
.t-h1 {
  font-size: 32px;
  font-weight: 600;
  line-height: 37px;
  letter-spacing: -0.8px;
}

.t-h2 {
  font-size: 24px;
  font-weight: 600;
  line-height: 29px;
  letter-spacing: -0.48px;
}

.t-h3 {
  font-size: 19px;
  font-weight: 600;
  line-height: 26px;
  letter-spacing: -0.19px;
}

.t-body-l { font-size: 18px; line-height: 29px; }
.t-body-m { font-size: 16px; line-height: 26px; }
.t-body-s { font-size: 15px; line-height: 23px; }

.t-meta {
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
}

.t-caps {
  font-size: 12px;
  font-weight: 500;
  line-height: 14px;
  letter-spacing: 0.96px;
}

.t-muted { color: var(--color-text-muted); }
.t-secondary { color: var(--color-text-secondary); }

/* Вторичный текст на пастельной подложке.
   `text/muted` на story-1..5 даёт контраст 3,6–4,0 при норме 4,5 — это
   ловит проверка доступности и, что важнее, плохо читают люди. `secondary`
   даёт 7,8–8,8 и сохраняет иерархию: заголовок темнее, пояснение светлее. */
.tile .t-muted,
.hero__form .legal,
.cta__card .legal {
  color: var(--color-text-secondary);
}

@media (min-width: 1240px) {
  .t-h1 {
    font-size: 52px;
    line-height: 56px;
    letter-spacing: -1.3px;
  }

  .t-h2 {
    font-size: 36px;
    line-height: 42px;
    letter-spacing: -0.72px;
  }
}

/* --- Кнопка -------------------------------------------------------------
   Подпись везде «Узнать стоимость»: один текст на одно действие. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: 28px;
  font-size: 16px;
  font-weight: 600;
  line-height: 20px;
  letter-spacing: -0.16px;
  white-space: nowrap;
  border-radius: var(--radius-md);
  transition: background-color 0.15s ease;
}

.btn--primary {
  height: 58px;
  color: var(--color-text-on-action);
  background: var(--color-bg-action);
}

.btn--primary:hover { background: var(--color-bg-action-hover); }
.btn--primary:active { background: var(--color-bg-action-pressed); }

.btn--pill {
  height: auto;
  padding: 12px 22px;
  font-size: 14px;
  line-height: 18px;
  letter-spacing: -0.14px;
  color: var(--color-text-on-action);
  background: var(--color-bg-action);
  border-radius: var(--radius-pill);
}

.btn--pill:hover { background: var(--color-bg-action-hover); }

/* --- Правовая строка ----------------------------------------------------
   Две отдельные строки без галочки. С 01.09.2025 (156-ФЗ) согласие
   на обработку данных нельзя объединять с принятием соглашения
   в одном чекбоксе. Объединять обратно нельзя. */
.legal {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xs);
  font-size: 15px;
  line-height: 23px;
  color: var(--color-text-muted);
}

.legal a {
  color: var(--color-text-accent);
  text-decoration: underline;
}

/* --- Поля формы --------------------------------------------------------- */
.field {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  height: 70px;
  padding: 11px 14px 12px;
  background: var(--color-bg-field);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-md);
}

.field__label {
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  color: var(--color-text-muted);
}

/* Значение — всегда одна строка с многоточием: «Научно-исследовательская
   работа» иначе встаёт в три строки и вылезает за поле. */
.field__value {
  width: 100%;
  overflow: hidden;
  font-size: 16px;
  line-height: 26px;
  color: var(--color-text-muted);
  text-overflow: ellipsis;
  white-space: nowrap;
  background: none;
  border: 0;
  appearance: none;
}

.field__chevron {
  position: absolute;
  top: 27px;
  right: 14px;
  width: 16px;
  height: 16px;
  pointer-events: none;
}

/* Поле контакта: слева переключатель способа связи, справа ввод.
   Переключатели 52×48 — проходят норму тач-зоны 44. */
.contact {
  display: flex;
  gap: var(--spacing-sm);
  align-items: center;
  height: 70px;
  padding: 0 14px 0 8px;
  background: var(--color-bg-field);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-md);
}

.contact__ways {
  display: flex;
  gap: 6px;
}

/* Способ связи — радиокнопка внутри подписи: без скрипта выбор тоже
   уходит с формой. Сама кнопка невидима, выбранную подсвечивает :has. */
.contact__way {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 48px;
  background: var(--color-bg-sheet);
  border: 1.5px solid transparent;
  border-radius: 10px;
  cursor: pointer;
}

.contact__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}

.contact__way:has(.contact__radio:checked) {
  background: var(--color-bg-accent-soft);
  border-color: var(--color-border-accent);
}

/* Фокус с клавиатуры виден на подписи: сама кнопка прозрачная. */
.contact__way:has(.contact__radio:focus-visible) {
  outline: 2px solid var(--color-border-accent);
  outline-offset: 2px;
}

.contact__way img { width: 22px; }
.contact__way--mail img { width: 24px; }

.contact__divider {
  width: 1px;
  height: 32px;
  background: var(--color-border-default);
}

.contact__input {
  min-width: 0;
  flex: 1;
  font-size: 16px;
  line-height: 26px;
  background: none;
  border: 0;
  outline: none;
}

.contact__input::placeholder { color: var(--color-text-muted); }

/* --- Состояния формы ------------------------------------------------------
   Макет: борд «Состояния формы» (199:430). */

/* Ошибка в поле: рамка 1.5 цвета danger, текст под полем. */
.field--error,
.contact--error {
  border: 1.5px solid var(--color-border-danger);
}

.form__errors {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xs);
}

/* Контейнер есть всегда, скрипт пишет в него сам. Пустой не должен
   добавлять зазор в колонке формы. */
.form__errors:empty { display: none; }

.form__error {
  font-size: 15px;
  line-height: 23px;
  color: var(--color-text-danger);
}

/* Кнопка во время отправки: спиннер 18 слева от подписи. */
.btn[aria-busy="true"]::before {
  width: 18px;
  height: 18px;
  margin-right: 10px;
  content: "";
  background: url("/static/icon/spinner.svg") center / contain no-repeat;
  animation: btn-spin 0.8s linear infinite;
}

@keyframes btn-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .btn[aria-busy="true"]::before { animation: none; }
}

/* Вторичная кнопка — запасной путь вроде телеграма (компонент «Кнопка»). */
.btn--secondary {
  height: 58px;
  color: var(--color-text-accent);
  background: var(--color-bg-card);
  border: 1.5px solid var(--color-border-accent);
}

.btn--secondary:hover { background: var(--color-bg-accent-soft); }

/* Поле-приманка для роботов: уведено за экран, а не display:none —
   часть рассыльщиков пропускает скрытые поля. */
.form__trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Плашка «Не получилось отправить» (199:491). */
.form-fail {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
  /* danger-soft полупрозрачный: на голубой подложке формы он выходил
     сиреневым. Под него подложен белый — розовый, как в макете. */
  background: linear-gradient(var(--color-bg-danger-soft), var(--color-bg-danger-soft)), var(--color-bg-card);
  border-radius: 20px;
}

.form-fail .btn { width: 100%; }

/* В макете muted; на розовой подложке он не добирает контраста 4,5. */
.form-fail__note { color: var(--color-text-secondary); }

.form-fail__note a {
  color: var(--color-text-accent);
  text-decoration: underline;
}
