/* ============================================================================
   voxa — сайт. Дизайн-система «Obsidian», общая для ВСЕХ страниц сайта.

   Один файл на весь сайт. Подключается так:
       <link rel="stylesheet" href="/assets/style.css">

   ПРАВИЛА, КОТОРЫЕ НЕЛЬЗЯ НАРУШАТЬ НА НОВЫХ СТРАНИЦАХ
   ---------------------------------------------------
   1. Никаких внешних загрузок. Ни шрифтов, ни картинок, ни скриптов с чужих
      адресов. Часть пользователей ходит через провайдеров, у которых чужие CDN
      просто не отвечают, — сайт не должен от этого разваливаться.
   2. Постоянно идущая анимация — только transform и opacity. Никаких
      box-shadow / filter / width / height / top / left в @keyframes и в
      transition длиннее ховера.
   3. backdrop-filter на сайте НЕ используется совсем (см. комментарий у .nav).
   4. Всё, что шире экрана (таблицы, код, длинные строки), обязано скроллиться
      внутри своего контейнера, а не растягивать страницу.

   Тема ТОЛЬКО тёмная — обоснование в site/README.md.
   ============================================================================ */

/* ---------------------------------------------------------------- токены -- */

:root {
  /* фон и поверхности — значения взяты из launcher/src/styles/global.css,
     тема dark, чтобы сайт и приложение были одним продуктом */
  --bg: #060606;
  --bg-top: #0d0e11;
  --bg-raised: #0b0b0c;

  --text-1: #f2f0ec;
  --text-2: #a3a3a0;
  --text-3: #7a7a77;

  --hairline: rgba(255, 255, 255, 0.08);
  --stroke: rgba(255, 255, 255, 0.11);
  --surface: rgba(255, 255, 255, 0.035);
  --surface-hover: rgba(255, 255, 255, 0.06);
  --surface-active: rgba(255, 255, 255, 0.09);

  /* акценты: янтарь — голос, кобальт — демонстрация экрана */
  --ember-1: #ff7a1a;
  --ember-2: #ff3d2e;
  --cobalt-1: #2b4bff;
  --cobalt-2: #6aa4ff;

  --ok: #4a9d6e;
  --danger: #e5544d;
  --on-accent: #0a0a0a;
  --focus: rgba(255, 122, 26, 0.55);

  /* геометрия */
  --radius-card: 22px;
  --radius-glass: 20px;
  --radius-input: 12px;
  --radius-pill: 999px;

  /* раскладка */
  --wrap: 1120px;
  --gutter: clamp(16px, 4vw, 32px);
  --nav-h: 64px;
  --section-y: clamp(56px, 9vw, 116px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Шрифты — системные стеки. В приложении стоят Unbounded/Manrope/JetBrains
     Mono, но тащить их на сайт значит либо CDN (запрещено), либо +300 КБ
     шрифтов на первый экран. Роль «фирменного» несёт моноширинный оверлайн —
     он читается так же, как .overline в приложении. */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", "SF Mono",
    Consolas, "Liberation Mono", Menlo, monospace;

  color-scheme: dark;
}

/* --------------------------------------------------------------- сброс ---- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* якоря не должны прятаться под липкой шапкой */
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* страховка от горизонтального переполнения: если что-то вылезет вбок,
     страница не поедет. clip, а не hidden — не ломает position:sticky */
  overflow-x: clip;
}

/* Вертикальный перелив фона — как в приложении (светлее кверху).
   Это статический градиент, он ничего не анимирует. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background: linear-gradient(180deg, var(--bg-top) 0%, var(--bg) 62%);
}

/* Виньетка — как в приложении. Тоже статическая. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 120% at 50% 30%, transparent 52%, rgba(0, 0, 0, 0.55) 100%);
}

img,
svg,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
dl,
dd,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

a {
  color: var(--cobalt-2);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

::selection {
  background: rgba(255, 122, 26, 0.26);
  color: #f2f0ec;
}

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

/* тонкий скроллбар — как в приложении */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.12);
  border-radius: var(--radius-pill);
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.2);
  background-clip: content-box;
}

/* ------------------------------------------------------------ утилиты ----- */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Ссылка «к содержанию» для клавиатуры. Видна только при фокусе. */
.skip {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--radius-input);
  background: var(--bg-raised);
  border: 1px solid var(--stroke);
  color: var(--text-1);
  transform: translateY(-160%);
}
/* именно :focus, а не :focus-visible — ссылка нужна ровно тогда, когда на неё
   вообще встал фокус, и терять её из-за эвристики «видимости» нельзя */
.skip:focus {
  transform: translateY(0);
  text-decoration: none;
}

.overline {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
}

.muted {
  color: var(--text-2);
}
.faint {
  color: var(--text-3);
}
.mono {
  font-family: var(--font-mono);
}

.nowrap {
  white-space: nowrap;
}

/* Ограничитель длины строки. На широком мониторе строка во всю карточку
   в 1120 px не читается — глаз теряет начало следующей. */
.measure {
  max-width: 76ch;
}

/* Плейсхолдер, который владелец обязан заменить перед публикацией.
   Оформлен ровно так же, как .ph в site/legal/*.html — жёлтый, в пунктирной
   рамке. Смысл в том, чтобы незаполненное выглядело незаполненным. */
.ph {
  background: #3a3116;
  color: #f0d68a;
  border: 1px dashed #6d5b23;
  border-radius: 4px;
  padding: 0 0.3em;
  font-weight: 600;
  font-size: 0.94em;
  word-break: break-word;
}

/* ------------------------------------------------------------ типографика - */

.display {
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.04;
  text-wrap: balance;
}

.h1 {
  font-size: clamp(34px, 7.2vw, 64px);
}
.h2 {
  font-size: clamp(26px, 4.2vw, 40px);
}
.h3 {
  font-size: clamp(19px, 2.2vw, 22px);
  letter-spacing: -0.015em;
  line-height: 1.25;
  font-weight: 650;
}

.lead {
  font-size: clamp(17px, 1.8vw, 20px);
  line-height: 1.6;
  color: var(--text-2);
  text-wrap: pretty;
}

/* --------------------------------------------------------------- кнопки --- */

.btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 650;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  /* Ховер: только transform/opacity/цвета. Свечение сделано отдельным слоем
     ::after с готовой тенью — анимируется его opacity, а не сама тень. */
  transition:
    transform 0.18s var(--ease),
    background-color 0.18s var(--ease),
    border-color 0.18s var(--ease),
    color 0.18s var(--ease);
}
a.btn,
a.btn:hover {
  text-decoration: none;
}
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s var(--ease);
}
.btn:hover {
  transform: translateY(-1px);
}
.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: var(--text-1);
  color: var(--on-accent);
}
.btn--primary::after {
  box-shadow: 0 12px 38px -12px rgba(255, 255, 255, 0.5);
}
.btn--primary:hover::after {
  opacity: 1;
}

.btn--ember {
  background: linear-gradient(120deg, var(--ember-1), var(--ember-2));
  color: #160d05;
}
.btn--ember::after {
  box-shadow: 0 14px 42px -12px rgba(255, 122, 26, 0.75);
}
.btn--ember:hover::after {
  opacity: 1;
}

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

.btn--sm {
  height: 38px;
  padding: 0 18px;
  font-size: 14px;
}
.btn--lg {
  height: 52px;
  padding: 0 30px;
  font-size: 16px;
}

/* Ряд кнопок. На узком экране кнопки становятся во всю ширину — палец
   попадает, а не мажет. */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
@media (max-width: 460px) {
  .btn-row {
    flex-direction: column;
    align-items: stretch;
  }
  .btn-row .btn {
    width: 100%;
  }
}

/* ---------------------------------------------------------------- стекло -- */

/* Наше «стекло» — без backdrop-filter. Размытие фона под элементом заставляет
   браузер перерисовывать область на каждом кадре прокрутки; на слабой машине
   это ровно тот эффект «мышь тормозит», на который жаловался владелец в
   приложении. Здесь глубину дают полупрозрачная заливка, волосяная грань и
   светлый внутренний блик — тот же вид, ноль цены за кадр. */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-card);
  padding: clamp(20px, 3vw, 28px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.card--flat {
  background: rgba(255, 255, 255, 0.02);
  border-color: var(--hairline);
}

/* Карточка-ссылка: приподнимается на ховере. */
.card--link {
  display: block;
  color: inherit;
  transition:
    transform 0.2s var(--ease),
    border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}
.card--link:hover {
  transform: translateY(-2px);
  border-color: var(--surface-active);
  background: var(--surface-hover);
  text-decoration: none;
}

.hairline {
  height: 1px;
  border: 0;
  background: linear-gradient(to right, transparent, var(--hairline), transparent);
  margin: 0;
}

/* ----------------------------------------------------------------- чипы --- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
}
.chip__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ember-1);
  flex: none;
}

/* ------------------------------------------------------------- навигация -- */

/* Липкая шапка. Крепление сделано на самом монтажном контейнере (#site-nav),
   иначе sticky «отлипал» бы, как только его собственная коробка уезжает вверх.
   Состояние «прокручено» переключается через IntersectionObserver по невидимому
   сторожку над шапкой — обработчика scroll на сайте нет ни одного. */
.nav-mount {
  position: sticky;
  top: 0;
  z-index: 60;
  /* высота зарезервирована заранее: разметку шапки подставляет app.js, и без
     этой строки страница дёрнулась бы в момент подстановки */
  height: var(--nav-h);
}

.nav {
  height: var(--nav-h);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition:
    background-color 0.2s var(--ease),
    border-color 0.2s var(--ease);
}
/* прокрутили — шапка становится непрозрачной подложкой (без размытия) */
.nav.is-stuck {
  background: rgba(8, 8, 9, 0.92);
  border-bottom-color: var(--hairline);
}

.nav__in {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-1);
  flex: none;
}
.nav__brand:hover {
  text-decoration: none;
}
.nav__mark {
  display: block;
  width: 26px;
  height: 26px;
  flex: none;
}
.nav__word {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-inline-start: 18px;
  flex: 1 1 auto;
  min-width: 0;
}
.nav__links a {
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 14.5px;
  color: var(--text-2);
  transition:
    color 0.15s var(--ease),
    background-color 0.15s var(--ease);
}
.nav__links a:hover {
  color: var(--text-1);
  background: var(--surface-hover);
  text-decoration: none;
}
.nav__links a[aria-current] {
  color: var(--text-1);
}

.nav__cta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  margin-inline-start: auto;
}

.nav__burger {
  display: none;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  border: 1px solid var(--hairline);
  color: var(--text-1);
}
.nav__burger:hover {
  background: var(--surface-hover);
}
/* три полоски: верхняя и нижняя разъезжаются в крест — только transform */
.nav__burger span {
  position: relative;
  display: block;
  width: 18px;
  height: 1.5px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s var(--ease), opacity 0.15s var(--ease);
}
.nav__burger span::before,
.nav__burger span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.2s var(--ease);
}
.nav__burger span::before {
  transform: translateY(-6px);
}
.nav__burger span::after {
  transform: translateY(6px);
}
.nav__burger[aria-expanded="true"] span {
  opacity: 0;
}

/* мобильное меню */
.nav__sheet {
  position: fixed;
  left: 0;
  right: 0;
  top: var(--nav-h);
  z-index: 55;
  max-height: calc(100dvh - var(--nav-h));
  overflow-y: auto;
  padding: 12px var(--gutter) 24px;
  background: rgba(8, 8, 9, 0.98);
  border-bottom: 1px solid var(--hairline);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-8px);
  transition:
    opacity 0.18s var(--ease),
    transform 0.18s var(--ease),
    visibility 0s linear 0.18s;
}
.nav__sheet.is-open {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition:
    opacity 0.18s var(--ease),
    transform 0.18s var(--ease),
    visibility 0s;
}
/* :not(.btn) обязательно. Без него эти правила перебивают .btn по
   специфичности (0,1,1 против 0,1,0) и ломают кнопку «Скачать» внутри меню:
   display:block вместо inline-flex (текст уезжает влево), своя padding, свой
   цвет — светлый текст на оранжевой заливке даёт контраст 2,3:1, — а на ховере
   background затирал бы саму заливку. */
.nav__sheet a:not(.btn) {
  display: block;
  padding: 13px 12px;
  border-radius: 12px;
  color: var(--text-1);
  font-size: 16px;
}
.nav__sheet a:not(.btn):hover {
  background: var(--surface-hover);
  text-decoration: none;
}
.nav__sheet .btn {
  width: 100%;
  margin-top: 10px;
}
.nav__sheet hr {
  margin: 10px 0;
}

@media (max-width: 860px) {
  .nav__links {
    display: none;
  }
  .nav__burger {
    display: inline-flex;
  }
}
@media (max-width: 400px) {
  /* На совсем узком «Скачать» уезжает в меню — иначе шапка ломается. */
  .nav__cta .btn {
    display: none;
  }
}

/* -------------------------------------------------------------- секции ---- */

.section {
  padding-block: var(--section-y);
}
.section--tight {
  padding-block: calc(var(--section-y) * 0.62);
}

.section__head {
  max-width: 62ch;
  margin-bottom: clamp(28px, 4vw, 46px);
}
.section__head .overline {
  display: block;
  margin-bottom: 14px;
}
.section__head p {
  margin-top: 14px;
}

.grid {
  display: grid;
  gap: clamp(14px, 1.6vw, 20px);
}
.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
}
.grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
}

/* --------------------------------------------------------------- герой ---- */

.hero {
  position: relative;
  padding-block: clamp(56px, 11vw, 120px) clamp(50px, 8vw, 96px);
}

/* Подсветка за героем. Единственная постоянно идущая анимация на сайте:
   два мягких пятна, движение — чистый transform. Слой не ловит события,
   лежит под контентом и полностью подрезан по ширине родителя. */
.hero__glowbox {
  position: absolute;
  inset: -20% 0 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  /* обрезка на уровне слоя, чтобы пятна не создавали прокрутку вбок */
  contain: paint;
}
.hero__glow {
  position: absolute;
  width: min(760px, 90vw);
  aspect-ratio: 1;
  border-radius: 50%;
  opacity: 0.5;
  will-change: transform;
}
.hero__glow--ember {
  top: -14%;
  left: -8%;
  background: radial-gradient(circle, rgba(255, 122, 26, 0.28) 0%, rgba(255, 61, 46, 0.1) 42%, transparent 68%);
  animation: drift-a 38s var(--ease) infinite;
}
.hero__glow--cobalt {
  top: 4%;
  right: -14%;
  background: radial-gradient(circle, rgba(43, 75, 255, 0.24) 0%, rgba(106, 164, 255, 0.09) 44%, transparent 68%);
  animation: drift-b 46s var(--ease) infinite;
}

@keyframes drift-a {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(6%, 4%, 0) scale(1.14);
  }
}
@keyframes drift-b {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1.06);
  }
  50% {
    transform: translate3d(-7%, 5%, 0) scale(1);
  }
}

.hero__inner {
  max-width: 46rem;
}
.hero h1 {
  margin-top: 18px;
}
.hero .lead {
  margin-top: 22px;
  max-width: 40rem;
}
.hero .btn-row {
  margin-top: 32px;
}
.hero__note {
  margin-top: 18px;
  font-size: 14px;
  color: var(--text-3);
}

/* Строка «на чём это стоит» под героем. */
.hero__facts {
  margin-top: clamp(38px, 6vw, 62px);
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-glass);
  overflow: hidden;
}
.hero__fact {
  background: rgba(10, 10, 11, 0.6);
  padding: 20px clamp(16px, 2vw, 24px);
}
/* Фактов три, а сетка auto-fit: в полосе ~435–655px она даёт два столбца,
   и правый нижний угол оставался пустой ячейкой — выглядело как дырка.
   Ниже 655px третьего столбца не бывает (3×200px + зазоры уже не влезают),
   поэтому здесь можно безопасно растянуть последний факт на всю ширину.
   На одном столбце правило ничего не меняет. */
@media (max-width: 654px) {
  .hero__fact:last-child {
    grid-column: 1 / -1;
  }
}
.hero__fact b {
  display: block;
  font-size: 15.5px;
  font-weight: 650;
  color: var(--text-1);
  margin-bottom: 4px;
}
.hero__fact span {
  font-size: 14px;
  color: var(--text-3);
  line-height: 1.5;
}

/* ------------------------------------------------------- карточки-фичи ---- */

.feature {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.feature__icon {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 13px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--ember-1);
  margin-bottom: 4px;
  flex: none;
}
.feature__icon--cobalt {
  color: var(--cobalt-2);
}
.feature p {
  color: var(--text-2);
  font-size: 15.5px;
}
.feature__meta {
  margin-top: auto;
  padding-top: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--text-3);
}

/* ------------------------------------------------------------- списки ----- */

.ticks li,
.crosses li {
  position: relative;
  padding-left: 30px;
  margin-bottom: 12px;
  color: var(--text-2);
  font-size: 15.5px;
  line-height: 1.55;
}
.ticks li::before,
.crosses li::before {
  position: absolute;
  left: 0;
  top: 0.05em;
  font-family: var(--font-mono);
  font-size: 15px;
}
.ticks li::before {
  content: "✓";
  color: var(--ok);
}
.crosses li::before {
  content: "—";
  color: var(--text-3);
}
.ticks li b,
.crosses li b {
  color: var(--text-1);
  font-weight: 650;
}

/* нумерованные шаги */
.steps {
  counter-reset: step;
  display: grid;
  gap: clamp(14px, 1.6vw, 20px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
.steps li {
  counter-increment: step;
  position: relative;
  padding: clamp(20px, 3vw, 26px);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  background: rgba(255, 255, 255, 0.02);
}
.steps li::before {
  content: counter(step);
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-bottom: 14px;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ember-1);
}
.steps b {
  display: block;
  font-size: 17px;
  font-weight: 650;
  margin-bottom: 6px;
}
.steps p {
  color: var(--text-2);
  font-size: 15px;
}

/* --------------------------------------------------------- блок «итог» ---- */

.callout {
  border: 1px solid var(--stroke);
  border-radius: var(--radius-card);
  padding: clamp(24px, 4vw, 40px);
  background:
    linear-gradient(180deg, rgba(255, 122, 26, 0.06), rgba(255, 122, 26, 0) 60%),
    var(--surface);
}
.callout .btn-row {
  margin-top: 26px;
}

/* ------------------------------------------------- бесплатно и Voxa+ ------ */

/* Две карточки рядом в обычной .grid--2: слева «без подписки», справа Voxa+.
   Цена — самый крупный элемент карточки НАМЕРЕННО: человек, который пришёл
   выяснить «сколько это стоит», не должен её искать. По той же причине «0 ₽»
   стоит слева и выглядит ровно так же, как «199 ₽»: бесплатное — это тариф,
   а не сноска мелким шрифтом. */
.plan {
  display: flex;
  flex-direction: column;
}
.plan .overline {
  display: block;
  margin-bottom: 10px;
}
.plan__price {
  font-size: clamp(30px, 4.4vw, 40px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 20px;
}
.plan__per {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--text-3);
}
/* Тёплая подсветка платного варианта — та же, что у .callout и карточки
   доступной системы на странице загрузки. Никакого «выделенного тарифа»
   с рамкой и лентой «выгодно»: это подписка на украшения, а не спасение. */
.plan--plus {
  background:
    linear-gradient(180deg, rgba(255, 122, 26, 0.07), rgba(255, 122, 26, 0) 62%),
    var(--surface);
}
.plan__note {
  margin-top: 10px;
  color: var(--text-3);
  font-size: 14.5px;
  line-height: 1.55;
}
/* Строка «кассы пока нет». Её задача — быть замеченной раньше, чем человек
   пойдёт искать кнопку «купить», поэтому она оформлена как предупреждение,
   а не как сноска. */
.plan__note--warn {
  margin-top: 16px;
  padding: 11px 14px;
  border: 1px solid var(--stroke);
  border-left: 2px solid var(--ember-1);
  border-radius: var(--radius-input);
  background: rgba(255, 122, 26, 0.06);
  color: var(--text-2);
}

/* ----------------------------------------------- страница загрузки -------- */

/* Используется только на /download.html, но живёт здесь: одна таблица стилей
   на весь сайт — это один запрос и один источник правды по токенам.

   Подсветка «это ваша система» сделана ЦЕЛИКОМ на CSS, по атрибуту
   <html data-os="win|mac|linux|android|ios">, который download.js проставляет
   ещё до первой отрисовки. Скрипт при этом ничего не дописывает в разметку:
   ни моргания, ни перерасчёта раскладки после загрузки. Атрибута нет —
   значит систему не распознали, и список просто показывается без подсветки. */

.dl-top {
  max-width: 46rem;
  margin-bottom: clamp(26px, 3.6vw, 40px);
}
.dl-top .overline {
  display: block;
  margin-bottom: 14px;
}
.dl-top .lead {
  margin-top: 18px;
}

/* Строка «вы, похоже, не с Windows». Показывается, только когда систему
   распознали И это не Windows. Без скриптов её нет вовсе. */
.dl-foreign {
  display: none;
  margin-top: 20px;
  max-width: 54ch;
  padding: 12px 16px;
  border: 1px solid var(--stroke);
  border-left: 2px solid var(--ember-1);
  border-radius: var(--radius-input);
  background: rgba(255, 122, 26, 0.06);
  color: var(--text-2);
  font-size: 15px;
  line-height: 1.5;
}
html[data-os] .dl-foreign {
  display: block;
}
html[data-os="win"] .dl-foreign {
  display: none;
}

/* Вариант системы. Доступный (.os--ready) — обычная стеклянная карточка
   с тёплой подсветкой; недоступный (.os--none) — тише и БЕЗ единого признака
   кликабельности: это <div>, у него нет ни ховера, ни курсора-руки, ни
   подъёма. Недоступное обязано выглядеть недоступным. */
.os {
  position: relative;
}
.os--ready {
  background:
    linear-gradient(180deg, rgba(255, 122, 26, 0.07), rgba(255, 122, 26, 0) 62%),
    var(--surface);
}

.os__head {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.os__icon {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 13px;
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--ember-1);
  flex: none;
}
.os__title {
  flex: 1 1 auto;
  min-width: 0;
}
.os__sub {
  margin-top: 3px;
  color: var(--text-3);
  font-size: 14px;
}
.os__act {
  margin-top: clamp(18px, 2.4vw, 24px);
}
.os__meta {
  margin-top: 14px;
  color: var(--text-3);
  font-size: 14px;
}

/* РАСКЛАДКА маленькой плитки — отдельно от её СОСТОЯНИЯ. Раньше колонку задавал
   сам `.os--none`, и плитка, которая стала доступной, теряла вместе с ним всю
   вёрстку. Теперь `os--stack` — это «как стоит», а `os--none` — «сборки нет». */
.os--stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: clamp(18px, 2.4vw, 22px);
}
.os--none .os__icon {
  width: 38px;
  height: 38px;
  color: var(--text-3);
}
.os--none h3 {
  color: var(--text-2);
}

/* Доступная маленькая плитка: значок и заголовок в полную силу — разница с
   недоступной обязана читаться до чтения текста. */
.os--stack.os--ready .os__icon {
  width: 38px;
  height: 38px;
  color: var(--ember-1);
}

/* Кнопка и строка под ней внутри маленькой плитки. Ширина полная: в узкой
   колонке кнопка по содержимому выглядит обрезком, а палец мимо неё мажет. */
.os__act--sm {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 2px;
}
.os__act--sm .os__meta {
  margin: 0;
}

/* «Сборки нет» — тот же вид, что у .chip, но без точки состояния. */
.os__state {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* «Ваша система» лежит в разметке у КАЖДОГО варианта и скрыта; показывается
   ровно один — по data-os. */
.os__badge {
  display: none;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 122, 26, 0.4);
  background: rgba(255, 122, 26, 0.1);
  color: #ffb37a;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
html[data-os="win"] #os-win .os__badge,
html[data-os="linux"] #os-linux .os__badge,
html[data-os="mac"] #os-mac .os__badge,
html[data-os="android"] #os-android .os__badge,
html[data-os="ios"] #os-ios .os__badge {
  display: inline-flex;
}

/* Подсветка недоступного варианта: человек на macOS должен УВИДЕТЬ, что для
   него сборки нет, а не искать это глазами. */
html[data-os="linux"] #os-linux,
html[data-os="mac"] #os-mac,
html[data-os="android"] #os-android,
html[data-os="ios"] #os-ios {
  border-color: rgba(255, 122, 26, 0.34);
  background: rgba(255, 122, 26, 0.04);
}

/* Четыре варианта в ряд на широком, по два на планшете, в столбик на узком.
   auto-fit здесь не годится: он оставляет одинокую карточку в последнем ряду. */
.os-grid {
  display: grid;
  gap: clamp(12px, 1.6vw, 18px);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 820px) {
  .os-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (max-width: 380px) {
  .os-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.dl-tail {
  margin-top: clamp(22px, 3vw, 30px);
  max-width: 72ch;
  font-size: 14.5px;
}

/* Блок приглашения (?invite=КОД в адресе). В разметке он скрыт атрибутом
   hidden — показывает его download.js; поэтому у самого .invite НЕТ правила
   display: оно перебило бы hidden, и блок торчал бы у всех без разбора.
   Тёплый акцент — тот же приём, что у .os--ready, только заметнее: это
   единственная карточка на странице, ради которой человек сюда пришёл
   по личной ссылке. */
.invite {
  margin-bottom: clamp(18px, 2.6vw, 28px);
  border-color: rgba(255, 122, 26, 0.34);
  background:
    linear-gradient(180deg, rgba(255, 122, 26, 0.09), rgba(255, 122, 26, 0) 68%),
    var(--surface);
}
.invite__overline {
  display: block;
  margin-bottom: 12px;
  color: #ffb37a;
}
/* Код крупно и моноширинно. overflow-wrap — чтобы на самом узком экране
   код с разрядкой переносился, а не растягивал страницу (правило 4
   из шапки этого файла). */
.invite__code {
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: clamp(21px, 4.6vw, 30px);
  font-weight: 650;
  letter-spacing: 0.14em;
  color: var(--text-1);
  overflow-wrap: anywhere;
}
.invite__act {
  margin-top: 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
/* Подпись-фолбэк вместо кнопки, когда буфер обмена недоступен. */
.invite__hint {
  color: var(--text-3);
  font-size: 14px;
}
.invite__note {
  margin-top: 12px;
  color: var(--text-2);
  font-size: 14.5px;
}

/* --------------------------------------------------------------- подвал --- */

.foot {
  border-top: 1px solid var(--hairline);
  background: rgba(9, 9, 10, 0.6);
  padding-block: clamp(40px, 6vw, 64px) 32px;
  font-size: 15px;
}
.foot__cols {
  display: grid;
  gap: clamp(28px, 4vw, 44px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
/* Колонке реквизитов нужно больше места: почта — длинная неразрывная строка,
   в равной четверти она распадается на три обрывка. */
@media (min-width: 900px) {
  .foot__cols {
    grid-template-columns: 1.15fr 0.85fr 1.15fr 1.15fr;
  }
}
.foot__col h2 {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 500;
  margin-bottom: 14px;
}
.foot__col li {
  margin-bottom: 9px;
}
.foot__col a {
  color: var(--text-2);
  font-size: 15px;
}
.foot__col a:hover {
  color: var(--text-1);
}

.foot__brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text-1);
  margin-bottom: 12px;
}
.foot__brand:hover {
  text-decoration: none;
}
.foot__about {
  color: var(--text-3);
  font-size: 14px;
  max-width: 28ch;
  line-height: 1.55;
}

.foot__req {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 14px;
  margin: 0;
  font-size: 14.5px;
}
.foot__req dt {
  color: var(--text-3);
}
.foot__req dd {
  margin: 0;
  color: var(--text-2);
  word-break: break-word;
}
/* На узком экране колонка значения сжимается до ~130 px, и почта переносится
   посреди адреса («help@voxavoice.\nru»). Кладём подпись над значением —
   значению достаётся вся ширина, и адрес остаётся адресом. */
@media (max-width: 560px) {
  .foot__req {
    grid-template-columns: 1fr;
    gap: 2px;
  }
  .foot__req dd {
    margin-bottom: 10px;
  }
}

/* Нижняя строка подвала. Столбиком, а не рядом: абзацев тут два (общий
   и обязательный платёжный — цена, способы оплаты, возврат), и в ряд они
   складывались бы по-разному в зависимости от ширины. */
.foot__bottom {
  margin-top: clamp(32px, 5vw, 48px);
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--text-3);
  font-size: 13.5px;
}
.foot__bottom p {
  max-width: 68ch;
}

/* Запасной подвал для случая «скрипты отключены». Видит его меньшинство,
   но документы обязаны быть доступны и ему. */
.foot-noscript {
  border-top: 1px solid var(--hairline);
  padding: 28px var(--gutter);
  font-size: 15px;
  color: var(--text-2);
}
.foot-noscript ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-bottom: 14px;
}

/* ------------------------------------------------ появление при прокрутке - */

/* Прячем ТОЛЬКО когда скрипт жив (класс .js ставит app.js первой строкой).
   Если скрипт не загрузился, ничего не прячется и страница читается как есть. */
/* will-change здесь намеренно НЕ ставится: таких блоков на странице полтора
   десятка, и держать под каждым отдельный слой всё время — дороже, чем разовое
   продвижение слоя в момент самого перехода, которое браузер делает сам. */
.js .reveal {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition:
    opacity 0.55s var(--ease),
    transform 0.55s var(--ease);
  transition-delay: var(--d, 0s);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* ------------------------------------------------------- уменьшить движение */

/* Требование: движение должно ВЫКЛЮЧАТЬСЯ, а не замедляться. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
  }
  .hero__glow {
    animation: none !important;
    will-change: auto;
  }
  .js .reveal,
  .js .reveal.is-in {
    opacity: 1 !important;
    transform: none !important;
  }
  .btn:hover,
  .btn:active,
  .card--link:hover {
    transform: none !important;
  }
}

/* --------------------------------------------------------------- печать --- */

@media print {
  body::before,
  body::after,
  .hero__glowbox,
  .nav-mount,
  .nav__sheet {
    display: none !important;
  }
  body {
    background: #fff;
    color: #000;
  }
}
