/* База: reset, документ, сетка, шкала текста, языки, состояния движения. Сырых значений здесь нет – только токены. */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  position: relative;
  min-height: 100dvh;
  background: var(--color-bg-page);
  color: var(--color-fg);
  font-family: var(--font-text);
  font-size: var(--fs-body-l);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-page);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, video, canvas, svg { display: block; max-width: 100%; }
img, video { height: auto; }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
p, h1, h2, h3, h4 { overflow-wrap: break-word; }
h1, h2, h3 { text-wrap: balance; }
p, li { text-wrap: pretty; }

/* Языки: в разметке оба текста (data-l), показывается язык <html lang> – переключатель в шапке, js/main.js */
html[lang="ru"] [data-l="en"], html[lang="en"] [data-l="ru"] { display: none; }

/* Сетка страницы (фирменная разметка канваса): квадраты по 4 на ширину экрана (2 на телефоне), крестики на стыках.
   Закреплена на экране, под содержимым секций (внутри main); псевдоэлемент – не пустой div */
/* main – белый лист страницы над подвалом: уезжает вверх и открывает его (подвал закреплён под страницей, отступ – высота экрана) */
main { position: relative; z-index: var(--z-section); margin-bottom: 100svh; background: var(--color-bg-page); }
main::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: var(--z-grid);
  pointer-events: none;
  background-image: var(--grid-pattern);
  background-size: var(--grid-cell) var(--grid-cell);
}

/* Контейнер с полями и 12 колонок. Ширина элементов – через grid-column, не через px */
.wrapper {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--page-margin);
}
.grid-12 {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
}
.section {
  position: relative;
  z-index: var(--z-section);
  padding-block: var(--space-section);
}
.section--sheet {
  background: var(--color-bg-sheet);
}

/* Шкала текста. Размер текста в правилах секций не ставится – только эти классы. Одинаковый текст – один размер */
.display-xl { font-family: var(--font-display); font-size: var(--fs-display-xl); line-height: var(--lh-display); letter-spacing: var(--ls-display); font-weight: var(--fw-display); }
.display-l  { font-family: var(--font-display); font-size: var(--fs-display-l);  line-height: var(--lh-display-l); letter-spacing: var(--ls-display); font-weight: var(--fw-display); }
.title-m    { font-family: var(--font-display); font-size: var(--fs-title-m);    line-height: var(--lh-title); letter-spacing: var(--ls-title); font-weight: var(--fw-title); }
.title-xxs  { font-family: var(--font-text);    font-size: var(--fs-title-xxs);  line-height: var(--lh-title-xxs); letter-spacing: var(--ls-title); font-weight: var(--fw-semibold); }
.body-l     { font-size: var(--fs-body-l); line-height: var(--lh-body); letter-spacing: var(--ls-body); }
.label      { font-size: var(--fs-label); line-height: var(--lh-tight); letter-spacing: var(--ls-label); font-weight: var(--fw-semibold); }
.body-s     { font-size: var(--fs-body-s); line-height: var(--lh-small); font-weight: var(--fw-medium); }
.label-l    { font-size: var(--fs-btn); line-height: var(--lh-tight); letter-spacing: var(--ls-btn); font-weight: var(--fw-title); }
.hand       { font-family: var(--font-hand); font-size: var(--fs-hand); line-height: var(--lh-title); letter-spacing: 0; font-weight: 400; }
.hand-l     { font-family: var(--font-hand); font-size: var(--fs-hand-l); line-height: var(--lh-title); letter-spacing: 0; font-weight: 400; }
.muted      { color: var(--color-fg-muted); }
/* Акцент в заголовке – слово внутри <em> */
.display-xl em, .display-l em { font-style: normal; color: var(--color-accent); }

/* Движение: пока JS не подготовил элемент, он скрыт – но только когда движение включено (html.has-motion).
   Без JS, в ?static и при prefers-reduced-motion класса нет, и всё видно сразу */
.has-motion [data-reveal]:not(.is-ready) { visibility: hidden; }
/* Приём decode (docs/motion.md): буквы заголовка как отдельные ячейки; курсор набора и акцент */
.ch { display: inline-block; white-space: pre; }
.ch.is-cursor { background: var(--color-fg); }
.ch.is-acc { color: var(--color-accent); }

/* Холст сцены: единственное абсолютное позиционирование по умолчанию (docs/scene.md) */
[data-scene] { position: relative; }
[data-scene] canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: var(--z-scene); }
[data-scene] > :not(canvas) { position: relative; z-index: var(--z-content); }
[data-scene].is-live .scene__fallback { display: none; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

@media (max-width: 768px) {
  .wrapper { padding-inline: var(--page-margin-mobile); }
  .section { padding-block: var(--space-section-mobile); }
  .body-l { font-size: var(--fs-body-l-mobile); }
  main { margin-bottom: 0; }
  .hand-l { font-size: var(--fs-hand-l-mobile); }
}

/* Режим съёмки для Figma (?static&figma): шапка, подвал и сетка – в потоке страницы, а не на экране, – куски склеиваются без повторов */
.is-figma .site-header { position: absolute; }
.is-figma main { margin-bottom: 0; }
.is-figma main::before { position: absolute; }
.is-figma .site-footer { position: relative; }
