/*
 * Общее для всех чистовых страниц: сброс, типографика страницы, контейнер,
 * логотип, кнопки, блок ошибки.
 *
 * Зачем отдельный файл. Экраны входа должны выглядеть так же, как лендинг,
 * а «так же» через копирование правил живёт ровно до первой правки: цвет
 * кнопки меняют в одном файле и забывают в другом. Общее лежит здесь,
 * своё у каждой страницы — в её файле (landing.css, auth.css).
 *
 * Правило 4 из docs/frontend-rules.md действует и здесь: ни одного hex-кода,
 * ни одного font-family, ни одного размера мимо tokens.css.
 */

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

/*
 * Атрибут hidden должен побеждать любой display из этого файла.
 * Правило браузера [hidden] { display: none } — стиль пользовательского
 * агента, и авторский display: inline-block у .button перебивает его
 * независимо от специфичности: скрытая кнопка осталась бы видимой.
 */
[hidden] { display: none !important; }

/*
 * Место под полосу прокрутки резервируется всегда, даже когда прокручивать
 * нечего.
 *
 * Без этого страницы дёргаются друг относительно друга: лендинг длинный,
 * полоса на нём есть и сужает окно на свою ширину; экран входа помещается
 * целиком, полосы нет — и центрированный контейнер вместе со всей шапкой
 * съезжает на половину её ширины. При переходе это видно как прыжок логотипа.
 *
 * Ширину полосы браузер выбирает сам, и токеном она быть не может: на macOS
 * с наложенными полосами она нулевая, в Windows — нет.
 */
html { scrollbar-gutter: stable; }

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
}

a { color: var(--color-link); text-decoration: none; }
a:hover { color: var(--color-primary-400); }

::selection {
  background: var(--color-selection-surface);
  color: var(--color-selection-text);
}

:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/*
 * Ширина из прототипа (--layout-max-width), поля — ближайший шаг сетки:
 * в прототипе 56px, ступени 56 в spacing нет, ближайшая --space-16 = 64px.
 */
.container {
  max-width: var(--layout-max-width);
  margin: 0 auto;
  padding: 0 var(--space-16);
}

/*
 * На узком экране поля контейнера уменьшаются: 64px с каждой стороны съедали
 * треть экрана шириной 375px, и в шапке кабинета логотип с блоком входа
 * переставали помещаться в одну строку.
 *
 * Правило живёт здесь, а не в файлах страниц: оно было продублировано
 * в landing.css, auth.css и booking.css и просто забыто в cabinet.css —
 * ровно тот случай, ради которого заведён общий слой.
 *
 * Брейкпоинт md дизайн-системы (≥768px). Переменной он быть не может:
 * пользовательские свойства в media-запросах не работают.
 */
@media (max-width: 767px) {
  .container { padding: 0 var(--space-6); }
}

/* ============================================================ ЛОГОТИП */

.logo {
  font-family: var(--font-heading);
  font-weight: var(--font-weight-extrabold);
  font-size: var(--text-h4-size);
  letter-spacing: var(--text-h2-tracking);
  text-transform: uppercase;
  color: var(--color-text);
}

.logo:hover { color: var(--color-text); }
.logo__dot { color: var(--color-accent); }

/* ============================================================ КНОПКИ */

.button {
  display: inline-block;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-line);
  border-radius: var(--radius-md);
  border: var(--border-width) solid transparent;
  padding: var(--space-3) var(--space-6);
  text-align: center;
}

.button--lg {
  font-size: var(--text-body-size);
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-md);
}

.button--primary {
  background: var(--color-button);
  color: var(--color-button-text);
}

.button--primary:hover {
  background: var(--color-button-hover);
  color: var(--color-button-text);
}

.button--ghost {
  background: transparent;
  color: var(--color-link);
}

.button--ghost:hover {
  background: var(--color-primary-50);
  color: var(--color-link);
}

.button--outline {
  background: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text-body);
}

.button--outline:hover {
  background: var(--color-surface);
  color: var(--color-text-body);
}

/*
 * Второстепенная кнопка дизайн-системы — из разметки блока «Форма услуги»,
 * токены --color-button-secondary-*. Нужна рядом с основной на белой карточке:
 * у .button--outline наведение заливает кнопку цветом поверхности, и на
 * карточке его не видно. Первое место — «Войти через Яндекс» на А-1 и А-2.
 */
.button--secondary {
  background: var(--color-button-secondary-surface);
  border-color: var(--color-button-secondary-border);
  color: var(--color-button-secondary-text);
}

.button--secondary:hover {
  background: var(--color-button-secondary-hover-surface);
  color: var(--color-button-secondary-text);
}

/* Кнопка на карточке услуги: контур акцентом. */
.button--accent-outline {
  background: transparent;
  border-color: var(--color-accent);
  color: var(--color-link);
}

.button--accent-outline:hover {
  background: var(--color-primary-50);
  color: var(--color-link);
}

/* Кнопка на акцентной заливке баннера. */
.button--on-accent {
  background: var(--color-surface);
  color: var(--color-link);
}

.button--on-accent:hover {
  background: var(--color-primary-50);
  color: var(--color-link);
}

/*
 * Заблокированная кнопка. В дизайн-системе этого состояния нет вовсе
 * (tokens.css, пункт 2 списка пропусков: нарисованы только базовое
 * и наведение). Собрано из нейтральной шкалы — новых значений это
 * не вводит, но выбор оттенков здесь мой, а не из макета.
 */
.button[disabled] {
  cursor: not-allowed;
  background: var(--color-neutral-200);
  border-color: transparent;
  color: var(--color-neutral-500);
}

.button[disabled]:hover {
  background: var(--color-neutral-200);
  color: var(--color-neutral-500);
}

/* ============================================================ СООБЩЕНИЯ */

/*
 * Ошибку API показываем текстом на экране (правило 7): в консоли её человек
 * не увидит, для него это просто зависшая кнопка.
 */
.load-error {
  margin: 0 0 var(--space-8);
  padding: var(--space-4) var(--space-6);
  border: var(--border-width) solid var(--color-danger-border);
  border-radius: var(--radius-md);
  background: var(--color-danger-surface);
  color: var(--color-danger-text);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
}

.empty {
  margin: 0;
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--color-text-muted);
}

/* ============================================================ МОДАЛЬНОЕ ОКНО */

/*
 * Окно поверх страницы: отмена записи в кабинете (К-4), форма и подтверждение
 * удаления в панели администратора. Разметка — родной <dialog> с showModal():
 * он сам держит фокус внутри, закрывается по Esc и рисует затемнение.
 *
 * Лежит здесь по той же причине, по которой сюда переехали поля форм: правила
 * жили в cabinet.css, а понадобились второму разделу. Скопированные, они
 * разошлись бы на первой же правке. Своё у окна остаётся в файле раздела —
 * в cabinet.css это блок правил отмены и предупреждение о позднем отказе.
 */

.modal {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  padding: var(--space-8);
  max-width: var(--measure-lg);
  width: 100%;
  color: var(--color-text);
}

.modal::backdrop { background: var(--color-neutral-900); opacity: 0.4; }

.modal__title {
  font-family: var(--font-heading);
  font-weight: var(--text-h3-weight);
  font-size: var(--text-h3-size);
  line-height: var(--text-h3-line);
  letter-spacing: var(--text-h3-tracking);
  margin: 0 0 var(--space-3);
}

.modal__body {
  margin: 0 0 var(--space-4);
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
  color: var(--color-text-body);
}

.modal__actions {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-6);
  flex-wrap: wrap;
}

/*
 * Окно не должно вырастать выше экрана: с предупреждением о поздней отмене
 * оно доходило до 602px при экране 640px, и вторая кнопка уезжала за край.
 * Теперь высота ограничена, содержимое прокручивается внутри окна,
 * а кнопки прижаты к его низу и видны всегда.
 *
 * Единица dvh, а не vh: на телефоне адресная строка то появляется,
 * то исчезает, и vh считается по большему из состояний — окно вылезало бы
 * ровно на её высоту.
 */
@media (max-width: 767px) {
  .modal {
    padding: var(--space-6);
    max-height: calc(100dvh - var(--space-8));
    overflow-y: auto;
  }

  .modal__actions {
    flex-direction: column;
    position: sticky;
    bottom: 0;
    background: var(--color-surface);
    padding-top: var(--space-4);
    padding-bottom: var(--space-2);
  }
}

/* ============================================================ ПОЛЯ ФОРМ */

/*
 * Поля используют и экраны входа, и форма контактов на подтверждении записи.
 * Лежали в auth.css — и на booking.html оказывались неподключёнными: поля
 * рисовались браузером по умолчанию. Общее место лечит это раз и навсегда.
 */

.field { margin-bottom: var(--space-6); }

.field__label {
  display: block;
  font-size: var(--text-label-size);
  line-height: var(--text-label-line);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.field__optional { color: var(--color-text-subtle); }

.field__input {
  display: block;
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--color-text);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border-strong);
  /* Радиус полей админки (--radius-sm) в системе назначен админке; клиентское
     поле берёт радиус кнопки, рядом с которой стоит. */
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
}

.field__input::placeholder { color: var(--color-text-subtle); }

/*
 * Поле с ошибкой. Состояния ошибки у поля в дизайн-системе нет вовсе
 * (tokens.css, пункт 4 списка пропусков), поэтому взят --color-danger —
 * токен, объявленный в системе именно как «ошибка формы».
 */
.field--invalid .field__input { border-color: var(--color-danger); }

.field__error {
  margin: var(--space-2) 0 0;
  font-size: var(--text-body-sm-size);
  line-height: var(--text-body-sm-line);
  color: var(--color-danger-text);
}
