:root {
  color-scheme: dark;
  --bg: #000000;
  --text: #ffffff;
  --muted: rgba(255, 255, 255, 0.62);
  --soft: rgba(255, 255, 255, 0.42);
  --line: rgba(255, 255, 255, 0.12);
  --line-strong: rgba(255, 255, 255, 0.28);
  --danger: #ef8f7a;
  --accent: #72f2c0;

  --max: 1200px;
  --gutter: clamp(20px, 5vw, 64px);
  --rhythm: clamp(72px, 12vh, 144px);
  --radius: 18px;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* `overflow-x: clip` страхует от горизонтального скролла, который
     создают full-bleed элементы с `width: 100vw` (footer-glow,
     block01-grid, #tracking::before, #pricing::before и т.п.):
     100vw включает ширину вертикального скроллбара, тогда как body
     рендерится только в content-зоне, поэтому ~15-17px стабильно
     вылезали за правый край. `clip` не создаёт scroll-контейнер
     (в отличие от `hidden`), сохраняет position:sticky у header'а. */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", Inter, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; }
img, svg { display: block; max-width: 100%; }

h1, h2, h3, h4, p, ul, figure {
  margin: 0;
  padding: 0;
}

ul { list-style: none; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}

.dev-badge {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 100;
  padding: 4px 10px;
  font: 11px var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(0, 0, 0, 0.7);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  pointer-events: none;
  backdrop-filter: blur(6px);
}

.skip-link {
  position: absolute;
  left: -10000px;
  top: -10000px;
}
.skip-link:focus {
  position: fixed;
  left: 12px;
  top: 12px;
  z-index: 1000;
  padding: 8px 14px;
  background: var(--bg);
  border: 1px solid var(--text);
  border-radius: 999px;
}

/* Floating pill header — закреплён по верху с воздухом по бокам и сверху,
   ширина по контентной сетке (var(--max) с гуттерами). Фон — белый при
   ~4% прозрачности, в связке с backdrop-blur даёт «матовое стекло».
   Обводки нет, отделение от фона — только тенью и блюром. */
.site-header {
  position: sticky;
  top: clamp(12px, 1.5vh, 18px);
  z-index: 50;
  width: calc(100% - 2 * var(--gutter));
  max-width: var(--max);
  margin: clamp(12px, 1.5vh, 18px) auto 0;
  padding: 16px 14px 16px 16px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 30px;
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.16);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
  backdrop-filter: blur(22px) saturate(1.4);
  transition:
    padding 420ms cubic-bezier(0.32, 0.72, 0.24, 1),
    background-color 420ms ease,
    box-shadow 420ms ease,
    border-color 420ms cubic-bezier(0.32, 0.72, 0.24, 1);
}

/* Fallback на случай браузеров без backdrop-filter — белые ~4% сольются
   со скроллящимся контентом, поэтому ставим плотный тёмный фон. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header {
    background: rgba(18, 18, 18, 0.94);
  }
}

/* Compact-on-scroll: после первых ~24px пилюля заметно сужается по
   высоте и чуть плотнеет по тинту — добавляет «живости» без прыжков.
   Сужение ~16px (8px сверху + 8px снизу) хорошо читается глазом. */
.site-header--scrolled {
  padding-top: 8px;
  padding-right: 8px;
  padding-bottom: 8px;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  border-color: transparent;
}
/* Явное закрепление колонок: иначе при `display: none` на .nav
   автоплейсмент grid'а съезжает — CTA попадает во второй (1fr) трек
   и стретчит до полной ширины. С фиксированными grid-column всегда
   brand в первом, nav во втором, CTA — в третьем (auto), независимо
   от того, скрыт nav или показан. */
.site-header > .brand { grid-column: 1; }
.site-header > .nav { grid-column: 2; }
.site-header > .header-cta { grid-column: 3; }

.brand {
  display: inline-flex;
  align-items: center;
  color: var(--text);
  opacity: 0.92;
  transition: opacity 160ms ease;
}
.brand:hover { opacity: 1; }

.brand img {
  display: block;
  height: 28px;
  width: 136px;
  color: var(--text);
  object-fit: contain;
  /* Оптическая компенсация: lockup чуть «вспливает» над геометрическим
     центром из-за восходящих/нисходящих элементов в начертании, поэтому
     сдвигаем вниз на 2px — выглядит ровнее. */
  transform: translateY(2px);
  transition:
    width 420ms cubic-bezier(0.32, 0.72, 0.24, 1),
    height 420ms cubic-bezier(0.32, 0.72, 0.24, 1);
}

/* Compact-on-scroll: лого сжимается на 20 % (136×28 → 108.8×22.4)
   синхронно с сужением хедера, тем же easing'ом, что и padding/border.
   Дробные значения держат ровную исходную пропорцию 136:28. */
.site-header--scrolled .brand img {
  width: 108.8px;
  height: 22.4px;
}

.nav {
  display: none;
  gap: 28px;
  font-size: 0.92rem;
  color: var(--muted);
  justify-content: center;
}
.nav a {
  transition: color 160ms ease;
}
.nav a:hover { color: var(--text); }

.site-header .nav a.nav-link-producthunt,
.site-header .nav a.nav-link-producthunt:visited {
  color: #ff615a;
}

.site-header .nav a.nav-link-producthunt:hover,
.site-header .nav a.nav-link-producthunt:focus-visible,
.site-header .nav a.nav-link-producthunt[aria-current="page"] {
  color: #ff7b75;
}

/* Nav-меню в шапке появляется только на десктопах (≥ 1024px). На
   планшетах и мобильных оно скрыто — brand слева, CTA справа, между
   ними воздух. Раньше брейкпойнт был 768px (планшет уже показывал
   меню), но он теснил CTA и плохо читался. */
@media (min-width: 1024px) {
  .nav { display: flex; }
}

.header-cta {
  font-size: 0.88rem;
  height: 36px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  white-space: nowrap;
  transition:
    border-color 160ms ease,
    background-color 160ms ease,
    color 160ms ease,
    height 420ms cubic-bezier(0.32, 0.72, 0.24, 1),
    padding 420ms cubic-bezier(0.32, 0.72, 0.24, 1);
}

/* Apple-иконка внутри header-cta стартует приглушённой (10 % альфы)
   и мягко «загорается» до 50 % на ховере вместе с бордером. */
.header-cta .apple-icon {
  opacity: 0.1;
  transition: opacity 160ms ease;
}

/* Compact-on-scroll: CTA сжимается синхронно с пилюлей, с тем же easing.
   Без этого расстояние от кнопки до края контейнера визуально «прыгает». */
.site-header--scrolled .header-cta {
  height: 32px;
  padding: 0 12px;
}
.header-cta:hover {
  border-color: rgba(255, 255, 255, 0.3);
  background-color: rgba(255, 255, 255, 0.04);
}

.header-cta:hover .apple-icon {
  opacity: 1;
}

.header-cta[aria-disabled="true"],
.nav-cta[aria-disabled="true"] {
  cursor: default;
}

.header-cta[aria-disabled="true"]:hover {
  border-color: rgba(255, 255, 255, 0.1);
  background-color: transparent;
}

.header-cta[aria-disabled="true"]:hover .apple-icon {
  opacity: 0.1;
}

/* — Mobile nav — */
/* Hamburger is hidden on desktop; below 1024px it replaces the inline nav,
   which becomes a dropdown panel under the sticky header. State is toggled by
   `.nav-open` on .site-header (set in site.js, with aria-expanded on the button). */
.nav-toggle {
  display: none;
  grid-column: 3;
  justify-self: end;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 36px;
  margin-right: -6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--text);
}

.nav-toggle-lines,
.nav-toggle-lines::before,
.nav-toggle-lines::after {
  display: block;
  width: 20px;
  height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 220ms ease, opacity 160ms ease;
}

.nav-toggle-lines {
  position: relative;
}

.nav-toggle-lines::before,
.nav-toggle-lines::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle-lines::before { top: -6px; }
.nav-toggle-lines::after { top: 6px; }

.site-header.nav-open .nav-toggle-lines {
  background: transparent;
}
.site-header.nav-open .nav-toggle-lines::before {
  transform: translateY(6px) rotate(45deg);
}
.site-header.nav-open .nav-toggle-lines::after {
  transform: translateY(-6px) rotate(-45deg);
}

/* CTA that only appears inside the open mobile menu. */
.nav-cta { display: none; }

@media (max-width: 1023px) {
  .nav-toggle { display: inline-flex; }

  .site-header > .header-cta { display: none; }

  /* Дропдаун в той же форме, что и сам хедер — пилюля под пилюлей.
     На мобиле фон солидный (без backdrop-filter): стекло там слабо
     отделяет меню от контента. Отделение — тенью. */
  .nav {
    position: absolute;
    top: calc(100% + 10px);
    left: -14px;
    right: -14px;
    grid-column: 1 / -1;
    flex-direction: column;
    gap: 0;
    padding: 12px 18px 18px;
    background: #0c0c0e;
    border-radius: 30px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    text-align: left;
  }

  .site-header.nav-open .nav { display: flex; }

  .nav a {
    padding: 13px 2px;
    font-size: 1rem;
    color: var(--text);
    border-bottom: 1px solid var(--line);
  }

  .nav-link-download { display: none; }

  .nav .nav-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 46px;
    margin-top: 14px;
    padding: 0 18px;
    border: 1px solid var(--text);
    border-radius: 999px;
    background: var(--text);
    color: var(--bg);
    font-weight: 500;
  }
}

.prod-topbar {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 18px var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.prod-topbar-actions {
  display: flex;
  align-items: center;
  gap: 18px;
}

.prod-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
  color: var(--soft);
  white-space: nowrap;
}

.prod-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 14px rgba(114, 242, 192, 0.42);
}

.section {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 125px var(--gutter);
}

.eyebrow {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--soft);
}

h1, h2 {
  letter-spacing: -0.025em;
  line-height: 1.04;
  font-weight: 500;
  text-wrap: balance;
}

.hero-title {
  font-size: clamp(2.75rem, 7vw, 5.6rem);
  max-width: none;
}

.hero-title span {
  display: block;
  white-space: nowrap;
}

h2 {
  font-size: clamp(1.75rem, 4vw, 3.25rem);
  max-width: 22ch;
}

h3 {
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

p {
  color: var(--muted);
  max-width: 60ch;
}

.body, .hero-lead {
  font-size: clamp(1rem, 1.05vw, 1.1rem);
  line-height: 1.6;
}

/* — Hero — vertical stack: text on top, big 16:9 visual below.
   Эта секция всегда single-column, даже на десктопе. */
.section--hero {
  padding-top: max(66px, calc(clamp(96px, 18vh, 200px) - 30px));
  display: grid;
  gap: clamp(40px, 6vh, 72px);
}

.hero-text {
  display: grid;
  gap: 22px;
  max-width: 720px;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 4px;
}

.hero-note {
  margin: 0;
  max-width: 38ch;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--soft);
}

.hero-note span {
  white-space: nowrap;
}

/* — Hero video — рамка + крупный радиус для эстетики.
   `overflow: hidden` нужен, чтобы Safari клипал видео по border-radius.
   Естественные пропорции из source-файла (1600×1138) — без принуждения к 16:9. */
.hero-video {
  width: 100%;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 24px;
  overflow: hidden;
  background: var(--bg);
}

.hero-video video {
  display: block;
  width: 100%;
  height: auto;
}

.surface-video video {
  width: calc(100% + 10px);
  max-width: none;
  margin: -5px;
}

/* — Split sections — */
.split-text {
  display: grid;
  gap: 18px;
  align-content: center;
  max-width: 520px;
}

.section--split {
  display: grid;
  gap: 40px;
  align-items: center;
}

@media (min-width: 900px) {
  .section--split {
    grid-template-columns: 1fr 1fr;
    gap: 64px;
  }

  /* Зигзаг: на reverse-секциях текст уезжает вправо, визуал — влево.
     На мобилке reverse игнорируется — стек всегда «текст → визуал». */
  .section--reverse .split-text {
    grid-column: 2;
    grid-row: 1;
  }
  .section--reverse > .placeholder {
    grid-column: 1;
    grid-row: 1;
  }
}

/* — Section header (для секций с групповым контентом ниже) — */
.section-head {
  display: grid;
  gap: 14px;
  margin-bottom: clamp(40px, 6vh, 72px);
  max-width: 720px;
}

/* — Library section (03) — chip cloud — */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.92rem;
  color: var(--text);
}

.chip:hover { border-color: var(--line-strong); }

/* Block 05: техническая строка-«мостик» под основным body — мельче и
   тусклее основного текста, ведёт к чипам со spec'ами. */
.tech-bridge {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--soft);
  max-width: 60ch;
  /* +22px к 18px grid-gap'у в .split-text = 40px воздуха от body выше. */
  margin-top: 22px;
}

/* Spec-чипы: чуть компактнее библиотечных, текст одной строкой. */
.tech-chips {
  margin-top: 6px;
}
.tech-chips .chip {
  height: 32px;
  padding: 0 13px;
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
}

/* — Demo stage — рамка/радиус как у placeholder'а, но без empty-state
   типографики (uppercase / mono / soft color), чтобы внутрь можно было
   смонтировать произвольную анимацию без леака стилей через inherit. */
.demo-stage {
  position: relative;
  width: 100%;
  border: 1px solid var(--line);
  /* 24px — синхронизировано с `.hero-video`, чтобы demo-блоки
     визуально читались в одном языке с hero-видео. */
  border-radius: 24px;
  overflow: hidden;
  background: var(--bg);
}

.demo-stage--16x9 { aspect-ratio: 16 / 9; }
.demo-stage--4x3  { aspect-ratio: 4 / 3; }
.demo-stage--32x9 { aspect-ratio: 32 / 9; }

/* Сквозной фон через секции 04 → 05 → 06: основной #000 плавно темнеет
   до #111110 (= bgColor канваса в head-tracking.js) к началу Block 05,
   держится сплошным фоном через head-tracking, потом так же плавно
   возвращается в #000 к концу Block 06.

   Реализовано тремя full-bleed `::before`-подложками (по одной на секцию).
   Состыковываются по границам: bottom 04 = #111110 = top 05; bottom 05 =
   #111110 = top 06. Полная ширина viewport'а — через `width: 100vw` +
   `transform: translateX(-50%)` (секции ограничены max-width: 1200px). */
#timer,
#tracking,
#pricing {
  position: relative;
  isolation: isolate;
}
#timer::before,
#tracking::before,
#pricing::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0 0 0 50%;
  width: 100vw;
  transform: translateX(-50%);
  pointer-events: none;
}
#timer::before    { background: linear-gradient(to bottom, #000000 0%, #111110 100%); }
#tracking::before { background: #111110; }
#pricing::before  { background: linear-gradient(to bottom, #111110 0%, #000000 100%); }
/* На десктопе текст и стейдж кладутся в одну grid-ячейку и перекрываются:
   стейдж тянется почти на всю ширину секции и центрируется/уезжает
   вправо, текст сидит слева поверх левой трети анимации (z-index:2).
   Силуэт в анимации центрирован по канвасу — слева у него много
   «воздуха» вокруг колец, так что текст ложится на разреженную часть. */
@media (min-width: 900px) {
  #tracking.section--split {
    grid-template-columns: 1fr;
    align-items: center;
  }
  #tracking .split-text {
    grid-column: 1;
    grid-row: 1;
    max-width: 550px;
    position: relative;
    z-index: 2;
  }
  #tracking #block05-tracking {
    grid-column: 1;
    grid-row: 1;
    justify-self: end;
    /* Анимация плавно растёт от 380px @ 900vw до 880px @ 1500vw — на
       узких side-by-side viewport'ах внешние кольца не наезжают на
       текст (max-width: 550), на широких раскрывается на полный
       размер. (880-380)/(1500-900) = 0.833 — линейная интерполяция
       через clamp(). */
    width: min(
      100%,
      clamp(380px, calc(380px + (100vw - 900px) * 0.833), 880px)
    );
    margin: 0;
  }
}

/* На широких viewport'ах (≥ 1500px) анимация сдвигается на 200px
   правее контейнера — внешние кольца перестают перекрывать текст
   (max-width: 550), между ними появляется воздушный зазор. До 1500px
   сдвиг отключён: в свободном gutter'е снаружи 1200-контейнера не
   хватает места под 200px, и stage визуально вылезал за правый край
   viewport'а (создавая горизонтальный overflow). */
@media (min-width: 1500px) {
  #tracking #block05-tracking {
    margin: 0 -200px 0 0;
  }
}
#block05-tracking {
  /* JS-модуль форсит высоту = width × 0.75, аспект 4:3 держится. */
  border: none;
  background: transparent;
}

/* Block 04: таймер живёт «в воздухе» — без рамки и фона, контентом сразу
   на тёмном полотне страницы. Аспект-ratio и size остаются от .demo-stage,
   просто снимаем декорации. */
#block04-timer {
  border: none;
  background: transparent;
  border-radius: 0;
  /* gentle-timer.js ставит `align-items: center` инлайном — перебиваем
     через !important, чтобы цифры/чипы выровнялись к левому краю
     стейджа в reverse-секции. */
  align-items: flex-start !important;
}

/* Block 01: placed-around анимация — full-bleed фоном секции, текст
   поверх. Mask из двух radial-gradient'ов в composite=exclude даёт
   «бублик»: дыра в центре под текстом, опаковый ring вокруг, плавный
   fade-out на внешних краях. */
#build {
  position: relative;
  /* overflow: hidden убран — он обрезал host'а с `width: 100vw` до
     ширины секции (1200px). Вертикально host не вылезает за пределы
     секции (top/bottom: -125px = section outer bounds), горизонтально
     теперь свободно дотягивается до краёв viewport'а. */
  /* +50px сверху и снизу к стандартным 125px = 175px вертикального
     дыхания вокруг текста и анимации. */
  padding-top: 175px;
  padding-bottom: 175px;
}
#build .section-head {
  position: relative;
  z-index: 2;
  /* Полупрозрачная подложка + blur поверх анимации: текст читается без
     угадывания размеров mask-«дыры», иконки за ним остаются видимыми,
     просто размытыми. padding/margin-выступ — чтобы blur-зона
     визуально обнимала текст с воздухом по краям. */
  padding: 28px 36px;
  margin: -28px -36px;
  background: rgba(0, 0, 0, 0.42);
  -webkit-backdrop-filter: blur(18px) saturate(1.05);
  backdrop-filter: blur(18px) saturate(1.05);
  border-radius: 24px;
}
#block01-grid {
  position: absolute;
  top: -175px;     /* выходит в section padding-top (= 175px) */
  bottom: -175px;  /* и в padding-bottom */
  left: 50%;
  width: 100vw;    /* расширяемся до краёв viewport'а */
  transform: translateX(-50%);
  z-index: 1;
  pointer-events: none;

  /* Только vertical fade — горизонтально анимация на всю ширину
     viewport'а. Текст «закрывается» сам через backdrop-filter на
     .section-head, поэтому радиальной «дыры» больше не нужно. */
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, black 18%, black 82%, transparent 100%);
  mask-image:
    linear-gradient(to bottom, transparent 0%, black 18%, black 82%, transparent 100%);
}

/* — Generic placeholder — */
.placeholder {
  position: relative;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  font: 11px var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soft);
}

.placeholder--16x9 { aspect-ratio: 16 / 9; }
.placeholder--32x9 { aspect-ratio: 32 / 9; }   /* ultrawide — 1/2 высоты от 16:9 */
.placeholder--4x3  { aspect-ratio: 4 / 3; }
.placeholder--1x1  { aspect-ratio: 1 / 1; }

/* Слот-метка «loop» — отмечает, что сюда поедет видео-петля.
   В surface-card не показываем — там одна аннотация на 3 карточки лишняя. */
.placeholder[data-kind="demo"]::after {
  content: "loop";
  position: absolute;
  bottom: 12px;
  right: 14px;
  font: 10px var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soft);
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
}

/* — Buttons — */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
  transition: filter 160ms ease, border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}

.btn--primary {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.btn--primary:hover { filter: brightness(0.92); }

.btn[aria-disabled="true"] {
  cursor: default;
}

.btn--primary[aria-disabled="true"]:hover {
  filter: none;
}

/* Apple-логотип внутри кнопок. Ширина в em → масштабируется вместе
   с font-size кнопки (нативно ≈14px для .btn, ≈13px для header-cta).
   `currentColor` на path'е через `fill="currentColor"` в SVG —
   логотип наследует цвет текста кнопки (чёрный на btn--primary,
   белый на header-cta), без отдельных override'ов. */
.apple-icon {
  width: 0.95em;
  aspect-ratio: 16 / 20;
  height: auto;
  flex-shrink: 0;
  /* Оптическая компенсация: глиф Apple-логотипа смещён вверх внутри
     своего bounding-box'а, поэтому подталкиваем чуть ниже базы текста. */
  margin-top: -1px;
}

.btn--ghost { background: transparent; color: var(--text); }
.btn--ghost:hover { border-color: var(--text); }

/* — Pricing — */
/* max-width: var(--max) синхронизирует левый край контента pricing'а
   с остальными секциями: текст начинается ровно по границе общего
   1200px-контейнера. */
.section--pricing {
  display: grid;
  gap: 28px;
  align-items: center;
  max-width: var(--max);
  text-align: left;
}

.pricing-copy {
  display: grid;
  gap: 22px;
  max-width: 620px;
}

/* Spec-чипы под body — наследуют .tech-chips, доп. отступ сверху
   для воздуха относительно body (+22 к 22px gap'у grid'а = ~44px). */
.pricing-chips {
  margin-top: 14px;
}

/* Правая колонка — стейдж для генеративного знака ∞. Внутри живёт
   canvas (animations/lifetime-mark.js), рисующий Lissajous 1:2 с
   фосфорным fade. Контейнер задаёт только габариты; высота через
   aspect-ratio — canvas получает предсказуемое CSS-пространство. */
.pricing-mark {
  width: 100%;
  max-width: 360px;
  aspect-ratio: 16 / 10;
  justify-self: center;
  align-self: center;
}

@media (min-width: 900px) {
  .section--pricing {
    grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr);
    gap: 56px;
  }
}

/* — Final CTA — */
.section--cta {
  display: grid;
  gap: 26px;
  justify-items: center;
  max-width: 840px;
  text-align: center;
  /* Сверху чуть тише (168px), снизу более раскрыто (198px) — финальный
     CTA-блок ощущается как «выдох», но не вылезает в footer. */
  padding-top: 168px;
  padding-bottom: 198px;
}

/* App-иконка над eyebrow'ом. Размер 120px — крупно, как app-preview в
   Finder/Dock, но не давит композицию. У PNG уже своя rounded-square
   обводка macOS-стиля, поэтому border-radius не добавляем.
   margin-bottom: 34px поверх 26px grid-gap'а = 60px от иконки до eyebrow. */
.cta-icon {
  width: 120px;
  height: 120px;
  display: block;
  margin-bottom: 34px;
}

.section--cta h2,
.section--cta p {
  margin-inline: auto;
}

.download-panel {
  width: 100%;
  max-width: 620px;
  margin-top: 4px;
  display: grid;
  justify-items: center;
  gap: 14px;
}

.download-actions {
  display: flex;
  justify-content: center;
  width: 100%;
  gap: 10px;
}

.download-note {
  max-width: 52ch;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--soft);
}

.download-note span {
  white-space: nowrap;
}

@media (max-width: 520px) {
  .hero-title span {
    white-space: normal;
  }

  .hero-actions .btn,
  .download-actions .btn { width: 100%; }

  /* Header CTA в мобильной — компактная фиксированная ширина по
     контенту, не растягиваем на всё доступное пространство колонки.
     justify-self: end приклеивает к правому краю grid-ячейки, width:
     auto + max-content страхует от стрейча. Шапочный gap уменьшаем,
     чтобы brand и CTA не тёрлись друг о друга при узких экранах. */
  .site-header { gap: 12px; }
  .header-cta {
    justify-self: end;
    width: max-content;
    padding: 0 12px;
  }
}

/* — Beta page — */
.section--beta-hero,
.section--beta-flow,
.section--beta-support {
  max-width: var(--max);
}

.section--beta-hero {
  padding-top: max(72px, calc(clamp(96px, 18vh, 200px) - 24px));
  display: grid;
  gap: 32px;
  align-items: start;
}

.beta-hero-copy {
  display: grid;
  gap: 22px;
  max-width: 660px;
}

.beta-hero-copy h1 {
  font-size: clamp(2.35rem, 5.8vw, 4.9rem);
  max-width: 10ch;
}

.beta-hero-copy .hero-lead {
  max-width: 56ch;
}

.beta-inline-note {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--soft);
  max-width: 44ch;
}

.beta-actions,
.beta-support-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.beta-panel,
.beta-note-card,
.beta-support {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.02);
}

.beta-panel {
  border-radius: 24px;
  padding: clamp(22px, 3vw, 32px);
  display: grid;
  gap: 22px;
}

.beta-panel-head,
.beta-mini-head,
.beta-support-copy {
  display: grid;
  gap: 10px;
}

.beta-panel-head h2,
.beta-mini-head h2,
.beta-support-copy h2 {
  max-width: none;
  font-size: clamp(1.45rem, 2.6vw, 2.2rem);
}

.beta-panel-head p,
.beta-mini-head p,
.beta-support-copy p {
  max-width: 58ch;
}

.beta-step-list,
.beta-mini-grid {
  display: grid;
  gap: 14px;
}

.beta-step-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 14px;
  align-items: start;
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 18px 18px 17px;
  background: rgba(255, 255, 255, 0.02);
}

.beta-step-index {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  font: 0.8rem var(--mono);
}

.beta-step-copy,
.beta-note-card {
  display: grid;
  gap: 8px;
}

.beta-step-copy h3,
.beta-note-card h3 {
  color: var(--text);
}

.beta-step-copy p,
.beta-note-card p {
  font-size: 0.96rem;
  line-height: 1.62;
}

.beta-mini-head {
  margin-bottom: clamp(28px, 4vh, 40px);
  max-width: 700px;
}

.beta-note-card {
  border-radius: 18px;
  padding: 18px;
}

.beta-support {
  width: 100%;
  border-radius: 28px;
  padding: clamp(24px, 4vw, 40px);
  display: grid;
  gap: 22px;
}

.beta-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (min-width: 980px) {
  .section--beta-hero {
    grid-template-columns: minmax(0, 1.02fr) minmax(360px, 0.98fr);
    gap: 52px;
  }

  .beta-mini-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .beta-actions .btn,
  .beta-support-actions .btn {
    width: 100%;
  }

  .beta-step-item {
    grid-template-columns: 1fr;
  }
}

/* — Legal pages (Privacy / Terms) — */
.section--legal {
  max-width: 760px;
  padding-top: clamp(72px, 14vh, 144px);
  padding-bottom: clamp(56px, 10vh, 120px);
}

.section--legal .eyebrow {
  margin-bottom: 18px;
}

.section--legal h1 {
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: -0.02em;
  line-height: 1.08;
  font-weight: 500;
  margin-bottom: 14px;
  max-width: 20ch;
}

.section--legal .meta {
  font-size: 0.85rem;
  color: var(--soft);
  margin-bottom: clamp(40px, 6vh, 64px);
  max-width: none;
}

.section--legal .lead {
  font-size: clamp(1.05rem, 1.1vw, 1.15rem);
  color: var(--text);
  margin-bottom: clamp(28px, 4vh, 40px);
  max-width: 60ch;
  line-height: 1.55;
}

.section--legal h2 {
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.25;
  margin: clamp(40px, 5vh, 56px) 0 14px;
  max-width: none;
  color: var(--text);
}

.section--legal h3 {
  font-size: 1rem;
  font-weight: 500;
  margin: 22px 0 6px;
  color: var(--text);
}

.section--legal p,
.section--legal li {
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.65;
  max-width: 65ch;
}

.section--legal p + p {
  margin-top: 14px;
}

.section--legal ul,
.section--legal ol {
  padding-left: 1.4em;
  margin: 14px 0;
}

.section--legal li {
  margin-top: 8px;
  list-style: disc;
}

.section--legal ol li {
  list-style: decimal;
}

.section--legal a {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--line-strong);
  text-decoration-thickness: 1px;
  transition: text-decoration-color 160ms ease;
}

.section--legal a:hover {
  text-decoration-color: var(--text);
}

/* — Update pages (Changelog / Roadmap) — */
.section--page {
  padding-top: clamp(72px, 14vh, 144px);
  padding-bottom: clamp(56px, 10vh, 120px);
}

.page-hero {
  display: grid;
  gap: 28px;
  margin-bottom: clamp(56px, 8vh, 88px);
}

/* Small accent tick before the page eyebrow — a quiet detail that signals
   "this is a section start" and ties the page to the app's accent colour. */
.page-hero .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.page-hero .eyebrow::before {
  content: "";
  width: 18px;
  height: 1px;
  background: var(--accent);
  opacity: 0.7;
}

.page-hero--plain .eyebrow::before {
  display: none;
}

.page-hero h1 {
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  max-width: 12ch;
}

.page-lead {
  font-size: clamp(1.05rem, 1.1vw, 1.18rem);
  line-height: 1.65;
  max-width: 66ch;
}

.page-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.page-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.02);
}

.page-chip strong {
  color: var(--text);
  font-weight: 500;
}

.release-stack {
  display: grid;
  gap: 18px;
}

.release-card {
  border: 1px solid var(--line);
  border-radius: 24px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.015)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.release-card {
  padding: 38px 42px 40px;
}

.release-head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 24px;
}

.release-head h2 {
  max-width: none;
  font-size: clamp(1.4rem, 2vw, 2rem);
}

.release-version {
  font: 0.78rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.release-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  margin: 18px 0 0;
  font-size: 0.9rem;
  color: var(--soft);
}

.release-meta strong {
  color: var(--text);
  font-weight: 500;
}

.release-card p {
  max-width: 72ch;
}

.changelog-timeline {
  position: relative;
  display: grid;
  gap: 28px;
  padding-left: 28px;
}

.changelog-timeline::before {
  content: "";
  position: absolute;
  left: 8px;
  top: 10px;
  bottom: 10px;
  width: 1px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0.08));
}

.timeline-entry {
  position: relative;
}

.timeline-entry::before {
  content: "";
  position: absolute;
  /* Centre the dot on the timeline rail: rail centre sits at 8.5px from the
     list edge, the card edge sits at padding-left (28px), so an 11px dot
     hangs back by 28 + 5.5 − 8.5 = 25px to land its centre on the line. */
  left: -25px;
  top: 20px;
  width: 11px;
  height: 11px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.02);
}

.timeline-entry--pending::before {
  border-color: rgba(114, 242, 192, 0.48);
  box-shadow:
    0 0 0 3px rgba(114, 242, 192, 0.06),
    0 0 14px rgba(114, 242, 192, 0.12);
}

.timeline-card {
  border: 1px solid var(--line);
  border-radius: 26px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  padding: 34px 38px 36px;
}

.timeline-head {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 22px;
}

.timeline-version {
  font: 0.78rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
  margin-bottom: 10px;
}

.timeline-status {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 13px 6px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  font: 0.72rem var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--soft);
  white-space: nowrap;
}

.timeline-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--soft);
}

.timeline-status--pending {
  border-color: rgba(114, 242, 192, 0.32);
  background: rgba(114, 242, 192, 0.05);
  color: var(--accent);
}

.timeline-status--pending .timeline-status-dot {
  background: var(--accent);
  box-shadow: 0 0 10px rgba(114, 242, 192, 0.55);
}

.timeline-head h2 {
  max-width: none;
  font-size: clamp(1.5rem, 2.2vw, 2.3rem);
}

.timeline-body {
  display: grid;
  gap: 20px;
}

.timeline-body p {
  max-width: 72ch;
  line-height: 1.72;
}

.timeline-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  font-size: 0.9rem;
  color: var(--soft);
}

.timeline-meta strong {
  color: var(--text);
  font-weight: 500;
}

.timeline-note {
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

/* Terminal node at the foot of the timeline — closes the line visually and
   sets the expectation that new entries land here, so a single-entry
   changelog doesn't read as unfinished. Marker dot matches the entry dots. */
.timeline-upcoming {
  position: relative;
  padding: 4px 0 2px;
}

.timeline-upcoming::before {
  content: "";
  position: absolute;
  /* Same rail centre as the entry dots; the 11px dot needs 28 + 5.5 = 33.5 ≈
     25px back from the card edge to keep its centre on the line. */
  left: -25px;
  top: 6px;
  width: 11px;
  height: 11px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--line);
}

.timeline-upcoming-label {
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
  margin-bottom: 6px;
}

.timeline-upcoming-text {
  color: var(--muted);
  max-width: 48ch;
}

.roadmap-note {
  margin-top: 32px;
  padding: 22px 26px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.008)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  color: var(--muted);
  line-height: 1.65;
  max-width: 80ch;
}

.roadmap-note strong {
  color: var(--text);
  font-weight: 500;
}

.roadmap-stack {
  display: grid;
  gap: 28px;
}

.roadmap-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.012);
  overflow: hidden;
}

/* Hero banner sits full-width on top of each card. Aspect ratio keeps the
   layout from jumping while an image loads, and reads as a cinematic strip
   without dominating the text beneath it. */
.roadmap-visual {
  position: relative;
  width: 100%;
  aspect-ratio: 21 / 9;
  overflow: hidden;
}

/* Placeholder palette gradients until a real hero image is supplied. Drop an
   <img class="roadmap-hero-img"> inside the visual to override. */
.roadmap-visual--now {
  background:
    linear-gradient(135deg, rgba(249, 207, 170, 0.95), rgba(247, 241, 229, 0.92) 48%, rgba(223, 230, 250, 0.9));
}

.roadmap-visual--considering {
  background:
    linear-gradient(135deg, rgba(235, 237, 188, 0.92), rgba(248, 245, 233, 0.94) 42%, rgba(219, 233, 207, 0.9));
}

.roadmap-hero-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.roadmap-copy {
  padding: clamp(36px, 4vw, 56px);
}

.roadmap-number {
  display: inline-flex;
  min-width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  margin-bottom: 26px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  color: var(--text);
  font: 0.85rem var(--mono);
  letter-spacing: 0.04em;
}

.roadmap-stage {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 14px;
  margin-left: 14px;
  font: 0.8rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

/* Stage dot picks up the accent of each card's visual gradient (warm → green),
   so "Now / Considering" reads as a small colour progression. */
.roadmap-stage::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.85;
}

.roadmap-card:nth-child(1) .roadmap-stage::before {
  background: #f4b48a;
  box-shadow: 0 0 10px rgba(244, 180, 138, 0.5);
}

.roadmap-card:nth-child(2) .roadmap-stage::before {
  background: #bcd98a;
  box-shadow: 0 0 10px rgba(188, 217, 138, 0.5);
}

.roadmap-copy h2 {
  margin-bottom: 16px;
  font-size: clamp(1.9rem, 2.6vw, 2.8rem);
}

/* The lead paragraph that frames each section before the points grid. */
.roadmap-lead {
  max-width: 64ch;
  margin-bottom: 36px;
  font-size: 1.04rem;
  line-height: 1.7;
  color: var(--muted);
}

/* Concrete anchor points under the lead — 2 columns on desktop, 1 on mobile.
   Each item: a <strong> label and a short <p> detail. */
.roadmap-points {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 26px 44px;
  max-width: 88ch;
}

.roadmap-point strong {
  display: block;
  margin-bottom: 6px;
  color: var(--text);
  font-weight: 500;
}

.roadmap-point p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
  font-size: 0.96rem;
}

/* — Journal (hub) — */
/* Built on the same tokens as changelog/roadmap so the section reads as part
   of one system. The "orbit" is a small spatial-audio metaphor: a white core
   (the listener) with placed sound-dots around it, on a dark radial space. */
.journal-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border: 1px solid rgba(114, 242, 192, 0.3);
  border-radius: 999px;
  background: rgba(114, 242, 192, 0.06);
  color: var(--accent);
  font: 0.66rem var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.journal-dot-sep {
  color: var(--soft);
  opacity: 0.55;
}

.journal-card-eyebrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
  font: 0.78rem var(--mono);
  letter-spacing: 0.03em;
  color: var(--soft);
}

.journal-featured {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  border: 1px solid var(--line);
  border-radius: 26px;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition: border-color 200ms ease, transform 200ms ease;
}

.journal-featured:hover {
  border-color: var(--line-strong);
  transform: translateY(-2px);
}

.journal-featured-visual {
  position: relative;
  min-height: 320px;
  display: grid;
  place-items: center;
  border-right: 1px solid var(--line);
  background:
    radial-gradient(circle at 50% 42%, rgba(54, 78, 90, 0.55), rgba(10, 12, 14, 0.98) 68%),
    #07090b;
}

.journal-featured-body {
  padding: clamp(28px, 3.4vw, 46px);
  display: grid;
  align-content: center;
}

.journal-featured-title {
  margin-bottom: 16px;
  font-size: clamp(1.6rem, 2.6vw, 2.4rem);
  max-width: 20ch;
}

.journal-featured-excerpt {
  margin-bottom: 24px;
  max-width: 48ch;
  color: var(--muted);
  line-height: 1.62;
}

.journal-card-cta {
  display: inline-flex;
  align-items: center;
  font-size: 0.92rem;
  color: var(--text);
  transition: color 160ms ease;
}

.journal-featured:hover .journal-card-cta {
  color: var(--accent);
}

/* — Spatial "orbit" decoration — */
.journal-orbit {
  position: relative;
  width: 200px;
  height: 200px;
  display: grid;
  place-items: center;
  animation: journalOrbitSpin 48s linear infinite;
}

.journal-orbit::before,
.journal-orbit::after {
  content: "";
  position: absolute;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
}

.journal-orbit::before { width: 100%; height: 100%; }
.journal-orbit::after { width: 56%; height: 56%; }

.journal-orbit-core {
  position: relative;
  width: 15px;
  height: 15px;
  border-radius: 999px;
  background: #ffffff;
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.55);
}

.journal-orbit-dot {
  position: absolute;
  width: 11px;
  height: 11px;
  border-radius: 999px;
}

.journal-orbit-dot--1 {
  top: 4%;
  left: calc(50% - 5.5px);
  background: var(--accent);
  box-shadow: 0 0 14px rgba(114, 242, 192, 0.7);
}

.journal-orbit-dot--2 {
  bottom: 16%;
  left: 14%;
  background: #f4b48a;
  box-shadow: 0 0 14px rgba(244, 180, 138, 0.7);
}

.journal-orbit-dot--3 {
  top: 38%;
  right: 6%;
  background: #cba8ef;
  box-shadow: 0 0 14px rgba(203, 168, 239, 0.7);
}

.journal-orbit--large {
  width: 260px;
  height: 260px;
}

@keyframes journalOrbitSpin {
  to { transform: rotate(360deg); }
}

/* — Article visuals — */
/* One CSS-only animation per article so covers are not all the same orbit.
   All decorative (aria-hidden) and frozen by prefers-reduced-motion. They size
   to a square that scales down on small screens (see the media queries). */
.viz {
  position: relative;
  display: grid;
  place-items: center;
  width: 260px;
  height: 260px;
}

/* Manifesto — calm breathing rings emanating from a soft center ("a place"). */
.viz-rings .viz-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  transform: scale(0.35);
  opacity: 0;
  animation: vizRipple 6s ease-out infinite;
}
.viz-rings .viz-ring:nth-child(2) { animation-delay: 2s; }
.viz-rings .viz-ring:nth-child(3) { animation-delay: 4s; }

.viz-rings .viz-core {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  background: #ffffff;
  box-shadow: 0 0 24px rgba(255, 255, 255, 0.5);
  animation: vizBreathe 6s ease-in-out infinite;
}

@keyframes vizRipple {
  0% { transform: scale(0.35); opacity: 0; }
  15% { opacity: 0.7; }
  100% { transform: scale(1.5); opacity: 0; }
}
@keyframes vizBreathe {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50% { transform: scale(1.28); opacity: 1; }
}

/* Essay — a gentle equalizer wave (sound, breathing). */
.viz-wave {
  display: flex;
  align-items: center;
  gap: 11px;
  width: auto;
  height: 150px;
}
.viz-wave span {
  width: 6px;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(114, 242, 192, 0.55), rgba(255, 255, 255, 0.14));
  transform: scaleY(0.28);
  transform-origin: center;
  animation: vizWave 2.8s ease-in-out infinite;
}
.viz-wave span:nth-child(1) { animation-delay: -0.2s; }
.viz-wave span:nth-child(2) { animation-delay: -0.6s; }
.viz-wave span:nth-child(3) { animation-delay: -1.0s; }
.viz-wave span:nth-child(4) { animation-delay: -1.4s; }
.viz-wave span:nth-child(5) { animation-delay: -1.0s; }
.viz-wave span:nth-child(6) { animation-delay: -0.6s; }
.viz-wave span:nth-child(7) { animation-delay: -0.2s; }

@keyframes vizWave {
  0%, 100% { transform: scaleY(0.28); }
  50% { transform: scaleY(1); }
}

/* Head tracking — fixed anchors + a rotating "gaze" sweep around the listener. */
.viz-tracking .viz-track-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
}
.viz-tracking .viz-track-core {
  position: relative;
  z-index: 2;
  width: 14px;
  height: 14px;
  border-radius: 999px;
  background: #ffffff;
  box-shadow: 0 0 16px rgba(255, 255, 255, 0.5);
}
.viz-tracking .viz-track-sweep {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 50%;
  height: 2px;
  transform-origin: left center;
  background: linear-gradient(90deg, rgba(114, 242, 192, 0.65), transparent);
  animation: vizSweep 7s linear infinite;
}
.viz-tracking .viz-track-anchor {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 999px;
}
.viz-tracking .viz-track-anchor--1 {
  top: 10%;
  left: calc(50% - 5px);
  background: #72f2c0;
  box-shadow: 0 0 12px rgba(114, 242, 192, 0.6);
}
.viz-tracking .viz-track-anchor--2 {
  bottom: 20%;
  left: 16%;
  background: #f4b48a;
  box-shadow: 0 0 12px rgba(244, 180, 138, 0.6);
}
.viz-tracking .viz-track-anchor--3 {
  top: 40%;
  right: 10%;
  background: #cba8ef;
  box-shadow: 0 0 12px rgba(203, 168, 239, 0.6);
}

@keyframes vizSweep {
  to { transform: rotate(360deg); }
}

/* Build a room — layers lighting up in sequence (stacking a mix). */
.viz-layers {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 210px;
  height: auto;
}
.viz-layers span {
  height: 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  opacity: 0.4;
  animation: vizLayer 4.8s ease-in-out infinite;
}
.viz-layers span:nth-child(1) { width: 100%; animation-delay: 0s; background: rgba(114, 242, 192, 0.4); }
.viz-layers span:nth-child(2) { width: 72%; animation-delay: 0.5s; }
.viz-layers span:nth-child(3) { width: 88%; animation-delay: 1s; }
.viz-layers span:nth-child(4) { width: 56%; animation-delay: 1.5s; }

@keyframes vizLayer {
  0%, 100% { opacity: 0.32; }
  50% { opacity: 1; }
}

.journal-upcoming {
  margin-top: 22px;
  padding: 24px 26px;
  border: 1px dashed var(--line);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.01);
}

.journal-upcoming-label {
  margin-bottom: 8px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.journal-upcoming-text {
  max-width: 62ch;
  color: var(--muted);
  line-height: 1.6;
}

/* Grid of secondary article cards under the featured post. */
.journal-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin-top: 18px;
}

.journal-card {
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 2.6vw, 32px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.01)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition: border-color 200ms ease, transform 200ms ease;
}

.journal-card:hover {
  border-color: var(--line-strong);
  transform: translateY(-2px);
}

.journal-card .journal-card-eyebrow {
  margin-bottom: 14px;
}

.journal-card-title {
  margin-bottom: 12px;
  max-width: 24ch;
  font-size: clamp(1.2rem, 1.6vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.2;
  color: var(--text);
}

.journal-card-excerpt {
  flex: 1;
  margin-bottom: 20px;
  max-width: 46ch;
  color: var(--muted);
  line-height: 1.6;
}

.journal-card .journal-card-cta {
  margin-top: auto;
}

.journal-card:hover .journal-card-cta {
  color: var(--accent);
}

/* — Article (single post) — */
.section--article {
  max-width: 820px;
  padding-top: clamp(40px, 9vh, 96px);
  padding-bottom: clamp(56px, 10vh, 120px);
}

.article-back {
  margin-bottom: clamp(24px, 4vh, 40px);
}

.article-back a,
.article-more a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 0.8rem var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--soft);
  transition: color 160ms ease;
}

.article-back a:hover,
.article-more a:hover {
  color: var(--text);
}

.article-header {
  display: grid;
  gap: 22px;
  margin-bottom: clamp(28px, 4vh, 44px);
}

.article-kicker {
  display: flex;
  align-items: center;
  gap: 12px;
  font: 0.78rem var(--mono);
  letter-spacing: 0.03em;
  color: var(--soft);
}

.article-header h1 {
  font-size: clamp(2.1rem, 4.4vw, 3.4rem);
  max-width: 18ch;
}

.article-standfirst {
  font-size: clamp(1.15rem, 1.7vw, 1.42rem);
  line-height: 1.55;
  color: var(--muted);
  max-width: 52ch;
}

.article-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font: 0.82rem var(--mono);
  letter-spacing: 0.03em;
  color: var(--soft);
}

.article-cover {
  position: relative;
  margin: clamp(28px, 4vh, 44px) 0;
  min-height: 340px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 24px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 42%, rgba(54, 78, 90, 0.55), rgba(10, 12, 14, 0.98) 68%),
    #07090b;
}

.article-cover video,
.article-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.article-cover-canvas {
  position: absolute;
  inset: 0;
}

.article-prose {
  display: grid;
  gap: 24px;
}

.article-prose p {
  font-size: 1.12rem;
  line-height: 1.78;
  color: rgba(255, 255, 255, 0.82);
}

.article-prose em {
  font-style: italic;
  color: var(--text);
}

.article-prose strong {
  color: var(--text);
  font-weight: 600;
}

.article-prose h2 {
  margin-top: 18px;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.article-prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(114, 242, 192, 0.4);
  transition: text-decoration-color 160ms ease;
}

.article-prose a:hover {
  text-decoration-color: var(--accent);
}

.article-list {
  display: grid;
  gap: 14px;
}

.article-list li {
  position: relative;
  padding-left: 26px;
  font-size: 1.08rem;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.82);
}

.article-list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0.7;
}

.article-list strong {
  color: var(--text);
}

.article-callout {
  margin: 8px 0;
  padding: 22px 26px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: 14px;
  background:
    linear-gradient(180deg, rgba(114, 242, 192, 0.05), rgba(114, 242, 192, 0.012)),
    rgba(255, 255, 255, 0.01);
}

.article-callout-label {
  margin-bottom: 8px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.article-callout p:last-child {
  color: var(--muted);
  line-height: 1.62;
}

.article-footer {
  margin-top: clamp(40px, 6vh, 64px);
  display: grid;
  gap: 28px;
}

.article-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(26px, 3vw, 40px);
  border: 1px solid var(--line);
  border-radius: 24px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.article-cta-text {
  display: grid;
  gap: 8px;
  max-width: 46ch;
}

.article-cta-eyebrow {
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.article-cta-text h3 {
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.article-cta-text p {
  color: var(--muted);
  line-height: 1.55;
}

/* — FAQ — */
/* Native <details>/<summary> accordion: zero JS, accessible, and the answer
   text stays in the DOM (good for SEO and in-page search) even when closed.
   Used on both the dedicated /faq.html page and the homepage FAQ block. */
.faq-list {
  display: grid;
  gap: 12px;
  max-width: 820px;
}

.faq-item {
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.012);
  transition: border-color 160ms ease, background-color 160ms ease;
}

.faq-item[open] {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.022);
}

.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 19px 22px;
  font-size: 1.06rem;
  font-weight: 500;
  color: var(--text);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary:hover {
  color: var(--text);
}

.faq-item:not([open]) summary:hover {
  color: var(--muted);
}

/* Plus → minus toggle, built from two bars; the vertical bar fades and
   rotates out when the item opens. */
.faq-icon {
  position: relative;
  flex-shrink: 0;
  width: 14px;
  height: 14px;
}

.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  background: var(--soft);
  transition: transform 220ms ease, opacity 220ms ease;
}

.faq-icon::before {
  top: 50%;
  left: 0;
  width: 100%;
  height: 1.5px;
  transform: translateY(-50%);
}

.faq-icon::after {
  left: 50%;
  top: 0;
  width: 1.5px;
  height: 100%;
  transform: translateX(-50%);
}

.faq-item[open] .faq-icon::after {
  opacity: 0;
  transform: translateX(-50%) rotate(90deg);
}

.faq-answer {
  padding: 0 22px 21px;
  max-width: 66ch;
  color: var(--muted);
  line-height: 1.7;
}

.faq-answer p + p {
  margin-top: 14px;
}

.faq-answer a,
.page-lead a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(114, 242, 192, 0.4);
  transition: text-decoration-color 160ms ease;
}

.faq-answer a:hover,
.page-lead a:hover {
  text-decoration-color: var(--accent);
}

/* Homepage FAQ block link → full page */
.faq-more-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 26px;
  font-size: 0.95rem;
  color: var(--text);
  transition: color 160ms ease;
}

.faq-more-link:hover {
  color: var(--accent);
}

/* Support CTA at the foot of the FAQ page */
.faq-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-top: clamp(36px, 5vh, 56px);
  padding: clamp(24px, 3vw, 36px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)),
    rgba(255, 255, 255, 0.01);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.faq-cta-text {
  display: grid;
  gap: 6px;
}

.faq-cta-eyebrow {
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.faq-cta-text h3 {
  font-size: clamp(1.25rem, 1.8vw, 1.6rem);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.faq-cta-text p {
  color: var(--muted);
}

/* Homepage FAQ section keeps the list under the section-head, reading width. */
.section--faq .faq-list {
  margin-top: clamp(28px, 4vh, 44px);
}

/* Анимация открытия/закрытия аккордеона на главной — нативный <details>
   через ::details-content + interpolate-size (Chrome 131+/Safari 18.2+).
   В браузерах без поддержки фолбэк безболезненный — мгновенный toggle. */
@supports (interpolate-size: allow-keywords) {
  .section--faq {
    interpolate-size: allow-keywords;
  }

  .section--faq .faq-item::details-content {
    height: 0;
    overflow: clip;
    transition:
      height 320ms cubic-bezier(0.32, 0.72, 0.24, 1),
      content-visibility 320ms allow-discrete;
  }

  .section--faq .faq-item[open]::details-content {
    height: auto;
  }
}

/* — Docs layout (GitBook-style) — */
/* Used by /faq.html: a sticky left nav + a reading column. Built as a generic
   .docs-* shell so other long-form pages (guides, references) can reuse it. */
.docs-layout {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(32px, 6vh, 64px) var(--gutter) clamp(64px, 10vh, 120px);
  display: grid;
  grid-template-columns: 256px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}

.docs-sidebar {
  position: sticky;
  top: 88px;
  align-self: start;
  padding-right: 8px;
}

.docs-nav-title {
  margin-bottom: 12px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soft);
}

.docs-nav-list {
  display: grid;
  gap: 3px;
}

/* Раскрывающаяся группа на нативном <details>/<summary> +
   name="docs-nav" — только одна группа открыта одновременно (native
   exclusive accordion). interpolate-size позволяет плавно анимировать
   height: 0 → auto через ::details-content. */
.docs-nav-group {
  interpolate-size: allow-keywords;
}

.docs-nav-group-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  list-style: none;
  transition: color 160ms ease;
}

.docs-nav-group-summary::-webkit-details-marker {
  display: none;
}

.docs-nav-group-summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--soft);
  border-bottom: 1.5px solid var(--soft);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 240ms cubic-bezier(0.32, 0.72, 0.24, 1);
  flex-shrink: 0;
  margin-right: 4px;
}

.docs-nav-group[open] > .docs-nav-group-summary::after {
  transform: rotate(-135deg) translate(-1px, -1px);
}

.docs-nav-group-summary:hover {
  color: var(--accent);
}

.docs-nav-group::details-content {
  height: 0;
  overflow: clip;
  transition:
    height 280ms cubic-bezier(0.32, 0.72, 0.24, 1),
    content-visibility 280ms allow-discrete;
}

.docs-nav-group[open]::details-content {
  height: auto;
}

.docs-nav-sub {
  display: grid;
  gap: 2px;
  margin: 4px 0 10px;
  border-left: 1px solid var(--line);
}

.docs-nav-sub a {
  display: block;
  margin-left: -1px;
  padding: 7px 0 7px 16px;
  border-left: 1px solid transparent;
  font-size: 0.845rem;
  line-height: 1.4;
  color: var(--soft);
  transition: color 160ms ease, border-color 160ms ease;
}

.docs-nav-sub a:hover {
  color: var(--text);
}

.docs-nav a.is-active {
  color: var(--text);
  border-left-color: var(--accent);
}

.docs-content {
  min-width: 0;
}

.docs-header {
  display: grid;
  gap: 18px;
  margin-bottom: clamp(32px, 5vh, 52px);
  padding-bottom: clamp(24px, 3vh, 32px);
  border-bottom: 1px solid var(--line);
}

.docs-header h1 {
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  max-width: 18ch;
}

.docs-lead {
  max-width: 60ch;
  font-size: clamp(1.05rem, 1.2vw, 1.2rem);
  line-height: 1.6;
  color: var(--muted);
}

.docs-section {
  margin-top: clamp(44px, 6vh, 68px);
  scroll-margin-top: 96px;
}

.docs-section:first-of-type {
  margin-top: 0;
}

.docs-section-title {
  max-width: none;
  margin-bottom: 4px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
}

.docs-qa {
  margin-top: 30px;
  scroll-margin-top: 96px;
}

.docs-qa h3 {
  margin-bottom: 10px;
  font-size: 1.18rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}

.docs-qa p {
  max-width: 68ch;
  font-size: 1.06rem;
  line-height: 1.72;
  color: rgba(255, 255, 255, 0.8);
}

.docs-qa p + p {
  margin-top: 14px;
}

.docs-qa strong {
  color: var(--text);
  font-weight: 600;
}

.docs-qa a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(114, 242, 192, 0.4);
  transition: text-decoration-color 160ms ease;
}

.docs-qa a:hover {
  text-decoration-color: var(--accent);
}

.docs-content .faq-cta {
  margin-top: clamp(48px, 7vh, 72px);
}

/* Lead-in paragraph under a section title — turns the section from a bare
   Q&A list into documentation. */
.docs-section-intro {
  max-width: 68ch;
  margin-top: 22px;
  font-size: 1.08rem;
  line-height: 1.72;
  color: var(--muted);
}

.docs-section-intro + .docs-section-intro {
  margin-top: 14px;
}

/* Figure slot for diagrams / screenshots. The placeholder is a self-contained
   dark panel (no external asset) so the page never looks broken before the
   real visual is dropped in — replace .docs-figure-media with an <img>/<video>. */
.docs-figure {
  margin: 30px 0 8px;
}

.docs-figure--panel {
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
}

.docs-figure-media {
  display: grid;
  place-items: center;
  min-height: 280px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    radial-gradient(circle at 50% 42%, rgba(54, 78, 90, 0.45), rgba(10, 12, 14, 0.98) 70%),
    #07090b;
  color: var(--soft);
  font: 0.74rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.docs-figure img,
.docs-figure video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 18px;
  border: 1px solid var(--line);
}

.docs-figure figcaption {
  margin-top: 12px;
  max-width: 60ch;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--soft);
}

/* Free vs Lifetime Pro comparison block — две карточки бок-о-бок,
   Pro-карточка с лёгким акцентным тинтом. На мобиле стакаются. */
.tier-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 22px;
  max-width: 720px;
}

.tier {
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.012);
}

.tier-name {
  margin-bottom: 6px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.tier-price {
  margin-bottom: 4px;
  font-size: 1.4rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
}

.tier-price-note {
  margin-left: 6px;
  font-size: 0.74rem;
  font-weight: 400;
  color: var(--soft);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tier-tagline {
  margin-bottom: 16px;
  font-size: 0.88rem;
  color: var(--soft);
}

.tier-list {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tier-list li {
  position: relative;
  padding-left: 22px;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--muted);
}

.tier-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent);
  font-size: 0.92rem;
  line-height: 1.55;
}

.tier--pro {
  border-color: rgba(114, 242, 192, 0.22);
  background:
    linear-gradient(180deg, rgba(114, 242, 192, 0.05), rgba(255, 255, 255, 0.01)),
    rgba(255, 255, 255, 0.012);
}

@media (max-width: 640px) {
  .tier-grid {
    grid-template-columns: 1fr;
  }
}

/* Inline-иконка прямо в потоке текста — мини-кнопка с реальной
   иконкой Recenter, чтобы читатель сразу видел, о каком глифе речь. */
.inline-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin: 0 3px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  vertical-align: -7px;
}

/* Чиповый список звуковых категорий — спокойный визуальный «прейскурант»
   того, что в библиотеке, под ответом «What sounds are included?». */
.sound-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 18px 0 18px;
  padding: 0;
  max-width: 620px;
  list-style: none;
}

.sound-tag {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.025);
  font-size: 0.88rem;
  color: var(--muted);
  letter-spacing: 0.01em;
}

/* Data-flow визуализация — две карточки бок-о-бок: «что остаётся на маке»
   vs «что уходит наружу». Оба нейтральные по тону, чтобы не намекать на
   «good/bad» — задача показать честную картину. */
.data-flow {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin: 22px 0 22px;
  max-width: 760px;
}

.data-flow-side {
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.012);
}

.data-flow-name {
  margin-bottom: 14px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

.data-flow-list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.data-flow-list li {
  position: relative;
  padding-left: 22px;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--muted);
}

.data-flow-list li::before {
  content: "•";
  position: absolute;
  left: 4px;
  top: 0;
  color: var(--soft);
  line-height: 1.55;
}

.data-flow-list strong {
  color: var(--text);
  font-weight: 500;
}

@media (max-width: 640px) {
  .data-flow {
    grid-template-columns: 1fr;
  }
}

/* <code>-инлайны в docs-ответах — приглушённый mono, чтобы пути и
   технические идентификаторы читались как «технический объект». */
.docs-qa code {
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  font: 0.85em var(--mono);
  color: var(--text);
  letter-spacing: 0;
  word-break: break-all;
}

/* System requirements — компактная карточка из label/value пар.
   Аналог press-facts, только встроенный в FAQ-ответ. */
.system-req {
  display: grid;
  gap: 14px;
  margin: 18px 0 18px;
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.012);
  max-width: 620px;
}

.system-req-row {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr);
  gap: 18px;
  align-items: baseline;
}

.system-req-label {
  font: 0.72rem var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
  margin: 0;
}

.system-req-value {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--text);
  margin: 0;
}

.system-req-note {
  display: block;
  margin-top: 4px;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--soft);
}

@media (max-width: 640px) {
  .system-req-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

/* — Press kit — */
/* Press kit использует docs-layout без сайдбара — единственная колонка для
   контента, отступы и max-width наследуются от .docs-layout. Дивайдеры от
   docs-стилей (под hero и под заголовками секций) убираем и компенсируем
   воздухом: press читается как factsheet, а не как документация. */
.press-layout {
  grid-template-columns: minmax(0, 1fr);
}

.press-header {
  margin-bottom: clamp(56px, 8vh, 88px);
  padding-bottom: 0;
  border-bottom: 0;
}

.press-content .docs-section {
  margin-top: clamp(64px, 9vh, 104px);
}

.press-content .docs-section-title {
  margin-bottom: clamp(20px, 2.6vh, 32px);
  padding-bottom: 0;
  border-bottom: 0;
}

.press-header h1 {
  max-width: 16ch;
}

.press-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 4px;
}

.press-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--line);
}

.press-facts div {
  min-width: 0;
  padding: 18px 20px;
  background: rgba(255, 255, 255, 0.025);
}

.press-facts dt {
  margin-bottom: 8px;
  font: 0.72rem var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--soft);
}

.press-facts dd {
  color: rgba(255, 255, 255, 0.84);
  line-height: 1.45;
}

.press-facts a,
.press-copy-block a,
.press-asset a,
.press-link-grid a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(114, 242, 192, 0.4);
  transition: text-decoration-color 160ms ease;
}

.press-facts a:hover,
.press-copy-block a:hover,
.press-asset a:hover,
.press-link-grid a:hover {
  text-decoration-color: var(--accent);
}

.press-copy-block {
  margin-top: 18px;
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
}

/* Content paragraphs inside a copy block (i.e. everything except the eyebrow label).
   Sized for comfortable long-form reading; sibling rule adds gap between paragraphs. */
.press-copy-block p:not(.article-callout-label) {
  max-width: 68ch;
  font-size: 1.04rem;
  line-height: 1.68;
  color: rgba(255, 255, 255, 0.82);
}

.press-copy-block p + p {
  margin-top: 14px;
}

.press-assets {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 28px;
}

.press-asset {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 16px;
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
    rgba(255, 255, 255, 0.01);
}

.press-asset img,
.press-asset video {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #07090b;
}

/* Icons and logos sit inside the same 16:10 frame as screenshots so card heights match.
   contain + padding keeps the mark from touching the frame edges. */
.press-asset--contain img,
.press-asset--contain .press-asset-placeholder {
  object-fit: contain;
  padding: 32px;
}

/* For screenshots where the meaningful detail sits at the top of the source image
   (e.g. the Notch Bar). Default object-position is center; this pins to top so the
   crop reveals the top edge instead of slicing through it. */
.press-asset--align-top img {
  object-position: center top;
}

/* Same idea, but anchored to the top-right corner — for screens where the meaningful
   UI sits in the upper-right of the source (e.g. menu bar drop-down). */
.press-asset--align-top-right img {
  object-position: right top;
}

/* For cut-out screenshot PNGs (window-shaped, transparent background) where the whole
   image should breathe inside the frame instead of being crop-fitted to fill it. */
.press-asset--float img {
  object-fit: contain;
  padding: 18px;
}

.press-asset h3 {
  margin-bottom: 8px;
  font-size: 1.08rem;
  font-weight: 600;
}

.press-asset p {
  margin-bottom: 12px;
  color: var(--muted);
  line-height: 1.55;
}

.press-asset--video {
  grid-column: 1 / -1;
}

/* Sub-heading inside media-assets, labels each asset group (Logos, Screenshots, etc).
   Mono-cased like an eyebrow so it reads as a section divider, not a heading. */
.press-asset-group {
  margin: 38px 0 14px;
  font: 0.78rem var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--soft);
}
.press-asset-group:first-of-type {
  margin-top: 28px;
}

/* Multi-link row inside an asset card — e.g. PNG 400 · PNG 800 · PNG 1600. */
.press-asset-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 0.94rem;
}

/* Placeholder block — sized identically to press-asset img/video so card heights match.
   Dashed border + mono label makes it instantly readable as "to be filled". */
.press-asset-placeholder {
  width: 100%;
  aspect-ratio: 16 / 10;
  border: 1px dashed rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.015);
  display: grid;
  place-items: center;
  text-align: center;
  color: var(--soft);
  font: 0.7rem var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Pending download link — dimmed and non-interactive, signals "file not ready yet". */
.press-asset-link--pending {
  color: var(--soft) !important;
  opacity: 0.5;
  pointer-events: none;
  cursor: not-allowed;
  text-decoration-color: rgba(255, 255, 255, 0.12) !important;
}

/* Pending card — chrome a touch softer so the eye lands on ready assets first. */
.press-asset--pending {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.018), rgba(255, 255, 255, 0.006)),
    rgba(255, 255, 255, 0.004);
}

/* Dark-on-light logo previews need a light backplate so they stay visible. */
.press-asset--logo-dark img,
.press-asset--logo-dark .press-asset-placeholder {
  background: #ebeae6;
  border-color: rgba(0, 0, 0, 0.08);
}

.press-link-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 24px;
}

.press-link-grid a {
  padding: 15px 18px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.018);
  color: rgba(255, 255, 255, 0.86);
  text-decoration: none;
}

.press-link-grid a:hover {
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--text);
}

/* — Footer — */
/* Footer полностью чёрный — чтобы glow-PNG, расположенный над/под
   границей футера, выглядел как «свет из-под»: нижняя половина glow'а
   прячется под чёрной плашкой, видна только верхняя — соответствует
   ощущению, что источник света находится под футером.
   Компактный layout: 20px вертикали, 14px горизонтали (симметрично
   header'у). Brand-колонка слева (логотип + копирайт под ним),
   nav-ссылки справа. */
.site-footer {
  position: relative;
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding: 20px 14px;
  font-size: 0.88rem;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  justify-content: space-between;
}

.footer-brand-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

/* Правая колонка футера, симметричная brand-колонке слева:
   email-контакт сверху, юр-ссылки снизу. align-items: flex-end —
   обе строки правого блока прижаты к правому краю. */
.footer-links-col {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

.footer-contact {
  font-size: 0.88rem;
  color: var(--muted);
  transition: color 160ms ease;
}
.footer-contact:hover { color: var(--text); }

/* `.footer-glow` — sibling-элемент ПЕРЕД .site-footer в DOM. Он
   высотой 0 в normal flow (не двигает остальное), но содержит
   absolute pseudo с PNG-свечением. Pseudo центрирован вертикально
   ровно на границе CTA/footer (top: 0 от .footer-glow = top футера),
   половина glow'а уезжает вверх в CTA-зону (видна), половина вниз —
   в футер-зону, где её закрывает чёрная подложка footer'а.
   Так как .footer-glow стоит в DOM ДО footer'а, фон футера на ней
   рендерится поверх по правилам стэкинга — никаких z-index трюков. */
.footer-glow {
  --glow-progress: 0;
  position: relative;
  height: 0;
  pointer-events: none;
}

.footer-glow::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: min(100vw, 3840px);
  aspect-ratio: 3840 / 654;
  /* Anchor — bottom: 0 (= footer-top, т.к. .footer-glow высотой 0).
     translateY: постоянный +50px (финал «утоплен» в footer-зону) +
       переменная (1 - progress) * 40px = слайд снизу вверх.
     scale: 0.94 → 1.0 по мере прогресса — лёгкое «распускание» glow'а.
       transform-origin: 50% 100% — расширение идёт от нижней середины
       (= точки, прибитой к footer-top), чтобы scale не уезжал вверх. */
  transform:
    translate(
      -50%,
      calc(50px + (1 - var(--glow-progress)) * 40px)
    )
    scale(calc(0.94 + 0.06 * var(--glow-progress)));
  transform-origin: 50% 100%;
  background: url("assets/gradient_footer.png?v=2") center / 100% 100% no-repeat;
  /* Финальная непрозрачность — 35% (раньше было 100%). Glow ощущается
     как мягкая подсветка, а не выраженный световой блик. */
  opacity: calc(var(--glow-progress) * 0.35);
  will-change: opacity, transform;
}

@media (prefers-reduced-motion: reduce) {
  .footer-glow {
    --glow-progress: 1;
  }
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}
.footer-copy {
  margin: 0;
  font-size: 0.72rem;
  color: var(--soft);
}

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

@media (max-width: 900px) {
  .roadmap-visual {
    aspect-ratio: 16 / 9;
  }

  .roadmap-copy {
    padding: 26px 24px 32px;
  }

  .roadmap-points {
    grid-template-columns: 1fr;
    gap: 22px;
  }

  .journal-featured {
    grid-template-columns: 1fr;
  }

  .journal-featured-visual {
    min-height: 240px;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  /* Docs: stack the nav above the content and drop the sticky behaviour.
     Only the top-level category links stay, so the nav stays short. */
  .docs-layout {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .docs-sidebar {
    position: static;
    max-height: none;
    overflow: visible;
    padding-right: 0;
    padding-bottom: 22px;
    border-bottom: 1px solid var(--line);
  }

  .docs-nav-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
  }

  /* Мобильный sidebar: только заголовки групп в строку как чипы,
     сабы скрываем (на сжатом экране 28 пунктов — overkill). Шеврон
     тоже скрываем — на тапе summary'и JS просто перематывает к секции. */
  .docs-nav-sub {
    display: none;
  }

  .docs-nav-group-summary {
    padding: 4px 0;
  }

  .docs-nav-group-summary::after {
    display: none;
  }

  .press-layout {
    grid-template-columns: 1fr;
  }

  .press-assets,
  .press-facts {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .page-meta-row {
    gap: 10px;
  }

  .release-card {
    padding: 20px;
  }

  .changelog-timeline {
    padding-left: 24px;
    gap: 22px;
  }

  /* Rail centre unchanged (8.5px), but the card edge moves in to 24px, so an
     11px dot hangs back by 24 + 5.5 − 8.5 = 21px to stay centred on the line. */
  .timeline-entry::before {
    left: -21px;
  }

  .timeline-upcoming::before {
    left: -21px;
  }

  .timeline-card {
    padding: 24px 20px 24px;
  }

  .roadmap-visual {
    aspect-ratio: 4 / 3;
  }

  .roadmap-copy {
    padding: 22px 18px 26px;
  }

  .roadmap-number {
    margin-bottom: 18px;
  }

  .footer-links-col {
    align-items: flex-start;
  }

  .footer-nav {
    gap: 14px 18px;
  }

  .journal-featured-body {
    padding: 24px 20px 26px;
  }

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

  .journal-orbit {
    width: 150px;
    height: 150px;
  }

  .article-cover {
    min-height: 240px;
  }

  .journal-orbit--large {
    width: 180px;
    height: 180px;
  }

  .viz {
    width: 190px;
    height: 190px;
  }

  .viz-wave {
    height: 120px;
    gap: 9px;
  }

  .viz-layers {
    width: 170px;
  }

  .article-cta {
    flex-direction: column;
    align-items: flex-start;
    padding: 24px 20px;
  }

  .press-actions .btn {
    width: 100%;
  }

  .press-link-grid {
    grid-template-columns: 1fr;
  }

  .article-prose p,
  .article-list li {
    font-size: 1.05rem;
  }
}
