/* ==========================================================================
   Клуб тайского бокса BANGKOK, Краснодар — стили

   Схема: тёплый чёрный + золото из логотипа. Красного в логотипе нет вообще
   (проверено по гистограмме: 1467 золотых пикселей против 2 в красной зоне),
   и в нише чёрно-красных 7 сайтов из 15 — поэтому идём в золото.
   Обоснование решений — docs/KONTSEPTSIYA.md.
   ========================================================================== */

:root {
  /* Цвет */
  --ink:     #12100E;   /* фон. Чистый #000 — признак конструктора */
  --ink-2:   #1B1714;
  --ink-3:   #2A241D;
  --gold:    #C8A24A;   /* из логотипа, поднято по насыщенности */
  --gold-hi: #E8C46B;
  --gold-lo: #6E5828;
  --cream:   #F5EFE2;
  --cream-2: #B9B2A6;
  --cream-3: #948C7F;   /* было #7C756A — 4.17:1, ниже нормы WCAG AA */
  --blood:   #C1121F;   /* только пульс: «идёт набор», ошибки формы */
  /* Золото на кремовом фоне даёт 2.1:1 — ссылку в светлой секции им красить
     нельзя. Отдельный тон под светлый фон. */
  --gold-ink: #7A5D1C;

  /* Типографика.
     Дисплейный — Alumni Sans: сжатый тяжёлый атлетический гротеск, ближайшая
     к букве логотипа кириллица на Google Fonts. Anton/Bebas ближе по латинице,
     но кириллицы у них нет вовсе. Текстовый — Manrope. */
  --f-d: 'Alumni Sans', 'Oswald', 'Arial Narrow', system-ui, sans-serif;
  --f-b: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Ритм */
  --wrap: 1320px;
  --pad: clamp(16px, 4vw, 44px);
  --sp: clamp(64px, 9vw, 132px);
  --r: 4px;              /* почти без скруглений: ринг — это углы */

  --ease: cubic-bezier(.16, 1, .3, 1);
  --ease-out: cubic-bezier(.2, .8, .2, 1);

  /* Длительности — тоже токены. Иначе через месяц в файле пять разных
     «примерно четверть секунды», и движение сайта перестаёт быть общим. */
  --t-fast: .22s;
  --t-mid: .45s;
  --t-slow: .9s;
}

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

a, button, summary, input, select, label { -webkit-tap-highlight-color: transparent; }
a, button, summary { touch-action: manipulation; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--ink);
  color: var(--cream);
  font: 400 17px/1.62 var(--f-b);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* height:auto обязателен: у картинок проставлены width/height (резервируют
   место и убирают скачок вёрстки), без него max-width сжимает ширину,
   а высота остаётся от атрибута — фото растягивается по вертикали. */
/* -webkit-user-drag снимает нативное перетаскивание: без него зажатая ЛКМ
   на любом фото начинает drag-and-drop и таскает за курсором призрак кадра.
   Особенно заметно на первом экране, где картинка занимает весь экран. */
img { max-width: 100%; height: auto; display: block; -webkit-user-drag: none; user-select: none; }
a { color: inherit; }

h1, h2, h3 {
  font-family: var(--f-d); font-weight: 900; line-height: .92;
  margin: 0; letter-spacing: -.015em; text-transform: uppercase;
}
h1 { font-size: clamp(58px, 11vw, 148px); }
h2 { font-size: clamp(38px, 6vw, 86px); text-wrap: balance; }
h3 { font-size: clamp(24px, 2.6vw, 34px); }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

.wrap { width: min(100% - var(--pad) * 2, var(--wrap)); margin-inline: auto; }
.sec { padding-block: var(--sp); position: relative; scroll-margin-top: 84px; }
.sec--light { background: var(--cream); color: var(--ink); }
.sec--tint { background: var(--ink-2); }

.skip {
  position: fixed; top: 8px; left: 8px; z-index: 300;
  padding: 10px 18px; background: var(--gold); color: var(--ink); font-weight: 700;
  transform: translateY(-200%); transition: transform .2s;
}
.skip:focus { transform: none; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

/* ---------- Общие элементы ---------------------------------------------- */

/* Надзаголовок-ярлык. Сжатый гротеск вразрядку — держит «спортивный» тон
   без крика, в отличие от красных плашек у конкурентов. */
.eyebrow {
  font: 700 clamp(12px, 1.1vw, 14px)/1 var(--f-d);
  letter-spacing: .22em; text-transform: uppercase; color: var(--gold);
  margin: 0 0 18px; display: flex; align-items: center; gap: 12px;
}
.eyebrow::before { content: ''; width: 34px; height: 2px; background: currentColor; flex: none; }
.sec--light .eyebrow { color: var(--gold-lo); }

.lead { font-size: clamp(17px, 1.5vw, 21px); line-height: 1.55; color: var(--cream-2); max-width: 62ch; }
.sec--light .lead { color: #4A443B; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 17px 32px; border: 2px solid transparent; border-radius: var(--r);
  font: 700 15px/1 var(--f-b); letter-spacing: .02em; text-decoration: none;
  cursor: pointer; position: relative; overflow: hidden; isolation: isolate;
  transition: color .3s var(--ease-out), border-color .3s, transform .2s;
}
/* Заливка приезжает снизу, а не мигает сменой фона — движение читается
   как «нажатие», и это дешевле по отрисовке, чем анимировать background. */
.btn::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--gold-hi); transform: translateY(101%);
  transition: transform .42s var(--ease);
}
.btn:hover::before, .btn:focus-visible::before { transform: none; }
.btn:active { transform: translateY(1px); }

.btn--gold { background: var(--gold); color: var(--ink); }
.btn--ghost { border-color: rgba(245, 239, 226, .28); color: var(--cream); }
.btn--ghost:hover, .btn--ghost:focus-visible { color: var(--ink); border-color: var(--gold-hi); }
.sec--light .btn--ghost { border-color: rgba(18, 16, 14, .22); color: var(--ink); }

/* Зерно. Inline-SVG feTurbulence, а не GIF с чужого CDN: 0.4 КБ, один запрос
   в никуда меньше, и в отличие от гифки не мерцает на 120 Гц. */
.grain {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  opacity: .16; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}

/* Золотое сияние из логотипа — повторяющийся мотив за ключевыми блоками. */
.rays {
  position: absolute; pointer-events: none; z-index: 0;
  width: min(1100px, 140vw); aspect-ratio: 1; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(200, 162, 74, .10) 0deg 1.6deg, transparent 1.6deg 8deg);
  -webkit-mask-image: radial-gradient(circle, transparent 4%, #000 22%, transparent 62%);
  mask-image: radial-gradient(circle, transparent 4%, #000 22%, transparent 62%);
  animation: spin 140s linear infinite;
}
@keyframes spin { to { transform: rotate(1turn); } }

/* ---------- Шапка -------------------------------------------------------- */

.hdr {
  position: fixed; inset: 0 0 auto; z-index: 100;
  transition: background .35s, backdrop-filter .35s, border-color .35s;
  border-bottom: 1px solid transparent;
}
/* backdrop-filter работает только когда за элементом реально что-то есть,
   и только если у самого элемента фон полупрозрачный, а не прозрачный. */
.hdr.is-stuck {
  background: rgba(18, 16, 14, .82);
  backdrop-filter: saturate(1.3) blur(14px);
  border-bottom-color: var(--ink-3);
}
.hdr__in { display: flex; align-items: center; gap: clamp(14px, 2vw, 30px); min-height: 84px; }
.hdr.is-stuck .hdr__in { min-height: 68px; transition: min-height .35s; }

.hdr__logo { display: flex; align-items: center; gap: 12px; text-decoration: none; flex: none; }
/* Подложка снята: фон вырезан, монохром выведен в кремовый (tools/logo.mjs).
   Задаём высоту, ширину считает браузер — эмблема шире, чем выше, и жёсткий
   квадрат её плющил. Масштабируем через transform, а не через width/height:
   те дёргают раскладку на каждом кадре. */
.hdr__logo img {
  height: 46px; width: auto; transform-origin: left center;
  transition: transform .35s var(--ease);
}
.hdr.is-stuck .hdr__logo img { transform: scale(.86); }
.hdr__name { font: 900 20px/1 var(--f-d); letter-spacing: .01em; text-transform: uppercase; }
.hdr__name small { display: block; font: 700 11px/1.4 var(--f-b); letter-spacing: .18em; color: var(--gold); margin-top: 4px; }

.hdr__nav { display: flex; gap: clamp(12px, 1.8vw, 26px); margin-left: auto; }
/* Телефон и кнопка внутри навигации нужны ТОЛЬКО в раскрытом мобильном меню.
   Правило `display:none` стояло внутри @media (max-width:1100px), и на
   широком экране блок оказывался прямо в строке шапки: 223x77 px лишнего
   рядом с пунктами меню. Прячем на базовом уровне, показываем точечно. */
.hdr__navx { display: none; }
.hdr__nav a {
  position: relative; padding: 8px 0; text-decoration: none;
  font: 700 13px/1 var(--f-b); letter-spacing: .06em; text-transform: uppercase;
  color: var(--cream-2); transition: color .22s; white-space: nowrap;
}
.hdr__nav a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--gold);
  transform: scaleX(0); transform-origin: left; transition: transform .3s var(--ease);
}
.hdr__nav a:hover, .hdr__nav a.is-here { color: var(--cream); }
.hdr__nav a:hover::after, .hdr__nav a.is-here::after { transform: none; }

.hdr__tel {
  font: 800 16px/1 var(--f-b); text-decoration: none; white-space: nowrap; flex: none;
  transition: color .2s;
}
.hdr__tel:hover { color: var(--gold); }
.hdr__cta { flex: none; padding: 13px 22px; font-size: 13px; }

.hdr__burger {
  display: none; margin-left: auto; width: 46px; height: 46px; flex: none;
  border: 1px solid var(--ink-3); background: rgba(255, 255, 255, .04);
  border-radius: var(--r); cursor: pointer; position: relative;
}
.hdr__burger span, .hdr__burger::before, .hdr__burger::after {
  content: ''; position: absolute; left: 13px; right: 13px; height: 2px; background: var(--cream);
  transition: transform .28s var(--ease), opacity .18s;
}
.hdr__burger::before { top: 16px; }
.hdr__burger span { top: 22px; }
.hdr__burger::after { top: 28px; }
.hdr__burger[aria-expanded='true']::before { transform: translateY(6px) rotate(45deg); }
.hdr__burger[aria-expanded='true'] span { opacity: 0; }
.hdr__burger[aria-expanded='true']::after { transform: translateY(-6px) rotate(-45deg); }

/* ---------- Первый экран -------------------------------------------------- */

.hero {
  position: relative; min-height: clamp(600px, 100svh, 1000px);
  display: grid; align-items: end; overflow: hidden; isolation: isolate;
}
/* Фон декоративный (aria-hidden) — мышь его вообще не касается. */
.hero__media { position: absolute; inset: 0; z-index: 0; background: #070605; pointer-events: none; }
.hero__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; filter: grayscale(.55) contrast(1.08) brightness(.72);
  transition: opacity 1.6s ease;
}
/* Наезд Кена Бёрнса: медленное движение прячет то, что исходники всего
   800 px по большой стороне — глаз не успевает зацепиться за мягкость. */
.hero__media img.is-on { opacity: 1; animation: kb 15s linear forwards; }
@keyframes kb {
  from { transform: scale(1.03) translate3d(0, 0, 0); }
  to   { transform: scale(1.16) translate3d(-1.2%, -1.6%, 0); }
}

/* Затемнение слоями, а не плоскими rgba(0,0,0,.5): виньетка держит центр,
   вертикальный градиент — низ под текстом, тёплый слой уводит синеву зала
   в сторону золота. У референса заказчика ровно одна плоская заливка. */
.hero__veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    /* Горизонтальный слой добавлен: весь текст героя стоит слева, а
       затемнения слева не было вовсе — читаемость висела на том, какой
       кадр слайдшоу сейчас показан и куда доехал наезд. На светлых кадрах
       (зелень за рингом, белый канат) подпись под заголовком садилась
       до пятна. Правая треть не тронута — там лицо тренера. */
    linear-gradient(to right, rgba(6, 5, 4, .74) 0%, rgba(6, 5, 4, .46) 34%, rgba(6, 5, 4, .08) 58%, transparent 72%),
    radial-gradient(115% 85% at 50% 42%, transparent 26%, rgba(6, 5, 4, .62) 78%, rgba(6, 5, 4, .9) 100%),
    linear-gradient(to top, var(--ink) 2%, rgba(18, 16, 14, .84) 26%, rgba(18, 16, 14, .1) 62%, rgba(18, 16, 14, .55) 100%),
    linear-gradient(160deg, rgba(110, 88, 40, .22), transparent 55%);
}
.hero .rays { top: -22%; left: 50%; translate: -50% 0; opacity: .55; }

.hero__in { position: relative; z-index: 4; padding-block: clamp(120px, 16vh, 190px) clamp(40px, 6vh, 76px); }
/* Полоса прокрутки стоит absolute у нижнего края героя и раньше протыкала
   подписи под числами на КАЖДОЙ ширине шире 720 px: на 1024 и 900 она
   проходила прямо сквозь «медалей за сезон». На телефоне это когда-то
   заметили и просто спрятали полосу — здесь вместо этого отводим ей
   собственную полосу под содержимым, и пересечение становится невозможным. */

/* Заголовок выезжает из-под маски по словам. Маска — overflow:hidden
   на внешнем span, движется внутренний. Так буквы не «проявляются»,
   а именно въезжают, как из-за края ринга. */
.hero h1 { max-width: 15ch; }
/* Вторая строка мельче первой: «муай тай» — вывеска, «искусство восьми
   конечностей» — подпись под ней. Одинаковый кегль сделал бы из этого
   сплошную стену капслока. */
.h1__sub { display: block; margin-top: .14em; font-size: .46em; line-height: .98; letter-spacing: 0; }
.mask { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .06em; }
.mask > i {
  display: inline-block; font-style: normal;
  transform: translateY(105%); opacity: 0;
  transition: transform 1.05s var(--ease), opacity .5s ease;
  transition-delay: calc(var(--i, 0) * 110ms + 180ms);
}
.is-lit .mask > i { transform: none; opacity: 1; }
.hero h1 em { font-style: normal; color: var(--gold); }

.hero__lead { margin-top: 26px; max-width: 46ch; font-size: clamp(16px, 1.5vw, 20px); color: var(--cream-2); }
.hero__btns { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }

/* Три числа в герое — приём, который в нише использует один сайт из 15. */
.hero__nums {
  display: flex; flex-wrap: wrap; gap: clamp(24px, 5vw, 68px);
  margin-top: clamp(38px, 6vh, 64px); padding-top: 30px;
  border-top: 1px solid rgba(245, 239, 226, .16);
}
.num b { display: block; font: 900 clamp(38px, 5vw, 62px)/1 var(--f-d); color: var(--gold); letter-spacing: -.02em; }
.num span { display: block; margin-top: 6px; font-size: 13px; letter-spacing: .06em; color: var(--cream-3); text-transform: uppercase; }

.hero__scroll {
  position: absolute; z-index: 4; left: 50%; bottom: 26px; translate: -50% 0;
  width: 1px; height: 46px; background: linear-gradient(var(--gold), transparent);
  overflow: hidden;
}
.hero__scroll::after {
  content: ''; position: absolute; inset: 0; background: var(--gold);
  animation: drop 2.4s var(--ease) infinite;
}
@keyframes drop { 0% { transform: translateY(-100%); } 60%, 100% { transform: translateY(100%); } }

/* ---------- Бегущая строка ------------------------------------------------ */

/* Лента дублируется в разметке дважды и едет на -50%: так шов не виден
   и не нужен JS. У понравившегося заказчику референса таких строк 16 —
   нам хватит трёх, иначе приём съедает сам себя. */
.marquee {
  --dur: 34s;
  position: relative; overflow: hidden; padding: 22px 0;
  border-block: 1px solid var(--ink-3); background: var(--ink-2);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__row { display: flex; width: max-content; animation: slide var(--dur) linear infinite; }
.marquee__row > span {
  display: flex; align-items: center; gap: 34px; padding-right: 34px;
  font: 900 clamp(22px, 3vw, 40px)/1 var(--f-d); text-transform: uppercase;
  letter-spacing: .01em; color: transparent; -webkit-text-stroke: 1px var(--gold-lo);
  white-space: nowrap;
}
.marquee__row > span i { font-style: normal; color: var(--gold); -webkit-text-stroke: 0; }
.marquee__row > span::after { content: '◆'; font-size: .42em; color: var(--gold); -webkit-text-stroke: 0; }
@keyframes slide { to { transform: translateX(-50%); } }
.marquee--light { background: var(--cream); border-color: #E0D8C7; }
.marquee--light .marquee__row > span { -webkit-text-stroke-color: #CBBFA6; }

/* ---------- Появление при скролле ----------------------------------------- */

/* Своя система вместо AOS: у четырёх конкурентов из выборки стоит именно
   AOS «из коробки», и её узнаёшь по одинаковой кривой. Здесь сдвиг мягче,
   кривая длиннее, а задержка идёт по индексу внутри группы. */
.rv { opacity: 0; transform: translateY(22px); }
.rv.is-in {
  opacity: 1; transform: none;
  transition: opacity .8s var(--ease-out), transform .9s var(--ease);
  transition-delay: calc(var(--i, 0) * 90ms);
}



/* ---------- Направления ---------------------------------------------------- */

.dirs { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); margin-top: clamp(38px, 5vw, 60px); }
.dir {
  position: relative; display: block; text-decoration: none; overflow: hidden;
  aspect-ratio: 3 / 4; background: var(--ink-2); isolation: isolate;
}
.dir img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  /* Рассинхрон таймингов filter и transform — то, что даёт «дорогое»
     ощущение: цвет возвращается быстрее, чем заканчивается наезд. */
  filter: grayscale(1) contrast(1.12) brightness(.78);
  transform: scale(1.02);
  transition: filter .65s ease, transform 1.1s var(--ease);
}
.dir::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(9, 8, 7, .96) 2%, rgba(9, 8, 7, .62) 38%, rgba(9, 8, 7, .12) 72%, transparent 100%);
  transition: opacity .5s;
}
.dir:hover img, .dir:focus-visible img { filter: grayscale(0) contrast(1.02) brightness(1); transform: scale(1.08); }
.dir__in { position: absolute; inset: auto 0 0; z-index: 2; padding: clamp(20px, 2.4vw, 30px); }
.dir__age { font: 700 12px/1 var(--f-b); letter-spacing: .16em; color: var(--gold); text-transform: uppercase; }
.dir__n { margin: 12px 0 0; font: 900 clamp(26px, 2.4vw, 36px)/.95 var(--f-d); text-transform: uppercase; color: var(--cream); }
.dir__d {
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  transition: grid-template-rows .5s var(--ease);
  color: var(--cream-2); font-size: 15px;
}
.dir__d > span { min-height: 0; }
.dir__d p { margin: 12px 0 0; }
.dir:hover .dir__d, .dir:focus-visible .dir__d, .dir:focus-within .dir__d { grid-template-rows: 1fr; }
/* На тач-устройствах ховера нет — раскрываем сразу, иначе текст недоступен. */


/* ---------- Плитки зала -----------------------------------------------------
   Отдельный компонент, а не карточка направления: раньше зал переиспользовал
   класс .dir, и мобильные правила для направлений (текст под фото, цвет
   вместо ч/б) ломали его — подписи вылезали за левый край, а синева зала
   била по чёрно-золотой схеме.
   -------------------------------------------------------------------------- */

.tiles { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); margin-top: clamp(36px, 5vw, 60px); }
.tile { position: relative; margin: 0; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-2); }
.tile img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) contrast(1.12) brightness(.84);
  transition: filter .65s ease, transform 1.1s var(--ease);
}
.tile:hover img { filter: grayscale(0) contrast(1.02) brightness(1); transform: scale(1.06); }
.tile::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to top, rgba(9, 8, 7, .92) 2%, rgba(9, 8, 7, .4) 34%, transparent 66%);
}
.tile__n {
  position: absolute; inset: auto 0 0; z-index: 2; padding: clamp(16px, 2vw, 24px);
  font: 900 clamp(19px, 1.8vw, 25px)/1 var(--f-d); text-transform: uppercase; color: var(--cream);
}

/* ---------- Восемь конечностей --------------------------------------------- */

/* Фигура была 360x630 против плитки в 339 px: при align-items:center вокруг
   плитки оставалось по 145 px пустоты сверху и снизу, и блок читался как
   маленькая табличка, приставленная к длинному рисунку. Колонку рисунка
   сузили, сам рисунок уменьшили — высоты сошлись, воздух стал полем, а
   не провалом. Плитка при этом получила ширину, а карточки — воздух внутри. */
.limbs { display: grid; gap: clamp(32px, 4vw, 60px); grid-template-columns: minmax(180px, .4fr) minmax(0, 1fr); align-items: center; margin-top: clamp(36px, 5vw, 56px); }
.limbs__fig { position: relative; }
.limbs__fig svg { width: 100%; max-width: 296px; height: auto; display: block; margin-inline: auto; }
.limbs__dot {
  fill: var(--gold); cursor: pointer; transition: fill .25s, transform .25s var(--ease);
  transform-box: fill-box; transform-origin: center;
}
.limbs__dot:hover, .limbs__dot.is-on { transform: scale(1.25); fill: var(--gold-hi); }
.limbs__list { display: grid; gap: 2px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.limb {
  padding: clamp(18px, 2vw, 26px) clamp(20px, 2vw, 28px); background: var(--ink-2); border: 1px solid transparent;
  cursor: pointer; text-align: left; font: inherit; color: inherit;
  transition: background .25s, border-color .25s, transform .25s var(--ease);
}
.limb:hover, .limb.is-on { background: #221D17; border-color: var(--gold-lo); transform: translateX(4px); }
.limb b { display: block; font: 900 clamp(19px, 1.7vw, 24px)/1 var(--f-d); text-transform: uppercase; }
.limb i { display: block; font-style: normal; margin-top: 7px; font-size: 14px; color: var(--gold); letter-spacing: .04em; }
.limb span { display: block; margin-top: 7px; font-size: 14px; line-height: 1.5; color: var(--cream-3); }

/* ---------- Шаги первой тренировки ------------------------------------------ */

.steps { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: clamp(36px, 5vw, 56px); }
.step { position: relative; padding: clamp(26px, 3vw, 38px); background: rgba(255, 255, 255, .03); border: 1px solid var(--ink-3); }
.sec--light .step { background: rgba(18, 16, 14, .035); border-color: #E2DACA; }
/* Нумерация по-тайски — деталь, которой нет ни у кого в нише. */
.step h3 { margin-top: 18px; }
.step p { margin-top: 12px; font-size: 15px; color: var(--cream-3); }
.sec--light .step p { color: #5C554A; }

/* ---------- Тренеры ---------------------------------------------------------- */

.team { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); margin-top: clamp(36px, 5vw, 56px); }
/* Карточка — <button>, поэтому сбрасываем всё, что кнопке даёт браузер,
   и растягиваем на ячейку сетки: иначе кнопка сжимается по содержимому. */
.coach {
  text-align: left; background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; width: 100%; display: flex; flex-direction: column;
}
/* margin-top:auto прижимает ссылку к низу карточки-флекса. Общее правило
   .limb__more,.coach__more ниже по файлу ставит margin-top:14px при той же
   специфичности и перебивало его: на 390 px «Подробнее» в карточках
   с короткой ролью висело на 21 px выше соседних. Возвращаем прижатие
   ПОСЛЕ общего правила — см. .coach__more ниже. */
.coach__more { padding-top: 12px; }
.coach__ph { position: relative; aspect-ratio: 3 / 4; overflow: hidden; background: var(--ink-2); }
.coach__ph img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) contrast(1.05) brightness(.9);
  transition: filter .6s ease, transform 1s var(--ease);
}
.coach:hover .coach__ph img, .coach:focus-visible .coach__ph img { filter: none; transform: scale(1.05); }
/* Световая линия снизу — «гонг». Быстрая, 0.7 с, только на ховере. */
.coach__blade { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--gold); transform: scaleX(0); transform-origin: left; transition: transform .7s var(--ease); z-index: 2; }
.coach:hover .coach__blade, .coach:focus-visible .coach__blade { transform: none; }
.coach__n { display: block; margin-top: 16px; font: 900 clamp(22px, 1.9vw, 28px)/1 var(--f-d); text-transform: uppercase; }
.coach__r { display: block; margin-top: 8px; font-size: 14px; color: var(--gold); letter-spacing: .04em; }

/* ---------- Цены -------------------------------------------------------------- */

.plans { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin-top: clamp(36px, 5vw, 56px); }
.plan { position: relative; padding: clamp(28px, 3vw, 40px); background: rgba(255, 255, 255, .03); border: 1px solid var(--ink-3); display: flex; flex-direction: column; }
.plan--hot { border-color: var(--gold); background: rgba(200, 162, 74, .07); }
/* Выделенная карточка отличалась только рамкой и подложкой — глаз видел
   «другую», но не знал почему. Ярлык называет причину словом. */
.plan__hot {
  position: absolute; top: 0; left: clamp(28px, 3vw, 40px); translate: 0 -50%;
  padding: 7px 13px; background: var(--gold); color: var(--ink);
  font: 700 11px/1 var(--f-b); letter-spacing: .14em; text-transform: uppercase;
  white-space: nowrap;
}
.plan__t { font: 900 clamp(24px, 2.2vw, 32px)/1 var(--f-d); text-transform: uppercase; }
.plan__p { margin-top: 18px; font: 900 clamp(38px, 4vw, 54px)/1 var(--f-d); color: var(--gold); }
.plan__p small { font: 700 15px/1 var(--f-b); color: var(--cream-3); margin-left: 6px; }
.plan ul { list-style: none; margin: 24px 0 28px; padding: 0; display: grid; gap: 11px; font-size: 15px; }
.plan li { position: relative; padding-left: 24px; color: var(--cream-2); }
.plan li::before { content: '◆'; position: absolute; left: 0; top: .1em; font-size: 10px; color: var(--gold); }
.plan .btn { margin-top: auto; }

/* ---------- Форма --------------------------------------------------------------- */

.form { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 34px; }
.form label { display: block; }
.form span { display: block; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--cream-3); margin-bottom: 8px; }
.form input, .form select {
  width: 100%; padding: 15px 18px; background: rgba(255, 255, 255, .04);
  border: 1px solid var(--ink-3); border-radius: var(--r); color: var(--cream);
  font: 400 16px/1.3 var(--f-b); transition: border-color .25s, background .25s;
}
.form input:focus, .form select:focus { outline: 0; border-color: var(--gold); background: rgba(255, 255, 255, .07); }
.form__wide { grid-column: 1 / -1; }
.form__note { grid-column: 1 / -1; font-size: 13px; line-height: 2; padding-block: 6px; color: var(--cream-3); }
/* Ссылка внутри предложения: рвать строку ради 44 px нельзя, но область
   попадания растянуть можно — отступ вверх-вниз и такой же отрицательный
   внешний. Строка не сдвигается, цель становится 275x44 вместо 275x18.
   (WCAG 2.5.8 ссылку внутри текста и так не требует — но промах пальцем
   по ней реален независимо от того, что требует норма.) */
.form__note a { color: var(--gold); display: inline; padding-block: 13px; margin-block: -13px; }

/* Форма живёт на кремовой секции, а поля наследовали тёмную схему: белый
   фон и кремовый текст. Человек печатал телефон и не видел, что печатает —
   самая дорогая ошибка на странице. */
.sec--light .form span { color: #6B6357; }
.sec--light .form input, .sec--light .form select {
  background: #fff; border-color: #D8CFBC; color: var(--ink);
}
.sec--light .form input::placeholder { color: #A79E8E; }
.sec--light .form input:focus, .sec--light .form select:focus {
  border-color: var(--gold-lo); background: #fff;
  box-shadow: 0 0 0 3px rgba(200, 162, 74, .22);
}
/* Стрелка у select: без неё поле не отличить от текстового. */
.sec--light .form select {
  appearance: none; padding-right: 46px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%237A5D1C' stroke-width='2'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 18px center;
}
.sec--light .form__note { color: #6B6357; }
.sec--light .form__note a { color: var(--gold-ink); text-underline-offset: 3px; }

/* ---------- Подвал ------------------------------------------------------------- */

.ftr { background: #0C0A09; border-top: 1px solid var(--ink-3); padding-block: clamp(48px, 6vw, 76px) 32px; position: relative; overflow: hidden; }
.ftr__in { display: grid; gap: clamp(28px, 4vw, 56px); grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr)); position: relative; z-index: 1; }
.ftr h3 { font: 700 12px/1 var(--f-b); letter-spacing: .2em; text-transform: uppercase; color: var(--gold); margin: 0 0 18px; }
.ftr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; font-size: 15px; }
/* Ссылка-телефон обязана быть не меньше 44 px по высоте: промах пальцем
   по ней читается как «сайт не работает». */
.ftr a { text-decoration: none; color: var(--cream-2); transition: color .2s; }
.ftr li { display: flex; align-items: center; min-height: 44px; }
.tel-tap { display: inline-flex; align-items: center; min-height: 44px; }
.ftr a:hover { color: var(--gold); }
/* align-items обязателен: ссылка справа — inline-flex ростом 44 px (цель
   нажатия), а копирайт слева — голый текст. При растяжке по умолчанию текст
   прилипал к верху своей ячейки, ссылка стояла по центру своей — базовые
   линии расходились на 11 px. */
/* .ftr a { color: cream-2 } перебивает .btn--gold по специфичности (0,2,0
   против 0,1,0) — кнопка выходила светлым текстом по светлому золоту.
   Кнопки в подвале забираем из-под общего правила ссылок. */
/* Контейнерные правила ссылок — .ftr a и .hdr__nav a — имеют специфичность
   (0,2,0) и перебивают (0,1,0) у .btn--gold: кнопка выходила светлым текстом
   по светлому золоту, 1.14:1. Поймано дважды подряд, в подвале и в шапке,
   поэтому правило одно на оба места. */
.ftr .btn--gold, .hdr__nav .btn--gold { color: var(--ink); }
.ftr .btn--gold:hover, .ftr .btn--gold:focus-visible,
.hdr__nav .btn--gold:hover, .hdr__nav .btn--gold:focus-visible { color: var(--ink); }
.ftr__cta { margin-top: 26px; }
.ftr__bot { margin-top: clamp(36px, 5vw, 56px); padding-top: 24px; border-top: 1px solid var(--ink-3); display: flex; flex-wrap: wrap; align-items: center; gap: 16px; justify-content: space-between; font-size: 13px; color: var(--cream-3); position: relative; z-index: 1; }

/* ---------- Адаптив ------------------------------------------------------------- */

/* Порядок медиазапросов: от широкого к узкому, каждый следующий перекрывает
   предыдущий. Перестановка ломает каскад молча. */



/* ---------- Поповеры (удары и тренеры) ------------------------------------ */

/* Нативный <dialog>: даёт ловушку фокуса, Esc и ::backdrop бесплатно.
   Самодельная модалка на div требует всего этого руками и обычно
   half-built — фокус уезжает на страницу под затемнением. */
.pop {
  border: 0; padding: 0; background: transparent; color: var(--cream);
  width: min(1020px, 94vw); max-height: 90vh; overflow: visible;
}
.pop::backdrop { background: rgba(6, 5, 4, .84); backdrop-filter: blur(7px); }
.pop[open] { animation: pop-in .34s var(--ease); }
.pop[open]::backdrop { animation: fade-in .3s ease; }
@keyframes pop-in { from { opacity: 0; transform: translateY(22px) scale(.985); } }
@keyframes fade-in { from { opacity: 0; } }

.pop__box {
  display: grid; grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr);
  /* minmax(0, 1fr) обязателен: у элемента сетки min-height по умолчанию auto,
     строка вырастает под содержимое, и .pop__body получает высоту контента —
     прокрутка внутри не появляется, а лишнее просто срезается overflow:hidden.
     Так у поповеров пропадала нижняя часть с кнопкой. */
  grid-template-rows: minmax(0, 1fr);
  background: var(--ink-2); border: 1px solid var(--ink-3);
  max-height: min(90vh, 780px); overflow: hidden; position: relative;
}

/* Левая половина — место под фото или видео удара. Пока материал не пришёл,
   там пунктирная рамка с подписью: пустое место честнее случайной картинки. */
.pop__media { position: relative; min-height: 0; background: #0C0A09; }
.pop__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pop__slot {
  position: absolute; inset: 18px; border: 1px dashed var(--gold-lo);
  display: grid; place-items: center; align-content: center; gap: 10px;
  text-align: center; padding: 24px; color: var(--cream-3); font-size: 13px; line-height: 1.5;
}
.pop__slot b { font: 900 clamp(20px, 2vw, 26px)/1 var(--f-d); color: var(--gold-lo); text-transform: uppercase; }

/* ---------- Метка «здесь будет содержимое клуба» ---------------------------
   Заглушки на сайте стоят сознательно (docs/ZAGLUSHKI.md): выдуманным
   фактам на сайте живого клуба не место. Но набраны они были обычным
   текстом — «медалей за прошлый сезон — ждём точную цифру от клуба»
   посетитель читает как фразу сайта, а не как записку разработчика.
   Пунктирная рамка уже применялась к месту под фото в поповерах; здесь
   тот же приём выведен в один класс и распространён на ВСЕ незаполненные
   места. Теперь несделанное отличается от сделанного с одного взгляда —
   и заказчику видно ровно то, что от него ждут. */
.slot {
  display: inline-flex; align-items: center; gap: 8px; vertical-align: middle;
  padding: 6px 11px; border: 1px dashed var(--gold-lo); border-radius: var(--r);
  background: rgba(200, 162, 74, .06);
  font: 700 11px/1.25 var(--f-b); letter-spacing: .13em; text-transform: uppercase;
  color: var(--gold); text-align: left;
}
/* Метка ромба привязана к ПЕРВОЙ строке, а не к середине блока: подписи
   короткие, но на 360 px любая из них может уйти в две строки, и ромб
   тогда повисал между строк. */
.slot::before {
  content: ''; width: 7px; height: 7px; flex: none;
  align-self: start; margin-top: .3em;
  border: 1px solid currentColor; rotate: 45deg;
}
.sec--light .slot { border-color: #C3B694; background: rgba(122, 93, 28, .07); color: var(--gold-ink); }
/* Целый незаполненный блок, а не приписка к строке. */
.slot--block { display: flex; width: fit-content; max-width: 100%; margin-top: 10px; }

.pop__body { padding: clamp(26px, 3vw, 44px); min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.pop__body h3 { margin-bottom: 10px; }
.pop__th { margin: 0 0 20px; }
.pop__lead { color: var(--cream-2); font-size: 16px; }

.pop__list { list-style: none; margin: 24px 0 0; padding: 22px 0 0; border-top: 1px solid var(--ink-3); display: grid; gap: 18px; }
.pop__list b { display: block; font: 900 19px/1.05 var(--f-d); text-transform: uppercase; }
.pop__list i { display: inline-flex; font-style: normal; margin-top: 8px; }
.pop__list span { display: block; margin-top: 6px; font-size: 15px; line-height: 1.5; color: var(--cream-3); }

.pop__note { margin-top: 24px; padding: 16px 18px; background: rgba(200, 162, 74, .08); border-left: 2px solid var(--gold); font-size: 15px; color: var(--cream-2); }
.pop .btn { margin-top: 26px; }

.pop__x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 44px; height: 44px; border: 1px solid var(--ink-3); background: rgba(18, 16, 14, .8);
  color: var(--cream); cursor: pointer; border-radius: var(--r);
  font: 400 22px/1 var(--f-b); transition: background .2s, color .2s, transform .2s;
}
.pop__x:hover { background: var(--gold); color: var(--ink); transform: rotate(90deg); }

/* Подсказка на карточке: без неё не видно, что она кликабельна. */
.limb__more, .coach__more {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 14px;
  font: 700 12px/1 var(--f-b); letter-spacing: .1em; text-transform: uppercase; color: var(--gold);
  /* Была opacity:.6 — 2,75:1 на золоте. На мыши это состояние живёт долю
     секунды, а на сенсорном экране наведения нет вовсе: единственная
     подсказка, что карточка нажимается, оставалась нечитаемой навсегда.
     Чинить это через @media (hover:none) нельзя — порог контраста не может
     зависеть от устройства ввода. Приглушение убрано совсем; откликом
     работает расхождение стрелки, которое и так было. */
  transition: gap .25s var(--ease);
}
.limb:hover .limb__more, .limb.is-on .limb__more,
.coach:hover .coach__more, .coach:focus-visible .coach__more { gap: 12px; }
/* Прижатие к низу карточки — после общего правила, иначе оно его перебивает. */
.coach__more { margin-top: auto; }



/* ---------- Расписание: подбор группы -------------------------------------- */

/* Главная мысль раздела: человек ищет не «расписание клуба», а «куда идти
   мне». Поэтому сверху не таблица, а выбор «кто пойдёт», и сетка сразу
   сжимается до подходящих групп. Фильтра расписания нет ни у одного из
   15 разобранных сайтов ниши. */
.pick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: clamp(28px, 3.5vw, 40px); }
.pick__b {
  padding: 16px 20px; border: 1px solid var(--ink-3); background: rgba(255, 255, 255, .03);
  color: var(--cream-2); font: 700 14px/1 var(--f-b); cursor: pointer; border-radius: var(--r);
  transition: background .22s, color .22s, border-color .22s, transform .22s var(--ease);
}
.pick__b:hover { color: var(--cream); border-color: var(--gold-lo); transform: translateY(-2px); }
.pick__b[aria-pressed='true'] { background: var(--gold); border-color: var(--gold); color: var(--ink); }

.groups { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); margin-top: 26px; }
.grp {
  display: flex; flex-direction: column; gap: 18px;
  padding: clamp(24px, 2.6vw, 32px); background: rgba(255, 255, 255, .03);
  border: 1px solid var(--ink-3); transition: border-color .25s, background .25s;
}
.grp:hover { border-color: var(--gold-lo); background: rgba(255, 255, 255, .05); }
.grp.is-off { display: none; }
.grp__n { font: 900 clamp(24px, 2.2vw, 30px)/1 var(--f-d); text-transform: uppercase; }
.grp__age { display: block; margin-top: 8px; font-size: 14px; color: var(--gold); letter-spacing: .04em; }

/* Полоска недели: занятые дни золотом. Читается за полсекунды —
   быстрее, чем строка «Пн · Ср · Пт». */
.week { display: flex; gap: 4px; }
.week span {
  flex: 1; text-align: center; padding: 9px 0; font: 700 12px/1 var(--f-b);
  letter-spacing: .04em; color: var(--cream-3); background: rgba(255, 255, 255, .03);
  border: 1px solid transparent; border-radius: var(--r);
}
.week span.on { color: var(--ink); background: var(--gold); font-weight: 800; }

.grp__t { font: 900 clamp(22px, 2vw, 28px)/1 var(--f-d); font-variant-numeric: tabular-nums; }
.grp__t small { display: block; margin-top: 7px; font: 400 14px/1.4 var(--f-b); color: var(--cream-3); }
.grp__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: auto; }
/* У карточки «Персональные» ярлык «По договорённости» длиннее прочих, и
   кнопка срывалась на вторую строку — низ единственной карточки в ряду
   не совпадал с остальными восемью. Кнопка держит место и прижата вправо,
   переносится, если надо, текст ярлыка. */
.grp .btn { padding: 13px 22px; font-size: 14px; margin-left: auto; }

.tag { display: inline-flex; align-items: center; gap: 7px; font: 700 12px/1 var(--f-b); letter-spacing: .08em; text-transform: uppercase; color: var(--cream-3); }
.tag--open { color: var(--gold); }
.tag--open::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--blood); box-shadow: 0 0 0 0 rgba(193, 18, 31, .6); animation: pulse 2.4s infinite; }
@keyframes pulse { 70% { box-shadow: 0 0 0 8px rgba(193, 18, 31, 0); } 100% { box-shadow: 0 0 0 0 rgba(193, 18, 31, 0); } }

.pick__none { margin-top: 26px; padding: 28px; border: 1px dashed var(--ink-3); text-align: center; color: var(--cream-3); }

/* Крупная нумерация шагов вместо тайских цифр: цифра на тайском — это просто
   цифра, читателю она ничего не даёт. */
.step__n { font: 900 clamp(42px, 4vw, 58px)/1 var(--f-d); color: var(--gold); letter-spacing: -.02em; }
.sec--light .step__n { color: var(--gold-lo); }

/* ---------- Липкая панель записи на мобильном ----------------------------- */

/* Восемь из десяти посетителей клуба придут с телефона, а кнопка «Записаться»
   в шапке на узком экране прячется под бургер. Панель снизу решает это
   и стоит 20 строк. Появляется после первого экрана, чтобы не спорить
   с кнопками героя. */
.dock {
  position: fixed; inset: auto 0 0; z-index: 95; display: none;
  gap: 8px; padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: rgba(18, 16, 14, .94); border-top: 1px solid var(--ink-3);
  transform: translateY(110%); transition: transform var(--t-mid) var(--ease);
}
.dock.is-up { transform: none; }
.dock .btn { flex: 1; padding: 15px 18px; }
.dock__call {
  flex: none; width: 54px; display: grid; place-items: center;
  border: 1px solid var(--ink-3); border-radius: var(--r); color: var(--cream);
  text-decoration: none; transition: background var(--t-fast), color var(--t-fast);
}
.dock__call:hover { background: var(--gold); color: var(--ink); }
.dock__call svg { width: 21px; height: 21px; fill: currentColor; }


/* ---------- Полоса-оффер под первым экраном -------------------------------- */

/* Разбор мировых сайтов: интро-оффер идёт вторым экраном, до всего
   остального. Человек пришёл с запроса «тайский бокс рядом» — ему нужно
   за пять секунд получить «где, для кого, сколько». */
.offer { background: var(--gold); color: var(--ink); }
.offer__in { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(18px, 3vw, 40px); padding-block: clamp(22px, 3vw, 34px); }
.offer__i { display: flex; align-items: baseline; gap: 10px; font-size: 15px; font-weight: 600; }
.offer__i b { font: 900 clamp(20px, 1.8vw, 26px)/1 var(--f-d); text-transform: uppercase; letter-spacing: -.01em; }
.offer__in .btn { margin-left: auto; background: var(--ink); color: var(--cream); }
.offer__in .btn::before { background: #000; }
.offer__in .btn:hover { color: var(--gold-hi); }

/* ---------- Достижения ------------------------------------------------------ */

.wins { display: grid; gap: clamp(28px, 4vw, 56px); grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); align-items: center; margin-top: clamp(36px, 5vw, 56px); }
.wins__ph { position: relative; overflow: hidden; aspect-ratio: 4 / 3; }
.wins__ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.12) brightness(.86); transition: filter var(--t-slow) ease, transform 1.2s var(--ease); }
.wins__ph:hover img { filter: none; transform: scale(1.05); }
.wins__list { display: grid; gap: 2px; }
.win {
  display: grid; grid-template-columns: clamp(76px, 8vw, 116px) minmax(0, 1fr); align-items: baseline;
  gap: 18px; padding: 20px 0; border-bottom: 1px solid var(--ink-3);
}
.win b { font: 900 clamp(32px, 3.4vw, 48px)/1 var(--f-d); color: var(--gold); }
.win span { color: var(--cream-2); font-size: 15px; }

/* ---------- Отзывы ---------------------------------------------------------- */

/* Между ценами и остальным, а не в подвале: внизу отзывы не читает никто. */
/* Группа .rev* НЕ используется: секция отзывов заменена цитатой со
   ссылкой на Яндекс.Карты, пока настоящих отзывов нет (см. комментарий
   над секцией в index.html). Стили оставлены намеренно — вернутся вместе
   с отзывами. Не удалять как «мёртвые». */
.revs { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); margin-top: clamp(32px, 4vw, 48px); }
.rev { padding: clamp(24px, 2.6vw, 34px); background: rgba(255, 255, 255, .03); border: 1px solid var(--ink-3); display: flex; flex-direction: column; gap: 16px; }
.rev__stars { color: var(--gold); letter-spacing: .2em; font-size: 15px; }
.rev__t { font-size: 16px; line-height: 1.6; color: var(--cream-2); }
.rev__who { margin-top: auto; font-size: 14px; color: var(--cream-3); }
.rev__who b { display: block; color: var(--cream); font-weight: 700; font-size: 15px; margin-bottom: 4px; }
.rev--slot { border-style: dashed; border-color: var(--gold-lo); color: var(--cream-3); align-items: flex-start; justify-content: center; }

/* ---------- Вопросы --------------------------------------------------------- */

/* <details> вместо самодельного аккордеона: работает без JS, доступен
   с клавиатуры и находится поиском по странице в закрытом виде. */
.faq { margin-top: clamp(32px, 4vw, 48px); border-top: 1px solid var(--ink-3); }
.sec--light .faq { border-top-color: #E2DACA; }
.q { border-bottom: 1px solid var(--ink-3); }
.sec--light .q { border-bottom-color: #E2DACA; }
.q > summary {
  list-style: none; cursor: pointer; padding: 26px 56px 26px 0; position: relative;
  font: 900 clamp(23px, 2.2vw, 30px)/1.15 var(--f-d); text-transform: uppercase;
  transition: color var(--t-fast);
}
.q > summary::-webkit-details-marker { display: none; }
.q > summary:hover { color: var(--gold); }
.q > summary::after {
  content: ''; position: absolute; right: 8px; top: 50%; width: 16px; height: 2px;
  background: var(--gold); transition: transform var(--t-mid) var(--ease);
}
.q > summary::before {
  content: ''; position: absolute; right: 15px; top: 50%; width: 2px; height: 16px;
  margin-top: -7px; background: var(--gold); transition: transform var(--t-mid) var(--ease), opacity var(--t-fast);
}
.q[open] > summary::before { transform: rotate(90deg); opacity: 0; }
.q__a { padding: 0 0 26px; max-width: 68ch; color: var(--cream-2); font-size: 16px; }
.sec--light .q__a { color: #4A443B; }

/* ---------- Как найти -------------------------------------------------------- */

.find { display: grid; gap: 2px; grid-template-columns: minmax(0, .72fr) minmax(0, 1.28fr); margin-top: clamp(32px, 4vw, 48px); }
.find__info { padding: clamp(26px, 3vw, 40px); background: rgba(255, 255, 255, .03); border: 1px solid var(--ink-3); display: grid; align-content: start; gap: 24px; }
.find__row b { display: block; font: 700 12px/1 var(--f-b); letter-spacing: .18em; text-transform: uppercase; color: var(--gold); margin-bottom: 9px; }
.find__row span, .find__row a { font-size: 17px; text-decoration: none; }
.find__row a:hover { color: var(--gold); }

/* ---------- Лента фотографий -------------------------------------------------- */

/* scroll-snap вместо карусельной библиотеки: работает мышью, пальцем,
   колесом и клавиатурой, весит ноль. */
.strip {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(78vw, 420px); gap: 2px;
  overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  margin-top: clamp(28px, 3.5vw, 44px); padding-bottom: 12px;
  scrollbar-width: thin; scrollbar-color: var(--gold-lo) transparent;
}
.strip > figure { scroll-snap-align: start; margin: 0; position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-2); }
.strip img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) brightness(.86); transition: filter var(--t-slow) ease, transform 1.2s var(--ease); }
.strip > figure:hover img { filter: none; transform: scale(1.05); }
/* Подписи ленты набирались 13 px обычным начертанием, а подписи плиток над
   ней — 19–25 px заглавными в акцидентной гарнитуре. Один и тот же тип
   элемента в одной секции выглядел из двух разных наборов. */
.strip figcaption {
  position: absolute; inset: auto 0 0; z-index: 2; padding: 16px 18px;
  background: linear-gradient(transparent, rgba(9, 8, 7, .92));
  font: 900 16px/1.15 var(--f-d); letter-spacing: .015em;
  text-transform: uppercase; color: var(--cream);
}

/* Лента обрывается по правому краю прямо посреди кадра. На пальце это
   понятно, мышью на большом экране — нет: полосы прокрутки не видно, и срез
   читается как обрезанная вёрстка. Растушёванный край и подпись объясняют,
   что дальше есть ещё. */
.strip__wrap { position: relative; }
.strip__wrap::after {
  content: ''; position: absolute; inset: 0 0 12px auto; width: clamp(40px, 7vw, 96px);
  background: linear-gradient(to left, var(--ink), transparent);
  pointer-events: none; z-index: 3;
}
.sec--tint .strip__wrap::after { background: linear-gradient(to left, var(--ink-2), transparent); }
.strip__hint {
  display: flex; align-items: center; gap: 9px; margin-top: 14px;
  font: 700 11px/1 var(--f-b); letter-spacing: .18em; text-transform: uppercase;
  color: var(--cream-3);
}
.strip__hint::after { content: '→'; font-size: 14px; letter-spacing: 0; color: var(--gold); }



/* ---------- Светлая схема для блока цен ------------------------------------- */

/* Приём Peloton: тёмный герой, но цифры — на светлом. На кремовом фоне
   цена читается лучше, и длинный тёмный кусок страницы разбивается.
   Все значения выведены из тех же токенов, новых hex не заводим. */
.sec--light .plan { background: rgba(18, 16, 14, .035); border-color: #E2DACA; }
.sec--light .plan--hot { border-color: var(--gold-lo); background: rgba(200, 162, 74, .13); }
.sec--light .plan__p { color: #8A6B22; }
.sec--light .plan__p small { color: #6B6357; }
.sec--light .plan li { color: #4A443B; }
.sec--light .plan li::before { color: var(--gold-lo); }
/* На кремовом фоне главная кнопка была залита --gold-lo (#6E5828) — глухой
   болотный оттенок, и это самая важная кнопка сайта: «Записаться на
   бесплатную». Заливаем чернилами: контраст с кремовым текстом 16:1 против
   прежних 5,5, цвет тот же, что у заголовков этих секций, а золото остаётся
   акцентом цены и наводки. */
.sec--light .btn--gold { background: var(--ink); color: var(--cream); }
.sec--light .btn--gold::before { background: var(--gold); }
.sec--light .btn--gold:hover, .sec--light .btn--gold:focus-visible { color: var(--ink); }

/* ==========================================================================
   МОБИЛЬНАЯ ВЕРСИЯ

   Не «сжатый десктоп»: часть блоков собрана иначе. Разбор и обоснование —
   docs/MOBILE.md. Проверять: node tools/audit-mobile.mjs index.html
   ========================================================================== */

/* --- Поповер как нижний лист ---------------------------------------------
   На телефоне окно по центру с прокруткой внутри — чужой паттерн: кнопка
   внизу обрезается, а лист снизу привычен и прокручивается целиком. */







/* На узком экране описания групп раскрыты по ширине, а не только по
   `hover: none`: на планшете с мышью правило не срабатывало и человек
   видел четыре фотографии без единого слова. */


/* ---------- Карта -----------------------------------------------------------

   Решение перенесено с сайта «Облака» и доказало себя там. Суть: на устройстве
   с мышью карта живая, на сенсорном экране — картинка, а маршрут строится по
   кнопке под ней. Иначе палец, попавший в карту при прокрутке, тащит карту,
   а не страницу, и человек застревает в блоке.
   -------------------------------------------------------------------------- */

.map { display: grid; gap: 16px; }
/* Рамка: тонкая золотая подложка и внутреннее кольцо. Виджет Яндекса приходит
   со своим прямоугольным холстом, поэтому скругление держим и на обёртке,
   и на самом iframe — иначе по углам вылезает белый прямоугольник. */
.map__box {
  position: relative; padding: 7px; border-radius: calc(var(--r) + 8px);
  background: linear-gradient(135deg, rgba(200, 162, 74, .5), rgba(110, 88, 40, .28));
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.map__box::before {
  content: ''; position: absolute; inset: 7px; border-radius: var(--r);
  box-shadow: inset 0 0 0 1px rgba(200, 162, 74, .55);
  pointer-events: none; z-index: 2;
}
.map__badge {
  position: absolute; z-index: 3; top: 20px; left: 20px;
  padding: 10px 16px; border-radius: var(--r);
  background: rgba(18, 16, 14, .92); backdrop-filter: blur(8px);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .5);
  font: 700 13px/1 var(--f-b); letter-spacing: .04em; color: var(--cream);
  pointer-events: none;
}
/* Подложка под виджетом. Пока карта грузится — а у кого-то она не загрузится
   вовсе: заблокированный iframe, оффлайн, отвалившийся Яндекс — на её месте
   была чёрная коробка в золотой рамке высотой в пол-экрана. Теперь под ней
   лежит адрес и ссылка: блок остаётся полезным, даже когда карты нет.
   Виджет непрозрачен и перекрывает подложку, как только приходит. */
.map__fb {
  position: absolute; inset: 7px; z-index: 0; border-radius: var(--r);
  display: grid; place-content: center; justify-items: center; gap: 14px;
  padding: 28px; text-align: center; background: var(--ink-2);
}
.map__fb b { font: 900 clamp(20px, 2vw, 26px)/1.1 var(--f-d); text-transform: uppercase; color: var(--cream); }
.map__fb span { font-size: 15px; color: var(--cream-3); max-width: 34ch; }

.map__frame {
  position: relative; z-index: 1;
  width: 100%; max-width: 100%; height: clamp(320px, 54vh, 500px);
  /* Фон обязан быть прозрачным: с непрозрачным собственным фоном пустой
     iframe закрашивал подложку, и смысла в ней не было никакого. Пока
     карта не пришла — сквозь iframe видно адрес; пришла — виджет
     непрозрачен и перекрывает подложку сам. */
  border: 0; border-radius: var(--r); display: block; background: transparent;
  /* Яндекс отдаёт светлую карту — приглушаем, чтобы она не выбивалась
     из тёмной схемы, но остаётся читаемой. */
  filter: grayscale(.3) contrast(1.04) brightness(.94);
}
.map__open {
  display: none; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 26px; border: 1px solid var(--ink-3); border-radius: var(--r);
  font: 700 15px/1 var(--f-b); text-decoration: none; color: var(--cream);
  background: rgba(255, 255, 255, .04);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.map__open::before {
  content: ''; width: 16px; height: 16px; flex: none;
  background: var(--gold); border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
}
.map__open:hover { background: var(--gold); color: var(--ink); border-color: var(--gold); }

/* На устройстве с мышью виджет Яндекса сам рисует ссылку в углу карты —
   вторая рядом выглядела бы небрежно. Кнопка нужна там, где карта не
   принимает касания. */




/* Мелкие цели нажатия в подвале: ссылка 24 px по высоте — промах пальцем. */
.ftr__bot a { display: inline-flex; align-items: center; min-height: 44px; }

/* Разделитель в бегущей строке на кремовом фоне: золото давало 2.1:1. */
.marquee--light .marquee__row > span i,
.marquee--light .marquee__row > span::after { color: var(--gold-ink); }
.ftr__nav li { min-height: 44px; }
.ftr__nav a { display: inline-flex; align-items: center; min-height: 44px; }

/* Последние мелкие цели нажатия: ссылка-адрес и короткие пункты подвала. */
.ftr ul a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }

/* ---------- Состояния формы записи ------------------------------------------ */

.form input[aria-invalid='true'], .form select[aria-invalid='true'] {
  border-color: var(--blood);
  box-shadow: 0 0 0 3px rgba(193, 18, 31, .18);
}
.form__err {
  display: block; margin-top: 7px; font-size: 13px; color: var(--blood); font-weight: 600;
}
.sec--light .form__err { color: #A3101B; }
/* Сообщение о результате отправки. Живёт в aria-live, поэтому читается
   вслух и не требует от человека искать глазами, что изменилось. */
.form__msg {
  grid-column: 1 / -1; margin: 0; padding: 16px 18px; border-radius: var(--r);
  font-size: 15px; line-height: 1.55;
}
.form__msg:empty { display: none; }
.form__msg[data-kind='ok'] { background: rgba(200, 162, 74, .16); border-left: 3px solid var(--gold); }
.form__msg[data-kind='err'] { background: rgba(193, 18, 31, .12); border-left: 3px solid var(--blood); }
.sec--light .form__msg[data-kind='ok'] { background: rgba(200, 162, 74, .22); }
.btn[aria-busy='true'] { opacity: .6; pointer-events: none; }

/* ==========================================================================
   МЕДИАЗАПРОСЫ — все в одном месте и по убыванию ширины.

   Раньше их было четырнадцать блоков вразнобой: max-width 1100 стоял
   после max-width 720 и молча перекрывал его правила. Один такой
   конфликт уже нашёлся (.dir__d). Порядок «от широкого к узкому» —
   единственное, что удерживает каскад от подобных сюрпризов.
   ========================================================================== */

@media (max-width: 1100px) {
  .hdr__nav { display: none; }
  .hdr__burger { display: block; }
  .hdr__tel, .hdr__cta { display: none; }

  /* --- Открытое мобильное меню -----------------------------------------
     Класс .is-open навешивал JS с самого начала, а правила под него в CSS
     не было ВООБЩЕ: на каждой ширине ≤1100 (то есть на любом телефоне,
     планшете и узком окне ноутбука) бургер честно менял aria-expanded
     на true и ставил замок прокрутки — и не показывал ничего. Навигация
     была недостижима ни глазами, ни с клавиатуры, а скринридеру при этом
     сообщалось, что меню раскрыто.

     Панель кладём на весь экран (inset: 0), а не под шапку: высота шапки
     меняется на прокрутке (84 -> 68 px), и привязка к ней разъезжалась бы.
     Шапка выше по z-index (100 против 99), поэтому логотип и бургер
     остаются поверх панели и бургер можно нажать повторно. */
  .hdr__nav.is-open {
    display: flex; flex-direction: column; align-items: stretch;
    /* НЕ `inset: 0`. У .hdr.is-stuck стоит backdrop-filter, а элемент
       с фильтром становится опорой для position:fixed внутри себя — как
       только шапка залипает при прокрутке, панель разворачивается по
       шапке (390x132), а не по экрану. В неподвижном состоянии страницы
       баг не виден вовсе, поэтому ловится он только проверкой, которая
       сначала прокручивает страницу.
       Явные размеры от окна верны в обоих случаях: шапка начинается
       в 0,0 и растянута во всю ширину, так что её угол совпадает
       с углом экрана. */
    position: fixed; top: 0; left: 0; width: 100%; height: 100vh; height: 100dvh;
    z-index: 99; margin: 0; gap: 0;
    padding: 104px var(--pad) calc(28px + env(safe-area-inset-bottom));
    background: #0C0A09;
    overflow-y: auto; overscroll-behavior: contain;
  }
  .hdr__nav.is-open a {
    padding: 17px 0; white-space: normal; color: var(--cream);
    font: 900 clamp(23px, 6vw, 32px)/1.05 var(--f-d);
    letter-spacing: .01em; text-transform: uppercase;
    border-bottom: 1px solid var(--ink-3);
  }
  /* Подчёркивание-«шторка» рассчитано на строку 13 px в ряд — на крупных
     пунктах столбца оно превращается в полосу во всю ширину экрана. */
  .hdr__nav.is-open a::after { display: none; }
  /* Шапка — position:fixed с z-index, то есть собственный контекст
     наложения, и z-index панели считается ВНУТРИ него. Панель (99)
     перекрывала бургер, у которого z-index не задан вовсе: программный
     клик меню закрывал, а палец попадал в панель — закрыть его повторным
     нажатием было нельзя. Поднимаем логотип и бургер над панелью. */
  .hdr__logo, .hdr__burger { position: relative; z-index: 100; }
  .hdr__nav.is-open a.is-here { color: var(--gold); }

  /* Телефон и кнопка записи в шапке скрыты на этих ширинах, а до липкой
     панели надо ещё долистать: без них открытое меню было бы навигацией
     без единого действия. */
  .hdr__nav.is-open .hdr__navx { display: grid; gap: 12px; margin-top: 28px; }
  .hdr__nav.is-open .hdr__navx a {
    border-bottom: 0; font: 700 16px/1 var(--f-b); text-transform: none;
    letter-spacing: .02em; padding: 17px 22px; text-align: center;
  }
  .hdr__nav.is-open .hdr__navx .hdr__navtel {
    color: var(--gold); font: 800 22px/1 var(--f-b); padding: 6px 0 10px; text-align: left;
  }
  .limbs { grid-template-columns: 1fr; }
  .ftr__in { grid-template-columns: 1fr 1fr; }
  .dock { display: flex; }
  .wins, .find { grid-template-columns: 1fr; }
  /* --- A2. Место под липкую панель --------------------------------------
     Панель фиксирована, и без отступа последний блок уезжает под неё. */
  body { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }

  /* Кнопка звонка в шапке: до появления панели позвонить было нечем. */
  .hdr__call {
    display: grid; place-items: center; margin-left: auto; flex: none;
    width: 46px; height: 46px; border: 1px solid var(--ink-3);
    border-radius: var(--r); color: var(--cream); text-decoration: none;
    background: rgba(255, 255, 255, .04);
  }
  .hdr__call + .hdr__burger { margin-left: 8px; }
  .hdr__call svg { width: 20px; height: 20px; fill: currentColor; }
}

@media (max-width: 900px) {
 .dir__d { grid-template-rows: 1fr; } 
}

@media (max-width: 860px) {
  .pop__box { grid-template-columns: 1fr; }
  .pop {
    width: 100%; max-width: 100%; max-height: 88svh;
    margin: 0; align-self: end; justify-self: center;
    position: fixed; inset: auto 0 0; transform: none;
  }
  .pop[open] { animation: sheet-up .38s var(--ease); }
  @keyframes sheet-up { from { transform: translateY(100%); } }
  .pop__box {
    border-radius: 18px 18px 0 0; border-bottom: 0;
    max-height: 88svh; overflow-y: auto; overscroll-behavior: contain;
    /* На узком экране прокручивается сам лист целиком, поэтому строки
       свободные, а не ограниченные, как на десктопе. */
    grid-template-rows: auto auto;
  }
  .pop__body { overflow: visible; padding-bottom: calc(28px + env(safe-area-inset-bottom)); }
  .pop__media { min-height: 190px; height: 190px; }
  /* Полоска-ручка сверху: показывает, что лист тянется и закрывается. */
  .pop__box::before {
    content: ''; position: sticky; top: 8px; z-index: 4; grid-column: 1 / -1;
    justify-self: center; width: 44px; height: 4px; margin-bottom: -4px;
    border-radius: 99px; background: rgba(245, 239, 226, .3);
  }
}

@media (max-width: 720px) {
  .stamp { display: none; }   /* налезал на ярлык секции */
  .hero { min-height: 92svh; }
  .hero__nums { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 24px; }
  /* Две кнопки героя вставали в столбец шириной по своему тексту: 252 px
     и 216 px друг под другом — ступенька, которая читается как небрежность.
     В колонке одной ширины обе цели ещё и крупнее под палец. */
  .hero__btns { display: grid; gap: 12px; }
  .form { grid-template-columns: 1fr; }
  .ftr__in { grid-template-columns: 1fr; }
  .marquee { --dur: 22s; }
  /* --- B1. Схема ударов: на телефоне не нужна --------------------------
     Вся её ценность — в наведении, которого здесь нет, а места она занимает
     полэкрана. Смысл блока «ударов восемь, вот они» плитка передаёт лучше. */
  .limbs__fig { display: none; }
  .limbs { gap: 0; }
  .limbs__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px; }
  .limb { padding: 16px 14px; }
  .limb b { font-size: 21px; }
  .limb span:not(.limb__more) { font-size: 13px; }

  /* --- B4. Направления: текст под фото, а не поверх --------------------
     На тёмном кадре мелкий текст всегда хуже, чем на честном фоне. */
  .dirs { gap: 20px; }
  .dir { aspect-ratio: auto; display: grid; grid-template-rows: auto auto; background: none; }
  .dir picture { position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden; }
  /* Было grayscale(.25) — то есть почти цвет. Причина осветления верна:
     текст здесь ушёл ПОД фото, и затемнять кадр ради читаемости больше
     не нужно. Но осветлить и раскрасить — разные вещи: монохром держат
     ВСЕ прочие фото сайта, включая плитки зала в соседнем правиле для
     сенсорных экранов. В цвете оставалась одна секция из шести, и на
     прокрутке это читалось как сбой, а не как приём. Увидеть это раньше
     было нельзя: правила для (hover:none) не применялись ни в одном
     снимке из-за поломанной эмуляции. */
  .dir img { position: absolute; filter: grayscale(1) brightness(.95); }
  .dir::after { inset: 0 0 auto; height: 0; }
  .dir__in { position: static; padding: 14px 0 0; }
  .dir__n { margin-top: 8px; }
  .dir__d { grid-template-rows: 1fr; }
  .dir__d p { color: var(--cream-2); }

  /* --- B3. Тренеры в две колонки ---------------------------------------
     Весь состав виден разом — это и есть вопрос, на который человек хочет
     ответить за секунду. */
  .team { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .coach__n { font-size: 19px; margin-top: 12px; }
  .coach__r { font-size: 13px; }

  /* --- B2. Расписание --------------------------------------------------
     Чипы одной лентой вместо четырёх строк; карточка кликабельна целиком,
     девять одинаковых кнопок подряд — шум. */
  .pick {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity;
    overscroll-behavior-x: contain; padding-bottom: 10px;
    margin-inline: calc(var(--pad) * -1); padding-inline: var(--pad);
    scrollbar-width: none;
  }
  .pick::-webkit-scrollbar { display: none; }
  .pick__b { flex: none; scroll-snap-align: start; white-space: nowrap; }

  .groups { gap: 12px; }
  .grp { gap: 14px; padding: 20px 18px; }
  .grp__t { font-size: 24px; }
  /* Кнопку не прячем: карточка-ссылка без настоящей ссылки недоступна
     с клавиатуры и невидима для чтеца экрана. Вместо этого кнопка становится
     полосой во всю ширину карточки — одна понятная цель на карточку. */
  .grp__foot { margin-top: 0; flex-wrap: wrap; }
  .grp .btn { margin-left: 0; width: 100%; order: 2; }
  .grp .tag { order: 1; }

  /* --- Прочее ----------------------------------------------------------- */
  /* Карточки тарифов лежат стопкой с зазором 2 px, и ярлык, посаженный
     верхом на рамку, накрывал край предыдущей карточки — читался как
     принадлежащий шву, а не тарифу. В столбце он просто первая строка. */
  .plan__hot { position: static; translate: none; align-self: flex-start; margin-bottom: 16px; }

  .hero__scroll { display: none; }   /* полоса тут не нужна: экран и так короткий */
  .strip { grid-auto-columns: min(84vw, 340px); }
  .offer__in { gap: 14px; }
  .offer__in .btn { margin-left: 0; width: 100%; }
  .q > summary { padding: 22px 46px 22px 0; }
  .map__frame { pointer-events: none; }
  .map__open { display: inline-flex; }
  .find__open { display: none; }
  .map__badge { top: 14px; left: 14px; font-size: 12px; padding: 8px 13px; }
  .h1__sub { font-size: .5em; }
}

@media (min-width: 721px) {
  .hero__in { padding-bottom: clamp(96px, 11vh, 128px); }
  .grp__foot { flex-wrap: nowrap; }
  .grp__foot .tag { min-width: 0; line-height: 1.35; }
  .grp__foot .btn { flex: none; margin-left: auto; }
}

@media (min-width: 901px) {
  #reviews .wrap {
    display: grid; align-items: center;
    grid-template-columns: minmax(0, .92fr) minmax(0, 1fr);
    column-gap: clamp(40px, 5vw, 76px);
  }
  #reviews .eyebrow { grid-area: 1 / 1; align-self: end; margin-bottom: 18px; }
  #reviews h2       { grid-area: 2 / 1; align-self: start; }
  #reviews .quote   { grid-area: 1 / 2 / 3 / 3; margin-top: 0; max-width: none; }

  .flow { display: grid; grid-template-columns: minmax(300px, .78fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 72px); align-items: start; }
  .flow__head { position: sticky; top: 128px; }
  .flow .steps { grid-template-columns: 1fr; gap: 14px; margin-top: 0; }
  .flow .step {
    display: grid; grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: 'n t' 'n p'; gap: 4px clamp(18px, 2vw, 28px);
    align-items: baseline;
  }
  .flow .step__n { grid-area: n; }
  .flow .step h3 { grid-area: t; margin-top: 0; }
  .flow .step p { grid-area: p; margin-top: 10px; }
}

@media (min-width: 1101px) {
 .hdr__call { display: none; } 
}

@media (hover: none) {
  .tile img { filter: grayscale(1) brightness(.9); }
  .dir__d { grid-template-rows: 1fr; }
  /* Отсюда убран `.dir img { filter: grayscale(.3) brightness(.86) }`:
     на телефоне выполняются ОБА условия — и (max-width:720), и (hover:none), —
     а этот блок идёт позже, и подобранный для узкого экрана фильтр
     .25/.92 не применялся никогда. Ровно тот сорт молчаливого перекрытия,
     ради которого медиазапросы и собирали в одном месте по убыванию. */
  .map__frame { pointer-events: none; height: clamp(260px, 42vh, 380px); }
  .map__open { display: inline-flex; }
  .find__open { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rv { opacity: 1; transform: none; }
  .mask > i { transform: none; opacity: 1; }
  .marquee__row, .rays, .hero__media img.is-on, .hero__scroll::after { animation: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
  .rv-hit { opacity: 1; transform: none; }
  .rope, .limbs.is-counted .limbs__dot, .btn.is-hit::after { animation: none; }
}

/* ---------- История ---------------------------------------------------------- */

/* Лента времени, а не карточки: у истории есть порядок, и он тут смысловой.
   Годы крупно золотом — по ним взгляд и идёт. */
.era { display: grid; grid-template-columns: minmax(140px, 190px) minmax(0, 1fr); gap: clamp(20px, 3vw, 44px); padding: clamp(24px, 3vw, 34px) 0; border-top: 1px solid var(--ink-3); }
.era:last-child { border-bottom: 1px solid var(--ink-3); }
.era__y { font: 900 clamp(26px, 3vw, 40px)/1 var(--f-d); color: var(--gold); letter-spacing: -.02em; }
.era__y small { display: block; margin-top: 8px; font: 700 12px/1.4 var(--f-b); letter-spacing: .14em; text-transform: uppercase; color: var(--cream-3); }
.era h3 { font-size: clamp(21px, 2vw, 27px); }
.era p { margin-top: 12px; color: var(--cream-2); font-size: 16px; max-width: 72ch; }
.era b { color: var(--cream); font-weight: 700; }

/* ---------- Ритуал ----------------------------------------------------------- */

.rite { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); margin-top: clamp(36px, 5vw, 56px); }
.rite__c { padding: clamp(26px, 2.8vw, 36px); background: rgba(255, 255, 255, .03); border: 1px solid var(--ink-3); }
.rite__c h3 { font-size: clamp(22px, 2vw, 28px); }
/* Название по-тайски даём только в русском произношении: тайская вязь без
   расшифровки — украшение, а с расшифровкой рядом это одно и то же дважды. */
.rite__c i { display: block; font-style: normal; margin-top: 9px; font-size: 14px; color: var(--gold); letter-spacing: .04em; }
.rite__c p { margin-top: 14px; font-size: 15px; line-height: 1.6; color: var(--cream-3); }

/* ---------- Дополнительный раздел -------------------------------------------
   «О муай тай» стоит ниже коммерческих блоков и звучит тише: меньше
   вертикали, меньше заголовок. Это глубина для любопытных, а не то, ради
   чего человек открыл сайт.
   -------------------------------------------------------------------------- */

.sec--aside { padding-block: clamp(48px, 6vw, 84px); }
.h2--aside { font-size: clamp(30px, 3.6vw, 52px); }
.q__a--wide { max-width: none; }
/* Внутри свёрнутого блока лента времени и карточки идут компактнее:
   они уже вложены в аккордеон, второй уровень отступов тут лишний. */
.q__a--wide .era { grid-template-columns: minmax(120px, 160px) minmax(0, 1fr); padding-block: 20px; }
.q__a--wide .era:first-child { border-top: 0; padding-top: 0; }
.q__a--wide .era:last-child { border-bottom: 0; }
.q__a--wide .era__y { font-size: clamp(22px, 2.4vw, 32px); }
.q__a--wide .era h3 { font-size: clamp(18px, 1.7vw, 22px); }
.q__a--wide .era p { font-size: 15px; }
.q__a--wide .rite { margin-top: 0; }
.q__a--wide .rite__c { padding: 22px 24px; }
.q__a--wide .rite__c h3 { font-size: clamp(19px, 1.8vw, 23px); }

/* ---------- Крупная цитата вместо пустых карточек ---------------------------- */

.quote { margin-top: clamp(30px, 4vw, 44px); max-width: 74ch; padding-left: clamp(20px, 3vw, 34px); border-left: 3px solid var(--gold); }
.quote__t { font-size: clamp(18px, 1.8vw, 24px); line-height: 1.5; color: var(--cream); }
.quote .btn { margin-top: 26px; }

/* Секция-передышка: половина обычной вертикали. Не всё на странице обязано
   быть полноразмерным разделом — иначе ритма нет вовсе. */
.sec--mid { padding-block: clamp(48px, 6vw, 84px); }

/* Но передышка была собрана как все прочие секции — ярлык, огромный
   заголовок в две строки, текст под ним шириной 74ch, — и правые 620 px
   из 1320 оставались пустыми. Половинная вертикаль при полноразмерной
   шапке читалась не как пауза, а как недоделанный раздел. Разворачиваем
   в две колонки: слева обращение, справа сам ответ. Пустота становится
   полем между колонками, а не провалом справа. */

/* ==========================================================================
   ПРИЁМЫ

   Каждый оставлен только потому, что объясняет структуру или задаёт тон.
   Разбор и то, что осознанно НЕ делаем, — docs/POLISH.md.
   ========================================================================== */

/* --- Полоса прочитанного: канат ринга ------------------------------------
   Нативная scroll-driven анимация: ни строки JS, ни одного слушателя
   прокрутки. Где браузер не умеет — полосы просто нет, и это нормально. */
@supports (animation-timeline: scroll()) {
  .rope {
    position: fixed; inset: 0 auto auto 0; z-index: 120;
    height: 2px; width: 100%; transform-origin: left;
    background: linear-gradient(90deg, var(--gold-lo), var(--gold), var(--gold-hi));
    scale: 0 1;
    animation: rope linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes rope { to { scale: 1 1; } }
}

/* --- Удар в заголовках ---------------------------------------------------
   Мягкая кривая на всём подряд читается как всплывающее уведомление.
   Заголовкам даём резкий вход с микро-перелётом: движение — часть тона. */
.rv-hit { opacity: 0; transform: translateY(26px) scale(.985); }
.rv-hit.is-in {
  opacity: 1; transform: none;
  transition: opacity .34s ease-out, transform .52s cubic-bezier(.2, 1.5, .35, 1);
  transition-delay: calc(var(--i, 0) * 70ms);
}

/* --- Восемь точек по очереди --------------------------------------------
   При первом появлении точки вспыхивают от кулаков к голеням: без единого
   слова показывает, что их восемь и что они разные. */
.limbs__dot { animation: none; }
.limbs.is-counted .limbs__dot {
  animation: spark 2.6s var(--ease) both;
  /* Запас как у соседнего --i: точка без атрибута --n делала calc()
     невалидным целиком, и вспышка выпадала из очереди. */
  animation-delay: calc(var(--n, 0) * 150ms);
}
/* Через transform, а не через атрибут r: у SVG-геометрии в CSS до сих пор
   разная поддержка по браузерам, а масштаб работает везде и идёт на видеокарте.
   transform-box: fill-box нужен, иначе точка масштабируется от угла холста. */
@keyframes spark {
  0%   { transform: scale(1);   fill: var(--gold-lo); }
  8%   { transform: scale(1.6); fill: var(--gold-hi); }
  22%  { transform: scale(1);   fill: var(--gold); }
  100% { transform: scale(1);   fill: var(--gold); }
}

/* --- Залипающий заголовок в «Как всё пройдёт» ---------------------------
   Пока мимо идут четыре шага, заголовок стоит: последовательность
   чувствуется телом, а не читается как список. */

/* --- Контурное слово поверх зала ----------------------------------------
   Одна гарнитура в двух состояниях, залитом и контурном. Ни одного нового
   цвета, а глубина появляется. */
#gym { overflow: hidden; }
.stamp {
  /* Справа от заголовка, где всё равно пусто: за фотографиями слово было бы
     не видно вовсе, а поверх них — мешало бы.
     Было right:-3% «под вылет за край». На 1440 вылет выходил 43 px —
     ровно на последнюю букву: на экране читалось «Muay Tha», и это выглядит
     не приёмом, а поломкой. Приём работает, только когда срез либо глубокий,
     либо его нет вовсе; выбираем второе и держим слово в колонке текста. */
  position: absolute; z-index: 0; right: var(--pad); top: 2%;
  font: 900 clamp(70px, 10.5vw, 168px)/.8 var(--f-d); letter-spacing: -.03em;
  color: transparent; -webkit-text-stroke: 1px rgba(200, 162, 74, .17);
  white-space: nowrap; pointer-events: none; user-select: none;
}

/* --- Удар по кнопке ------------------------------------------------------
   Круг, расходящийся от точки нажатия. Полсекунды, чистый CSS, в зале
   читается как попадание. */
.btn { --rx: 50%; --ry: 50%; }
.btn::after {
  content: ''; position: absolute; left: var(--rx); top: var(--ry); z-index: -1;
  width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%;
  background: rgba(255, 255, 255, .55); opacity: 0; transform: scale(1);
  pointer-events: none;
}
.btn.is-hit::after { animation: hit .55s ease-out; }
@keyframes hit {
  from { opacity: .5; transform: scale(1); }
  to   { opacity: 0; transform: scale(34); }
}

