@font-face {
  font-family: "Golos Text";
  src: url("public/fonts/golos-cyrillic.woff2") format("woff2");
  font-display: swap;
  font-style: normal;
  font-weight: 400 900;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("public/fonts/jbmono-cyrillic.woff2") format("woff2");
  font-display: swap;
  font-style: normal;
  font-weight: 400 700;
}

:root {
  --black: #10100f;
  --black-soft: #181816;
  --black-warm: #22221f;
  --bone: #eeeae0;
  --bone-soft: #d6d1c7;
  --signal: #f24b32;
  --muted: #8f8c85;
  --muted-on-light: #5d5952;
  --muted-on-dark: #b5b0a7;
  /* Затемнённый акцент для мелкого белого текста на плашках: сам --signal
     даёт лишь 3.95:1 и не проходит AA. */
  --signal-deep: #c9331f;
  /* Акцент и серый для текста на светлых секциях. Мелкий текст требует 4.5:1,
     крупный 3:1, поэтому вариантов по два: иначе заголовки пришлось бы
     затемнять до бордового без необходимости.
     Проверено на --bone #eeeae0 и на более тёмном --bone-soft #d6d1c7. */
  --signal-on-light: #a52616;
  --signal-on-light-lg: #d43a22;
  --muted-on-light-lg: #767169;
  --line: rgba(238, 234, 224, 0.18);
  --line-dark: rgba(16, 16, 15, 0.18);
  --display: "Golos Text", Arial, sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;
  --page: min(1480px, calc(100vw - clamp(32px, 7vw, 112px)));
}

/* Базовый слой. Раньше он приходил из styles.css — стиля прошлого дизайна,
   который index.html подключал первым. Тот файл заодно приносил свои
   .final-cta, .final-cta__mark и mix-blend-mode, и они прорастали сквозь этот
   файл: круги в финальном блоке становились залитыми полосами, а знак получал
   object-fit: cover и режим наложения. Поэтому база живёт здесь, а styles.css
   с главной снят. */
* {
  box-sizing: border-box;
}

html {
  background: var(--bone);
  color-scheme: dark;
  scroll-behavior: smooth;
}

/* Плавная прокрутка выключается только по явному «Анимация: выкл».
   На медиазапрос её вешать нельзя: с выключенными анимациями Windows прокрутка
   становилась рывковой, и вместе с погашенными переходами это давало ровно тот
   «неплавный сайт», на который жаловался владелец. Перехвата колеса здесь нет —
   `scroll-behavior` действует только на переходы по якорям и scrollTo. */
html.no-motion {
  scroll-behavior: auto;
}

body {
  margin: 0;
  background: var(--bone);
  color: var(--black);
  font-family: var(--display);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

body.is-locked {
  overflow: hidden;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select,
textarea {
  font: inherit;
}

button {
  border: 0;
  cursor: pointer;
}

img {
  display: block;
  max-width: 100%;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1,
h2,
h3 {
  font-weight: 400;
  letter-spacing: -0.075em;
}

h2 {
  margin: 0;
  line-height: 0.82;
}

/* Зерно поверх страницы. Слой не перехватывает события и не участвует в
   раскладке, поэтому он не может ничего сдвинуть. */
body::after {
  position: fixed;
  z-index: 100;
  inset: 0;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.72' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.18'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
  content: "";
}

body::before {
  position: fixed;
  z-index: 99;
  inset: 0;
  pointer-events: none;
  border: 1px solid rgba(255, 255, 255, 0.08);
  content: "";
}

a,
button,
summary {
  -webkit-tap-highlight-color: transparent;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 4px;
}

.page-loader {
  position: fixed;
  z-index: 500;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 24px;
  background: var(--black);
  color: var(--bone);
  transition: opacity 0.55s ease, visibility 0.55s ease;
}

/* Во время перехода общий лоадер должен быть выше шумового слоя и контента. */
.page-loader.is-done {
  pointer-events: none;
}

.page-loader img {
  width: clamp(120px, 16vw, 230px);
  color: var(--bone);
  filter: invert(1);
  animation: loader-pulse 1.2s ease both;
}

.page-loader span {
  font: 10px/1 var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.page-loader.is-done {
  visibility: hidden;
  opacity: 0;
}

.site-header {
  position: sticky;
  z-index: 50;
  top: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  width: 100%;
  min-height: 82px;
  padding: 0 clamp(20px, 4vw, 64px);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--black) 92%, transparent);
  color: var(--bone);
  backdrop-filter: blur(18px);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  width: max-content;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.045em;
  text-transform: uppercase;
}

.wordmark img {
  width: 34px;
  height: 34px;
  color: currentColor;
  filter: invert(1);
}

.wordmark span {
  display: grid;
  gap: 4px;
}

.wordmark small {
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  font-weight: 400;
  letter-spacing: 0.1em;
}

.desktop-nav {
  display: flex;
  gap: clamp(22px, 3.5vw, 56px);
  color: var(--bone-soft);
  font: 10px/1 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.desktop-nav a,
.plain-link,
.footer-nav a {
  position: relative;
}

.desktop-nav a::after,
.plain-link::after,
.footer-nav a::after {
  position: absolute;
  right: 0;
  bottom: -7px;
  left: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s ease;
  content: "";
}

.desktop-nav a:hover::after,
.plain-link:hover::after,
.footer-nav a:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

.header-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 18px;
}

.plain-link {
  color: var(--bone-soft);
  font: 10px/1 var(--mono);
  text-transform: uppercase;
}

.ink-button,
.paper-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 36px;
  min-height: 48px;
  padding: 0 18px;
  overflow: hidden;
  background: var(--bone);
  color: var(--black);
  font: 10px/1 var(--mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  transform: translate3d(var(--magnet-x, 0), var(--magnet-y, 0), 0);
  transition: color 0.3s ease, transform 0.2s ease;
}

.ink-button::before,
.paper-button::before {
  position: absolute;
  inset: 0;
  background: var(--signal-deep);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.36s cubic-bezier(0.2, 0.75, 0.2, 1);
  content: "";
}

.ink-button span,
.ink-button b,
.paper-button span,
.paper-button b {
  position: relative;
  z-index: 1;
}

.ink-button b,
.paper-button b {
  font-size: 15px;
  font-weight: 400;
}

.ink-button:hover,
.paper-button:hover {
  color: #fff;
}

.ink-button:hover::before,
.paper-button:hover::before {
  transform: scaleX(1);
}

.ink-button--large {
  min-width: 220px;
  min-height: 59px;
  padding: 0 22px;
}

.menu-toggle,
.mobile-nav {
  display: none;
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(360px, 0.88fr);
  gap: clamp(32px, 5vw, 78px);
  align-items: center;
  min-height: min(820px, max(680px, calc(100vh - 82px)));
  padding: clamp(56px, 6vw, 96px) max(calc((100vw - 1480px) / 2), clamp(20px, 4vw, 64px));
  background: var(--black);
  color: var(--bone);
}

.hero-copy h1 {
  max-width: 1000px;
  margin: 30px 0 28px;
  font-size: clamp(62px, 7.2vw, 118px);
  font-weight: 600;
  letter-spacing: -0.095em;
  line-height: 0.78;
}

/* Внутри мобильной grid-колонки заголовок разбивается на inline-block-слова.
   Без нулевого min-width сам hero-copy выбирает min-content-ширину по самому
   длинному слову и добавляет несколько пикселей к документу. */
.hero-copy {
  min-width: 0;
}

.hero-copy h1 em,
.section-head h2 em,
.pitch-guide h2 em,
.final-cta h2 em {
  color: var(--muted);
  font-style: normal;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--muted);
  font: 10px/1.35 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Разделитель нарисован, а не набран. Символ «·» в 10px моношрифте занимает
   один-два пикселя, и субпиксельное сглаживание Windows раскрашивает его в
   тёплый цвет — на тёмном фоне это читается как оранжевая точка. Полоска
   рисуется фоном, у неё нет глифа и нет цветной каймы. */
.eyebrow-rule {
  flex: 0 0 auto;
  width: 14px;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.hero-lead {
  max-width: 620px;
  margin-bottom: 40px;
  color: var(--bone-soft);
  font-size: clamp(16px, 1.4vw, 20px);
  line-height: 1.5;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 22px;
}

.line-link {
  display: inline-flex;
  align-items: center;
  gap: 24px;
  padding: 18px 0 10px;
  border-bottom: 1px solid var(--line);
  color: var(--bone-soft);
  font: 10px/1 var(--mono);
  text-transform: uppercase;
}

.line-link:hover {
  border-color: var(--bone);
}

.proof-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  max-width: 690px;
  margin-top: 58px;
  border-top: 1px solid var(--line);
}

.proof-row div {
  min-height: 98px;
  padding: 18px 14px 0 0;
  border-right: 1px solid var(--line);
}

.proof-row div:not(:first-child) {
  padding-left: 18px;
}

.proof-row div:last-child {
  border-right: 0;
}

.proof-row strong,
.proof-row span {
  display: block;
}

.proof-row strong {
  margin-bottom: 14px;
  font: 14px/1 var(--mono);
  font-weight: 400;
  text-transform: uppercase;
}

.proof-row span {
  color: var(--muted-on-dark);
  font: 10px/1.4 var(--mono);
  text-transform: uppercase;
}

.hero-object {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 520px;
}

.hero-object__foot {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 15px 17px;
  color: var(--muted-on-dark);
  font: 10px/1.25 var(--mono);
  letter-spacing: 0.07em;
  border-top: 1px solid var(--line);
}

/* Сцена знака: без рамки и без подложки-квадрата. Перспектива живёт здесь,
   а не на самом знаке: если задать её на вращающемся элементе, точка схода
   поедет вместе с ним и вращение будет читаться как качание. */
.logo-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 450px;
  perspective: 1600px;
  perspective-origin: 50% 50%;
}

/* Круглое свечение уходит в прозрачность — границы блока не видно, квадрата
   вокруг знака нет. */
.logo-stage::after {
  position: absolute;
  z-index: -1;
  width: 88%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(51, 51, 47, 0.85) 0, rgba(27, 27, 24, 0.4) 48%, rgba(18, 18, 16, 0) 72%);
  content: "";
}

/* Монета из двух граней и гурта между ними. Одну картинку вращать нельзя:
   после 90° браузер покажет её зеркально, и знак прочитается как перевёрнутый.

   --coin-thickness задаёт толщину и в CSS, и в скрипте, который расставляет
   слои тела: скрипт читает значение из вычисленного стиля, поэтому менять
   толщину нужно только здесь. Грани стоят на ±половине толщины, слои тела
   заполняют промежуток между ними. */
.logo-coin {
  --coin-thickness: 26px;
  position: relative;
  width: min(360px, 62%);
  aspect-ratio: 1;
  transform-style: preserve-3d;
  /* Наклон в покое. Строго в 0° объёмный знак выглядит ровно как плоская
     картинка: толщина уходит за лицевую грань и не видна. На машинах без
     ускорения вращение не включается, и без этого наклона вся глубина
     пропадала — именно так знак и читался «плоским». */
  transform: rotateX(8deg) rotateY(-26deg);
}

/* Грани и слои тела рисуются маской по фигуре знака и сплошным цветом, а не
   картинкой с filter: invert(). Так было раньше, и на трёх десятках слоёв это
   не работает: каждый filter — отдельный проход растеризации, и знак перестаёт
   отрисовываться вовсе (симптом: пустое место на месте логотипа, снимок экрана
   не снимается по таймауту). Маска даёт тот же белый знак одним слоем краски. */
.logo-coin__face,
.logo-coin__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  mask: url("public/assets/logo-mark.svg") center / contain no-repeat;
  -webkit-mask: url("public/assets/logo-mark.svg") center / contain no-repeat;
  backface-visibility: hidden;
}

.logo-coin__face {
  background: var(--bone);
  opacity: 0.95;
}

/* Грани разнесены на рабочую толщину. Дополнительные слои тела отключены ниже:
   Chromium на Windows давал на них швы при каждом обороте маски. */
.logo-coin__face--front {
  transform: translateZ(calc(var(--coin-thickness) / 2));
}

.logo-coin__face--back {
  opacity: .28;
  transform: rotateY(180deg) translateZ(calc(var(--coin-thickness) / 2));
}

.logo-coin__layer {
  display: none;
}

html.gpu-motion .logo-coin {
  animation: coin-spin-clean 26s linear infinite;
  will-change: transform;
}

@keyframes coin-spin-clean {
  from { transform: rotateX(8deg) rotateY(0deg); }
  to { transform: rotateX(8deg) rotateY(360deg); }
}

/* Пауза, когда знак ушёл из вида или вкладка неактивна: кадры для того, чего
   не видно, всё равно считаются и греют видеокарту. */
html.gpu-motion .logo-coin.is-paused {
  animation-play-state: paused;
}

/* rotateX стоит первым и не меняется: наклон остаётся в мировых координатах, а
   знак вращается вокруг своей наклонённой оси. Если поменять порядок, наклон
   поедет вместе со знаком и вращение прочитается как качание. */
@keyframes coin-spin {
  from {
    transform: rotateX(8deg) rotateY(0deg);
  }

  to {
    transform: rotateX(8deg) rotateY(360deg);
  }
}

.statement {
  padding: clamp(90px, 12vw, 190px) max(calc((100vw - 1480px) / 2), clamp(20px, 4vw, 64px));
  background: var(--bone);
}

.statement p {
  max-width: 1280px;
  margin: 0;
  font-size: clamp(38px, 5.4vw, 82px);
  font-weight: 500;
  letter-spacing: -0.07em;
  line-height: 1.02;
}

.statement strong {
  color: var(--signal);
  font-weight: 500;
}

.roster {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  overflow: hidden;
  border-top: 1px solid var(--line-dark);
  border-bottom: 1px solid var(--line-dark);
  background: var(--bone);
  color: var(--black);
}

.roster-label {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 170px;
  padding: 17px 28px;
  border-right: 1px solid var(--line-dark);
  /* Не var(--signal): на фирменном акценте белый текст даёт 3.95:1, а для 10px
     нужно от 4.5:1. Затемнённый оттенок того же акцента даёт 5.28:1. */
  background: var(--signal-deep);
  color: #fff;
  font: 10px/1 var(--mono);
  text-transform: uppercase;
}

.roster-track {
  display: flex;
  min-width: 0;
  gap: 24px;
  align-items: center;
  width: max-content;
  padding: 15px 24px;
  font: 11px/1 var(--mono);
  text-transform: uppercase;
  animation: roster-scroll 36s linear infinite alternate;
}

/* Разделитель в бегущей строке тоже нарисован. Тот же «·» акцентным цветом
   давал ряд оранжевых точек — единственное цветное пятно на первом экране. */
.roster-track i {
  flex: 0 0 auto;
  width: 10px;
  height: 1px;
  background: var(--muted-on-light);
  font-style: normal;
  opacity: 0.6;
}

.section {
  padding: clamp(100px, 11vw, 180px) max(calc((100vw - 1480px) / 2), clamp(20px, 4vw, 64px));
}

.section-head {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) minmax(240px, 340px);
  gap: clamp(28px, 5vw, 80px);
  align-items: end;
  margin-bottom: clamp(60px, 8vw, 110px);
}

.section-number {
  display: block;
  margin-bottom: 22px;
  color: var(--signal);
  font: 14px/1 var(--mono);
}

.section-head h2,
.pitch-guide h2 {
  margin: 0;
  font-size: clamp(48px, 5.8vw, 88px);
  font-weight: 600;
  letter-spacing: -0.085em;
  line-height: 0.86;
}

.section-head > p {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
}

.process .section-head > p,
.faq .section-head > p,
.partners p {
  color: var(--muted-on-light);
}

.section-head--light {
  color: var(--bone);
}

.catalog {
  background: var(--black-soft);
  color: var(--bone);
}

.catalog .section-head > p,
.services .section-head > p,
.extra-services .section-head > p,
.catalog-proof p {
  color: var(--muted-on-dark);
}

.top-releases {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  background: transparent;
}

.top-release--feature {
  /* Все релизы имеют одну ячейку: так нет искусственной пустоты внутри первой
     карточки и шесть выходов образуют плотную сетку 3×2. */
  grid-row: auto;
  grid-column: auto;
}

/* Все элементы подборки — одна полка. Особая карточка не растягивается по строкам:
   иначе заголовок «Только сильные выходы» визуально распадается на разные ритмы. */
.top-release,
.top-release--feature {
  grid-row: span 1;
  min-height: 0;
  flex: 1 1 calc((100% - 40px) / 3);
  max-width: calc((100% - 40px) / 3);
}

/* position/overflow нужны обложке-подложке: она позиционируется по карточке и
   не должна выходить за её край при масштабировании на наведение. Карточка —
   ссылка <a>: вся площадь кликабельна до Яндекс Музыки (проверено владельцем). */
.top-release {
  position: relative;
  display: grid;
  overflow: hidden;
  align-content: stretch;
  min-height: 280px;
  padding: 22px;
  background: #20201d;
  color: var(--bone);
  text-decoration: none;
}

/* Текст поверх обложки. Своя ось z нужна, чтобы затемнение легло между
   картинкой и буквами, а не поверх всего. */
.top-release__body {
  position: relative;
  z-index: 1;
  display: grid;
  align-content: space-between;
  gap: 18px;
  height: 100%;
  min-height: 236px;
  padding-right: clamp(0px, 13vw, 170px);
  isolation: isolate;
}

.top-release__top {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  font: 10px/1.35 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.top-release__top > span {
  color: var(--signal);
}

.top-release__top small {
  color: var(--muted-on-dark);
  font: inherit;
  text-align: right;
}

.top-release--feature .top-release__top small {
  color: var(--muted-on-light);
}

/* Обложка — отдельная квадратная миниатюра, а не растянутый фон всей карточки.
   Так сохраняется читаемость названия и пропорции исходной обложки; саму карточку
   можно кликнуть целиком, не превращая изображение в декоративную полосу. */
.top-release__cover {
  position: absolute;
  inset: 0;
  z-index: 0;
  top: auto;
  left: auto;
  right: 22px;
  bottom: 22px;
  width: clamp(120px, 30%, 190px);
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  opacity: 1;
  filter: saturate(0.96) contrast(1.04);
  border: 1px solid rgba(238, 234, 224, 0.22);
  transition: transform 0.45s cubic-bezier(0.22, 0.75, 0.2, 1);
}

.top-release:hover .top-release__cover {
  transform: scale(1.035);
}

/* При миниатюрном варианте градиент между картинкой и текстом не нужен: текст
   живёт на сплошной карточке и не зависит от яркости конкретной обложки. */
.top-release__body::before {
  display: none;
}

/* Карточка без обложки: ни подложки, ни градиента — под текстом цвет карточки. */
.top-release.is-coverless .top-release__body::before,
.top-release.is-coverless .top-release__backdrop {
  display: none;
}

.top-release h3 {
  max-width: 520px;
  margin: 0 0 16px;
  font-size: clamp(32px, 4.3vw, 70px);
  font-weight: 600;
  letter-spacing: -.08em;
  line-height: .86;
}

.top-release:not(.top-release--feature) h3 {
  font-size: clamp(27px, 3vw, 46px);
}

.top-release__artists {
  max-width: 360px;
  margin: 0;
  color: #d2cec5;
  font: 11px/1.55 var(--mono);
  letter-spacing: .03em;
  text-transform: uppercase;
}

/* Подпись «слушать» внутри карточки-ссылки. Раньше это был отдельный <a>,
   вложенный в карточку; теперь вся карточка кликабельна, а подпись — просто
   последний ряд сетки с тем же видом. */
.top-release__listen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  color: #f4f0e8;
  font: 10px/1.4 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.top-release__listen b {
  color: var(--signal);
  transition: transform .35s ease;
}

.top-release:hover .top-release__listen b {
  transform: translate(3px, -3px);
}

/* В карточках каталога достаточно одной чёткой обложки: второй большой объект
   создавал на hover полосы и «пустую» область в сетке. */
.top-release__cover {
  will-change: auto;
}

/* У вращающегося знака больше нет пиксельного «пирога» из десятков масок:
   объём остаётся у статичной SVG-грани, а вращается один слой. Это убирает
   полосы и швы, которые появлялись на аппаратном композитинге. */
.logo-coin__layer {
  display: none;
}

.logo-coin__face--back {
  opacity: .28;
}

html.gpu-motion .logo-coin {
  animation: coin-spin-clean 26s linear infinite;
  transform-style: preserve-3d;
}

@keyframes coin-spin-clean {
  from { transform: rotateX(8deg) rotateY(0deg); }
  to { transform: rotateX(8deg) rotateY(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .top-release__cover { transition: none; }
}

/* Внутри карточки больше нет вложенной ссылки: сама карточка — <a>. Старое
   правило .top-release a повторно стилизовало всю карточку и ломало сетку. */
.top-release__listen {
  display: flex;
  justify-content: space-between;
  gap: 15px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--bone);
  font: 10px/1.2 var(--mono);
  text-transform: uppercase;
}

.catalog-proof {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  margin-top: 80px;
  padding-top: 35px;
  border-top: 1px solid var(--line);
}

.catalog-proof > div {
  max-width: 720px;
}

.catalog-proof span {
  color: var(--signal);
  font: 10px/1.2 var(--mono);
  text-transform: uppercase;
}

.catalog-proof strong {
  display: block;
  margin: 19px 0 10px;
  font-size: clamp(30px, 4vw, 58px);
  font-weight: 600;
  letter-spacing: -0.06em;
}

.catalog-proof p {
  max-width: 570px;
  margin: 0;
  color: var(--muted);
  line-height: 1.55;
}

.catalog-proof__source {
  display: inline-block;
  margin-top: 18px;
  color: var(--bone);
  font: 10px/1.2 var(--mono);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-transform: uppercase;
}

.catalog-sources {
  max-width: 390px;
  color: var(--muted-on-dark);
  font: 10px/1.65 var(--mono);
  text-transform: uppercase;
}

.catalog-sources a {
  color: var(--bone);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.catalog-meta {
  margin: 19px 0 0;
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.circle-link {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 18px;
  align-items: center;
  width: 180px;
  height: 180px;
  padding: 30px;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--bone);
  font: 10px/1.35 var(--mono);
  text-transform: uppercase;
  transform: translate3d(var(--magnet-x, 0), var(--magnet-y, 0), 0);
  transition: background 0.3s ease, color 0.3s ease, transform 0.2s ease;
}

.circle-link:hover {
  background: var(--signal-deep);
  color: #fff;
}

.circle-link b {
  font-size: 18px;
  font-weight: 400;
}

.partners {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 30px;
  align-items: center;
  padding: 43px max(calc((100vw - 1480px) / 2), clamp(20px, 4vw, 64px));
  border-bottom: 1px solid var(--line-dark);
  background: var(--bone);
}

.partners p {
  margin: 0;
  /* Владелец: «плохо видно». muted-on-light слишком бледный для подписи
     секции — берём почти чёрный. */
  color: var(--black);
  font: 11px/1.2 var(--mono);
  text-transform: uppercase;
}

.partners div {
  display: flex;
  justify-content: space-around;
  gap: 40px;
}

.partners strong {
  font-size: clamp(19px, 2.2vw, 30px);
  font-weight: 700;
  letter-spacing: -0.06em;
}

.services {
  background: var(--black);
  color: var(--bone);
}

.service-ledger {
  border-top: 1px solid var(--line);
}

.service-row {
  display: grid;
  grid-template-columns: 70px minmax(220px, 0.7fr) minmax(300px, 1fr) auto;
  gap: 28px;
  align-items: center;
  min-height: 150px;
  padding: 24px 0;
  border-bottom: 1px solid var(--line);
  transition: padding 0.28s ease, background 0.28s ease;
}

.service-row:hover {
  padding-right: 24px;
  padding-left: 24px;
  background: var(--black-warm);
}

.service-row > span,
.service-row > b {
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  font-weight: 400;
  text-transform: uppercase;
}

.service-row > b {
  color: var(--signal);
}

.service-row h3 {
  margin: 0;
  color: var(--bone);
  font-size: clamp(27px, 3vw, 44px);
  font-weight: 500;
  letter-spacing: -0.065em;
}

.service-row p {
  max-width: 640px;
  margin: 0;
  color: var(--muted-on-dark);
  font-size: 13px;
  line-height: 1.55;
}

.service-row--primary {
  background: var(--bone);
  color: var(--black);
}

.service-row--primary:hover {
  color: var(--bone);
  background: var(--black-warm);
}

.service-row--primary:hover h3 {
  color: var(--bone);
}

.service-row--primary:hover p,
.service-row--primary:hover > span {
  color: var(--muted-on-dark);
}

.service-row--primary h3 {
  color: var(--black);
}

.service-row--primary p,
.service-row--primary > span {
  color: var(--muted-on-light);
}

/* Основная строка при наведении становится тёмной. Явные цвета нужны, потому
   что обычные цвета этой строки рассчитаны на светлый фон и иначе заголовок
   исчезает на hover. */
.service-row--primary:hover {
  color: var(--bone);
  background: #20201d;
}

.service-row--primary:hover h3 {
  color: var(--bone);
}

.service-row--primary:hover p,
.service-row--primary:hover > span {
  color: var(--muted-on-dark);
}

.extra-services {
  background: var(--black-soft);
  color: var(--bone);
}

.service-groups {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
}

.service-group {
  padding: 26px;
  background: #1d1d1a;
}

.service-group__head {
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

.service-group__head span {
  color: var(--signal);
  font: 10px/1.4 var(--mono);
  letter-spacing: 0.06em;
}

.service-group__head h3 {
  margin: 0;
  font-size: clamp(24px, 2.6vw, 38px);
  font-weight: 500;
  letter-spacing: -0.065em;
}

.service-group__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.service-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px 20px;
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}

.service-item:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.service-item__name {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.02em;
}

.service-item__note {
  grid-column: 1;
  color: var(--muted-on-dark);
  font-size: 12px;
  line-height: 1.45;
}

.service-item__tag {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: start;
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Снятые с витрины позиции подсвечиваются акцентом: артист должен видеть, что
   строка существует и обсуждаема, а не считать её опечаткой. */
.service-item--request .service-item__tag {
  color: var(--signal);
}

.services-meta {
  margin: 19px 0 0;
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.prompt-list--deep {
  margin-top: 40px;
}

.pitch-points {
  max-width: 620px;
  margin: -4px 0 24px 43px;
  padding: 0 0 0 18px;
  color: var(--muted-on-light);
  font-size: 14px;
  line-height: 1.6;
}

.pitch-points li {
  margin-bottom: 10px;
}

.pitch-points li::marker {
  color: var(--signal-on-light);
  font-family: var(--mono);
  font-size: 12px;
}

.pitch-points b {
  color: var(--black);
  font-weight: 600;
}

.pitch-note {
  margin-top: 40px;
  padding-top: 26px;
  border-top: 1px solid var(--line-dark);
}

.pitch-note p {
  max-width: 620px;
  margin: 0 0 14px;
  color: var(--muted-on-light);
  font-size: 13px;
  line-height: 1.6;
}

.pitch-note p:last-child {
  margin-bottom: 0;
}

.process {
  background: var(--bone);
}

.process-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 1px;
  margin: 0;
  padding: 0;
  background: var(--line-dark);
  list-style: none;
}

.process-grid li {
  grid-column: span 2;
  min-height: 340px;
  padding: 24px;
  background: var(--bone);
}

.process-grid li > span {
  color: var(--signal);
  font: 10px/1 var(--mono);
}

.process-grid h3 {
  margin: 90px 0 18px;
  color: var(--black);
  font-size: clamp(30px, 3.1vw, 46px);
  font-weight: 500;
  letter-spacing: -0.07em;
}

.process-grid p {
  margin: 0;
  color: var(--muted-on-light);
  font-size: 13px;
  line-height: 1.55;
}

.process-cta {
  display: flex;
  justify-content: space-between;
  gap: 30px;
  margin-top: 28px;
  padding: 26px 30px;
  background: var(--signal-deep);
  color: #fff;
  font: 10px/1 var(--mono);
  text-transform: uppercase;
  transform: translate3d(var(--magnet-x, 0), var(--magnet-y, 0), 0);
  transition: transform 0.2s ease, background 0.2s ease;
}

.process-cta:hover {
  background: #b02a19;
}

.pitch-guide {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(380px, 0.75fr);
  gap: clamp(60px, 9vw, 150px);
  background: #d6d1c7;
}

.pitch-guide__body {
  padding-top: 56px;
}

.pitch-guide .lead {
  margin: 0 0 56px;
  font-size: clamp(20px, 2vw, 28px);
  letter-spacing: -0.035em;
  line-height: 1.35;
}

.prompt-list {
  border-top: 1px solid var(--line-dark);
}

.prompt-list details {
  border-bottom: 1px solid var(--line-dark);
}

/* В отличие от FAQ этот блок раньше раскрывался нативно и резко менял высоту.
   JS задаёт реальную высоту внутреннему wrapper-у: max-height не угадывает
   лимит для длинного списка и не обрезает подсказку на маленьком экране. */
.prompt-list details > p,
.prompt-list details > .pitch-points {
  max-height: 0;
  margin-top: 0;
  margin-bottom: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height .35s cubic-bezier(.22,.75,.2,1), margin .35s ease, opacity .2s ease;
}

.prompt-list details[open] > p,
.prompt-list details[open] > .pitch-points {
  max-height: var(--prompt-height, 1000px);
  margin-top: -4px;
  margin-bottom: 24px;
  opacity: 1;
}

.prompt-list summary {
  display: flex;
  gap: 24px;
  padding: 22px 0;
  cursor: pointer;
  list-style: none;
  font-size: 20px;
  font-weight: 600;
}

.prompt-list summary span {
  color: var(--signal);
  font: 10px/1.8 var(--mono);
}

.prompt-list p {
  max-width: 620px;
  margin: -4px 0 24px 43px;
  color: var(--muted-on-light);
  line-height: 1.55;
}

.faq {
  background: var(--bone);
}

.faq .section-head {
  grid-template-columns: 130px 1fr;
}

.faq-list {
  max-width: 1050px;
  margin-left: auto;
  border-top: 1px solid var(--line-dark);
}

.faq-list details {
  border-bottom: 1px solid var(--line-dark);
}

.faq-list summary {
  display: flex;
  justify-content: space-between;
  gap: 30px;
  padding: 27px 0;
  color: var(--black);
  cursor: pointer;
  list-style: none;
  font-size: clamp(18px, 2vw, 27px);
  font-weight: 600;
  letter-spacing: -0.04em;
}

.faq-list summary b {
  color: var(--signal);
  font: 23px/1 var(--mono);
  font-weight: 400;
  transition: transform 0.25s ease;
}

/* Плавное раскрытие. details сам не анимируется — высота задаётся через
   grid-template-rows на внутреннем wrapper-е: 0fr -> 1fr даёт честную
   анимацию высоты без JS и без фиксированных пикселей. */
.faq-list .faq-answer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s cubic-bezier(0.22, 0.75, 0.2, 1);
}

.faq-list details[open] .faq-answer {
  grid-template-rows: 1fr;
}

.faq-list .faq-answer > div {
  overflow: hidden;
}

.faq-list details[open] summary b {
  transform: rotate(45deg);
}

.faq-list details p {
  max-width: 760px;
  margin: -4px 70px 28px 0;
  color: var(--muted-on-light);
  font-size: 14px;
  line-height: 1.62;
}

.final-cta {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 720px;
  padding: 100px 30px;
  overflow: hidden;
  background: var(--black);
  color: var(--bone);
  text-align: center;
  isolation: isolate;
}

/* Кольца вынесены в отдельный элемент. Раньше это были ::before и ::after
   самой секции, и они наследовали top:0/bottom:0 из прежнего стиля: круг
   растягивался на всю высоту секции и превращался в залитую полосу. */
.final-cta__rings {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 650px;
  height: 650px;
  transform: translate(-50%, -50%);
}

.final-cta__rings i {
  position: absolute;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
}

.final-cta__rings i:last-child {
  width: 69%;
}

/* Дыхание колец вместо вращения: у круга вращение не видно, а медленная
   смена масштаба даёт движение без рывка и без пересчёта раскладки. */
@media (prefers-reduced-motion: no-preference) {
  .final-cta__rings i {
    animation: ring-breathe 11s ease-in-out infinite;
  }

  .final-cta__rings i:last-child {
    animation-duration: 14s;
    animation-direction: reverse;
  }
}

@keyframes ring-breathe {
  0%,
  100% {
    opacity: 0.75;
    transform: scale(1);
  }

  50% {
    opacity: 1;
    transform: scale(1.045);
  }
}

/* Знак был 42px. У этого начертания внутри вырезаны буквы U и M, и на 42px
   перемычки между ними схлопывались в пятно — со стороны знак выглядел
   перекошенным. 64px хватает, чтобы вырезы читались. */
.final-cta__mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
  margin-bottom: 28px;
  border: 1px solid var(--line);
  border-radius: 50%;
}

.final-cta__mark img {
  width: 64px;
  height: 64px;
  object-fit: contain;
  filter: invert(1);
}

/* Блок выровнен по центру, поэтому надзаголовок остаётся flex-строкой, но с
   центрированием. display:block здесь ронял нарисованный разделитель в нулевую
   ширину: у инлайнового элемента width не работает. */
.final-cta .eyebrow {
  justify-content: center;
}

.final-cta h2 {
  margin: 30px 0 43px;
  font-size: clamp(68px, 9vw, 140px);
  font-weight: 600;
  letter-spacing: -0.09em;
  line-height: 0.78;
}

.paper-button {
  min-width: 220px;
  min-height: 58px;
}

.site-footer {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 34px;
  align-items: center;
  min-height: 150px;
  padding: 30px max(calc((100vw - 1480px) / 2), clamp(20px, 4vw, 64px));
  border-top: 1px solid var(--line);
  background: var(--black);
  color: var(--bone);
}

.footer-nav {
  display: flex;
  gap: 24px;
  color: var(--muted-on-dark);
  font: 10px/1.2 var(--mono);
  text-transform: uppercase;
}

.footer-legal {
  display: flex;
  justify-content: flex-end;
  gap: 18px;
  color: var(--muted-on-dark);
  font: 10px/1.5 var(--mono);
  text-align: right;
}

/* Переключатель анимации. В шапке живёт среди пунктов меню, в подвале — рядом
   с реквизитами. Часть гостей на Windows сидит с выключенными системными
   «анимациями», и без явного выбора сайт для них всегда статичен. */
.motion-toggle {
  padding: 0;
  border: none;
  background: none;
  color: var(--muted);
  font: inherit;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}

.motion-toggle:hover,
.motion-toggle[aria-pressed="true"] {
  color: var(--bone);
}

.desktop-nav .motion-toggle {
  font-size: inherit;
}

/* Цели нажатия.
   ──────────────────────────────────────────────────────────────────────────────
   Моношрифт 10px даёт ссылку высотой 10–13px. Мышью попасть можно, пальцем —
   нет: промах открывает соседнюю ссылку или ничего. WCAG 2.5.8 требует 24×24.

   Правило на всех ширинах, не только в мобильном медиазапросе: ноутбуки с
   тачскрином отдают ширину десктопа при пальцевом вводе, и по ширине окна
   способ ввода определить нельзя.

   Отступ вертикальный, а не min-height: элементы строчные, высота на них не
   действует. Отрицательный margin убирает добавленный отступ из потока — цель
   растёт, видимая вёрстка не меняется. Проверять после правки замером
   getBoundingClientRect, а не на глаз: отступ невидим. */
.desktop-nav a,
.footer-nav a,
.catalog-sources a,
.catalog-proof__source,
.plain-link,
.motion-toggle {
  display: inline-block;
  padding-block: 7px;
  margin-block: -7px;
}

/* Тумблер в подвале растянут на всю строку: ему нужен только отступ, без
   отрицательного margin, иначе он налезает на реквизиты. */
.site-footer .motion-toggle {
  margin-block: 0;
}

.toast {
  position: fixed;
  z-index: 80;
  right: 20px;
  bottom: 20px;
  max-width: 350px;
  padding: 14px 17px;
  background: var(--signal-deep);
  color: #fff;
  font-family: var(--mono);
  font-size: 12px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.toast.is-visible {
  opacity: 1;
  transform: none;
}

/* Появление секций. Двигаются только opacity и transform — свойства, которые
   браузер считает на композиторе и которые не вызывают пересчёт раскладки.
   Задержку задаёт либо класс, либо переменная от скрипта: так соседние
   карточки въезжают каскадом, а не все разом. */
.reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.22, 0.75, 0.2, 1);
  transition-delay: var(--reveal-delay, 0s);
  will-change: opacity, transform;
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Слой снимается после проявления: постоянный will-change держит
   дополнительную текстуру на каждую секцию и на длинной странице это заметно
   по памяти видеокарты. */
.reveal.is-settled {
  will-change: auto;
}

.reveal--delay {
  --reveal-delay: 0.1s;
}

.reveal--delay-2 {
  --reveal-delay: 0.18s;
}

@keyframes loader-pulse {
  from { opacity: 0; transform: scale(0.88); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes roster-scroll {
  to { transform: translateX(min(-42%, -680px)); }
}

@media (max-width: 1100px) {
  .desktop-nav,
  .plain-link {
    display: none;
  }

  .site-header {
    grid-template-columns: 1fr auto;
  }

  .header-actions {
    gap: 12px;
  }

  .menu-toggle {
    display: block;
    padding: 10px 0;
    background: transparent;
    color: var(--bone);
    font: 10px/1 var(--mono);
    text-transform: uppercase;
  }

  .mobile-nav {
    position: absolute;
    top: 82px;
    right: 20px;
    left: 20px;
    display: grid;
    padding: 12px 20px;
    border: 1px solid var(--line);
    background: var(--black);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
  }

  .mobile-nav.is-open {
    visibility: visible;
    opacity: 1;
    transform: none;
  }

  .mobile-nav a {
    padding: 14px 0;
    border-bottom: 1px solid var(--line);
    color: var(--bone);
    font: 10px/1 var(--mono);
    text-transform: uppercase;
  }

  .hero {
    grid-template-columns: 1fr;
  }

  .hero-object {
    min-height: 590px;
  }

  .section-head {
    grid-template-columns: 100px 1fr;
  }

  .section-head > p {
    grid-column: 2;
  }

  .top-releases {
    grid-template-columns: 1fr 1fr;
  }

  .top-release--feature {
    grid-row: auto;
    grid-column: auto;
  }

  .top-release:last-child {
    grid-column: auto;
  }

  .service-row {
    grid-template-columns: 50px 0.8fr 1fr;
  }

  .service-row > b {
    grid-column: 2;
  }

  .process-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .process-grid li {
    grid-column: auto;
  }

  .process-grid li:last-child {
    grid-column: 1 / -1;
  }

  .pitch-guide {
    grid-template-columns: 1fr;
  }

  .pitch-guide__body {
    padding-top: 0;
  }
}

@media (max-width: 900px) {
  .service-groups {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .site-header {
    min-height: 72px;
    padding: 0 18px;
  }

  .wordmark small,
  .header-actions .ink-button {
    display: none;
  }

  .wordmark {
    font-size: 12px;
  }

  .wordmark img {
    width: 30px;
    height: 30px;
  }

  .mobile-nav {
    top: 72px;
  }

  .hero {
    grid-template-columns: 1fr;
    min-height: auto;
    padding: 76px 18px 90px;
  }

  .hero-copy h1 {
    margin-top: 32px;
    font-size: clamp(52px, 16vw, 82px);
  }

  .hero-lead {
    font-size: 15px;
  }

  .proof-row {
    margin-top: 58px;
  }

  .proof-row div {
    min-height: 90px;
    padding-left: 10px !important;
  }

  .proof-row strong {
    font-size: 10px;
  }

  .proof-row span {
    font-size: 10px;
  }

  .hero-object {
    min-height: 450px;
  }

  .logo-stage {
    min-height: 370px;
  }

  .statement {
    padding: 92px 18px;
  }

  .statement p {
    font-size: 38px;
  }

  .roster {
    grid-template-columns: 1fr;
  }

  .roster-track {
    width: 100%;
    max-width: 100%;
    overflow: hidden;
  }

  .roster-label {
    min-width: 0;
    border-right: 0;
    border-bottom: 1px solid var(--line-dark);
  }

  .section {
    padding: 92px 18px;
  }

  .section-head,
  .faq .section-head {
    grid-template-columns: 1fr;
    gap: 25px;
    margin-bottom: 58px;
  }

  .section-head > p {
    grid-column: auto;
  }

  .section-head h2,
  .pitch-guide h2 {
    font-size: 54px;
  }

  .top-releases {
    grid-template-columns: 1fr;
  }

  .top-release,
  .top-release--feature {
    min-height: 290px;
    grid-row: span 1;
  }

  .top-release--feature {
    grid-row: auto;
    grid-column: auto;
  }

  .top-release h3,
  .top-release:not(.top-release--feature) h3 {
    font-size: 42px;
  }

  .top-release__body {
    min-height: 248px;
    padding-right: 0;
    padding-bottom: 146px;
  }

  .top-release__cover {
    right: 22px;
    bottom: 22px;
    width: 128px;
    height: 128px;
  }

  .catalog-proof {
    align-items: flex-start;
    flex-direction: column;
  }

  .circle-link {
    width: 155px;
    height: 155px;
  }

  .partners {
    grid-template-columns: 1fr;
    padding: 35px 18px;
  }

  .partners div {
    justify-content: flex-start;
    flex-wrap: wrap;
  }

  .service-row {
    grid-template-columns: 34px 1fr;
    gap: 12px;
    min-height: 0;
    padding: 27px 0;
  }

  .service-row h3,
  .service-row p,
  .service-row > b {
    grid-column: 2;
  }

  .service-row h3 {
    font-size: 28px;
  }

  .service-group {
    padding: 22px 0;
  }

  .service-group__head h3 {
    font-size: 26px;
  }

  /* На узком экране подпись «по запросу» уходит под название: в две колонки
     длинные строки вроде «Цифровая дистрибуция 24 часа PREMIUM» переполняют
     вьюпорт. */
  .service-item {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .service-item__tag {
    grid-row: auto;
    grid-column: 1;
  }

  .pitch-points {
    margin-left: 0;
  }

  .process-grid {
    grid-template-columns: 1fr;
  }

  .process-grid li,
  .process-grid li:last-child {
    grid-column: auto;
    min-height: 290px;
  }

  .process-grid h3 {
    margin-top: 70px;
  }

  .process-cta {
    display: grid;
    line-height: 1.45;
  }

  .faq-list details p {
    margin-right: 10px;
  }

  .final-cta {
    min-height: 600px;
  }

  .final-cta h2 {
    font-size: 64px;
  }

  .site-footer {
    grid-template-columns: 1fr;
    align-items: start;
    padding: 45px 18px;
  }

  .footer-nav,
  .footer-legal {
    justify-content: flex-start;
    flex-wrap: wrap;
    text-align: left;
  }

  /* Кнопка меню: по ширине была 24px — уже цели, чем требует стандарт, и это
     главная кнопка навигации на телефоне.
     Вертикальный отступ берётся из правила выше (10px), здесь только боковой:
     сокращённая запись padding перебила бы его и сделала кнопку ниже. */
  .menu-toggle {
    padding-inline: 11px;
    margin-right: -11px;
  }
}

/* Сокращённое движение — два уровня, а не один выключатель.
   ────────────────────────────────────────────────────────────────────────────
   Раньше здесь стоял `@media (prefers-reduced-motion: reduce)`, который гасил
   `*` целиком. На машине с выключенным в Windows переключателем «Показывать
   анимации» это означало мёртвый сайт: знак не вращался, секции появлялись без
   перехода, наведения не работали. Владелец видел ровно это.

   Спецификация просит убрать **опасное** движение — размашистые смещения,
   параллакс, наезды, бегущие строки: от них укачивает. Проявление и короткий
   переход цвета к этой категории не относятся.

   Поэтому правила висят на классе `.reduced-motion`, который ставит скрипт, а
   не на медиазапросе: класс снимается явным «Анимация: вкл», и тогда гость
   получает полный набор. Медиазапрос снять нельзя, и именно это запирало сайт.

   Полная статика по-прежнему доступна: тумблер «Анимация: выкл» убирает класс
   `gpu-motion`, от которого зависят вращение знака и длинные переходы. */
html.reduced-motion .roster-track {
  animation: none;
}

html.reduced-motion .page-loader {
  display: none;
}

/* Размашистые эффекты: наезд картинки, магнитные кнопки, длинные смещения.
   Проявление секций и смена цвета остаются — они безопасны и без них страница
   выглядит сломанной, а не спокойной. */
html.reduced-motion .top-release:hover .top-release__cover,
html.reduced-motion .magnetic {
  transform: none !important;
}

html.reduced-motion .reveal {
  /* Смещение снизу убираем, прозрачность оставляем: контент появляется мягко,
     но ничего не едет по экрану. */
  transform: none !important;
}

/* Кому нужна полная статика — тумблер. Класс `no-motion` ставится им же и
   гасит уже всё, включая проявление: это осознанный выбор, а не догадка о
   намерении системы. */
html.no-motion *,
html.no-motion *::before,
html.no-motion *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  transition-delay: 0s !important;
}

html.no-motion .roster-track {
  animation: none;
}

html.no-motion .page-loader {
  display: none;
}

/* ═══ Движение по прокрутке ══════════════════════════════════════════════════
   Значения переменных пишет scroll-motion.js. Здесь только то, как они
   применяются. Разделение важно: скрипт не знает про раскладку, CSS не знает
   про прокрутку, и правка одного не ломает другое.

   Все эффекты ниже держатся на opacity и transform — единственных свойствах,
   которые браузер считает на композиторе. Замена любого из них на top/height
   вернёт рывки на прокрутке. */

/* Ссылка «к содержимому».
   Убрана за верхний край, а не спрятана display:none и не вынесена в
   отрицательный left: скрытая через display элемент не получает фокус вообще, а
   уход влево на 9999px заставляет некоторые браузеры считать документ шире окна
   и включать горизонтальную прокрутку. Сдвиг вверх безопасен: по вертикали
   прокрутка и так есть. */
.skip-link {
  position: fixed;
  z-index: 100;
  top: 0;
  left: 12px;
  padding: 11px 17px;
  background: var(--bone);
  color: var(--black);
  font: 10px/1 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
  transform: translateY(-120%);
  transition: transform .18s ease;
}

.skip-link:focus {
  transform: translateY(0);
}

/* Основной блок получает фокус программно и обводку от браузера при этом
   рисовать не должен: она обвела бы всю страницу целиком. Видимость перехода
   обеспечивает сама прокрутка к началу содержимого. */
main:focus {
  outline: none;
}

/* Полоса прочитанного под шапкой. scaleX от переменной: width пересчитывал бы
   раскладку в каждом кадре прокрутки. */
.scroll-progress {
  position: fixed;
  z-index: 60;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--signal);
  transform: scaleX(var(--progress, 0));
  transform-origin: 0 50%;
  pointer-events: none;
}

/* Шапка после 64px прокрутки: плотнее и с подложкой. Полупрозрачный фон с
   размытием нужен потому, что под шапкой проезжает и тёмная секция, и светлая,
   и сплошной цвет на одной из них выглядит заплаткой. */
.site-header {
  transition: padding 0.35s ease, background-color 0.35s ease, border-color 0.35s ease;
}

.site-header.is-condensed {
  background: rgba(12, 12, 11, 0.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

/* Сжатие только там, где у шапки есть запас по высоте: на узком экране она уже
   минимальна, и уменьшение отступов ломает попадание по кнопкам. */
@media (min-width: 861px) {
  .site-header.is-condensed {
    padding-top: 14px;
    padding-bottom: 14px;
  }
}

/* Сборка заголовка по словам. inline-block обязателен: на строчном элементе
   transform не действует, и слова просто появятся без движения.
   blur в начальном состоянии даёт ощущение наводки на фокус; он тяжелее
   opacity, поэтому снимается за 0.5s и только на заголовке, а не на всём
   тексте страницы. */
.hero-copy h1.is-split .word {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 0.34em, 0);
  filter: blur(6px);
  transition: opacity 0.62s ease, transform 0.62s cubic-bezier(0.22, 0.75, 0.2, 1), filter 0.5s ease;
  transition-delay: var(--word-delay, 0ms);
  will-change: opacity, transform;
}

.hero-copy h1.is-assembled .word {
  opacity: 1;
  transform: none;
  filter: none;
}

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

   `.is-settled`, а не просто `.hero-object`, — обязательно. Проявление секций
   ставит `.reveal.is-visible { transform: none }`, и по специфичности (0,2,0
   против 0,1,0) оно перебивало параллакс: переменная writeось, а элемент стоял.
   Симптом был именно такой — `--parallax-y` меняется, `transform` равен `none`.
   `is-settled` появляется после окончания проявления, то есть параллакс
   включается ровно тогда, когда въезд секции закончился и они больше не спорят
   за одно свойство. */
.hero-object.is-settled {
  transform: translate3d(0, var(--parallax-y, 0), 0);
}

.top-release__cover {
  /* Масштаб компенсирует сдвиг: без него параллакс уводит картинку от края и
     снизу появляется полоса цвета карточки. 1.08 покрывает ±34px сдвига на
     карточке от 315px высоты — если PARALLAX_RANGE в скрипте вырастет, это
     число надо поднять, иначе вернётся полоса. */
  transform: translate3d(0, var(--parallax-y, 0), 0) scale(1.08);
}

/* Наведение усиливает масштаб поверх параллакса. Правило дублирует базовое,
   потому что transform не складывается: указать только scale здесь — значит
   потерять сдвиг и получить прыжок картинки под курсором. */
.top-release:hover .top-release__cover {
  transform: translate3d(0, var(--parallax-y, 0), 0) scale(1.12);
}

/* Наклон карточки к курсору. perspective на самой карточке, а не на сетке:
   общая перспектива на контейнере даёт разный угол обзора для крайних карточек,
   и правая колонка выглядит перекошенной.

   `.is-settled` по той же причине, что у героя: карточки каталога получают
   `.reveal` от каскада, и `transform: none` из проявления перебивал наклон. */
.top-release.is-settled {
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  transform-style: preserve-3d;
  transition: transform 0.28s ease-out;
}

/* Курсор над карточкой — переход короче, иначе наклон отстаёт от мыши и
   ощущается как задержка ввода. Возврат наоборот медленнее: резкий отскок
   читается как дефект. */
.top-release.is-settled:hover {
  transition: transform 0.08s linear;
}

/* Переход между страницами. Затухание с лёгким подъёмом: чистая прозрачность
   выглядит как пропавшая связь, а не как переход. */
html.is-leaving body {
  opacity: 0;
  transform: translate3d(0, -8px, 0);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

/* ── Сокращённое движение: снимаем размашистое, оставляем смысловое ────────── */

/* Параллакс, наклон и подъём страницы — именно то, от чего укачивает.
   Полоса прогресса, сжатие шапки и счётчики остаются: они несут информацию, а
   не двигают картинку под глазами. */
/* no-motion здесь наравне с reduced-motion: без него карточки при выключенных
   анимациях всё равно получали perspective() и preserve-3d, то есть отдельный
   3D-слой композитора на каждую — расход есть, эффекта нет. */
html.reduced-motion .hero-object.is-settled,
html.reduced-motion .top-release__cover,
html.reduced-motion .top-release:hover .top-release__cover,
html.reduced-motion .top-release.is-settled,
html.no-motion .hero-object.is-settled,
html.no-motion .top-release.is-settled {
  transform: none !important;
}

html.no-motion .top-release.is-settled {
  transform-style: flat;
}

html.reduced-motion .hero-copy h1.is-split .word {
  /* Слова остаются, но без смещения и размытия: заголовок проявляется, а не
     собирается. Убрать правило целиком нельзя — начальная прозрачность 0
     оставит заголовок невидимым. */
  transform: none !important;
  filter: none !important;
}

html.reduced-motion.is-leaving body,
html.no-motion.is-leaving body {
  transform: none !important;
}

/* Полная статика: заголовок обязан быть виден сразу. Скрипт при `no-motion`
   разбор на слова не запускает, но класс мог остаться от переключения тумблера
   в уже открытой странице. */
html.no-motion .hero-copy h1.is-split .word {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
}

html.no-motion .scroll-progress {
  /* Полоса остаётся, но без плавности: она показывает позицию, а не движется. */
  transition: none;
}

/* Ниже — правки контраста для светлых поверхностей. Селекторы собраны обходом
   страницы: именно у них эффективный фон светлый, тогда как те же правила на
   тёмных секциях менять нельзя, они проходят AA как есть. */
.roster-track i,
.top-release--feature .top-release__top > span,
.top-release--feature a b,
.service-row--primary > b,
.process-grid li > span,
.process .section-number,
.pitch-guide .section-number,
.faq .section-number,
.prompt-list summary span,
.faq-list summary b {
  color: var(--signal-on-light);
}

/* Крупный текст: порог 3:1, поэтому оттенок светлее мелкого варианта. */
.statement strong {
  color: var(--signal-on-light-lg);
}

.process .eyebrow,
.faq .eyebrow,
.pitch-guide .eyebrow,
.partners .eyebrow {
  color: var(--muted-on-light);
}

.statement em,
.process .section-head h2 em,
.faq .section-head h2 em,
.pitch-guide h2 em {
  color: var(--muted-on-light-lg);
}

/* Страховка видимости. Наблюдатель появления может не сработать (драйвер
   видеокарты, режим энергосбережения, расширения браузера) — тогда секции так и
   остались бы прозрачными. Через таймаут после загрузки класс ставится всем, а
   правило ниже гарантирует: как только он стоит, содержимое показано при любом
   раскладе. transition гасится только на время страховки: правило стоит позже
   базового, поэтому без !important оно било бы анимацию появления у узлов,
   вставленных уже после срабатывания fallback-а. Компромисс осознанный:
   страховка включается лишь когда наблюдатель действительно молчал. */
html.reveals-failed .reveal:not(.is-visible) {
  opacity: 1;
}

/* Финальный вид каталога. Обложка — квадратная миниатюра внутри карточки, а не
   растянутая фон-подложка под текстом: исходная композиция релиза сохраняется,
   и пять карточек выглядят одинаково на главной и на мобильном экране. */
.top-release {
  display:grid;
  grid-template-columns:minmax(112px,38%) minmax(0,1fr);
  gap:20px;
  align-items:stretch;
  min-height:250px;
  padding:20px;
  background:#20201d;
}
.top-release__cover {
  position:relative;
  inset:auto;
  z-index:0;
  display:block;
  width:100%;
  height:auto;
  aspect-ratio:1;
  align-self:start;
  object-fit:cover;
  opacity:1;
  filter:none;
  transform:none;
  border:1px solid rgba(238,234,224,.18);
  transition:border-color .35s ease;
}
.top-release:hover .top-release__cover { opacity:1; transform:none; border-color:var(--signal); }
.top-release__body { display:flex; flex-direction:column; justify-content:space-between; gap:18px; height:auto; min-width:0; isolation:auto; }
.top-release__body::before { display:none; }
.top-release.is-coverless .top-release__body { grid-column:1 / -1; }
.top-release.is-coverless .top-release__cover { display:none; }
.top-release h3,
.top-release:not(.top-release--feature) h3 { max-width:none; margin:0 0 12px; font-size:clamp(24px,2.5vw,42px); line-height:.95; }
.top-release__artists { max-width:none; }
@media (max-width:720px) {
  .top-release,
  .top-release--feature {
    flex: 1 1 100%;
    max-width: 100%;
  }
  .top-release { grid-template-columns:96px minmax(0,1fr); gap:15px; min-height:210px; padding:16px; }
  .top-release h3,
  .top-release:not(.top-release--feature) h3 { font-size:clamp(22px,7vw,34px); }
}

/* Последний слой раскладки каталога. В подборке может быть пять релизов: grid
   рисует пустую шестую ячейку и визуально оставляет «сломанный» правый угол.
   Flex переносит только существующие карточки и центрирует неполный ряд; на
   телефоне каждая карточка снова занимает всю строку. */
.top-releases {
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:20px;
  background:transparent;
}
.top-releases > .top-release {
  flex:0 1 calc((100% - 40px) / 3);
  max-width:calc((100% - 40px) / 3);
  height:clamp(320px,28vw,380px);
}
.top-releases > .top-release .top-release__body { padding-right:0; }
@media (max-width:720px) {
  .top-releases > .top-release {
    flex-basis:100%;
    max-width:100%;
    height:auto;
  }
}
