/* ============================================================================
   ГУСІ — база: сброс, шрифты, система «сцены», доступность
   ========================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto; /* скроллом управляет Lenis */
}

body {
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  font-size: var(--fs-body);
  line-height: var(--lh-flat);
  color: var(--c-brand);
  background: var(--c-paper);
  overflow-x: hidden;
  text-transform: uppercase;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  text-transform: inherit;
}

ul {
  list-style: none;
}

::selection {
  background: var(--c-brand);
  color: #fff;
}

/* ----------------------------------------------------------------------
   ТИПОГРАФИЧЕСКИЕ УРОВНИ
   Каждый класс — ровно один уровень шкалы. Смешивать нельзя:
   если элементу нужен другой кегль, он меняет уровень целиком.
   -------------------------------------------------------------------- */
.t-display {
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
  line-height: var(--lh-flat);
}

.t-h1 {
  font-size: var(--fs-h1);
  font-weight: var(--fw-bold);
  line-height: var(--lh-flat);
}

/* Заголовок ВНУТРИ секции. Он обязан быть меньше названия секции —
   иначе на одном экране два одинаково крупных заголовка, и глазу негде
   выбрать главный. */
.t-h2 {
  font-size: var(--fs-h2);
  font-weight: var(--fw-bold);
  line-height: var(--lh-flat);
}

.t-h2--tight {
  font-size: var(--fs-h2);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
}

.t-logo {
  font-size: var(--fs-logo);
  font-weight: var(--fw-bold);
  line-height: var(--lh-flat);
}

.t-nav {
  font-size: var(--fs-nav);
  font-weight: var(--fw-regular);
  line-height: var(--lh-flat);
}

/* Подводка: одна фраза под заголовком. Крупнее абзаца, но заголовком не
   является — поэтому светлое начертание, а не жирное. */
.t-lead {
  font-size: var(--fs-lead);
  font-weight: var(--fw-regular);
  line-height: var(--lh-flat);
}

.t-body {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-flat);
}

.t-body--tight {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-tight);
}

/* Самый мелкий уровень страницы — подпись под товаром. */
.t-small {
  font-size: var(--fs-small);
  font-weight: var(--fw-regular);
  line-height: var(--lh-flat);
}

/* ----------------------------------------------------------------------
   СИСТЕМА «СЦЕНЫ»
   Каждая секция макета — это сцена фиксированного размера в юнитах макета.
   Дети позиционируются абсолютно по координатам из Figma, поэтому
   совпадение с макетом гарантировано, а не подгоняется на глаз.
   -------------------------------------------------------------------- */
.section {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.stage {
  position: relative;
  width: calc(var(--design-w) * var(--u));
  margin: 0 auto;
  /* --stage-h задаётся посекционно, значение — высота фрейма Figma */
  height: calc(var(--stage-h) * var(--u));
}

/* Элемент, позиционируемый по координатам Figma.
   --x / --y / --w / --h — числа из макета, без единиц. */
.at {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
}

.at--sized {
  width: calc(var(--w) * var(--u));
  height: calc(var(--h) * var(--u));
  /* Размер задан координатами макета, поэтому базовый max-width здесь не
     действует: в макете есть картинки шире своей карточки (их подрезает
     overflow карточки), и клампинг молча ужимал бы их вместо подрезки. */
  max-width: none;
}

.at--w {
  width: calc(var(--w) * var(--u));
}

/* Координаты в ДОЛЯХ РОДИТЕЛЯ, а не в юнитах макета.
   Нужно там, где сама коробка на мобиле другого размера, но той же
   пропорции: композиция внутри неё тогда переезжает целиком, одним
   правилом на родителя, вместо пересчёта каждого слоя на брейкпойнте.
   Так живут слои гуся во второй секции (коробка 1242×828 на десктопе и
   731×487 на мобиле — те же 3:2). */
.at--pc {
  left: calc(var(--x) * 1%);
  top: calc(var(--y) * 1%);
  width: calc(var(--w) * 1%);
  height: calc(var(--h) * 1%);
  max-width: none;
}

/* ЯКОРЬ ЦЕНТРА — точка, вокруг которой встаёт содержимое.

   Кнопкам левый край не годится: их ширину задаёт подпись, и она зависит
   от того, как именно легли метрики шрифта. В макете «ДАВЕДАЦЦА» лежит по
   координате левого края, но живая кнопка выходит на 30–60 юнитов шире
   фигмовской — и уезжает от оси текста, под которым стоит. Отсюда и брались
   «кнопки не по центру»: осью служил левый край, а не центр.

   Центрирует НЕ сама кнопка, а обёртка вокруг неё, и это принципиально.
   Сдвинуть кнопку на половину собственной ширины можно только двумя
   свойствами — transform и translate, — и оба у неё отняты: transform
   занимает GSAP (появление, параллакс), а translate он же обнуляет.
   CSSPlugin сворачивает отдельные translate/rotate/scale в свою матрицу
   и пишет элементу translate: none — центрирование слетало на первом же
   кадре анимации, причём только на живой странице: в ?static=1 GSAP не
   запускается вовсе, и проверка этого не видела.

   Обёртка же собственной анимации не имеет, трогать её некому.
   Нулевая ширина + justify-content: center — содержимое переполняет
   якорь симметрично, то есть встаёт ровно центром на --cx. Ни половин
   ширины в числах, ни пересчёта на resize.
   -------------------------------------------------------------------- */
.at--cx {
  left: calc(var(--cx) * var(--u));
  width: 0;
  display: flex;
  justify-content: center;
}

/* Кнопка внутри якоря не жмётся и не тянется — она ровно своей ширины. */
.at--cx > * {
  flex: none;
}

/* Figma отмеряет текстовую коробку от верха строки, браузер — от верха
   line-box; для «ГУСІ» в подвале разница ровно 0.1em кегля. Компенсируем
   её через токен, а не подбором координаты на каждом брейкпойнте. */
.at--cap-display {
  top: calc(var(--y) * var(--u) + var(--fs-display) * 0.1);
}

/* ----------------------------------------------------------------------
   СЛОИ ГЛУБИНЫ (0 — дальний фон, 5 — передний план)
   Используются скролл-параллаксом: каждый слой едет со своим множителем.
   -------------------------------------------------------------------- */
.layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.layer > * {
  pointer-events: auto;
}

.depth-0 { z-index: 0; }
.depth-1 { z-index: 1; }
.depth-2 { z-index: 2; }
.depth-3 { z-index: 3; }
.depth-4 { z-index: 4; }
.depth-5 { z-index: 5; }

/* ----------------------------------------------------------------------
   РАЗБИТЫЙ ТЕКСТ (см. js/split.js)
   .w — маска слова, .w__i — то, что едет внутри неё, .ch — отдельная буква.
   -------------------------------------------------------------------- */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}

.w__i {
  display: inline-block;
}

/* Обойма букв одного слова: слово переносится целиком, внутри не рвётся */
.wch {
  display: inline-block;
  white-space: nowrap;
}

.ch {
  display: inline-block;
  white-space: pre;
}

/* ----------------------------------------------------------------------
   ПРЕЛОАДЕР
   -------------------------------------------------------------------- */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: grid;
  place-items: center;
  background: var(--c-paper);
  transition: opacity 0.7s var(--ease-out), visibility 0.7s;
}

.preloader[hidden] {
  display: grid; /* [hidden] перебиваем — прячем через .is-done */
}

.preloader.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.preloader__mark {
  font-size: var(--fs-logo);
  font-weight: var(--fw-bold);
  letter-spacing: calc(4 * var(--u));
  color: var(--c-brand);
}

.preloader__bar {
  position: absolute;
  left: 50%;
  bottom: 22%;
  translate: -50% 0;
  width: calc(320 * var(--u));
  height: calc(2 * var(--u));
  background: rgba(169, 109, 205, 0.18);
  overflow: hidden;
}

.preloader__fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--c-brand);
  transition: width 0.35s var(--ease-out);
}

/* Перенос строки, работающий только в мобильном макете —
   в десктопном абзац переносится иначе. */
.br-mobile { display: none; }

/* ----------------------------------------------------------------------
   ДОСТУПНОСТЬ
   -------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: calc(2 * var(--u)) solid var(--c-brand);
  outline-offset: calc(4 * var(--u));
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ----------------------------------------------------------------------
   РЕЖИМ СВЕРКИ С МАКЕТОМ (?static=1)
   Скролл-анимации выключены, всё показано в финальном состоянии —
   так скриншот можно наложить на экспорт из Figma и померить расхождение.
   -------------------------------------------------------------------- */
html.is-static .preloader { display: none; }

html.is-static [data-split],
html.is-static [data-reveal],
html.is-static [data-brush],
html.is-static [data-card],
html.is-static [data-panel],
html.is-static .footer__wordmark-inner {
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
}

/* Дождь орнамента в режиме сверки стоит: снимок должен быть один и тот же
   при каждом прогоне, а бегущая лента ловилась бы в случайной фазе.
   Прежний ход был твином GSAP, и в этом режиме он не создавался вовсе —
   у css-анимации выключателя нет, поэтому он объявлен здесь. */
html.is-static .ornament__fall {
  animation: none;
}

/* Маска «фонарика» в режиме сверки снята: без курсора она оставила бы от
   слова серп, а на макете «ГУСІ» видно целиком. */
html.is-static .footer__torch {
  -webkit-mask-image: none;
          mask-image: none;
}

html.is-static #scroll-content { margin-bottom: 0; }

html.is-static .section--footer {
  position: relative;
  height: auto;
}

html.is-static { scrollbar-width: none; }
html.is-static::-webkit-scrollbar { display: none; }
