/* Сброс, типографика, сетка, появление блоков. */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 16px);
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--f-sans);
  font-size: var(--ty-body);
  line-height: var(--ty-body-lh);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden; /* страховка от случайного горизонтального скролла */
}

h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button, input { font: inherit; color: inherit; }

/* Роли заголовков (шкала 06/10/2026, DESIGN.md): размер следует уровню тега. Нужен вид заголовка у не-заголовка: p.t-h2 / p.t-h3 / p.t-h4 */
h1, h2, h3, h4, .t-h2, .t-h3, .t-h4 { text-wrap: balance; }
h1 { font-size: var(--ty-h1); line-height: var(--ty-h1-lh); font-weight: var(--ty-h1-fw); letter-spacing: var(--ty-h1-ls); }
h2, .t-h2 { font-size: var(--ty-h2); line-height: var(--ty-h2-lh); font-weight: var(--ty-h2-fw); letter-spacing: var(--ty-h2-ls); }
h3, .t-h3 { font-size: var(--ty-h3); line-height: var(--ty-h3-lh); font-weight: var(--ty-h3-fw); letter-spacing: var(--ty-h3-ls); }
h4, .t-h4 { font-size: var(--ty-h4); line-height: var(--ty-h4-lh); font-weight: var(--ty-h4-fw); }
b, strong { font-weight: var(--ty-fw-bold); }
p { text-wrap: pretty; }

a { color: var(--c-link); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--c-accent-hover); }

:focus-visible { outline: 3px solid var(--c-focus); outline-offset: 3px; border-radius: 6px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--s-4); top: -100px; z-index: 100;
  background: var(--c-ink); color: #fff; padding: var(--s-3) var(--s-4); border-radius: var(--r-s);
}
.skip:focus { top: var(--s-3); }

.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.section { padding-block: var(--space-section); position: relative; }
.section--soft { background: var(--c-bg-2); }
.section__head { max-width: 46rem; margin-bottom: var(--head-gap); }
.section__head h2 { max-width: var(--ty-h2-ch); }
.section__head .lead { margin-top: var(--ty-gap-h2-lead); }
.lead { font-size: var(--ty-lead); line-height: var(--ty-lead-lh); font-weight: var(--ty-lead-fw); color: var(--c-ink-2); }
.muted { color: var(--c-ink-3); }
.eyebrow {
  display: inline-block; margin-bottom: var(--ty-gap-eyebrow);
  font-size: var(--ty-small); line-height: var(--ty-small-lh); font-weight: var(--ty-eyebrow-fw);
  letter-spacing: var(--ty-eyebrow-ls); color: var(--c-ink-2);
}

/* Появление блоков: один keyframes, 0.4s.
   Где браузер умеет animation-timeline: view(), блок проявляется при входе в экран.
   Где нет, тот же fade проигрывается один раз при загрузке. Без скролл-пиннинга и параллакса. */
@keyframes fade-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
/* Базовое состояние блоков видимое. Скрытие и fade включаются только там, где есть animation-timeline: view()
   и пользователь не просил меньше движения. Без таких браузеров (и у краулеров, и без JS) всё видно сразу. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      animation: fade-in linear forwards; /* без backwards: до входа в экран блок виден, провала в пустоту нет */
      animation-timeline: view();
      animation-range: entry 0px entry 220px; /* длина, а не процент: высокий блок на мобильном не ждёт 45% высоты */
    }
  }
}
/* Запуск по видимости: класс .io ставит скрипт в head (есть IntersectionObserver), .is-live секции main ставит site.js
   (вошла в окно с запасом 10% = live, ушла дальше = пауза). Вне окна сцены, циклы и карусели стоят на паузе и ничего не считают,
   вошла в окно: идут с того же кадра. Без JS класса .io нет, анимации идут как обычно. */
.io main > section:not(.is-live) *,
.io main > section:not(.is-live) *::before,
.io main > section:not(.is-live) *::after { animation-play-state: paused !important; }
/* кот карусели hero (.pc__cat) может быть ниже первого экрана внутри живой секции: его анимации идут, только пока он сам в окне (.in-view ставит site.js) */
.io .pc__cat:not(.in-view) *,
.io .pc__cat:not(.in-view) *::before,
.io .pc__cat:not(.in-view) *::after { animation-play-state: paused !important; }

/* reduce: ни движения, ни переходов, включая псевдоэлементы и раскрытие details (::details-content) */
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal * { animation: none !important; }
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  details::details-content { transition: none !important; } /* отдельным правилом: старый браузер без ::details-content не должен ронять общее */
}

/* PERF-AUDIT шаг 4: form.js и waiters.js грузятся, когда блок подошёл к окну, и меняют его вид (прячут подсказку «без JS», ставят значки на лету).
   Чтобы это не давало сдвиг, в режиме .pf (JS есть) подсказка скрыта сразу, а подписи-«таблетки» ждут значков невидимыми.
   Без JS класса .pf нет, подсказка и таблетки видны как раньше. */
.pf .cform__nojs { display: none; }
.pf .wt:not(.wt--on) .wt__t { visibility: hidden; }

/* PERF-AUDIT шаг 1 (06/10/2026): секции ниже hero не раскладываются и не рисуются, пока не подойдут к окну.
   Класс .pf ставит скрипт в head (страницы с perf), класс .cv только страницам с замеренными --cv (флаг cv в PAGES: сейчас club и home); у остальных content-visibility не включается, иначе якоря промахиваются. Новая страница получает cv после замера своих --cv. Размеры --cv = полная высота секции, замерено на 390 и 1440 px (в contain-intrinsic-size идёт высота без отступов секции, поэтому минус два --space-section), auto запоминает реальную высоту после показа.
   Якоря и поиск по странице работают: браузер раскрывает цель сам. Выкл: убрать класс pf в head_links. */
.pf.cv main > section:not(:first-child):not(#quiz) { content-visibility: auto; contain-intrinsic-size: auto calc(var(--cv, 900px) - 2 * var(--space-section)); }
.pf #audience { --cv: 1733px; } .pf #method { --cv: 1426px; } .pf #facts { --cv: 379px; } .pf #learn { --cv: 1056px; }
.pf #stack { --cv: 516px; } .pf #program { --cv: 1650px; } .pf #howit { --cv: 1008px; } .pf #stories { --cv: 1856px; }
.pf #pricing { --cv: 1683px; } .pf #author { --cv: 1283px; } .pf #faq { --cv: 1824px; } .pf #cta { --cv: calc(1461px + var(--space-section)); }
@media (min-width: 960px) {
  .pf #audience { --cv: 1466px; } .pf #method { --cv: 911px; } .pf #facts { --cv: 226px; } .pf #learn { --cv: 1041px; }
  .pf #stack { --cv: 785px; } .pf #program { --cv: 1287px; } .pf #howit { --cv: 1013px; } .pf #stories { --cv: 964px; }
  .pf #pricing { --cv: 945px; } .pf #author { --cv: 807px; } .pf #faq { --cv: 1691px; } .pf #cta { --cv: calc(914px + var(--space-section)); }
}
