/* ===========================================================================
   Компоненты. Состояния оформлены сразу: hover / focus / active / disabled /
   loading / empty / error — иначе интерфейс молчит там, где должен отвечать.
   =========================================================================== */

/* --- кнопки -------------------------------------------------------------- */
.btn {
  --btn-bg: var(--brand);
  --btn-fg: var(--on-brand);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  min-height: 48px;
  padding: 0 var(--s-6);
  border: 1px solid transparent;
  border-radius: 3px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--text);
  font-size: var(--t-sm);
  font-weight: 600;
  text-decoration: none;
  /* Подпись кнопки не переносится: перенос превращает кнопку в абзац
     с рамкой. Если подпись не влезает — узкой оказалась колонка, и
     чинить надо колонку. Исключение — экраны уже 400 px, см. ниже. */
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--d-2) var(--e-move),
              transform var(--d-1) var(--e-out),
              border-color var(--d-2) var(--e-move);
}
.btn:hover  { --btn-bg: var(--brand-2); }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled='true'] {
  opacity: .45; cursor: not-allowed; transform: none;
}
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--fg);
  border-color: var(--line-2);
}
.btn--ghost:hover { --btn-bg: transparent; border-color: var(--fg); }
.btn--on-dark {
  --btn-bg: var(--on-dark); --btn-fg: var(--dark);
}
.btn--on-dark:hover { --btn-bg: var(--white); }
/* Кромка призрачной кнопки на тёмном раньше была --line-dark (#333A41):
   на фоне #15181B это 1.5:1, кнопка читалась как строка текста. Нетекстовому
   элементу нужно 3:1 — берём тот же нейтраль, что и у второстепенного текста
   (6.98:1), и кнопка наконец видна, в том числе поверх фотографии. */
.btn--ghost-dark {
  --btn-bg: transparent; --btn-fg: var(--on-dark);
  border-color: var(--on-dark-fg-3);
}
.btn--ghost-dark:hover { --btn-bg: rgb(255 255 255 / .08); border-color: var(--on-dark); }
.btn--lg { min-height: 56px; padding-inline: var(--s-7); font-size: var(--t-base); }
.btn--block { display: flex; width: 100%; }

/* На узком экране запрет переноса уводит страницу вбок: «Записаться
   на тренировку» требует 317 px, а в поле 320-пиксельного экрана
   остаётся 288. Горизонтальная прокрутка всей страницы хуже, чем
   подпись в две строки, поэтому здесь перенос разрешён. */
@media (max-width: 25em) {
  .btn {
    white-space: normal;
    text-align: center;
    line-height: 1.22;
    padding-block: .6rem;
  }
}

.btn.is-loading { pointer-events: none; opacity: .8; }
.btn.is-loading::after {
  content: ''; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn.is-loading::after { animation-duration: 2s; }
}

/* Заголовок в узкой колонке: кегль основного h2 там рвётся на четыре
   короткие строки и выглядит зажатым. */
.h2--tight { font-size: clamp(1.6rem, 2.7vw, 2.4rem); }

.lede {
  font-size: clamp(1.0625rem, 1.6vw, var(--t-md));
  line-height: 1.48;
  color: var(--fg-2);
  max-width: 62ch;
}

.meta {
  font-size: var(--t-xs);
  color: var(--fg-3);
}

/* WCAG 2.2 SC 2.5.8: самостоятельная ссылка — это цель нажатия, и она
   обязана быть не меньше 24×24. Исключение только для ссылок внутри
   предложения, где размер задан интерлиньяжем соседнего текста. */
.audience__card a,
.fact__src a,
.footer__list a,
.footer__legal a,
.footer__social a,
.crumbs a,
.dir__go,
.rating__where a,
.sched td a,
.coach a {
  display: inline-block;
  min-height: 24px;
  padding-block: 4px;
}
.footer__list a { display: block; }
.check input { width: 24px; height: 24px; }

/* Ссылка внутри абзаца по букве стандарта исключена из требования 24×24,
   но пальцу от этого не легче: мелкий текст даёт цель в 16–18px.
   Вертикальный padding у строчного элемента увеличивает область нажатия,
   не сдвигая ни строки, ни соседние блоки. */
p a:not(.btn),
li a:not(.btn),
dd a:not(.btn),
figcaption a,
.note a,
.doc a,
.faq__body a,
.timeline__d a,
.principle__d a,
.step__d a {
  padding-block: 4px;
}

/* --- цифра-факт: отдельный типографический приём ----------------------- */
.facts {
  display: grid; gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
  grid-template-columns: repeat(2, 1fr);
}
/* Пять фактов в двух колонках оставляют пустую ячейку — она читается как сбой.
   Последний факт занимает строку целиком. */
.facts > .fact:last-child { grid-column: 1 / -1; }
@media (min-width: 45em)  {
  .facts { grid-template-columns: repeat(3, 1fr); }
  .facts > .fact:last-child { grid-column: auto; }
}
@media (min-width: 66.25em) { .facts { grid-template-columns: repeat(5, 1fr); } }
.fact {
  background: var(--bg);
  padding: var(--s-7) var(--s-5) var(--s-6);
  display: flex; flex-direction: column; gap: var(--s-2);
}
/* Цифры — единственное громкое место в этой вёрстке. Всё остальное
   держится тихо, поэтому им можно отдать весь запас смелости. */
.fact__n {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(3.1rem, 6.4vw, 5.6rem);
  line-height: 0.84; letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}
.fact__n sup { font-size: 0.34em; vertical-align: super; letter-spacing: 0;
  font-weight: 400; margin-left: .06em; }
.fact__label { font-size: var(--t-sm); color: var(--fg-2); line-height: 1.34; }
.fact__src { font-size: var(--t-xs); color: var(--fg-3); }
.fact__src a { color: inherit; }

/* --- карточки направлений: разный вес и разный span --------------------- */
.dirs {
  display: grid; gap: var(--s-4);
  grid-template-columns: 1fr;
}
@media (min-width: 43.75em)  { .dirs { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 65em) { .dirs { grid-template-columns: repeat(6, 1fr); } }

.dir {
  position: relative;
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 300px;
  padding: var(--s-6);
  overflow: hidden;
  background: var(--dark-2);
  color: var(--on-dark);
  text-decoration: none;
  isolation: isolate;
}
@media (min-width: 65em) {
  .dir { grid-column: span 2; }
  .dir--wide  { grid-column: span 3; min-height: 400px; }
  .dir--tall  { grid-column: span 3; min-height: 400px; }
}
.dir__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform var(--d-6) var(--e-move), filter var(--d-4) var(--e-move);
  filter: saturate(.82);
}
.dir::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  /* Общая плёнка задаёт настроение кадра и держит контраст в верхней
     половине. Читаемость подписей обеспечивает не она, а подложка под
     самим текстом (.dir__body): плёнка, привязанная к высоте плитки,
     на короткой карточке с длинным названием оставляла подпись возраста
     на светлой стене. */
  background: linear-gradient(178deg,
    rgba(12,11,10,.16) 0%, rgba(12,11,10,.30) 40%, rgba(12,11,10,.46) 100%);
  transition: opacity var(--d-4) var(--e-move);
}
/* Детская карточка светлее остальных: тёмная агрессивная подача на детской
   аудитории работает против клуба. Плёнка слабее, фото ярче. */
.dir--kids .dir__img { filter: saturate(.95) brightness(1.14); }
.dir--kids::after {
  /* Светлее остальных, но не в ущерб читаемости: подпись на детской карточке
     ложится на светлую стену, поэтому середина плёнки плотнее верха. */
  background: linear-gradient(178deg,
    rgba(24,20,14,.06) 0%, rgba(24,20,14,.20) 40%, rgba(24,20,14,.34) 100%);
}
.dir:hover .dir__img { transform: scale(1.035); filter: saturate(.95); }
.dir:focus-visible { outline-offset: -3px; }

/* Подложка под текстом плитки: растягивается на всю ширину карточки
   и на её нижние поля, поэтому не зависит ни от высоты плитки, ни от
   того, во сколько строк легло название. */
.dir__body {
  display: flex; flex-direction: column;
  margin: 0 calc(var(--s-6) * -1) calc(var(--s-6) * -1);
  padding: 3rem var(--s-6) var(--s-6);
  background: linear-gradient(0deg,
    rgba(12,11,10,.90) 0%, rgba(12,11,10,.88) 58%,
    rgba(12,11,10,.62) 84%, rgba(12,11,10,0) 100%);
}
.dir--kids .dir__body {
  background: linear-gradient(0deg,
    rgba(24,20,14,.88) 0%, rgba(24,20,14,.85) 58%,
    rgba(24,20,14,.58) 84%, rgba(24,20,14,0) 100%);
}

.dir__age {
  font-size: var(--t-xs); font-weight: 500;
  /* Полупрозрачный белый на светлом кадре давал 2,26:1. Возраст —
     не украшение подписи, а условие набора в группу. */
  color: rgba(255,255,255,.94);
  margin-bottom: var(--s-3);
}
.dir__name {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 0.98;
  letter-spacing: -0.015em;
}
.dir--wide .dir__name, .dir--tall .dir__name { font-size: clamp(1.9rem, 4vw, 3rem); }
.dir__note {
  margin-top: var(--s-3);
  font-size: var(--t-sm); color: rgba(255,255,255,.78);
  max-width: 34ch;
}
.dir__go {
  margin-top: var(--s-5);
  font-size: var(--t-sm); font-weight: 600;
  border-bottom: 1px solid rgba(255,255,255,.4);
  align-self: flex-start; padding-bottom: 2px;
  transition: border-color var(--d-2) var(--e-move);
}
.dir:hover .dir__go { border-color: var(--white); }

/* --- принципы: редакционный список, не сетка одинаковых карточек -------- */
.principles { display: grid; gap: 1px; background: var(--line); }
.principle {
  background: var(--bg);
  display: grid; gap: var(--s-4);
  padding: var(--s-6) 0;
  grid-template-columns: 1fr;
}
@media (min-width: 51.25em) {
  .principle { grid-template-columns: 1fr 1.15fr; gap: var(--s-6); align-items: start;
    padding: var(--s-7) 0; }
}
.principle__t {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(1.3rem, 2.4vw, 1.9rem); line-height: 1.04;
  letter-spacing: -0.012em;
}
.principle__d { color: var(--fg-2); font-size: var(--t-base); }
.principle__d q { quotes: '«' '»' '„' '“'; font-style: normal; }

/* --- расписание -------------------------------------------------------------
   Плоский список на двадцать одну строку не отвечал на вопрос, ради которого
   на расписание смотрят: «мне-то куда и когда». Занятий двадцать одно, а
   групп восемь — одна группа ходит по нескольким дням в одно время.
   Поэтому первый уровень здесь направление, второй — группа, и только
   внутри группы дни и время. Второй вид, недельная сетка, для тех, кто
   идёт от свободного вечера, а не от группы. */

.sched__bar {
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6);
  align-items: center; justify-content: space-between;
  margin-bottom: var(--s-6);
}
.stabs {
  position: relative;
  display: flex; gap: var(--s-2);
  overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  margin-inline: calc(var(--pad) * -1);
  padding-inline: var(--pad);
  /* Лента длиннее экрана — это нормально; ненормально, когда обрыв ничем
     не обозначен и последняя вкладка выглядит просто обрезанной. */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
}
.stabs::-webkit-scrollbar { display: none; }
/* Когда всё помещается, маска не нужна: она бы съедала край последней вкладки. */
@media (min-width: 56.25em) {
  .stabs { -webkit-mask-image: none; mask-image: none; }
}
.stab {
  flex: 0 0 auto;
  min-height: 42px; padding: 0 var(--s-5);
  border: 1px solid var(--line-2); border-radius: 100px;
  background: transparent;
  font-family: var(--text); font-size: var(--t-sm); font-weight: 500;
  color: var(--fg-2); white-space: nowrap; cursor: pointer;
  transition: border-color var(--d-2) var(--e-move),
              color var(--d-2) var(--e-move),
              background var(--d-2) var(--e-move);
}
.stab:hover { border-color: var(--fg-2); color: var(--fg); }
.stab[aria-selected='true'] {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
}

.sched__views { display: flex; flex: 0 0 auto; border: 1px solid var(--line-2); }
.sview {
  min-height: 42px; padding: 0 var(--s-4);
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--text); font-size: var(--t-sm); font-weight: 500;
  color: var(--fg-3); white-space: nowrap;
  transition: color var(--d-2) var(--e-move), background var(--d-2) var(--e-move);
}
.sview + .sview { border-left: 1px solid var(--line-2); }
.sview:hover { color: var(--fg); }
.sview[aria-pressed='true'] { background: var(--bg-sunk); color: var(--fg); }

/* Карточки групп. Высоту ряда держит сетка, действие прижато к низу —
   иначе описания разной длины разносят нижнюю кромку ступенькой. */
.sched__groups {
  display: grid; gap: var(--s-4);
  grid-template-columns: 1fr;
  align-items: stretch;
}
@media (min-width: 42em)   { .sched__groups { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68.75em) { .sched__groups { grid-template-columns: repeat(3, 1fr); } }

.sgroup {
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
  background: var(--bg-3);
  padding: var(--s-5);
  transition: border-color var(--d-2) var(--e-move);
}
.sgroup.is-hidden { display: none; }
.sgroup:hover { border-color: var(--line-2); }
.sgroup__head { display: grid; gap: 4px; }
.sgroup__name {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-lg); line-height: 1.06; letter-spacing: -0.01em;
  margin: 0;
}
/* Тач-цель не меньше 24 px: подпись направления — ссылка, а не текст. */
.sgroup__dir {
  font-size: var(--t-xs); color: var(--fg-3);
  display: inline-flex; align-items: center; min-height: 24px;
  align-self: start;
}
.sgroup__dir:hover { color: var(--fg); }

.sgroup__slots {
  list-style: none; margin: var(--s-4) 0 0; padding: 0;
  display: grid; gap: 1px; background: var(--line);
  border-block: 1px solid var(--line);
}
/* День и время стояли по разным краям карточки: между «Ср» и «09:00–10:20»
   оставалось 225 px пустоты из 337. Время идёт сразу за днём. */
.sgroup__slot {
  display: grid; grid-template-columns: 2.6rem 1fr; align-items: baseline;
  gap: var(--s-4);
  background: var(--bg-3);
  padding: var(--s-3) 0;
}
.sgroup__slot b {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-md); letter-spacing: -0.01em;
}
.sgroup__slot time {
  font-family: var(--mono); font-size: var(--t-sm); font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--fg-2);
}
.sgroup__slot.is-today b { color: var(--accent-ink); }
.sgroup__slot.is-now {
  background: rgb(var(--accent-rgb) / .09);
  margin-inline: calc(var(--s-3) * -1); padding-inline: var(--s-3);
}
.sgroup__slot.is-now time { color: var(--accent-ink); }

/* Действие прижато к низу карточки: сколько бы дней ни было в группе,
   кнопки в ряду стоят на одной линии. */
.sgroup__foot {
  margin-top: auto; padding-top: var(--s-4);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-3);
}
.sgroup__go {
  font-size: var(--t-sm); font-weight: 500;
  text-decoration: none; color: var(--fg);
  border-bottom: 2px solid var(--accent);
  padding-block: 4px;
  transition: color var(--d-2) var(--e-move);
}
.sgroup__go:hover { color: var(--accent-ink); }

/* --- вид «по дням недели» --------------------------------------------- */
.sched__week {
  display: grid; gap: var(--s-3);
  grid-template-columns: 1fr;
}
@media (min-width: 42em)    { .sched__week { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62.5em)  { .sched__week { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 81.25em) { .sched__week { grid-template-columns: repeat(7, 1fr); } }
.wday { border: 1px solid var(--line); background: var(--bg-3); padding: var(--s-4); }
.wday.is-today { border-color: var(--accent); }
.wday__t {
  margin: 0 0 var(--s-3);
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-md); letter-spacing: -0.01em;
}
.wday.is-today .wday__t { color: var(--accent-ink); }
.wday__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.wday__item { display: grid; gap: 2px; padding-top: var(--s-3); border-top: 1px solid var(--line); }
.wday__item:first-child { padding-top: 0; border-top: 0; }
.wday__item.is-hidden { display: none; }
.wday__item.is-now { background: rgb(var(--accent-rgb) / .09);
  margin-inline: calc(var(--s-3) * -1); padding-inline: var(--s-3); }
.wday__item time {
  font-family: var(--mono); font-size: var(--t-sm); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.wday__group { font-size: var(--t-sm); color: var(--fg-2); }
.wday__dir { font-size: var(--t-xs); color: var(--fg-3); }
.wday__item--off .wday__group { color: var(--fg-3); font-style: italic; }

.sched__empty {
  padding: var(--s-7) var(--s-5);
  text-align: center; color: var(--fg-3);
  border: 1px dashed var(--line-2);
}

.tag {
  display: inline-block;
  font-size: var(--t-xs);
  padding: 3px 10px;
  border: 1px solid var(--line-2);
  border-radius: 100px;
  color: var(--fg-2);
  white-space: nowrap;
}

/* --- цены ---------------------------------------------------------------- */
.tariffs { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
@media (min-width: 47.5em)  { .tariffs { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 67.5em) { .tariffs { grid-template-columns: repeat(4, 1fr); } }
/* Карточки тарифов выровнены по строкам, а не по потоку: иначе название
   в две строки сдвигает цену вниз и колонка цен разъезжается. */
.tariff {
  background: var(--bg-3);
  border: 1px solid var(--line);
  padding: var(--s-6);
  display: grid;
  gap: var(--s-4);
  grid-template-rows: auto auto 1fr auto;
  align-content: start;
}
.tariff--lead { border-color: var(--fg); }
.tariff__name { font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-md); letter-spacing: -0.01em; line-height: 1.12;
  min-height: 2.24em; display: flex; align-items: flex-start; }
.tariff__price {
  font-family: var(--display); font-weight: 700;
  font-size: var(--t-2xl); line-height: 1; letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}
.tariff__price small { font-size: 0.4em; font-weight: 400; color: var(--fg-3);
  font-family: var(--text); letter-spacing: 0; }
.tariff__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2);
  font-size: var(--t-sm); color: var(--fg-2); }
.tariff__list li { padding-left: 1.1rem; position: relative; }
.tariff__list li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 6px; height: 1px; background: var(--fg-3);
}
.tariff__ask {
  /* «уточняется» — это отсутствие данных, а не состояние «идёт сейчас»,
     поэтому строка нейтральная. */
  font-size: var(--t-xs); color: var(--fg-3);
}

/* --- галерея зала: разный span, а не ровная сетка ---------------------- */
.gallery {
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(2, 1fr);
  /* Высоту ряда задаёт сетка, а не пропорция каждой плитки.
     Раньше .g-1 (3/4 в одну колонку) давала 393 px, а .g-2 (3/2 в две)
     — 385, и нижняя кромка ряда шла ступенькой. */
  grid-auto-rows: 1fr;
}
@media (min-width: 56.25em) { .gallery { grid-template-columns: repeat(4, 1fr); } }
.gallery figure { margin: 0; position: relative; overflow: hidden; background: var(--bg-2); }
.gallery img { width: 100%; height: 100%; object-fit: cover; }
.gallery figure, .gallery picture { display: block; }
/* Пропорция остаётся ориентиром высоты ряда, но не жёстким размером:
   плитка растягивается до общей высоты, кадр докадрируется по cover. */
.gallery .g-1 { aspect-ratio: 3 / 4; }
.gallery .g-2 { aspect-ratio: 3 / 2; }
.gallery .g-1, .gallery .g-2 { height: 100%; }
.gallery picture { height: 100%; }
@media (max-width: 56.1875em) {
  .gallery .g-1, .gallery .g-2 { aspect-ratio: 4 / 5; }
}
.gallery figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--s-6) var(--s-4) var(--s-3);
  font-size: var(--t-xs); font-weight: 500; color: var(--white);
  /* Плёнка доводит худшую точку под глифами до 4,5:1. Прежняя
     (transparent → .78) держала медиану, но на светлых кадрах — полка
     с кубками, окна, ринг при дневном свете — подпись падала до 2,7. */
  background: linear-gradient(transparent, rgba(10,9,8,.66) 42%, rgba(10,9,8,.95));
}
/* Ширина плитки задаётся сборкой: ряды всегда набирают четыре колонки,
   поэтому в галерее не остаётся дырявых строк. */
@media (min-width: 56.25em) {
  .gallery .g-1 { grid-column: span 1; }
  .gallery .g-2 { grid-column: span 2; }
}
@media (max-width: 56.1875em) {
}

/* --- отзывы: рейтинг со ссылкой, а не самописные карточки -------------- */
.rating {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-5);
}
.rating__score {
  font-family: var(--display); font-weight: 700;
  font-size: var(--t-num); line-height: 0.9; letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}
.rating__stars { display: flex; gap: 3px; }
.rating__stars svg { width: 18px; height: 18px; fill: var(--accent); }
.rating__where { font-size: var(--t-sm); color: var(--fg-2); }

/* --- форма --------------------------------------------------------------- */
.form { display: grid; gap: var(--s-5); }
.field { display: grid; gap: var(--s-2); }
.field label { font-size: var(--t-sm); font-weight: 500; }
.field .hint { font-size: var(--t-xs); color: var(--fg-3); }
.field input, .field select, .field textarea {
  font-family: var(--text); font-size: var(--t-base);
  min-height: 50px;
  padding: var(--s-3) var(--s-4);
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  border-radius: 3px;
  color: var(--fg);
  transition: border-color var(--d-2) var(--e-move), box-shadow var(--d-2) var(--e-move);
  width: 100%;
}
.field textarea { min-height: 110px; resize: vertical; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--fg-3); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--fg);
  box-shadow: 0 0 0 3px rgb(var(--fg-rgb) / .14);
}
.field input[aria-invalid='true'] { border-color: var(--accent); }
.field .error { font-size: var(--t-xs); color: var(--accent-ink); display: none; }
.field input[aria-invalid='true'] ~ .error { display: block; }
.field input:disabled { background: var(--bg-sunk); color: var(--fg-3); cursor: not-allowed; }

.check { display: grid; grid-template-columns: auto 1fr; gap: var(--s-3);
  align-items: start; font-size: var(--t-sm); color: var(--fg-2); }
.check input { width: 24px; height: 24px; margin: 0; accent-color: var(--fg);
  flex: 0 0 auto; cursor: pointer; }
.check label { cursor: pointer; font-weight: 400; line-height: 1.75; }
/* Ссылка внутри согласия — тоже цель нажатия: 18px строки мало для пальца. */
.check a { padding-block: 4px; }
.check a { color: var(--fg); }
.check input[aria-invalid='true'] { outline: 2px solid var(--accent); outline-offset: 2px; }

.form__status { font-size: var(--t-sm); min-height: 1.4em; }
.form__status[data-state='error'] { color: var(--accent-ink); }
.form__status[data-state='ok'] { color: var(--ok); }

/* --- аккордеон ----------------------------------------------------------- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none;
  padding: var(--s-5) 0;
  display: flex; gap: var(--s-4); align-items: baseline;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.15rem, 2vw, 1.5rem); line-height: 1.16;
  letter-spacing: -0.008em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; margin-left: auto;
  font-family: var(--mono); font-weight: 400; font-size: var(--t-md);
  color: var(--fg-3);
  transition: transform var(--d-3) var(--e-move);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq summary:hover { color: var(--fg); }
.faq__body { padding-bottom: var(--s-6); color: var(--fg-2); max-width: 68ch; }

/* --- шаги ---------------------------------------------------------------- */
.steps { display: grid; gap: 1px; background: var(--line); counter-reset: st; }
@media (min-width: 53.75em) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step { background: var(--bg); padding: var(--s-6) var(--s-5); counter-increment: st; }
.step__n {
  /* Красный на сайте означает ровно одно состояние — «идёт сейчас».
     Порядковая подпись — не состояние, поэтому она нейтральная. */
  font-size: var(--t-xs); font-weight: 600; color: var(--fg-3);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--s-4); display: block;
}
.step__n::before { content: 'шаг ' counter(st); }
/* Нумерация ставится только там, где содержимое действительно
   последовательность. Перечисление из четырёх равноправных пунктов —
   не последовательность, и цифры там врут о структуре. */
.steps--plain .step__n { display: none; }
.steps--plain .step__t { margin-top: 0; }
.step__t { font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-md); line-height: 1.08; margin-bottom: var(--s-3); }
.step__d { font-size: var(--t-sm); color: var(--fg-2); }

/* --- карточка тренера ----------------------------------------------------- */
.coaches { display: grid; gap: var(--s-5); grid-template-columns: 1fr; }
@media (min-width: 45em)  { .coaches { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 65em) { .coaches { grid-template-columns: repeat(3, 1fr); } }
.coach {
  display: flex; flex-direction: column; gap: var(--s-4);
  text-decoration: none;
  padding: var(--s-4);
  border: 1px solid transparent;
  background: transparent;
  transition: background var(--d-2) var(--e-move),
              border-color var(--d-2) var(--e-move);
}
.coach__img { background: var(--bg-2); overflow: hidden; position: relative; }
.coach__img img { width: 100%; aspect-ratio: 4/5; object-fit: cover;
  transition: transform var(--d-5) var(--e-move); }
.coach__name { font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: var(--t-lg); line-height: 1.02; letter-spacing: -0.012em;
  transition: color var(--d-2) var(--e-move); }
.coach__role { font-size: var(--t-xs); color: var(--fg-3); }
.coach__regalia { font-size: var(--t-sm); color: var(--fg-2); }
/* Карточка со страницей внутри должна отличаться от карточки без неё.
   Раньше обе выглядели одинаково: ни рамки, ни стрелки, ни отклика на
   наведение — единственным признаком ссылки был курсор. */
a.coach { cursor: pointer; }
/* Ячейка без человека: рамка пунктиром говорит «здесь пока пусто», а не
   притворяется карточкой тренера. */
.coach--pending {
  border-style: dashed; border-color: var(--line-2);
  background: var(--bg-2);
  justify-content: center;
}
.coach--pending .coach__name { color: var(--fg-3); }
a.coach:hover { background: var(--bg-3); border-color: var(--line); }
a.coach:hover .coach__img img { transform: scale(1.04); }
a.coach:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.coach__go {
  margin-top: auto; padding-top: var(--s-4);
  display: inline-flex; align-items: center; gap: var(--s-3);
  align-self: start;
  font-size: var(--t-sm); font-weight: 600; color: var(--fg);
}
.coach__go span { border-bottom: 2px solid var(--accent); padding-bottom: 2px; }
.coach__go svg {
  width: 18px; height: 18px; flex: 0 0 18px; fill: none;
  stroke: currentColor; stroke-width: 2;
  transition: transform var(--d-2) var(--e-move);
}
a.coach:hover .coach__go svg { transform: translateX(5px); }
@media (prefers-reduced-motion: reduce) {
  a.coach:hover .coach__img img { transform: none; }
  a.coach:hover .coach__go svg { transform: none; }
}

/* --- окно записи ----------------------------------------------------------
   Кнопка «Записаться» в шапке уводила на другую страницу и роняла человека
   в самый низ формы. Теперь она открывает диалог поверх страницы: та же
   форма, тот же обработчик, страница под ней не теряется. Без скрипта
   ссылка работает по-старому и ведёт на /reference/courage/first-visit/#signup. */
.modal {
  width: min(40rem, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
  color: var(--fg);
}
.modal::backdrop { background: rgb(9 10 12 / .82); }
.modal__box {
  position: relative;
  background: var(--bg-3);
  border-top: 3px solid var(--accent);
  padding: clamp(1.15rem, 3.2vw, 2rem);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal__box .form h2 { font-size: var(--t-xl); padding-right: 3rem; }

/* Форма в окне обязана помещаться в экран целиком: прокрутка внутри диалога
   не читается как прокрутка, и кнопка отправки оказывается за краем.
   Всё ниже — про плотность, а не про размер целей нажатия: поля остаются
   46 px, флажки 24 px. */
.modal .form { gap: var(--s-4); }
.modal .field { gap: 5px; }
.modal .field input,
.modal .field select { min-height: 46px; }
.modal .check label { line-height: 1.45; }
/* Строка ответа занимает место, пока в ней ничего нет. */
.modal .form__status:empty { display: none; }

@media (min-width: 34em) {
  /* Имя и телефон в одну строку: короткие поля не требуют полной ширины,
     а форма становится на ряд короче. */
  .modal .form { grid-template-columns: 1fr 1fr; align-items: start; }
  .modal .form > * { grid-column: 1 / -1; }
  .modal .form > .field--half { grid-column: auto; }
}

/* Низкий экран (телефон 4,7″, ноутбук с открытой панелью): жертвуем
   подводкой и кеглем заголовка — поля и кнопка важнее. Размеры целей
   нажатия не трогаем. */
@media (max-height: 700px) {
  .modal__box { padding: 1rem; }
  .modal .form { gap: 12px; }
  .modal .form h2 { font-size: var(--t-lg); }
  .modal .form > .lede { display: none; }
}
.modal__x {
  position: absolute; top: var(--s-4); right: var(--s-4);
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
  transition: background var(--d-2) var(--e-move),
              border-color var(--d-2) var(--e-move);
}
.modal__x:hover { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.modal__x svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; }
.modal[open] { animation: modal-in var(--d-3) var(--e-in); }
.modal[open]::backdrop { animation: modal-fade var(--d-3) linear; }
@keyframes modal-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes modal-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .modal[open], .modal[open]::backdrop { animation: none; }
}
html.is-locked { overflow: hidden; }

/* --- карточка с цитатой клуба ---------------------------------------------
   Длинная цитата в общем потоке неотличима от авторского текста: на странице
   тренеров два таких абзаца стояли рядом с двумя своими и складывались
   в сплошное полотно на два экрана. Карточка отделяет чужие слова от наших
   формой, а не только кавычками. */
.quote-card {
  margin: 0;
  background: var(--bg-3);
  border-top: 2px solid var(--accent);
  padding: var(--s-6);
  display: flex; flex-direction: column; gap: var(--s-5);
}
.quote-card p {
  margin: 0;
  font-size: var(--t-md); line-height: 1.42;
  text-wrap: pretty;
}
/* Подпись источника набирается обычным строчным: разряженный ALL-CAPS
   eyebrow — опознанный признак шаблонной вёрстки 2026 года, и проверка
   fingerprint-2026 считает именно его. */
.quote-card cite {
  font-style: normal; font-size: var(--t-xs);
  color: var(--fg-3);
  margin-top: auto;
}

/* --- врезка-предупреждение ----------------------------------------------- */
.note {
  align-self: start;
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  padding: var(--s-5) var(--s-5) var(--s-5) var(--s-6);
  font-size: var(--t-sm);
}
.note--quiet { border-left-color: var(--line-2); background: var(--bg-2); }

/* Левая колонка таблицы сравнения — подпись строки, а не день недели:
   тот же inline-стиль повторялся в разметке шесть раз. */
.sched .day--label {
  font-size: var(--t-sm);
  text-transform: none;
}

/* --- таблица шире экрана прокручивается внутри себя ------------------------
   Обёртка стояла в разметке с самого начала, но правила у неё не было:
   на 320 px таблица сравнения уводила вбок всю страницу. Полоса прокрутки
   спрятана, обрыв обозначен затуханием справа — иначе человек не узнаёт,
   что у таблицы есть продолжение. */
.sched-scroll {
  position: relative;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.sched-scroll::-webkit-scrollbar { display: none; }
.sched-scroll > table { min-width: 30rem; }

/* --- пустое состояние ----------------------------------------------------- */
.empty {
  padding: var(--s-8) var(--s-5);
  border: 1px dashed var(--line-2);
  text-align: center; color: var(--fg-3);
}

/* --- цитата основателя ---------------------------------------------------- */
.pullquote {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.5rem, 3.4vw, 2.75rem);
  line-height: 1.06; letter-spacing: -0.018em;
  text-transform: none;
  max-width: 22ch;
  hanging-punctuation: first;
}
.pullquote--wide { max-width: 30ch; }
