/* ============================================================================
   OBS Shell - landing v2
   Тёмная тема, синий акцент, плоские поверхности.
   Глубина - только WebGL-канвас, плоские слои, тени и блики вплотную к объектам.
   Градиенты запрещены на всём, что больше 200px по любой стороне.
   ============================================================================ */

/* ============================================================================
   1. ТОКЕНЫ
   ============================================================================ */
:root {
  /* --- типографическая шкала (design-system, раздел 2) --- */
  --t-hero:    clamp(48px, 7vw, 88px);
  --t-section: clamp(36px, 5vw, 64px);
  --t-num:     clamp(48px, 5.5vw, 72px);
  --t-card-h:  clamp(21px, 2.2vw, 28px);
  --t-tile-h:  24px;
  --t-lead:    clamp(19px, 1.7vw, 24px);
  --t-body-l:  21px;
  --t-body:    17px;
  --t-caption: 14px;
  --t-eyebrow: 17px;
  --t-label:   12px;

  --tr-tight: -0.03em;
  --tr-snug:  -0.025em;
  --tr-card:  -0.015em;
  --tr-text:  -0.01em;

  /* --- цвет (design-system, раздел 6) --- */
  --bg:        #08090c;
  --bg-deep:   #050609;
  --surface:   #111318;
  --surface-2: #16181d;
  --surface-3: #1c1f25;

  --line:        rgba(255,255,255,.08);
  --line-2:      rgba(255,255,255,.05);
  --line-strong: rgba(255,255,255,.14);

  --ink:      #f2f3f5;
  --ink-dim:  #9a9ca4;
  --ink-mute: #62656e;

  --accent:      #3b82f6;
  --accent-soft: #6ea8fe;
  --accent-bg:   rgba(59,130,246,.16);

  --status: #22c55e;
  --rec:    #e05a4d;
  --stream: #a06bf2;
  --warn:   #f59e0b;

  /* Кнопка покупки - единственный лаймовый элемент страницы (бренд-знак Pro
     из v1, раздел «неприкосновенное»). Бейджи Pro остаются синими по
     дизайн-системе: синий - язык продукта, лайм - язык денег. */
  --buy:      #aad63a;
  --buy-hot:  #b8e448;
  --buy-ink:  #12210a;

  /* --- радиусы --- */
  --r-xl:   28px;
  --r-lg:   20px;
  --r-md:   12px;
  --r-pill: 980px;

  /* --- ритм --- */
  --section-y: clamp(80px, 10vw, 160px);
  --head-gap:  56px;   /* заголовочный блок -> контент */
  --grid-gap:  20px;
  --pad:       24px;   /* боковое поле страницы */
  --maxw:      1200px;
  --maxw-text: 980px;

  /* --- движение (design-system, раздел 5) --- */
  --ease:    cubic-bezier(0.32, 0.72, 0, 1);
  --ease-io: cubic-bezier(0.25, 0.1, 0.25, 1);
  --dur-reveal: 800ms;
  --dur-switch: 400ms;
  --dur-hover:  280ms;
  --dur-icon:   300ms;

  /* --- шрифты --- */
  --font: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  color-scheme: dark;
}

@media (max-width: 640px) {
  :root {
    --t-tile-h: 21px;
    --t-body-l: 19px;
    --t-eyebrow: 15px;
    --r-xl: 20px;
    --r-lg: 16px;
    --head-gap: 36px;
    --grid-gap: 14px;
    --pad: 20px;
  }
}

/* ============================================================================
   2. БАЗА
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 72px;
  overflow-x: clip;                 /* clip, не hidden: не ломает position:sticky */
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.5;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul, ol { list-style: none; }
::selection { background: rgba(59,130,246,.35); color: #fff; }

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

::-webkit-scrollbar { width: 11px; }
::-webkit-scrollbar-track { background: var(--bg-deep); }
::-webkit-scrollbar-thumb { background: #26282e; border-radius: 99px; border: 2px solid var(--bg-deep); }
::-webkit-scrollbar-thumb:hover { background: #34373f; }

/* Живой WebGL-фон. Позиционирование продублировано инлайном в HTML.
   Фолбэк без WebGL - плоский --bg, никаких радиальных пятен. */
#bg { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
#bg.no-webgl { background: var(--bg); }

/* Весь контент выше канваса */
main, .foot, .nav { position: relative; z-index: 1; }
.nav { z-index: 50; }

/* Спрайт иконок не занимает места */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Скип-линк. Выезжает трансформом, а не top: анимация top пересчитывает
   раскладку на каждом кадре, transform едет на композиторе. */
.skip {
  position: absolute; left: 12px; top: 12px; z-index: 100;
  padding: 10px 16px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line-strong);
  font-size: 14px; font-weight: 600;
  transform: translateY(-72px);
  transition: transform 200ms var(--ease-io);
}
.skip:focus { transform: none; }

/* Контейнеры. Поле страницы входит в max-width, чтобы содержимое
   имело ровно 1200 / 980 при любом --pad. */
.wrap {
  width: 100%;
  max-width: calc(var(--maxw) + var(--pad) * 2);
  margin-inline: auto;
  padding-inline: var(--pad);
}
.wrap-text {
  width: 100%;
  max-width: calc(var(--maxw-text) + var(--pad) * 2);
  margin-inline: auto;
  padding-inline: var(--pad);
}

/* Базовая иконка. В моках панели переопределяется на em. */
.ic { width: 20px; height: 20px; flex: none; display: block; }

/* ============================================================================
   3. ТИПОГРАФИКА
   ============================================================================ */
h1, h2, h3 { font-weight: 700; }

.eyebrow {
  font-size: var(--t-eyebrow);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--accent-soft);
}

.h2 {
  font-size: var(--t-section);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: var(--tr-snug);
  max-width: 16ch;
  text-wrap: balance;
}
.h2-sm { font-size: clamp(32px, 3.6vw, 48px); }

.lead {
  font-size: var(--t-lead);
  font-weight: 500;
  line-height: 1.38;
  letter-spacing: var(--tr-text);
  color: var(--ink-dim);
  max-width: 640px;
  text-wrap: pretty;
}

.body-l {
  font-size: var(--t-body-l);
  font-weight: 400;
  line-height: 1.38;
  letter-spacing: var(--tr-text);
  color: var(--ink-dim);
}

.caption {
  font-size: var(--t-caption);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink-mute);
}

/* Правило двух цветов: белая часть + серое продолжение в одном абзаце */
.ink { color: var(--ink); }
.dim { color: var(--ink-dim); }

/* Клавиши и пути в тексте */
.kbd {
  font-family: var(--mono);
  font-size: .82em;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 7px;
}

/* Заголовочный блок секции: eyebrow -> 12 -> h2 -> 20 -> lead -> --head-gap */
.sec-head { margin-bottom: var(--head-gap); }
.sec-head .eyebrow { display: block; margin-bottom: 12px; }
.sec-head .lead { margin-top: 20px; }
.sec-head-center { text-align: center; }
.sec-head-center .h2 { margin-inline: auto; }
.sec-head-center .lead { margin-inline: auto; }

/* ============================================================================
   4. КНОПКИ И БЕЙДЖИ
   ============================================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 44px;
  padding: 0 24px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: var(--tr-text);
  line-height: 1;
  white-space: nowrap;
  transition: background 200ms var(--ease-io), border-color 200ms var(--ease-io),
              color 200ms var(--ease-io), transform 120ms var(--ease-io);
}
.btn:active { transform: scale(.98); }

.btn-primary { background: var(--accent); color: #fff; }
.btn-glass   { background: rgba(255,255,255,.06); color: var(--ink); border-color: var(--line-strong); }

/* Кнопка ОС: две строки (название + версия системы). */
.btn-os {
  flex-direction: column;
  gap: 0;
  height: 64px;
  min-width: 232px;
  padding: 0 28px;
}
.b-top { display: flex; align-items: center; gap: 9px; font-size: 17px; font-weight: 600; }
.b-sub {
  display: block;
  margin-top: 5px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .02em;
  opacity: .68;
}
.btn-os-logo { width: 17px; height: 17px; flex: none; }

/* Купить PRO - плоский лайм, без глянца и градиента. */
.btn-buy {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 9px;
  height: auto;
  padding: 13px 26px 14px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  background: var(--buy);
  color: var(--buy-ink);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: var(--tr-text);
  line-height: 1.1;
  transition: background 200ms var(--ease-io), transform 120ms var(--ease-io);
}
.btn-buy .b-sub { width: 100%; margin-top: 6px; color: #2c3d1a; opacity: .78; font-weight: 500; }
.btn-buy:active { transform: scale(.98); }
.btn-buy:disabled { opacity: .6; pointer-events: none; }

/* Мини-бренд PRO внутри лаймовой кнопки */
.pro-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px 7px 3px;
  border-radius: 6px;
  background: var(--buy-ink);
  color: #eafccb;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
}

/* Бейджи Free / Pro на карточках */
.badge {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
}
.badge-pro  { background: var(--accent-bg); color: var(--accent-soft); }
.badge-free { background: rgba(255,255,255,.08); color: var(--ink-dim); }

@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: #4f8ff7; }
  .btn-glass:hover   { background: rgba(255,255,255,.11); border-color: var(--line-strong); }
  .btn-buy:hover     { background: var(--buy-hot); }
}

/* ============================================================================
   5. NAV - липкая шапка 48px
   ============================================================================ */
.nav {
  position: sticky;
  top: 0;
  height: 48px;
  /* На самом верху шапка прозрачная - фон страницы читается целиком.
     Стекло и линия появляются только после 40px скролла (класс .scrolled из JS). */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 220ms var(--ease-io), border-color 220ms var(--ease-io);
}
.nav.scrolled {
  background: rgba(8,9,12,.72);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-bottom-color: var(--line);
}
.nav-inner { display: flex; align-items: center; gap: 24px; height: 100%; }

.nav-brand { display: flex; align-items: center; gap: 11px; flex: none; }
.nav-logo { width: 30px; height: 30px; }
.nav-name { font-size: 17px; font-weight: 700; letter-spacing: var(--tr-text); }

.nav-links { display: flex; align-items: center; gap: 26px; margin-inline: auto; }
.nav-link {
  font-size: 14px; font-weight: 500; color: var(--ink-dim);
  transition: color 200ms var(--ease-io);
}

.nav-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.nav-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 14px;
  border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; line-height: 1; white-space: nowrap;
  transition: background 200ms var(--ease-io), transform 120ms var(--ease-io);
}
.nav-btn .ic { width: 14px; height: 14px; }
.nav-btn:active { transform: scale(.96); }
.nav-btn-glass { background: rgba(255,255,255,.07); color: var(--ink); border: 1px solid var(--line-strong); }
.nav-btn-buy   { background: var(--buy); color: var(--buy-ink); font-weight: 700; }

@media (hover: hover) and (pointer: fine) {
  .nav-link:hover { color: var(--ink); }
  .nav-btn-glass:hover { background: rgba(255,255,255,.13); }
  .nav-btn-buy:hover { background: var(--buy-hot); }
}

/* ============================================================================
   6. ЖИВЫЕ МОКИ ПРОДУКТА
   Панель (.cbar) свёрстана в em: 1em = 1 условная единица.
   Базовая ширина - 124.4em, высота 23em. Реальный масштаб задаётся
   font-size у контейнера в cqw, поэтому проценты .spot в закадровой
   секции совпадают с зонами панели без единой строки JS.
   ============================================================================ */
.cbar-wrap {
  position: relative;
  display: inline-block;
  /* Тень раньше была filter: drop-shadow. Фильтр растрирует всё содержимое в
     отдельный композитный слой, и поверх живого WebGL-фона границы этого слоя
     проступали прямоугольниками. box-shadow рисуется по форме элемента и слоя
     не создаёт, поэтому артефактов нет. Сама тень висит на .cbar - у него есть
     радиус скругления, у обёртки его нет. */
}

.cbar {
  font-size: 8px;                    /* фолбэк, если cqw недоступны */
  display: flex;
  align-items: stretch;
  gap: .7em;
  width: 124.4em;
  height: 23em;
  padding: 2em;
  background: rgba(13,14,17,.96);
  box-shadow: 0 0 26px rgba(59,130,246,.14), 0 16px 40px rgba(0,0,0,.55);
  border: 1px solid var(--line-strong);
  border-radius: 2.6em;
  letter-spacing: 0;
  line-height: 1.25;
}

/* --- карточка подключения --- */
.cb-id {
  display: flex;
  flex-direction: column;
  gap: 1.1em;
  width: 23.4em;
  flex: none;
  padding: 1.6em;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--line);
  border-radius: 1.8em;
}
.idtop { display: flex; align-items: center; gap: 1.2em; }
.cb-logo { width: 5.2em; height: 5.2em; flex: none; }
.idmeta { display: flex; flex-direction: column; gap: .5em; min-width: 0; }
.cb-id .nm { font-size: 1.9em; font-weight: 800; letter-spacing: -.02em; white-space: nowrap; }
.cb-id .st { display: flex; align-items: center; gap: .62em; font-size: 1.3em; color: var(--ink-dim); }
.cb-id .st .d {
  width: .62em; height: .62em; border-radius: 50%; flex: none;
  background: var(--warn); box-shadow: 0 0 .7em rgba(245,158,11,.7);
}
.cb-id .st.ok .d { background: var(--status); box-shadow: 0 0 .7em rgba(34,197,94,.7); }
.cb-id .host { font-family: var(--mono); font-size: 1.3em; color: var(--ink-dim); }
.cb-id .divider { height: 1px; background: var(--line); }
.cb-id .scene {
  display: flex; align-items: center; gap: .7em;
  margin-top: auto;
  height: 3.8em;
  padding: 0 1em;
  font-size: 1.4em;
  color: var(--ink-dim);
  background: rgba(255,255,255,.03);
  border: 1px solid var(--line);
  border-radius: .85em;
  white-space: nowrap;
}
.cb-id .scene .ic { width: 1.25em; height: 1.25em; }
.cb-id .scene b { color: var(--ink); font-weight: 700; }
.cb-id .scene .chev { width: 1.15em; height: 1.15em; margin-left: auto; color: var(--ink-mute); }

/* --- аудиометры --- */
.cb-audio {
  display: flex;
  justify-content: space-evenly;
  gap: 1.6em;
  width: 11.7em;
  flex: none;
  margin-left: .6em;
  padding: 1.6em 1.2em;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--line);
  border-radius: 1.8em;
}
.cb-meter { display: flex; flex-direction: column; align-items: center; gap: 1em; }
/* Обводка метра - зелёный низ / серый / красный верх. Элемент мелкий (< 200px),
   градиент здесь разрешён и повторяет настоящий метр в приложении. */
.cb-mwrap {
  width: 1.7em;
  flex: 1 1 auto;
  border-radius: .8em;
  padding: .16em;
  background: linear-gradient(to top,
    rgba(34,197,94,.6) 0%, rgba(120,124,135,.4) 52%, rgba(239,68,68,.65) 100%);
}
.cb-mbar {
  position: relative;
  height: 100%;
  border-radius: .64em;
  overflow: hidden;
  background: linear-gradient(to top, #16a34a 0%, #22c55e 45%, #eab308 78%, #ef4444 100%);
}
/* Маска сверху прячет «непройденную» часть: видимая высота снизу = громкость.
   Маска всегда во всю высоту, уровень задаёт scaleY от верхнего края: высота
   пересчитывала раскладку четыре раза в секунду на каждом моке страницы,
   scaleY той же заливки выглядит точно так же и живёт на композиторе.
   will-change оправдан: это единственные элементы, которые двигаются
   непрерывно всё время, пока мок в кадре. */
.cb-mbar i {
  position: absolute; left: 0; right: 0; top: 0;
  height: 100%;
  transform: scaleY(.62);
  transform-origin: top center;
  background: #14151a;
  transition: transform 160ms linear;
}
.cb-meter > .ic { width: 1.9em; height: 1.9em; color: var(--ink-dim); }

/* --- сегмент действий --- */
.cseg { display: flex; align-items: stretch; gap: .7em; flex: none; }
.cb-act {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  width: 10.7em;
  padding: 2.2em 1.1em;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--line);
  border-radius: 1.8em;
  color: var(--ink-dim);
  text-align: center;
}
.cb-act .lbl { font-size: 1.7em; font-weight: 700; color: var(--ink); white-space: nowrap; }
.cb-act .ic  { width: 3.4em; height: 3.4em; }
.cb-act .sub { font-size: 1.3em; color: var(--ink-mute); white-space: nowrap; }
.cb-act.on-ok  { border-color: rgba(34,197,94,.45); background: rgba(34,197,94,.09); }
.cb-act.on-ok .ic, .cb-act.on-ok .sub { color: var(--status); }
.cb-act.on-rec { border-color: rgba(224,90,77,.5); background: rgba(224,90,77,.1); }
.cb-act.on-rec .ic, .cb-act.on-rec .sub { color: var(--rec); }

/* --- библиотека --- */
.cb-lib {
  display: flex;
  align-items: center;
  gap: 1.4em;
  width: 23.4em;
  flex: none;
  margin-left: .6em;
  padding: 0 1.8em;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--line);
  border-radius: 1.8em;
}
.cb-lib .lic { width: 3em; height: 3em; color: var(--accent-soft); }
.cb-lib .lt { min-width: 0; }
.cb-lib .lt .a { font-size: 1.7em; font-weight: 800; white-space: nowrap; }
.cb-lib .lt .b { font-size: 1.3em; color: var(--ink-mute); white-space: nowrap; }
.cb-lib .cnt {
  margin-left: auto;
  padding-left: 1.6em;
  border-left: 1px solid var(--line);
  text-align: center;
}
.cb-lib .cnt .n { font-size: 3.4em; font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.cb-lib .cnt .u { font-size: 1.1em; color: var(--ink-mute); letter-spacing: .04em; }

/* --- сетка 2x2 справа --- */
.cb-mini {
  display: grid;
  grid-template-columns: repeat(2, 5.9em);
  grid-auto-rows: 5.9em;
  gap: 1.2em;
  width: 13em;
  flex: none;
  align-content: center;
  align-self: center;
}
.cb-icon {
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.02);
  border: 1px solid var(--line);
  border-radius: 1.6em;
  color: var(--ink-dim);
}
.cb-icon .ic { width: 2.4em; height: 2.4em; }
/* Микрофон и камера в приложении пока не переключаются: плитки декоративные,
   поэтому глуше и без намёка на клик. */
.cb-icon-static { color: var(--ink-mute); border-color: var(--line-2); }

/* --- пилюля-индикатор --- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 1em;
  height: 3.8em;
  padding: 0 1.6em;
  font-size: 10px;
  background: rgba(16,17,20,.94);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  box-shadow: 0 1.4em 3.6em -1em rgba(0,0,0,.7);
  line-height: 1;
  white-space: nowrap;
  /* пилюля - свой слой укладки, чтобы кольцо пульса легло за точкой,
     но поверх фона пилюли (isolation ничего не меняет на вид) */
  isolation: isolate;
}
/* Пульс - расходящееся кольцо за точкой. Раньше кольцо рисовал box-shadow, и
   каждый кадр перекрашивалась область вокруг точки: box-shadow не умеет жить
   на композиторе, а пилюль на странице семь и пульс бесконечный. Кольцо на
   ::after - тот же рисунок (сплошной круг того же цвета, .9em + по .7em с
   каждой стороны = масштаб 2.556), но едет трансформом и прозрачностью. */
.pill .dot {
  position: relative;
  width: .9em; height: .9em; border-radius: 50%; flex: none;
  background: var(--rec);
}
.pill .dot::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  border-radius: 50%;
  background: rgba(224,90,77,.5);
  animation: recpulse 1.8s infinite;
}
/* Вкладка в фоне - пульс стоит (тот же смысл, что у пула интервалов в JS) */
body.is-hidden-tab .pill .dot::after { animation-play-state: paused; }
.pill .lbl { font-size: 1.35em; font-weight: 700; letter-spacing: .04em; }
.pill .tm  { font-family: var(--mono); font-size: 1.3em; color: var(--ink-dim); }
@keyframes recpulse {
  0%   { transform: scale(1); opacity: 1; }
  70%  { transform: scale(2.556); opacity: 0; }
  100% { transform: scale(2.556); opacity: 0; }
}

/* Пилюля в hero зеркалит живую панель, поэтому у неё есть покой:
   ничего не пишется - точка серая и не пульсирует, таймера нет. */
.pill.is-idle .dot { background: var(--ink-mute); }
.pill.is-idle .dot::after { display: none; }
.pill.is-idle .tm  { display: none; }
/* Индикатор эфира: появляется, когда включён стрим */
.pill .pill-air {
  display: inline-flex; align-items: center; gap: .5em;
  font-size: 1.2em; font-weight: 700; letter-spacing: .04em;
  color: var(--stream);
}
.pill .pill-air::before {
  content: ""; width: .7em; height: .7em; border-radius: 50%; flex: none;
  background: var(--stream);
}
.pill .pill-air[hidden] { display: none; }

/* ============================================================================
   7. HERO
   ============================================================================ */
/* ----------------------------------------------------------------------------
   7.0 Постановочное появление hero (один раз при загрузке)

   Сценарий (все задержки от первого кадра страницы):
     0      надзаголовок
     90     h1
     190    лид
     300    кнопки
     390    цена / сноска
     470    панель целиком: выезд снизу + проявление (900 мс)
     800    карточки панели слева направо, шаг 50 мс (8 штук, до 1150)
     1440   загорается зелёная точка «Подключён»
     1570   оживают аудиометры
     1760   появляется пилюля в углу
     ~2200  сценарий закончен, интерфейс статичен
   Класс .is-intro стоит прямо в разметке: анимация обязана начаться на первом
   кадре, иначе виден готовый экран, который потом дёргается назад. JS только
   снимает класс - по таймеру или на первом действии пользователя.
   fill-mode: backwards, а не both. После проигрыша на элементах не остаётся ни
   одного анимационного стиля, поэтому hover, :active и transform панели
   работают как обычно. Если JS не загрузился, сценарий всё равно доигрывает и
   страница остаётся видимой; при prefers-reduced-motion блок 27 обнуляет
   длительности и задержки, и всё показывается сразу.
   Анимируем только opacity и transform.
   -------------------------------------------------------------------------- */
@keyframes hi-up    { from { opacity: 0; transform: translateY(18px); } }
@keyframes hi-panel { from { opacity: 0; transform: translateY(44px) scale(.988); } }
@keyframes hi-card  { from { opacity: 0; transform: translateY(12px); } }
@keyframes hi-dot   { from { opacity: 0; transform: scale(.2); } }
@keyframes hi-meter { from { opacity: 0; transform: scaleY(.12); } }
@keyframes hi-pill  { from { opacity: 0; transform: translateY(-7px) scale(.9); } }

/* текстовый блок - до панели, с опережением */
.hero.is-intro .hero-eyebrow,
.hero.is-intro .hero-title,
.hero.is-intro .hero-lead,
.hero.is-intro .hero-cta,
.hero.is-intro .hero-price,
.hero.is-intro .hero-note { animation: hi-up 720ms var(--ease) backwards; }
.hero.is-intro .hero-title { animation-delay: 90ms; }
.hero.is-intro .hero-lead  { animation-delay: 190ms; }
.hero.is-intro .hero-cta   { animation-delay: 300ms; }
.hero.is-intro .hero-price { animation-delay: 390ms; }
.hero.is-intro .hero-note  { animation-delay: 430ms; }

/* панель целиком */
.hero.is-intro .hero-product { animation: hi-panel 900ms var(--ease) 470ms backwards; }

/* карточки внутри панели - слева направо, шаг 50 мс */
.hero.is-intro .cb-id,
.hero.is-intro .cb-audio,
.hero.is-intro .cseg > .cb-act,
.hero.is-intro .cb-lib,
.hero.is-intro .cb-mini { animation: hi-card 460ms var(--ease) backwards; }
.hero.is-intro .cb-id                 { animation-delay: 800ms; }
.hero.is-intro .cb-audio              { animation-delay: 850ms; }
.hero.is-intro .cseg > .cb-act:nth-child(1) { animation-delay: 900ms; }
.hero.is-intro .cseg > .cb-act:nth-child(2) { animation-delay: 950ms; }
.hero.is-intro .cseg > .cb-act:nth-child(3) { animation-delay: 1000ms; }
.hero.is-intro .cseg > .cb-act:nth-child(4) { animation-delay: 1050ms; }
.hero.is-intro .cb-lib                { animation-delay: 1100ms; }
.hero.is-intro .cb-mini               { animation-delay: 1150ms; }

/* живые элементы - в самом конце: точка связи, метры, пилюля */
.hero.is-intro .cb-id .st .d { animation: hi-dot 420ms var(--ease) 1440ms backwards; }
.hero.is-intro .cb-mwrap {
  transform-origin: bottom;
  animation: hi-meter 480ms var(--ease) 1570ms backwards;
}
.hero.is-intro .hero-pillbox { animation: hi-pill 440ms var(--ease) 1760ms backwards; }

.hero { padding: 44px 0 0; }
.hero-inner {
  max-width: calc(var(--maxw-text) + var(--pad) * 2);
  text-align: center;
}
.hero-eyebrow { display: block; }
.hero-title {
  margin: 16px auto 0;
  font-size: var(--t-hero);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: var(--tr-tight);
  max-width: 14ch;
  text-wrap: balance;
}
.hero-lead { margin: 20px auto 0; }
.hero-cta {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: var(--grid-gap);
  flex-wrap: wrap;
  margin-top: 28px;
}
.hero-price { margin-top: 16px; font-size: var(--t-caption); color: var(--ink-mute); }
.hero-price b { color: var(--ink); font-weight: 700; }
.hero-note { margin-top: 8px; }
.hero-note b { color: var(--ink-dim); font-weight: 600; }

/* Продукт крупно.
   Сцена (.hero-screen) больше не пустой «экран» 16:9, из-за которого панель
   уезжала под сгиб: высота теперь по контенту, панель встаёт почти во всю
   ширину контейнера и попадает в первый экран целиком. */
.hero-product { margin-top: 36px; }
/* Рамки вокруг панели нет намеренно: коробка в коробке (сцена со своей
   границей, внутри неё панель со своей) съедала ширину и добавляла пустоты.
   Элемент оставлен невидимым контейнером - от его inline-size считается кегль
   панели ниже, поэтому убирать его целиком нельзя. */
.hero-screen {
  position: relative;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
}
/* Верхняя строка сцены: метка захвата слева, пилюля справа. Обе в потоке -
   пилюля больше не лежит абсолютом поверх панели и не может её перекрыть. */
.hero-screen-top {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  width: 100%;
  min-height: 34px;
}
.hero-pillbox { flex: none; }
.hero-pillbox .pill { font-size: clamp(8px, .95cqw, 12px); }
.hero-bar { position: relative; display: flex; justify-content: center; width: 100%; }
/* Панель занимает всю ширину контейнера: паддинга у сцены больше нет, поэтому
   100cqw - это вся доступная ширина. .cbar свёрстана в 124.4em, поэтому кегль
   считаем прямо от них; 2px - запас на субпиксель. */
.hero-screen .cbar { font-size: calc((100cqw - 2px) / 124.4); }
.hero-caption { max-width: 66ch; margin: 20px auto 0; text-align: center; }
.hero-caption .js-hk { font-family: var(--mono); color: var(--ink); }

/* ----------------------------------------------------------------------------
   7.1 Живая панель в hero
   Плитки - настоящие button (Enter/Space, aria-pressed). Состояние ведёт
   wireLiveBar; панель в closer-стейдже класса .is-live не имеет и остаётся
   картинкой. Всё внутри - демонстрация, наружу ничего не уходит.
   -------------------------------------------------------------------------- */
.cbar-wrap.is-live .cb-act {
  cursor: pointer;
  transition: transform var(--dur-hover) var(--ease-io),
              background-color 200ms var(--ease-io),
              border-color 200ms var(--ease-io),
              color 200ms var(--ease-io);
}
.cbar-wrap.is-live .cb-act:active { transform: translateY(0) scale(.97); }
.cbar-wrap.is-live .cb-act:focus-visible { outline-offset: 2px; }
.cbar-wrap.is-live .cb-icon,
.cbar-wrap.is-live .scene { transition: background-color 200ms var(--ease-io), border-color 200ms var(--ease-io); }

@media (hover: hover) and (pointer: fine) {
  .cbar-wrap.is-live .cb-act:hover {
    transform: translateY(-.35em);
    border-color: var(--line-strong);
    background: rgba(255,255,255,.055);
  }
  .cbar-wrap.is-live .cb-act.on-ok:hover     { border-color: rgba(34,197,94,.7);   background: rgba(34,197,94,.16); }
  .cbar-wrap.is-live .cb-act.on-rec:hover    { border-color: rgba(224,90,77,.75);  background: rgba(224,90,77,.17); }
  .cbar-wrap.is-live .cb-act.on-stream:hover { border-color: rgba(160,107,242,.75); background: rgba(160,107,242,.17); }
  .cbar-wrap.is-live .scene:hover { border-color: var(--line-strong); background: rgba(255,255,255,.06); }
  /* Микрофон и камера не кликаются: подсветка есть, курсора-руки нет */
  .cbar-wrap.is-live .cb-icon:hover { border-color: var(--line-strong); background: rgba(255,255,255,.05); }
}

/* Стрим в эфире - фиолетовый акцент продукта */
.cb-act.on-stream { border-color: rgba(160,107,242,.5); background: rgba(160,107,242,.1); }
.cb-act.on-stream .ic, .cb-act.on-stream .sub { color: var(--stream); }

/* Плитка записи носит две подписи: состояние и таймер */
.cb-act .subs { display: flex; flex-direction: column; align-items: center; gap: .3em; }
.cb-act .sub.tm { font-family: var(--mono); }

/* Вспышка при сохранении реплея */
.cb-act.is-flash { animation: cb-flash 380ms var(--ease-io) 2; }
@keyframes cb-flash {
  0%, 100% { border-color: var(--line); background: rgba(255,255,255,.02); }
  45%      { border-color: rgba(110,168,254,.75); background: rgba(59,130,246,.18); }
}

/* --- селектор сцены --- */
.cb-scene { position: relative; margin-top: auto; }
.cb-scene .scene { width: 100%; cursor: pointer; }
.cb-scene .scene[aria-expanded="true"] { border-color: var(--line-strong); background: rgba(255,255,255,.06); }
.cb-id .scene .chev { transition: transform var(--dur-icon) var(--ease); }
.cb-scene .scene[aria-expanded="true"] .chev { transform: rotate(180deg); color: var(--ink); }

.scene-pop {
  position: absolute;
  left: 0; right: 0; bottom: calc(100% + .4em);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: .25em;
  padding: .5em;
  background: rgba(20,22,27,.98);
  border: 1px solid var(--line-strong);
  border-radius: 1.2em;
  box-shadow: 0 1.6em 4em -1.2em rgba(0,0,0,.9);
}
/* [hidden] у браузера слабее классов, поэтому гасим список явно */
.scene-pop[hidden] { display: none; }
.scene-opt {
  display: flex;
  align-items: center;
  height: 3em;
  padding: 0 1em;
  font-size: 1.3em;
  border-radius: .8em;
  color: var(--ink-dim);
  white-space: nowrap;
  cursor: pointer;
}
.scene-opt.is-on { color: var(--ink); background: var(--accent-bg); }
@media (hover: hover) and (pointer: fine) {
  .scene-opt:hover { color: var(--ink); background: rgba(255,255,255,.07); }
}

/* --- подсказка «панель живая»: уходит при первом наведении --- */
.hero-try {
  text-align: center;
  transition: opacity 400ms var(--ease-io), visibility 0s linear 400ms;
}
.hero-try.is-gone { opacity: 0; visibility: hidden; }

/* --- тост «Реплей сохранён»: висит над панелью, поток не двигает --- */
.hero-toast {
  position: absolute;
  left: 50%; bottom: calc(100% + 12px);
  padding: 7px 14px;
  font-size: var(--t-caption);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  box-shadow: 0 10px 28px -14px rgba(0,0,0,.9);
  opacity: 0;
  transform: translate(-50%, 6px);
  pointer-events: none;
  transition: opacity 240ms var(--ease-io), transform 240ms var(--ease-io);
}
.hero-toast.is-on { opacity: 1; transform: translate(-50%, 0); }

/* ============================================================================
   8. HIGHLIGHTS - карусель
   ============================================================================ */
/* Секция меряется экраном, а не общим ритмом страницы: заголовок, карточка и
   точки обязаны уложиться в один экран ноутбука (1440x900) без прокрутки
   внутри блока. Отсюда собственные отступы вместо --section-y. */
.hl { padding-block: clamp(48px, 4.5vw, 88px); }
.hl .sec-head { margin-bottom: clamp(24px, 2.2vw, 32px); }
.hl-viewport { width: 100%; }
.hl-viewport:focus-visible { outline-offset: -2px; }

.hl-track {
  /* Высота карточки идёт от высоты экрана, ширина - от неё по 16:10.
     Потолки 600/1000 не дают карточке распухнуть на большом мониторе. */
  --hl-h: min(58vh, 600px);
  --hl-card: min(calc(var(--hl-h) * 1.6), 1000px, 92vw);
  display: flex;
  gap: var(--grid-gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Поле совпадает с полем .wrap: первая карточка встаёт ровно под заголовком,
     хвост ленты уходит за правый край экрана. Раньше поле считалось от ширины
     карточки, и на 1920 лента начиналась на 120px правее заголовка - колонка
     контента переставала читаться как колонка. scroll-padding нужен потому,
     что снап меряет от края скроллера, а не от его поля.
     Хвостовое поле по умолчанию зеркальное: в конце ленты последняя карточка
     встаёт ровно под правый край заголовка. На сверхшироком мониторе его
     подменяет --crs-end из landing.js - см. fitTail(). */
  --crs-gut: max(var(--pad), calc((100% - var(--maxw)) / 2));
  padding-inline: var(--crs-gut) var(--crs-end, var(--crs-gut));
  scroll-padding-inline: var(--crs-gut) var(--crs-end, var(--crs-gut));
}
.hl-track::-webkit-scrollbar { display: none; }

.hl-card {
  position: relative;
  flex: 0 0 auto;
  width: var(--hl-card);
  height: var(--hl-h);
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  overflow: hidden;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}

/* Подпись: две строки на десктопе, три - потолок. Кегль привязан к ширине,
   чтобы на узкой карточке фраза не уезжала в медиа-зону.
   24ch на кегле 26px ломали фразу в 63 знака на три строки, и третья строка
   налезала на верхний край кадра. 30ch дают две строки по 30 знаков - и то,
   и другое внутри потолка подписи карточки. */
.hl-cap {
  position: absolute;
  left: 32px; right: 32px; top: 30px;
  z-index: 2;
  font-size: clamp(20px, 1.85vw, 26px);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: var(--tr-card);
  max-width: 30ch;
}
.hl-cap .js-hk { font-family: var(--mono); color: var(--ink); }

/* Медиа-зона карточки: всегда ниже подписи, без затемняющих градиентов */
.hl-media { position: absolute; left: 32px; right: 32px; top: 146px; bottom: 32px; }
/* Кадр рабочего стола занимает медиа-зону целиком и упирается в нижний край
   карточки: экран как бы выезжает из неё. Воздуха вокруг мока не остаётся -
   раньше именно он и делал карточки пустыми. */
.hl-media-desk {
  left: 22px; right: 22px; top: 126px; bottom: 0;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-bottom: none;
}

/* ============================================================================
   8.1 КОНТРОЛЫ КАРУСЕЛЕЙ - общие для highlights и features
   Стрелок нет: мышью тянем ленту, пальцем свайпаем. Остаются точки и плеер.
   ============================================================================ */
.crs-controls { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: clamp(18px, 1.8vw, 24px); }
/* display:flex сильнее атрибута hidden, поэтому гасим явно: на сверхшироком
   экране короткая лента помещается целиком и листать её нечем. */
.crs-controls[hidden], .crs-arrows[hidden] { display: none; }
.crs-dots {
  display: flex; align-items: center; gap: 16px;
  height: 36px; padding: 0 16px;
  background: rgba(255,255,255,.08);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: var(--r-pill);
}
.crs-dot {
  position: relative;
  width: 8px; height: 8px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.4);
  transition: width var(--dur-icon) var(--ease), background var(--dur-icon) var(--ease-io);
}
/* Зона нажатия 24x32 без изменения видимого размера */
.crs-dot::after { content: ""; position: absolute; inset: -14px -8px; }
.crs-dot.is-active { width: 24px; background: #fff; }

/* Плеер: одна кнопка, две иконки, переключаются классом .is-paused */
.crs-play {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,.08);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--ink);
  transition: background 200ms var(--ease-io), transform 120ms var(--ease-io);
}
.crs-play .ic { width: 14px; height: 14px; }
.crs-play .ic-pl-play { display: none; }
.crs-play.is-paused .ic-pl-pause { display: none; }
.crs-play.is-paused .ic-pl-play { display: block; margin-left: 1px; }
.crs-play:active { transform: scale(.94); }

@media (hover: hover) and (pointer: fine) {
  .crs-play:hover { background: rgba(255,255,255,.18); }
  .crs-dot:hover { background: rgba(255,255,255,.72); }
  /* Ленту можно взять мышью */
  .hl-track { cursor: grab; }
  .hl-track.is-dragging { cursor: grabbing; }
}
/* Пока тянем - ни выделения текста, ни родного драга картинок */
.hl-track.is-dragging, .feat-track.is-dragging {
  user-select: none;
  -webkit-user-select: none;
}

/* ============================================================================
   8.2 ОЖИВЛЕНИЕ АКТИВНОЙ КАРТОЧКИ
   Класс .crs-anim ставит JS: без скриптов заголовки видны сразу.
   .is-seen - карточка хоть немного попала в кадр, .is-in - она в центре.
   ============================================================================ */
/* Прозрачность подписи переключается туда-обратно, пока карточку водят рукой,
   поэтому у неё симметричный ease-io: резкий --ease при развороте на полпути
   меняет скорость скачком и читается как щелчок. Подъём проигрывается один
   раз (.is-seen не снимается) - там --ease на месте. */
.crs-anim .hl-cap,
.crs-anim .feat-cap {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 520ms var(--ease-io), transform 600ms var(--ease);
}
.crs-anim .hl-card.is-seen .hl-cap { opacity: .45; transform: translateY(0); }
.crs-anim .hl-card.is-in .hl-cap { opacity: 1; }
/* Подпись возможности живёт под карточкой, на фоне страницы: приглушать её
   у соседей незачем, она проявляется один раз и остаётся читаемой. */
.crs-anim .feat-card.is-seen .feat-cap { opacity: 1; transform: none; }

/* Вторая половина фразы догоняет первую - будто её дописывают */
.crs-anim .hl-cap .dim,
.crs-anim .feat-cap .dim {
  opacity: 0;
  transition: opacity 600ms var(--ease) 120ms;
}
.crs-anim .hl-card.is-seen .hl-cap .dim,
.crs-anim .feat-card.is-seen .feat-cap .dim { opacity: 1; }

/* Кадр внутри карточки оседает: 1.03 -> 1 у активной, .985 у соседей.
   Масштаб ходит в обе стороны (карточка то в центре, то нет), поэтому здесь
   тоже симметричный ease-io: перехват на полпути не даёт рывка. */
.crs-anim .hl-media > * {
  transform: scale(1.03);
  transition: transform 760ms var(--ease-io);
}
.crs-anim .hl-card.is-seen .hl-media > * { transform: scale(.985); }
.crs-anim .hl-card.is-in .hl-media > * { transform: scale(1); }
/* Мок в карточке возможности оседает один раз, без пере-масштабирования соседей */
.crs-anim .feat-mock { transform: scale(1.04); transition: transform 800ms var(--ease); }
.crs-anim .feat-card.is-seen .feat-mock { transform: none; }

/* ============================================================================
   9. СЦЕНА КАРТОЧКИ КАРУСЕЛИ (.hstage)

   Раньше в каждой карточке лежал целый кадр рабочего стола: обои, строка меню,
   иконки, док, окно приложения - и где-то поверх мелкий объект продукта. Всё
   мелкое, ничего не читается, шесть карточек выглядели одинаковой серой кашей.
   Теперь правило одно, то же, что в секции «Возможности»: в кадре ОДИН крупный
   герой, вокруг него тихо. Контекст «поверх окна» остался только там, где он и
   есть смысл карточки (пилюля), и сведён к одной плоской плашке без деталей.

   Масштаб. Кадр меняет размер вместе с экраном, поэтому внутри всё считается в
   em от кегля сцены, а кегль берётся как минимум из ширины и высоты кадра:
   min(1.42cqw, 2.75cqh) - около 11px на 1440 и 13px на 1920. Контейнером
   меряется .hl-media-desk: элемент не может спрашивать собственный размер.
   Все заливки плоские, градиентов на крупных плоскостях нет.
   ============================================================================ */
.hl-media-desk { container-type: size; }

.hstage {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding: 2.2em;
  background: #0a0d14;
  overflow: hidden;
  font-size: min(1.42cqw, 2.75cqh);
  line-height: 1.2;
}
.hstage .ic { flex: none; }

/* --- 9.1 пилюля поверх всего -------------------------------------------------
   Герой - сама пилюля в кегле 2.9em: точка, REC и таймер размером с крупный
   заголовок. Под ней плоская плашка окна: одна полоса заголовка и один
   прямоугольник содержимого, чтобы было видно, ЧТО перекрывает пилюля, и при
   этом нечему было рябить. */
.hs-pill { padding: 0; }
.hsp-win {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: #101825;
}
.hsp-bar {
  display: flex;
  align-items: center;
  gap: .9em;
  flex: none;
  height: 3.6em;
  padding: 0 1.8em;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid rgba(255,255,255,.06);
}
.hsp-bar i {
  display: block;
  width: 1.1em; height: 1.1em;
  border-radius: 50%;
  background: rgba(255,255,255,.14);
}
.hsp-bar b {
  margin-left: 1.4em;
  font-size: 1.3em;
  font-weight: 500;
  color: var(--ink-mute);
}
.hsp-body {
  display: block;
  flex: 1;
  margin: 2.2em;
  border-radius: 1.4em;
  background: #18212f;
}
/* Пилюля висит НАД плашкой: своя тень, размытие фона под собой и светлый
   контур. Именно этот слой и продаёт слово «поверх». */
.hsp-pill {
  position: absolute;
  top: 3.2em; right: 3em;
  z-index: 3;
  font-size: 2.9em;
  background: rgba(7,9,13,.8);
  border-color: rgba(255,255,255,.3);
  backdrop-filter: blur(1.4em) saturate(120%);
  -webkit-backdrop-filter: blur(1.4em) saturate(120%);
  box-shadow: 0 1.6em 3.4em -.7em rgba(0,0,0,.9), 0 .3em 1em rgba(0,0,0,.55);
}
.hsp-note {
  position: absolute;
  left: 3.4em; bottom: 3em;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: .9em;
  padding: .9em 1.5em;
  border-radius: var(--r-pill);
  background: rgba(13,15,20,.78);
  border: 1px solid var(--line);
  font-size: 1.35em;
  color: var(--ink-dim);
}
.hsp-note .ic { width: 1.5em; height: 1.5em; color: var(--accent-soft); }

/* --- 9.2 панель по хоткею ----------------------------------------------------
   Панель целиком в этот кадр влезала только кеглем около 6px - нечитаемо.
   Показываем её главное: четыре плитки управления во всю высоту кадра и
   клавишу хоткея в шапке. Активна «Запись», таймер ведёт JS. */
.hs-panel { gap: 1.6em; }
.hpn-head { display: flex; align-items: center; gap: 1.1em; flex: none; }
.hpn-logo { display: block; width: 2.6em; height: 2.6em; object-fit: contain; }
.hpn-nm { font-size: 1.6em; font-weight: 600; letter-spacing: var(--tr-card); }
.hpn-ok {
  display: inline-flex; align-items: center; gap: .6em;
  font-size: 1.3em;
  color: var(--status);
}
.hpn-ok i { display: block; width: .85em; height: .85em; border-radius: 50%; background: currentColor; }
.hpn-key {
  margin-left: auto;
  padding: .7em 1.2em;
  border-radius: .8em;
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.05);
  font-family: var(--mono);
  font-size: 1.45em;
  font-weight: 500;
  letter-spacing: .03em;
  color: var(--ink);
}
/* Панель в карточке карусели - настоящий мок .cbar, а не самодельные плитки.
   Здесь только масштаб: кегль поднят, чтобы подписи читались в кадре, и снята
   ширина, которую .cbar держит в hero. */
.hpn-bar {
  flex: 1;
  min-height: 0;
  width: 100%;
  font-size: min(1.62cqw, 2.9cqh);
  align-items: stretch;
}
.hpn-bar .cseg { flex: 1; }
.hpn-bar .cb-act { min-height: 0; }
.hpn-foot .ic { width: 1.5em; height: 1.5em; }
.hpn-foot b { margin-left: auto; font-weight: 600; color: var(--ink); }

/* --- 9.3 мгновенный повтор ---------------------------------------------------
   Герой - шкала последних тридцати секунд во всю ширину кадра: подсвеченный
   хвост и есть тот кусок, который уедет в файл. Уровни столбиков ведёт JS
   (.js-replay-track), рисунок волны продублирован в CSS для reduced-motion. */
.hs-replay { gap: 1.6em; }
.hrp-toast {
  display: flex; align-items: center; gap: 1.4em;
  flex: none;
  padding: 1.3em 1.6em;
  border-radius: 1.4em;
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
}
.hrp-ic {
  display: flex; align-items: center; justify-content: center;
  width: 3.6em; height: 3.6em; flex: none;
  border-radius: 1.1em;
  background: rgba(34,197,94,.15);
  color: var(--status);
}
.hrp-ic .ic { width: 2em; height: 2em; }
.hrp-txt { display: flex; flex-direction: column; gap: .35em; min-width: 0; }
.hrp-txt b { font-size: 1.55em; font-weight: 600; }
.hrp-txt > span {
  overflow: hidden;
  font-family: var(--mono);
  font-size: 1.25em;
  color: var(--ink-mute);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.hrp-key {
  margin-left: auto; flex: none;
  padding: .6em 1.3em;
  border-radius: var(--r-pill);
  background: var(--accent-bg);
  font-family: var(--mono);
  font-size: 1.3em;
  color: var(--accent-soft);
}
.hrp-track {
  display: flex;
  align-items: flex-end;
  gap: .4em;
  flex: 1;
  min-height: 0;
  padding: 1.5em;
  border-radius: 1.4em;
  background: var(--bg-deep);
  border: 1px solid var(--line);
}
.hrp-scale {
  display: flex; align-items: center; justify-content: space-between;
  flex: none;
  font-family: var(--mono);
  font-size: 1.25em;
  color: var(--ink-mute);
}
.hrp-scale .now { color: var(--accent-soft); }

/* --- 9.4 библиотека клипов ---------------------------------------------------
   Окно занимает кадр целиком: восемь превью в четыре колонки, у каждого имя
   файла и вес - то, ради чего библиотеку и открывают. Раньше на месте имён
   лежали серые полоски, и окно читалось как заглушка. */
.hs-lib { padding: 0; }
.hlb-top {
  display: flex; align-items: center; gap: 1.2em;
  flex: none;
  padding: 1.1em 1.6em;
  border-bottom: 1px solid var(--line);
  background: rgba(255,255,255,.025);
}
.hlb-dots { display: flex; gap: .7em; flex: none; }
.hlb-dots i { display: block; width: 1em; height: 1em; border-radius: 50%; background: rgba(255,255,255,.14); }
.hlb-ttl { margin-left: .6em; font-size: 1.5em; font-weight: 600; }
.hlb-cnt { font-size: 1.25em; color: var(--ink-mute); }
.hlb-find {
  display: inline-flex; align-items: center; gap: .6em;
  margin-left: auto;
  padding: .6em 1.2em;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--bg-deep);
  font-size: 1.25em;
  color: var(--ink-mute);
}
.hlb-find .ic { width: 1.3em; height: 1.3em; }
.hlb-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-content: space-evenly;
  gap: 1.2em;
  padding: 1.3em;
  flex: 1;
  min-height: 0;
}
.hlb-card { display: block; min-width: 0; }
.hlb-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: 1em;
  border: 1px solid var(--line);
  background: #0e131c;
  overflow: hidden;
}
.hlb-card:nth-child(4n+2) .hlb-thumb { background: #101a22; }
.hlb-card:nth-child(4n+3) .hlb-thumb { background: #14141f; }
.hlb-card:nth-child(4n+4) .hlb-thumb { background: #0c1620; }
/* Треугольник плеера на бордерах: без лишнего SVG в разметке */
.hlb-play {
  position: absolute; left: 50%; top: 50%;
  width: 0; height: 0;
  margin: -.9em 0 0 -.6em;
  border-style: solid;
  border-width: .9em 0 .9em 1.4em;
  border-color: transparent transparent transparent rgba(255,255,255,.3);
}
.hlb-dur {
  position: absolute; right: .7em; bottom: .7em;
  padding: .25em .6em;
  border-radius: .6em;
  background: rgba(5,6,9,.85);
  font-family: var(--mono);
  font-size: 1.25em;
  font-weight: 500;
  color: var(--ink-dim);
}
.hlb-nm {
  display: block;
  margin-top: .6em;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 1.2em;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.hlb-meta { display: block; margin-top: .25em; font-size: 1.2em; color: var(--ink-mute); }
/* Низкий кадр (узкий ноутбук, планшет): вес клипа убираем, иначе второй ряд
   превью упирается в нижний край карточки. Запрос идёт к самому кадру. */
@container (max-height: 380px) {
  .hlb-meta { display: none; }
}
.hlb-card.is-on .hlb-thumb { border-color: rgba(59,130,246,.55); box-shadow: 0 0 0 .2em rgba(59,130,246,.2); }
.hlb-card.is-on .hlb-play { border-left-color: var(--accent-soft); }
.hlb-card.is-on .hlb-nm { color: var(--accent-soft); }

/* --- 9.5 сжатие видео --------------------------------------------------------
   Герой - две цифры и две полосы: было и стало. Список пресетов живёт в секции
   «Возможности», сюда он намеренно не продублирован. */
.hs-cmp { justify-content: center; gap: 1.5em; }
.hcm-file {
  display: flex; align-items: center; gap: .8em;
  font-family: var(--mono);
  font-size: 1.3em;
  color: var(--ink-mute);
}
.hcm-file .ic { width: 1.5em; height: 1.5em; }
.hcm-rows { display: flex; flex-direction: column; gap: 3em; }
.hcm-line { display: flex; align-items: baseline; justify-content: space-between; gap: 1.4em; }
.hcm-k { font-size: 1.5em; color: var(--ink-dim); }
.hcm-v { font-family: var(--mono); font-size: 4.9em; font-weight: 700; line-height: 1; letter-spacing: var(--tr-snug); }
.hcm-bar {
  display: block;
  height: 2.7em;
  margin-top: 1.1em;
  border-radius: 1.2em;
  background: rgba(255,255,255,.06);
  overflow: hidden;
}
.hcm-fill { display: block; height: 100%; border-radius: 1.2em; }
.hcm-fill-src { width: 100%; background: var(--accent); }
.hcm-fill-out { width: 23%; background: var(--status); }
.hcm-row.is-done .hcm-v { color: var(--status); }
.hcm-note {
  display: flex; align-items: baseline; gap: 1em;
  font-size: 1.35em;
  color: var(--ink-mute);
}
.hcm-note b { font-weight: 600; color: var(--status); }

/* --- 9.6 отправка в Telegram -------------------------------------------------
   Карточка отправки со стороны приложения: превью клипа, вес, выбранный чат и
   кнопка. В «Возможностях» тот же сюжет показан со стороны чата, поэтому два
   визуала не повторяют друг друга. */
.hs-send { justify-content: center; gap: 1.8em; }
.hsn-card {
  display: flex;
  gap: 2em;
  padding: 2.2em;
  border-radius: 1.8em;
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  box-shadow: 0 2.4em 6em -3em rgba(0,0,0,.85);
}
.hsn-thumb {
  position: relative;
  display: block;
  width: 29em; flex: none;
  aspect-ratio: 16 / 9;
  border-radius: 1.2em;
  border: 1px solid var(--line);
  background: #101a22;
  overflow: hidden;
}
.hsn-play {
  position: absolute; left: 50%; top: 50%;
  width: 0; height: 0;
  margin: -1.1em 0 0 -.75em;
  border-style: solid;
  border-width: 1.1em 0 1.1em 1.7em;
  border-color: transparent transparent transparent rgba(255,255,255,.32);
}
.hsn-dur {
  position: absolute; right: .8em; bottom: .8em;
  padding: .3em .7em;
  border-radius: .6em;
  background: rgba(5,6,9,.85);
  font-family: var(--mono);
  font-size: 1.2em;
  font-weight: 500;
  color: var(--ink-dim);
}
.hsn-body { display: flex; flex-direction: column; gap: .7em; flex: 1; min-width: 0; }
.hsn-nm {
  overflow: hidden;
  font-family: var(--mono);
  font-size: 1.7em;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.hsn-meta { font-size: 1.3em; color: var(--ink-mute); }
.hsn-to {
  display: flex; align-items: center; gap: .9em;
  margin-top: auto;
  padding: .9em 1.2em;
  border-radius: 1.2em;
  border: 1px solid rgba(59,130,246,.4);
  background: var(--accent-bg);
  font-size: 1.4em;
  color: var(--ink);
}
.hsn-av {
  display: flex; align-items: center; justify-content: center;
  width: 2.2em; height: 2.2em; flex: none;
  border-radius: 50%;
  background: rgba(110,168,254,.28);
  color: #dce9ff;
}
.hsn-av .ic { width: 1.3em; height: 1.3em; }
.hsn-ck {
  display: flex; align-items: center; justify-content: center;
  width: 1.9em; height: 1.9em; flex: none;
  margin-left: auto;
  border-radius: 50%;
  background: rgba(59,130,246,.38);
  color: #dce9ff;
}
.hsn-ck .ic { width: 1.1em; height: 1.1em; }
.hsn-btn {
  padding: 1em 0;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: #fff;
  font-size: 1.45em;
  font-weight: 600;
  text-align: center;
}
.hsn-done {
  display: flex; align-items: center; gap: .9em;
  font-size: 1.35em;
  color: var(--status);
}
.hsn-done .ic { width: 1.6em; height: 1.6em; }
/* ============================================================================
   10. МОК СЖАТИЯ
   ============================================================================ */
.cmpr { width: 100%; max-width: 300px; }
.cmpr-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.cmpr-k { font-size: 13px; color: var(--ink-dim); }
.cmpr-v { font-family: var(--mono); font-size: 15px; font-weight: 600; color: var(--ink); }
.cmpr-row-done .cmpr-v { color: var(--status); }
.cmpr-bar {
  height: 8px;
  margin: 9px 0 20px;
  border-radius: 6px;
  background: rgba(255,255,255,.06);
  overflow: hidden;
}
.cmpr-bar-done { margin-bottom: 0; }
.cmpr-fill { display: block; height: 100%; border-radius: 6px; }
.cmpr-fill-src { width: 100%; background: var(--accent); }
.cmpr-fill-out { width: 23%; background: var(--status); }
.cmpr-note { margin-top: 20px; font-family: var(--mono); font-size: 12px; color: var(--ink-mute); }

.cmpr-big { max-width: 380px; }
.cmpr-big .cmpr-k { font-size: 15px; }
.cmpr-big .cmpr-v { font-size: 19px; }
.cmpr-big .cmpr-bar { height: 10px; }

/* ============================================================================
   11. МОК РЕПЛЕЯ
   ============================================================================ */
.replayviz { width: 100%; max-width: 460px; }
.replay-track {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 108px;
  padding: 14px;
  border-radius: var(--r-md);
  background: var(--bg-deep);
  border: 1px solid var(--line);
}
/* Столбик - слот во всю высоту трека с обрезкой, сама полоска лежит на ::after
   и съезжает вниз трансформом: видно ровно --h снизу. Раньше JS гонял height,
   и каждый кадр перестраивал флекс-строку из четырёх десятков столбиков.
   Скругление при этом не плющится: полоска не масштабируется, а едет. */
.replay-bar {
  --h: 34%;
  --c: rgba(255,255,255,.1);
  position: relative;
  flex: 1;
  height: 100%;
  border-radius: 2px;
  overflow: hidden;
}
.replay-bar::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: 2px;
  background: var(--c);
  transform: translateY(calc(100% - var(--h)));
  transition: transform var(--dur-icon) var(--ease-io), background var(--dur-icon) var(--ease-io);
}
/* Рисунок волны, чтобы трек читался и без JS */
.replay-bar:nth-child(7n+1) { --h: 46%; }
.replay-bar:nth-child(7n+2) { --h: 72%; }
.replay-bar:nth-child(7n+3) { --h: 30%; }
.replay-bar:nth-child(7n+4) { --h: 88%; }
.replay-bar:nth-child(7n+5) { --h: 54%; }
.replay-bar:nth-child(7n+6) { --h: 38%; }
.replay-bar:nth-child(7n+7) { --h: 66%; }
.replay-bar.hot { --c: var(--accent); }

/* ============================================================================
   13. ALWAYS ON TOP - один крупный кадр
   ============================================================================ */
.aot { padding-block: var(--section-y); }
.aot-figure { display: block; }
.aot-frame {
  position: relative;
  /* Ни aspect-ratio, ни min-height: кадр ровно по контенту плюс воздух.
     С 16:9 половина рамки пустовала - та самая низкая заполненность. */
  background: #0b0e13;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 40px 120px -34px rgba(0,0,0,.85);
}
.aot-caption { max-width: 66ch; margin: 20px auto 0; text-align: center; }
/* ---- Пилюля в трёх состояниях, крупным планом ----
   Каскад окон отсюда убран: три полупустых прямоугольника выглядели бедно, а
   пилюля в углу терялась. Секция называется «Всегда поверх» и рассказывает про
   пилюлю - значит и показываем её саму, в натуральную величину, чтобы было
   видно шрифт, точку записи и таймер. Средняя крупнее боковых: это состояние,
   ради которого продукт и ставят. */
.aos {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  container-type: inline-size;
  padding: clamp(36px, 4.4cqw, 56px) 4%;
  width: 100%;
}
.aos-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(24px, 5cqw, 72px);
  width: 100%;
}
.aos-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(14px, 2.2cqw, 26px);
  flex: 0 1 auto;
  min-width: 0;
}
/* Боковые состояния приглушены, центральное - герой кадра */
.aos-item .aos-p { font-size: clamp(11px, 1.85cqw, 21px); opacity: .72; }
.aos-item-main .aos-p { font-size: clamp(16px, 3.2cqw, 38px); opacity: 1; }
.aos-p {
  filter: drop-shadow(0 .5em 1.2em rgba(0,0,0,.7));
  transform: translateZ(0);
}
.aos-cap {
  margin: 0;
  max-width: 22ch;
  text-align: center;
  font-size: clamp(13px, 1.35cqw, 17px);
  line-height: 1.5;
  color: var(--ink-mute);
}
.aos-cap b { display: block; font-weight: 600; color: var(--ink); font-size: 1.12em; margin-bottom: .34em; }
/* Эфир: тот же корпус, другой акцент - как в приложении */
.aos-p-air .dot { background: var(--stream); box-shadow: 0 0 .5em var(--stream); }
.aos-p-air .lbl { color: var(--stream); }

@container (max-width: 560px) {
  .aos-row { flex-direction: column; gap: clamp(18px, 5cqw, 30px); }
  .aos-item .aos-p, .aos-item-main .aos-p { font-size: clamp(12px, 4.2cqw, 20px); }
  .aos-cap { max-width: 26ch; }
}
.aot-caption { max-width: 66ch; margin: 20px auto 0; text-align: center; }

/* ============================================================================
   14. CLOSER LOOK - список слева, стейдж с подсветкой зоны справа
   ============================================================================ */
.closer { padding-block: var(--section-y); }
/* Колонки чуть смещены в пользу стейджа против дизайн-системы (5/7 при gap 64):
   панель - широкий бар, и каждый лишний процент ширины стейджа делает подписи
   на плитках читаемыми. Список из шести пунктов в 380px помещается свободно. */
.closer-grid {
  display: grid;
  grid-template-columns: minmax(340px, 4fr) minmax(0, 8fr);
  gap: 56px;
  align-items: start;
}

.closer-list { min-width: 0; }
.closer-item { position: relative; border-top: 1px solid var(--line); }
.closer-item:last-child { border-bottom: 1px solid var(--line); }

.closer-h { font: inherit; font-weight: inherit; }
.closer-head {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  width: 100%;
  min-height: 64px;
  padding: 20px 0;
  text-align: left;
}
.closer-title {
  font-size: var(--t-tile-h);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: var(--tr-card);
  color: var(--ink-dim);
  transition: color var(--dur-icon) var(--ease-io);
}
.closer-item.is-active .closer-title { color: var(--ink); }
/* В гиде активный пункт держит на себе внимание: не только цвет, но и вес.
   Строка выровнена по левому краю, поэтому смена веса не двигает соседей. */
.closer-item.is-active .closer-title { font-weight: 700; }

/* Плюс -> крестик */
.closer-plus, .faq-plus {
  position: relative;
  width: 20px; height: 20px; flex: none;
  color: var(--ink-dim);
  transition: transform var(--dur-icon) var(--ease), color var(--dur-icon) var(--ease-io);
}
.closer-plus::before, .closer-plus::after,
.faq-plus::before, .faq-plus::after {
  content: ""; position: absolute; background: currentColor; border-radius: 2px;
}
.closer-plus::before, .faq-plus::before { left: 0; right: 0; top: 9px; height: 2px; }
.closer-plus::after,  .faq-plus::after  { top: 0; bottom: 0; left: 9px; width: 2px; }
.closer-item.is-active .closer-plus { transform: rotate(45deg); color: var(--ink); }

/* Раскрытие через grid-template-rows, не max-height */
.closer-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-switch) var(--ease);
}
.closer-item.is-active .closer-body { grid-template-rows: 1fr; }
.closer-body-in { overflow: hidden; min-height: 0; }
.closer-text {
  padding-bottom: 24px;
  font-size: var(--t-body-l);
  line-height: 1.38;
  color: var(--ink-dim);
  opacity: 0;
  transition: opacity var(--dur-icon) var(--ease-io);
}
.closer-item.is-active .closer-text { opacity: 1; transition-delay: 100ms; }

/* Текст гида появляется вместе с наездом камеры: подъём на 10px и задержка
   120ms, чтобы движение панели началось первым, а подпись догнала его. */
.closer-text {
  transform: translateY(10px);
  transition: opacity 500ms var(--ease-io), transform 500ms var(--ease);
}
.closer-item.is-active .closer-text {
  opacity: 1;
  transform: none;
  transition-delay: 120ms;
}
/* Продолжение фразы приглушено и проступает на 90ms позже - тот же приём,
   что в каруселях highlights и features. */
.closer-text .dim {
  opacity: 0;
  transition: opacity 500ms var(--ease-io);
}
.closer-item.is-active .closer-text .dim { opacity: 1; transition-delay: 210ms; }

/* Полоска автоцикла. JS может остановить цикл, повесив .is-paused на список. */
.closer-progress {
  position: absolute;
  left: 0; top: -1px;
  width: 100%; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
}
.closer-item.is-active .closer-progress { animation: closerProgress 6s linear 1; }
.closer-list.is-paused .closer-progress { animation: none; }
@keyframes closerProgress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Стейдж */
.closer-stage { position: sticky; top: 96px; min-width: 0; }
.closer-stage-in {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}
/* Панель занимает 95.7% ширины стейджа - на этом держатся проценты .spot */
.closer-stage-in .cbar { font-size: 0.769cqw; }
/* Поля стейджа по бокам панели - всего ~2.2% ширины (16px при стейдже 761px),
   а базовое свечение .cbar-wrap размыто на 26px и 40px, поэтому overflow:hidden
   срезал его вертикальной линией. Внутри стейджа держим тень короче полей. */
.closer-stage-in .cbar-wrap {
  filter: drop-shadow(0 0 8px rgba(59,130,246,.16));
}

/* Прямоугольная подсветка зоны. Работает только там, где камера выключена:
   при наезде панель уезжает под трансформом, а .spot позиционируется в
   процентах от стейджа и указал бы мимо. Её роль - статичный указатель для
   prefers-reduced-motion и для узких экранов. */
.spot {
  position: absolute;
  left: 50%; top: 37%;
  width: 9%; height: 26%;
  border: 2px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: 0 0 0 6px rgba(59,130,246,.18), inset 0 0 0 1px rgba(59,130,246,.6);
  pointer-events: none;
  z-index: 3;
  transition: left 450ms var(--ease), top 450ms var(--ease),
              width 450ms var(--ease), height 450ms var(--ease),
              opacity 240ms var(--ease-io);
}
/* .is-cam ставит JS на время наезда: указатель уступает место камере */
.closer-stage-in.is-cam .spot { opacity: 0; }

/* Каллаут - две пилюли в одной ячейке грида. Сама обёртка невидима, фон и
   рамка живут на слоях, поэтому каждая подпись имеет свою ширину, а смена
   идёт кросс-фейдом: старая опадает, новая всплывает с перекрытием. */
.closer-callout {
  position: absolute;
  left: 50%; bottom: 8%;
  transform: translateX(-50%);
  z-index: 4;
  display: grid;
  justify-items: center;
  pointer-events: none;
}
.cal-l {
  grid-area: 1 / 1;
  padding: 7px 12px;
  border-radius: 9px;
  background: rgba(8,9,12,.85);
  border: 1px solid var(--line-strong);
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(7px);
  transition: opacity 190ms var(--ease-io), transform 190ms var(--ease);
}
.cal-l.is-on {
  opacity: 1;
  transform: none;
  transition: opacity 300ms var(--ease-io) 120ms, transform 460ms var(--ease) 120ms;
}

/* ============================================================================
   14.1 ИНТЕРАКТИВНЫЙ ГИД ПО ПАНЕЛИ
   Всё ниже висит на .is-guide - классе панели внутри closer-стейджа. Панель в
   hero (.js-cbar-live) этого класса не имеет и остаётся нетронутой.

   Камера: единственное, что анимируется у самой панели, - transform. Смещение
   и масштаб считает JS по реальным координатам карточек, здесь только переход.
   Переключение зоны идёт от текущего transform к следующему, поэтому панель
   едет напрямую, без возврата в исходное.
   ============================================================================ */
.is-guide {
  transform: translate3d(0px, 0px, 0) scale(1);
  transform-origin: 50% 50%;
  transition: transform 820ms var(--ease);
}
/* will-change поднимаем только на время наезда - JS снимает его по transitionend,
   иначе слой остаётся растрирован под старый масштаб и текст мылит. */
.is-guide.is-moving { will-change: transform; }

/* --- фокус на активной зоне --- */
.is-guide .cb-id,
.is-guide .cb-audio,
.is-guide .cb-act,
.is-guide .cb-lib,
.is-guide .cb-mini {
  position: relative;
  transition: opacity 400ms var(--ease-io), filter 400ms var(--ease-io);
}
.is-guide .cb-id .scene { position: relative; }

/* Неактивные карточки уходят в фон: тише и бледнее, но не исчезают - контекст
   панели должен читаться. */
.is-guide .is-dim { opacity: .34; filter: saturate(.45); }

/* Свечение повторяет форму карточки, а не пятно в фоне. Живёт на ::after,
   чтобы анимировалась только прозрачность: box-shadow не переходит. */
.is-guide .cb-id::after,
.is-guide .cb-audio::after,
.is-guide .cb-act::after,
.is-guide .cb-lib::after,
.is-guide .scene::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  box-shadow:
    0 0 0 .2em var(--accent),
    0 0 0 .85em rgba(59,130,246,.14),
    0 1.1em 2.8em -.5em rgba(59,130,246,.45);
  opacity: 0;
  transition: opacity 400ms var(--ease-io);
  pointer-events: none;
}
/* Кольцо зажигается только там, где работает камера. Без наезда (reduced-motion,
   узкие экраны, секция вне кадра) на зону показывает одна .spot - две рамки
   поверх одной карточки читались бы как шум. */
.is-cam .is-guide .is-focus::after { opacity: 1; }

/* --- зона «Запись»: точка пульсирует, таймер ведёт JS --- */
.is-guide .cb-pulse {
  position: absolute;
  top: 1.1em; right: 1.1em;
  width: 1.05em; height: 1.05em;
  border-radius: 50%;
  background: var(--rec);
  opacity: 0;
  transition: opacity 300ms var(--ease-io);
}
.is-guide .cb-pulse::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: .17em solid var(--rec);
  opacity: 0;
}
.is-guide.z-rec .cb-pulse { opacity: 1; animation: gDot 1.5s var(--ease-io) infinite; }
.is-guide.z-rec .cb-pulse::after { animation: gRing 1.5s var(--ease-io) infinite; }
@keyframes gDot { 0%, 100% { transform: scale(1); } 50% { transform: scale(.74); } }
@keyframes gRing { 0% { transform: scale(1); opacity: .7; } 100% { transform: scale(2.9); opacity: 0; } }

.is-guide.z-rec .cb-act[data-act="rec"] .sub { color: var(--rec); }

/* --- зона «Мгновенный повтор»: стрелка буфера крутится, окно последних
   30 секунд едет по треку --- */
.is-guide.z-replay .cb-act[data-act="buffer"] .ic { animation: gSpin 3.2s linear infinite; }
@keyframes gSpin { to { transform: rotate(360deg); } }

/* Стрелка «Сохранить» подсказывает, что клип уходит на диск одной кнопкой */
.is-guide.z-replay .cb-act[data-act="save"] .ic { animation: gBob 1.6s var(--ease-io) infinite; }
@keyframes gBob {
  0%, 100% { transform: translateY(0); }
  55%      { transform: translateY(.28em); }
}

.is-guide .cb-buf {
  position: absolute;
  left: 1.2em; right: 1.2em; bottom: 1.15em;
  height: .5em;
  border-radius: .25em;
  background: rgba(255,255,255,.09);
  overflow: hidden;
  opacity: 0;
  transition: opacity 300ms var(--ease-io);
}
.is-guide .cb-buf i {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 42%;
  border-radius: inherit;
  background: var(--status);
  transform: translateX(20%);
}
.is-guide.z-replay .cb-buf { opacity: 1; }
.is-guide.z-replay .cb-buf i { animation: gBuf 3.2s linear infinite; }
@keyframes gBuf { from { transform: translateX(-112%); } to { transform: translateX(250%); } }

/* --- зона «Стрим»: от иконки расходятся волны --- */
.is-guide .cb-waves {
  position: absolute;
  left: 50%; top: 51%;
  width: 3.4em; height: 3.4em;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity 300ms var(--ease-io);
  pointer-events: none;
}
.is-guide .cb-waves i {
  position: absolute;
  inset: 0;
  border: .2em solid var(--stream);
  border-radius: 50%;
  opacity: 0;
}
.is-guide.z-stream .cb-waves { opacity: 1; }
/* Три кольца через равные трети цикла: эфир идёт непрерывно, а не толчками */
.is-guide.z-stream .cb-waves i { animation: gWave 2.4s var(--ease-io) infinite; }
.is-guide.z-stream .cb-waves i:nth-child(2) { animation-delay: .8s; }
.is-guide.z-stream .cb-waves i:nth-child(3) { animation-delay: 1.6s; }
@keyframes gWave {
  0%   { transform: scale(.5); opacity: .8; }
  70%  { opacity: .14; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* --- зона «Аудио»: столбики ведёт JS, иконки метров подхватывают акцент --- */
.is-guide .cb-meter > .ic { transition: color 400ms var(--ease-io); }
.is-guide.z-audio .cb-meter > .ic { color: var(--accent-soft); }

/* --- зона «Сцены»: приоткрывается тот же .scene-pop, что живёт в hero.
   Список абсолютный, поэтому раскрытие не двигает раскладку панели и не сбивает
   геометрию, по которой посчитан наезд. В гиде он никогда не hidden - состояние
   ведёт только класс зоны, JS сюда не лезет. --- */
.is-guide .scene-pop {
  opacity: 0;
  transform: translateY(.7em) scale(.97);
  transform-origin: 50% 100%;
  transition: opacity 300ms var(--ease-io), transform 420ms var(--ease);
  pointer-events: none;
}
.is-guide.z-scene .scene-pop { opacity: 1; transform: none; }
.is-guide.z-scene .scene-opt.is-on { animation: gPick 1.9s var(--ease-io) infinite; }
@keyframes gPick {
  0%, 100% { background-color: rgba(59,130,246,.16); }
  50%      { background-color: rgba(59,130,246,.34); }
}

/* Сама строка сцены на своей зоне подсвечивается акцентом, шеврон разворачивается */
.is-guide .cb-id .scene {
  transition: border-color 400ms var(--ease-io), background-color 400ms var(--ease-io),
              color 400ms var(--ease-io);
}
.is-guide.z-scene .cb-id .scene {
  border-color: rgba(110,168,254,.75);
  background-color: rgba(59,130,246,.14);
  color: var(--ink);
}
.is-guide.z-scene .cb-id .scene .chev { transform: rotate(180deg); color: var(--ink); }

/* --- зона «Библиотека»: счётчик тикает вверх и обратно --- */
.is-guide .cb-lib .cnt .n { transition: color 400ms var(--ease-io); }
.is-guide.z-library .cb-lib .cnt .n { color: var(--accent-soft); }
.is-guide .cb-lib .cnt .n.is-pop { animation: gPop 420ms var(--ease); }
@keyframes gPop {
  0%   { transform: scale(1); }
  42%  { transform: scale(1.17); }
  100% { transform: scale(1); }
}

/* ============================================================================
   14.5 БИБЛИОТЕКА - отдельная секция: окно приложения + своя карусель

   Окно нарисовано на CSS по src/renderer/library/App.tsx: размеры, отступы и
   кегли взяты из его CSS-константы (сайдбар 210px, карточка radius 13/border
   1.5px, сетка auto-fill minmax(200px), имя 13px/600, подписи 11-12px).
   Палитра приложения живёт в локальных переменных --a-*, чтобы мок не поплыл
   от токенов сайта и читался как настоящее окно.
   Градиентов нет ни одного: диагональная фактура превью - это три плоские
   линии .lw-ln, а не repeating-gradient.
   ============================================================================ */
.lbr {
  padding-block: var(--section-y);
  --a-bg:    #1a1b1e;
  --a-panel: #23252b;
  --a-hover: #2a2d35;
  --a-line:  #2e3039;
  --a-ink:   #e0e1e6;
  --a-dim:   #8b8f9b;
  --a-mute:  #6d7280;
  --a-sel:   #3a5bc7;
  --a-star:  #f5c518;
  --a-live:  #7c3aed;
}
.lbr .sec-head .eyebrow .badge { margin-left: 8px; vertical-align: 2px; }
.lbr-cap { max-width: 64ch; margin: 20px auto 0; text-align: center; }

/* --- окно ------------------------------------------------------------------ */
.lw {
  border-radius: 16px;
  border: 1px solid var(--line-strong);
  background: var(--a-bg);
  overflow: hidden;
  /* шрифт системный: в приложении интерфейс рисуется им же */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: var(--a-ink);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 40px 120px -34px rgba(0,0,0,.85);
}

/* Рамка окна: точки слева, заголовок по центру - как в реальном окне на macOS */
.lw-bar {
  position: relative;
  display: flex; align-items: center;
  height: 38px; padding: 0 14px;
  background: #17181b;
  border-bottom: 1px solid var(--a-line);
}
.lw-dots { display: flex; gap: 7px; }
.lw-dots i { width: 11px; height: 11px; border-radius: 50%; background: #3a3d45; }
.lw-wt {
  position: absolute; left: 0; right: 0;
  text-align: center;
  font-size: 12.5px; font-weight: 500; color: var(--a-dim);
  pointer-events: none;
}

/* Топбар приложения - одна строка на всю ширину (в коде это .topbar) */
.lw-top {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--a-line);
}
.lw-ttl { font-size: 14px; font-weight: 700; }
.lw-cnt {
  padding: 2px 8px; border-radius: 10px;
  background: var(--a-panel); color: var(--a-dim);
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.lw-dir { font-size: 11px; color: var(--a-dim); white-space: nowrap; }
.lw-sp { flex: 1; }
.lw-search {
  display: flex; align-items: center; gap: 7px;
  height: 32px; width: 230px; flex: none;
  padding: 0 12px; border-radius: 11px;
  border: 1px solid var(--a-line); background: var(--a-panel);
  font-size: 13px; color: var(--a-mute);
  white-space: nowrap; overflow: hidden;
}
.lw-search .ic { width: 14px; height: 14px; color: var(--a-dim); }
.lw-lbl { font-size: 12px; color: var(--a-dim); white-space: nowrap; }
.lw-sel {
  display: flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 8px; border-radius: 9px;
  border: 1px solid var(--a-line); background: var(--a-panel);
  font-size: 13px; white-space: nowrap;
}
.lw-chev { width: 12px; height: 12px; color: var(--a-dim); }
.lw-ico {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: none;
  border: 1px solid var(--a-line); border-radius: 9px;
  background: var(--a-panel); color: var(--a-dim);
}
.lw-ico .ic { width: 16px; height: 16px; }

.lw-body { display: grid; grid-template-columns: 210px minmax(0, 1fr) 264px; }

/* --- сайдбар с разделами --------------------------------------------------- */
.lw-side {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px;
  border-right: 1px solid var(--a-line);
}
.lw-it {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 7px 10px;
  border-radius: 9px;
  font-size: 13px; color: var(--a-ink); text-align: left;
  transition: background var(--dur-hover) var(--ease-io), color var(--dur-hover) var(--ease-io);
}
.lw-it .ic { width: 15px; height: 15px; color: var(--a-dim); }
.lw-it-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-n { font-size: 12px; color: var(--a-dim); font-variant-numeric: tabular-nums; }
.lw-st { color: var(--a-star); font-size: 13px; line-height: 1; width: 15px; text-align: center; }
.lw-hash { color: var(--a-dim); font-size: 13px; width: 15px; text-align: center; }
.lw-it.is-on { background: var(--a-sel); color: #fff; }
.lw-it.is-on .ic,
.lw-it.is-on .lw-n,
.lw-it.is-on .lw-st,
.lw-it.is-on .lw-hash { color: #dbe2ff; }
.lw-sh {
  margin: 12px 0 4px; padding: 0 10px;
  font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  color: var(--a-dim);
}
@media (hover: hover) and (pointer: fine) {
  .lw-it:hover { background: var(--a-hover); }
  .lw-it.is-on:hover { background: var(--a-sel); }
}

/* --- сетка карточек -------------------------------------------------------- */
.lw-main { padding: 16px; min-width: 0; }
.lw-group + .lw-group { margin-top: 20px; }
.lw-group.is-off { display: none; }
.lw-gh { margin-bottom: 10px; font-size: 13px; font-weight: 700; }
.lw-gn { margin-left: 8px; font-size: 12px; font-weight: 500; color: var(--a-dim); }
.lw-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
  align-content: start;
}
.lw-empty { padding: 48px 0; text-align: center; font-size: 13px; color: var(--a-dim); }

.lw-card {
  position: relative;
  display: flex; flex-direction: column;
  padding: 0; text-align: left;
  background: var(--a-panel);
  border: 1.5px solid var(--a-line);
  border-radius: 13px;
  transition: border-color var(--dur-hover) var(--ease-io),
              transform var(--dur-hover) var(--ease),
              box-shadow var(--dur-hover) var(--ease-io);
}
.lw-card.is-off { display: none; }
@media (hover: hover) and (pointer: fine) {
  .lw-card:hover { border-color: #46557f; }
}
.lw-card.is-sel {
  border-color: var(--a-sel);
  transform: translateY(-3px);
  box-shadow: 0 0 0 1px var(--a-sel), 0 14px 30px -14px rgba(0,0,0,.85);
}

/* Превью: плоская подложка + три диагональные линии фактуры + подпись источника.
   Никаких градиентов - только плоские заливки. */
.lw-th {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: 11px 11px 0 0;
  overflow: hidden;
  background: #171a24;
}
.lw-th-game { background: #171a24; }
.lw-th-web  { background: #1b1722; }
.lw-th-desk { background: #131a1c; }
.lw-ln {
  position: absolute; left: -50%; width: 200%; height: 1px;
  background: rgba(255,255,255,.035);
  transform: rotate(-30deg);
  top: 26%;
}
.lw-ln-2 { top: 52%; }
.lw-ln-3 { top: 78%; }
.lw-th-t {
  position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%);
  text-align: center;
  font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .22em;
  color: rgba(255,255,255,.17);
}
.lw-bdg {
  position: absolute; top: 8px; left: 8px;
  padding: 2px 6px; border-radius: 6px;
  background: var(--a-live); color: #fff;
  font-size: 9px; font-weight: 700; letter-spacing: .04em;
}
.lw-fav {
  position: absolute; top: 6px; right: 6px;
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 7px;
  background: rgba(0,0,0,.55); color: var(--a-star);
  font-size: 12px; line-height: 1;
}
/* hidden на этих двух должен победить свой display - иначе JS не спрячет */
.lw-bdg[hidden], .lw-fav[hidden] { display: none; }
.lw-dur {
  position: absolute; right: 6px; bottom: 6px;
  padding: 1px 6px; border-radius: 6px;
  background: rgba(0,0,0,.75); color: #fff;
  font-family: var(--mono); font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.lw-meta { display: flex; flex-direction: column; gap: 5px; padding: 9px 10px 10px; min-width: 0; }
.lw-nm { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-sub { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 11.5px; color: var(--a-dim); min-width: 0; }
.lw-src { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-src .ic { width: 11px; height: 11px; flex: none; }
.lw-sz { flex: none; font-variant-numeric: tabular-nums; }
.lw-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 18px; }
.lw-dt { font-family: var(--mono); font-size: 10.5px; color: var(--a-mute); white-space: nowrap; }
.lw-tg {
  padding: 1px 7px; border-radius: 10px;
  background: var(--a-hover); color: #c7ccd6;
  font-size: 10.5px; white-space: nowrap;
}

/* --- панель деталей (демо: состояние держит landing.js) --------------------- */
.lw-det { padding: 14px 16px 16px; border-left: 1px solid var(--a-line); min-width: 0; }
.lw-dh { font-size: 11px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--a-dim); }
.lw-de[hidden], .lw-di[hidden] { display: none; }
.lw-de { display: flex; flex-direction: column; gap: 7px; padding-top: 34px; color: var(--a-dim); }
.lw-de .ic { width: 22px; height: 22px; color: var(--a-line); }
.lw-de b { margin-top: 3px; font-size: 13px; font-weight: 600; color: var(--a-ink); }
.lw-de span { font-size: 11.5px; line-height: 1.45; }
.lw-di { margin-top: 12px; animation: lwDet 420ms var(--ease) backwards; }
.lw-di .lw-th { border-radius: 10px; }
.lw-dn { margin-top: 11px; font-size: 12.5px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.lw-dl { display: grid; gap: 7px; margin-top: 12px; }
.lw-dl > div { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.lw-dl dt { font-size: 11.5px; color: var(--a-dim); }
.lw-dl dd { font-size: 11.5px; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lw-dtags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 12px; }
.lw-dtags:empty { display: none; }
.lw-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.lw-act {
  display: inline-flex; align-items: center; gap: 5px;
  height: 28px; padding: 0 10px; border-radius: 8px;
  border: 1px solid var(--a-line); background: var(--a-panel);
  font-size: 11.5px; color: var(--a-ink);
}
.lw-act .ic { width: 12px; height: 12px; }
.lw-act-go { background: var(--a-sel); border-color: var(--a-sel); color: #fff; }

@keyframes lwDet { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes lwIn  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* Пересборка сетки после смены раздела: карточки проявляются волной слева направо */
.lw-main.is-fresh .lw-card:not(.is-sel) {
  animation: lwIn 320ms var(--ease) backwards;
  animation-delay: calc(var(--k, 0) * 45ms);
}

/* ============================================================================
   14.55 ПОЯВЛЕНИЕ ОКНА БИБЛИОТЕКИ

   Витрина секции: окно выезжает снизу, потом по очереди оживают его части.
   Сценарий (задержки от первого кадра постановки):
     0      окно целиком: подъём на 48px + проявление, 900 мс
     380    сайдбар разделов слева
     560    строка поиска сверху
     720    заголовки групп
     760    карточки записей волной слева направо, шаг 55 мс (6 штук, до 1035)
     1150   панель деталей справа - последней
     ~1710  сценарий закончен
   JS ставит только два класса: .is-armed (разметка готова, части спрятаны) и
   .is-cast (постановка играет). После окончания оба снимаются - на элементах
   не остаётся ни анимационных стилей, ни will-change, и окно живёт обычной
   жизнью: hover, выбор записи, фильтры разделов.
   Анимируются только opacity и transform, ни одного свойства раскладки.
   ---------------------------------------------------------------------------- */
@keyframes lwWin   { from { opacity: 0; transform: translateY(48px) scale(.985); } }
@keyframes lwSide  { from { opacity: 0; transform: translateX(-16px); } }
/* Строка поиска встаёт снизу, а не сверху: уезжая вверх, она на пару кадров
   легла бы поверх тёмной шапки окна. Снизу под ней только пустые 8px отступа. */
@keyframes lwTop   { from { opacity: 0; transform: translateY(6px); } }
@keyframes lwHead  { from { opacity: 0; transform: translateY(8px); } }
@keyframes lwRise  { from { opacity: 0; transform: translateY(18px) scale(.94); } }
@keyframes lwDetIn { from { opacity: 0; transform: translateX(18px); } }

/* Окно ждёт своей очереди: скрипт пометил его до того, как секция вошла в кадр */
.lw.is-armed { opacity: 0; }

.lw.is-cast              { animation: lwWin 900ms var(--ease) backwards; }
.lw.is-cast .lw-side     { animation: lwSide 520ms var(--ease) 380ms backwards; }
.lw.is-cast .lw-top      { animation: lwTop 480ms var(--ease) 560ms backwards; }
.lw.is-cast .lw-gh       { animation: lwHead 420ms var(--ease) 720ms backwards; }
.lw.is-cast .lw-card {
  animation: lwRise 520ms var(--ease) backwards;
  animation-delay: calc(760ms + var(--k, 0) * 55ms);
}
.lw.is-cast .lw-det      { animation: lwDetIn 560ms var(--ease) 1150ms backwards; }

/* Слой поднимаем только на время постановки: оставленный will-change держит
   текст окна растрированным под промежуточный масштаб и мылит его. */
.lw.is-cast,
.lw.is-cast .lw-side,
.lw.is-cast .lw-top,
.lw.is-cast .lw-card,
.lw.is-cast .lw-det { will-change: transform, opacity; }

/* ============================================================================
   14.6 КАРУСЕЛЬ БИБЛИОТЕКИ
   Механика и вид карточек - общие с highlights (те же .hl-track/.hl-card/.hl-cap
   и тот же wireCarousel). Своя здесь только ширина карточки: лента библиотеки
   уже, чем главная, чтобы читалась как вложенный рассказ, а не второй хайлайт.
   ============================================================================ */
/* Воздух до ленты больше, чем внутри блока с окном: подпись под моком
   принадлежит окну, а лента - следующая мысль. 48px читались как «подпись и
   лента - одно целое», отсюда 76px на десктопе и 44px на телефоне. */
.lbc-viewport { width: 100%; margin-top: clamp(44px, 5.4vw, 76px); }
.lbc-viewport:focus-visible { outline-offset: -2px; }

/* Лента выровнена по колонке контента: первая карточка встаёт ровно под
   заголовком секции, хвост уходит за правый край экрана. Поэтому и снап у
   карточек по левому краю (в highlights он по центру - там лента-афиша). */
/* Поля ленты не дублируем: правило .lbc-track идёт после .hl-track и своей
   копией формулы перебивало бы хвостовое поле --crs-end. Поля наследуются от
   .hl-track, здесь остаются только размеры карточек. */
.lbc-track .hl-card {
  width: 440px; height: 372px;
  background: var(--surface-2);
  scroll-snap-align: start;
}
.lbc-track .hl-card--wide   { width: 580px; }
.lbc-track .hl-card--narrow { width: 360px; }
.lbc-track .hl-cap {
  left: 30px; right: 30px; top: 30px;
  font-size: 21px;
  line-height: 1.24;
  max-width: none;
}
.lbc-track .hl-media { left: 30px; right: 30px; top: 122px; bottom: 30px; }
.lbc-m { display: flex; align-items: center; justify-content: center; }
/* Мок занимает всю ширину карточки: три ширины ленты и есть три разных поля.
   min-width:0 обязателен: без него флекс-мок с плотной начинкой (24 деления
   дорожки, три превью) распирает себя шире зоны и съедает поле карточки. */
.lbc-track .lpl,
.lbc-track .lsr,
.lbc-track .ltr,
.lbc-track .lfv,
.lbc-track .lfd { width: 100%; min-width: 0; }
/* Кадр плеера и дорожка обрезки меряются высотой зоны, а не пропорцией:
   на широкой карточке 16:9 не помещается по высоте. */
.lbc-track .lpl-stage { aspect-ratio: auto; height: 166px; }
.lbc-track .ltr-track { height: 126px; }
.lbc-track .ltr-t { min-width: 0; }
.lbc-track .lfv { gap: 18px; }
.lbc-track .lfv-c { min-width: 0; }
.lbc-track .lfv-th { aspect-ratio: 4 / 3; }
.lbc-track .lfd-row { margin-top: 18px; }

/* Плеер */
.lpl { width: min(100%, 480px); }
.lpl-stage {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: #06080c;
  overflow: hidden;
}
.lpl-play {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 54px; border-radius: 50%;
  background: rgba(255,255,255,.12); color: #fff;
}
.lpl-play .ic { width: 20px; height: 20px; margin-left: 2px; }
.lpl-bar { position: relative; height: 4px; margin-top: 14px; border-radius: 2px; background: rgba(255,255,255,.12); }
.lpl-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 40%; border-radius: 2px; background: var(--accent); }
.lpl-knob { position: absolute; left: 40%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: #fff; }
.lpl-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; }
.lpl-t { font-family: var(--mono); font-size: 12px; color: var(--ink-mute); }
.lpl-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--ink-dim); }

/* Поиск */
.lsr { display: grid; gap: 10px; width: min(100%, 460px); }
.lsr-f {
  display: flex; align-items: center; gap: 10px;
  height: 44px; padding: 0 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-strong); background: var(--surface-2);
}
.lsr-f .ic { width: 16px; height: 16px; color: var(--ink-mute); }
.lsr-f b { font-size: 15px; font-weight: 500; color: var(--ink); }
.lsr-r {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--surface-2);
}
.lsr-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 12px; color: var(--ink-dim); }
.lsr-note { margin-top: 2px; text-align: center; font-family: var(--mono); font-size: 11px; letter-spacing: .04em; color: var(--ink-mute); }

/* Обрезка: дорожка и жёлтые ручки - как в .trimBar приложения */
.ltr { width: min(100%, 500px); }
.ltr-track {
  position: relative;
  display: flex; align-items: stretch; justify-content: space-between;
  height: 62px; padding: 0 6px;
  border-radius: 8px;
  border: 1px solid var(--line); background: #06080c;
}
.ltr-t { width: 1px; background: rgba(255,255,255,.07); }
.ltr-sel {
  position: absolute; top: -3px; bottom: -3px; left: 15%; right: 37%;
  border: 3px solid #f5c518; border-radius: 8px;
  background: rgba(245,197,24,.10);
}
.ltr-h { position: absolute; top: -3px; bottom: -3px; width: 12px; background: #f5c518; }
.ltr-h-l { left: -3px; border-radius: 8px 0 0 8px; }
.ltr-h-r { right: -3px; border-radius: 0 8px 8px 0; }
.ltr-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; }
.ltr-rng { font-family: var(--mono); font-size: 12px; color: var(--ink-dim); }
.ltr-btn { display: inline-flex; align-items: center; height: 32px; padding: 0 14px; border-radius: 9px; background: var(--accent); color: #fff; font-size: 12.5px; font-weight: 600; }

/* Избранное */
.lfv { display: grid; gap: 16px; width: min(100%, 460px); }
.lfv-side {
  display: flex; align-items: center; gap: 9px;
  height: 38px; padding: 0 14px; border-radius: 10px;
  background: var(--a-sel, #3a5bc7); color: #fff; font-size: 14px;
}
.lfv-side .lw-st { color: #fff; }
.lfv-side .lw-n { margin-left: auto; color: #dbe2ff; }
.lfv-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.lfv-c { position: relative; display: block; }
.lfv-th { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 8px; border: 1px solid var(--line); background: #171a24; }
/* Треугольник плеера на бордерах - без лишнего SVG в разметке */
.lfv-th::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 0; height: 0; margin: -7px 0 0 -5px;
  border-style: solid; border-width: 7px 0 7px 11px;
  border-color: transparent transparent transparent rgba(255,255,255,.22);
}
.lfv-c.is-fav .lfv-th { border-color: rgba(245,197,24,.38); }
.lfv-c .lw-fav { top: 5px; right: 5px; width: 18px; height: 18px; border-radius: 6px; font-size: 10px; }

/* Раскладка по папкам игр */
.lfd { width: min(100%, 420px); }
.lfd-root { display: flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 600; color: var(--ink); }
.lfd-root .ic { width: 18px; height: 18px; color: var(--accent-soft); }
.lfd-note { margin-left: auto; font-family: var(--mono); font-size: 11px; font-weight: 400; color: var(--ink-mute); }
.lfd-row { display: flex; align-items: center; gap: 11px; padding-left: 16px; margin-top: 14px; font-size: 14.5px; color: var(--ink-dim); }
.lfd-row .lw-n { margin-left: auto; font-size: 13px; }
.lfd-el { width: 16px; height: 11px; margin-top: -10px; flex: none; border-left: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong); border-radius: 0 0 0 4px; }

/* ============================================================================
   14.7 АДАПТИВ ОКНА БИБЛИОТЕКИ
   ============================================================================ */
@media (max-width: 1100px) {
  /* топбар сжимается первым: путь и подписи селектов уходят */
  .lw-dir, .lw-lbl { display: none; }
  .lw-body { grid-template-columns: 190px minmax(0, 1fr) 232px; }
}

@media (max-width: 980px) {
  /* деталей больше не хватает места сбоку - уезжают вниз строкой */
  .lw-body { grid-template-columns: 186px minmax(0, 1fr); }
  .lw-det { grid-column: 1 / -1; border-left: none; border-top: 1px solid var(--a-line); }
  .lw-di { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 6px 18px; align-items: start; }
  .lw-di > .lw-th { grid-column: 1; grid-row: 1 / span 4; }
  .lw-di > *:not(.lw-th) { grid-column: 2; }
  .lw-dn, .lw-dl, .lw-dtags, .lw-acts { margin-top: 0; }
  .lw-dl { margin-top: 10px; max-width: 460px; }
  .lw-de { padding-top: 12px; }
}

@media (max-width: 760px) {
  /* сайдбар превращается в строку чипов, как вкладки */
  .lw-body { grid-template-columns: minmax(0, 1fr); }
  .lw-side {
    flex-direction: row; gap: 6px;
    padding: 10px 12px;
    border-right: none; border-bottom: 1px solid var(--a-line);
    overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .lw-side::-webkit-scrollbar { display: none; }
  .lw-sh { display: none; }
  .lw-it {
    width: auto; flex: 0 0 auto;
    padding: 6px 11px; border-radius: var(--r-pill);
    border: 1px solid var(--a-line);
  }
  .lw-it-t { flex: none; }
  .lw-search { width: 190px; }
}

@media (max-width: 640px) {
  .lbr-cap { text-align: left; }
  .lw { border-radius: 14px; }
  .lw-wt { font-size: 11.5px; }
  .lw-top { flex-wrap: wrap; row-gap: 8px; padding: 10px 12px; }
  .lw-search { order: 3; width: 100%; }
  .lw-sel { order: 4; }
  .lw-ico { order: 5; }
  .lw-sp { display: none; }
  .lw-main { padding: 12px; }
  .lw-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .lw-nm { font-size: 11.5px; }
  .lw-sub, .lw-dl dt, .lw-dl dd { font-size: 11px; }
  .lw-meta { gap: 4px; padding: 8px 9px 9px; }
  /* В колонку 158px тег и дата вместе не влезают - тег остаётся в сайдбаре и деталях */
  .lw-card .lw-tg { display: none; }
  .lw-det { padding: 12px; }
  .lw-di { grid-template-columns: 116px minmax(0, 1fr); gap: 6px 12px; }
  /* На телефоне 36px читались как «подпись под окном и лента - одно целое» */
  .lbc-viewport { margin-top: 44px; }
}

@media (max-width: 360px) {
  .lw-grid { grid-template-columns: minmax(0, 1fr); }
  .lw-th-t { font-size: 10.5px; }
}

/* ============================================================================
   15. COMPRESS - split
   ============================================================================ */
.cmp { padding-block: var(--section-y); }
.cmp-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 64px; align-items: center; }

.cmp-media { min-width: 0; }
.cmp-frame {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 3;
  padding: 40px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}
.cmp-caption { max-width: 60ch; margin-top: 20px; }

.cmp-text { max-width: 440px; }
.cmp-text .eyebrow { display: block; margin-bottom: 12px; }
.cmp-text .h2 { max-width: 14ch; }
.cmp-text .body-l { margin-top: 20px; }
.cmp-text .body-l + .body-l { margin-top: 16px; }
.cmp-stat { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-top: 24px; }
.cmp-num {
  font-size: clamp(40px, 4vw, 56px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--tr-tight);
  color: var(--ink);
}
.cmp-unit { font-size: .5em; font-weight: 600; margin-left: .08em; vertical-align: .32em; }
.cmp-stat-t { font-size: var(--t-body); color: var(--ink-dim); }
.cmp-badge { margin-top: 24px; }

/* ============================================================================
   16. FEATURES - самостоятельные карточки в ряд
   Общей поверхности у секции больше нет: каждая карточка - отдельная плашка
   с визуалом, а подпись живёт ПОД плашкой, на фоне страницы. Заголовок слева,
   стрелки справа, точек и автопоказа нет: лента листается рукой или стрелками.
   ============================================================================ */
.feat { padding-block: var(--section-y); }

.feat-head {
  display: flex;
  /* Стрелки встают вровень с первой строкой заголовка, а не с низом сноски */
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
  margin-bottom: var(--head-gap);
}
.feat-head-l { min-width: 0; }
/* Две строки заголовка гарантированы разметкой, а не переносом по ширине */
.feat-h2 { max-width: none; }
.feat-h2 span { display: block; }
.feat-note { margin-top: 20px; max-width: 560px; }
.feat-note b { color: var(--accent-soft); font-weight: 600; }

/* Стрелки в правом верхнем углу секции */
.crs-arrows { display: flex; align-items: center; gap: 10px; flex: none; margin-top: clamp(2px, 1vw, 14px); }
.crs-arr {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: rgba(255,255,255,.08);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--ink);
  transition: background 200ms var(--ease-io), opacity 200ms var(--ease-io),
              transform 120ms var(--ease-io);
}
.crs-arr .ic { width: 16px; height: 16px; }
.crs-arr:first-child .ic { transform: rotate(90deg); }
.crs-arr:last-child  .ic { transform: rotate(-90deg); }
.crs-arr:active { transform: scale(.94); }
.crs-arr:disabled { opacity: .3; pointer-events: none; }

/* Лента. Поле слева совпадает с полем .wrap, поэтому первая карточка стоит
   ровно под заголовком, а хвост уходит за правый край экрана. */
.feat-viewport { width: 100%; }
.feat-viewport:focus-visible { outline-offset: -2px; }
.feat-track {
  display: flex;
  gap: var(--grid-gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  --crs-gut: max(var(--pad), calc((100% - var(--maxw)) / 2));
  padding-inline: var(--crs-gut) var(--crs-end, var(--crs-gut));
  /* Снап меряет от края скроллера, а не от его поля: без scroll-padding первая
     карточка залипала вплотную к краю экрана, мимо поля заголовка. */
  scroll-padding-inline: var(--crs-gut) var(--crs-end, var(--crs-gut));
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.feat-track::-webkit-scrollbar { display: none; }

/* Три ширины в одной ленте - ритм вместо ряда одинаковых плашек. Высота у всех
   одна, меняется только ширина: широкая под горизонтальный визуал, узкая под
   короткую мысль. Ширину назначает модификатор в разметке, не инлайн-стиль. */
.feat-card {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  width: 420px;
  scroll-snap-align: start;
}
.feat-card--wide   { width: 560px; }
.feat-card--mid    { width: 420px; }
.feat-card--narrow { width: 340px; }

/* Визуал: сам себе поверхность, скругление то же, что у карточки.
   Высота фиксированная, а не пропорция: пропорция при трёх ширинах дала бы
   три разные высоты и лента развалилась бы. */
.feat-media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 352px;
  padding: 52px 28px 28px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 30px 70px -44px rgba(0,0,0,.9);
}
.feat-badge { position: absolute; left: 20px; top: 20px; z-index: 2; }
.feat-mock { width: 100%; }
/* Поле мока задаёт карточка: собственные max-width оставляли бы на широкой
   карточке пустые поля по бокам - ровно та «низкая заполненность». */
.feat-mock.cset,
.feat-mock.tgc,
.feat-mock.monmock,
.feat-mock.pset,
.feat-mock.osset { max-width: none; }

@media (hover: hover) and (pointer: fine) {
  .feat-media { transition: border-color var(--dur-hover) var(--ease-io); }
  .feat-card:hover .feat-media { border-color: var(--line-strong); }
  .feat-track { cursor: grab; }
  .feat-track.is-dragging { cursor: grabbing; }
}

/* Подпись под карточкой: один кегль, белая первая фраза и серое продолжение.
   Ширина ограничена знаками, а не карточкой: на широкой карточке строка иначе
   уходила за 55 знаков и переставала читаться как подпись. */
.feat-cap {
  max-width: 38ch;
  margin-top: 20px;
  font-size: var(--t-body);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: var(--tr-text);
}

/* --- мок 1: буфер повтора --------------------------------------------------
   Кольцо - SVG, а не conic-gradient: на тёмном фоне дуга остаётся чистой.
   Крутится только пока карточка в кадре ленты (класс .is-in ставит JS). */
.rbuf { display: flex; flex-direction: column; align-items: center; gap: 22px; }
.rbuf-ring { position: relative; width: 168px; height: 168px; flex: none; }
/* На широкой карточке кольцо крупнее, иначе визуал теряется в поле */
.feat-card--wide .rbuf-ring { width: 180px; height: 180px; }
.rbuf-svg { display: block; width: 100%; height: 100%; }
.rbuf-bg { fill: none; stroke: rgba(255,255,255,.07); stroke-width: 6; }
.rbuf-arc {
  fill: none;
  stroke: var(--accent);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-dasharray: 88 245;
  transform-origin: 50% 50%;
  animation: rbufSpin 7s linear infinite;
  animation-play-state: paused;
}
.feat-card.is-in .rbuf-arc { animation-play-state: running; }
@keyframes rbufSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.rbuf-val {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.rbuf-val b { font-size: 44px; font-weight: 700; line-height: 1; letter-spacing: var(--tr-snug); }
.rbuf-val > span { font-size: 12.5px; color: var(--ink-mute); }
.rbuf-file {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface-2);
}
.rbuf-ic {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  border-radius: 10px;
  background: rgba(34,197,94,.14);
  color: var(--status);
}
.rbuf-ic .ic { width: 17px; height: 17px; }
.rbuf-nm { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rbuf-nm b {
  font-family: var(--mono); font-size: 12.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rbuf-nm > span { font-size: 12px; color: var(--ink-mute); }

/* --- мок 2: пресеты сжатия --- */
.cset { display: flex; flex-direction: column; gap: 18px; width: 100%; max-width: 300px; margin-inline: auto; }
.presets { display: flex; flex-direction: column; gap: 9px; width: 100%; }
.preset {
  display: flex; flex-direction: column; gap: 4px;
  padding: 7px 13px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: rgba(255,255,255,.02);
}
/* line-height задан явно: базовые 1.5 раздували список выше поля плашки */
.preset b { font-size: 13.5px; font-weight: 600; line-height: 1.2; }
.preset span { font-family: var(--mono); font-size: 11px; line-height: 1.2; color: var(--ink-mute); }
.preset.is-on { border-color: rgba(59,130,246,.5); background: var(--accent-bg); }
.preset.is-on b { color: var(--accent-soft); }
.cset-out { display: flex; align-items: center; justify-content: center; gap: 12px; line-height: 1.2; }
.cset-src { font-family: var(--mono); font-size: 14px; color: var(--ink-mute); text-decoration: line-through; }
.cset-arw { width: 15px; height: 15px; color: var(--ink-mute); transform: rotate(-90deg); }
.cset-dst { font-family: var(--mono); font-size: 17px; font-weight: 700; color: var(--status); }

/* --- мок 3: сообщение в Telegram --- */
.tgc { display: flex; flex-direction: column; gap: 15px; width: 100%; max-width: 268px; margin-inline: auto; }
.tgc-head { display: flex; align-items: center; gap: 11px; }
.tgc-av {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none;
  border-radius: 50%;
  background: var(--accent-bg);
  border: 1px solid rgba(59,130,246,.3);
  color: #d2e2ff;
}
.tgc-av .ic { width: 19px; height: 19px; }
.tgc-nm { display: flex; flex-direction: column; gap: 2px; }
.tgc-nm b { font-size: 14.5px; font-weight: 600; line-height: 1.25; }
.tgc-nm > span { font-size: 12px; line-height: 1.25; color: var(--ink-mute); }
.tgc-msg {
  display: flex; flex-direction: column; gap: 10px;
  padding: 12px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--surface-2);
}
.tgc-thumb {
  position: relative; display: block;
  height: 104px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: #06080c;
}
/* Треугольник плеера на бордерах: без лишнего SVG в разметке */
.tgc-pl {
  position: absolute; left: 50%; top: 50%;
  width: 0; height: 0; margin: -9px 0 0 -6px;
  border-style: solid; border-width: 9px 0 9px 14px;
  border-color: transparent transparent transparent rgba(255,255,255,.28);
}
.tgc-dur {
  position: absolute; right: 8px; bottom: 7px;
  padding: 2px 6px; border-radius: 6px;
  background: rgba(0,0,0,.75);
  font-family: var(--mono); font-size: 11px; color: #e8eaee;
}
.tgc-file { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tgc-file b {
  font-family: var(--mono); font-size: 12.5px; font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tgc-file > span { font-size: 12px; line-height: 1.25; color: var(--ink-mute); }
.tgc-status { display: flex; align-items: center; gap: 8px; font-size: 12.5px; line-height: 1.2; color: var(--status); }
.tgc-status .ic { width: 15px; height: 15px; }

/* --- мок 4: мониторы и сцены --- */
.monmock { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: center; gap: 26px; width: 100%; }
.feat-mock.monmock { max-width: none; margin-inline: auto; }
.mon { display: block; position: relative; }
.mon-screen { display: block; border: 1px solid var(--line-strong); border-radius: 6px; background: #0a0c10; }
.mon-1 .mon-screen { width: 150px; height: 92px; }
.mon-2 .mon-screen { width: 112px; height: 70px; }
.feat-card--wide .mon-1 .mon-screen { width: 186px; height: 114px; }
.feat-card--wide .mon-2 .mon-screen { width: 140px; height: 86px; }
.mon-base { display: block; width: 38%; height: 6px; margin: 0 auto; border-radius: 0 0 3px 3px; background: var(--surface-3); }
.scenemock { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.scene-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  font-size: 13.5px;
  color: var(--ink-dim);
}
.scene-row .ic { width: 16px; height: 16px; }
.scene-row.is-on { background: var(--accent-bg); border-color: rgba(59,130,246,.4); color: var(--ink); }
.scene-ck { display: flex; margin-left: auto; color: var(--accent-soft); }

/* --- мок 5: четыре дизайна пилюли ------------------------------------------
   Плашки собраны по CSS самого индикатора (src/renderer/indicator/App.tsx):
   капсула светится под статус, простая - серая, минимал без фона,
   у неона статус показывает контур, а точки нет вовсе. */
.pset { display: flex; flex-direction: column; gap: 42px; width: 100%; max-width: 280px; margin-inline: auto; }
.pset-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.pset-nm { font-size: 13px; color: var(--ink-mute); }
.pmini {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px;
  border-radius: 11px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .04em; line-height: 1;
  color: #f2f3f5; white-space: nowrap;
}
.pmini-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--rec); }
.pmini-t { font-family: var(--mono); font-size: 11px; font-weight: 500; font-style: normal; color: var(--ink-dim); }
.pmini-capsule { background: #202227; border: 1px solid rgba(224,90,77,.34); box-shadow: 0 0 9px -3px var(--rec), 0 2px 7px rgba(0,0,0,.5); }
.pmini-plain   { background: #202227; border: 1px solid rgba(255,255,255,.12); box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.pmini-minimal { background: transparent; border: 1px solid transparent; filter: drop-shadow(0 1px 3px rgba(0,0,0,.75)); }
.pmini-neon    { background: rgba(16,17,20,.55); border: 1px solid var(--rec); box-shadow: 0 0 5px rgba(224,90,77,.7), inset 0 0 6px rgba(0,0,0,.4); }

/* --- мок 6: две системы --- */
.osset { display: flex; flex-direction: column; gap: 24px; width: 100%; max-width: 292px; margin-inline: auto; }
.osset-row {
  display: flex; align-items: center; gap: 16px;
  padding: 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface-2);
}
.osset-logo { width: 26px; height: 26px; flex: none; color: var(--ink-dim); }
.osset-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.osset-t b { font-size: 15px; font-weight: 600; }
.osset-t > span { font-size: 12px; color: var(--ink-mute); }
.osset-note { text-align: center; font-size: 12px; color: var(--ink-mute); }

/* ============================================================================
   17. WHY - бенто на 12 колонок
   Карточки различаются шириной И внутренней композицией: объект (две пилюли),
   акцентная цифра, цифра с полосой-визуалом, короткое утверждение с чипами,
   горизонтальная полоса платформ. Ряды: 7+5 -> 4+4+4 -> 12.
   Скелет один на все: приглушённая подпись сверху, .wc-bot прижат к низу,
   под ним опциональная полоса .wc-strip (мониторы, чипы, волна буфера).
   ============================================================================ */
.why { padding-block: var(--section-y); }
.why-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  margin-bottom: var(--head-gap);
}
.why-h2 { max-width: 18ch; }
.why-sub {
  max-width: 420px;
  font-size: var(--t-caption);
  line-height: 1.5;
  color: var(--ink-mute);
  text-align: right;
  text-wrap: pretty;
}

.why-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gap);
}

.wc {
  display: flex;
  flex-direction: column;
  padding: 32px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}

/* Ритм рядов. Высоты разные по рядам, внутри ряда одинаковые - сетка должна
   читаться как сетка, а не как случайная мозаика. */
.wc--free   { grid-column: span 7; min-height: 344px; }
.wc--price  { grid-column: span 5; min-height: 344px; }
.wc--keys,
.wc--gpu,
.wc--replay { grid-column: span 4; min-height: 306px; }
.wc--os     { grid-column: span 12; }

/* --- общие части --- */
.wc-cap {
  max-width: 42ch;
  font-size: var(--t-caption);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-mute);
  text-wrap: pretty;
}
.wc-cap .ic {
  display: inline-block;
  width: 18px; height: 18px;
  margin-right: 8px;
  vertical-align: -4px;
}
.wc-cap .ic + .ic { margin-left: -2px; }
.wc-cap .js-hk { font-family: var(--mono); color: var(--ink-dim); }

/* margin-top:auto ровно один на карточку: несколько авто-отступов флекс
   делит между собой поровну и низ перестаёт быть низом. */
.wc-bot { margin-top: auto; padding-top: 32px; }
.wc-viz + .wc-bot { padding-top: 0; }

.wc-num {
  font-size: var(--t-num);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--tr-tight);
}
.wc-unit {
  margin-left: .14em;
  font-size: .36em;
  font-weight: 600;
  letter-spacing: var(--tr-snug);
  vertical-align: .5em;
  color: var(--ink-dim);
}
.wc-val {
  font-size: clamp(24px, 2.5vw, 32px);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: var(--tr-snug);
  text-wrap: balance;
}
.wc-val-sub { margin-top: 12px; font-size: clamp(19px, 1.5vw, 21px); }
/* Отступ до пояснения один и тот же после цифры и после фразы: разные 10 и 14
   разводили низ соседних карточек ряда на 4px. */
.wc-note { max-width: 42ch; margin-top: 14px; font-size: var(--t-caption); line-height: 1.45; color: var(--ink-dim); }
.wc-strip { margin-top: 24px; }

/* Ряд из трёх: полосы под текстом обязаны быть одной высоты. Мониторы 61px,
   чипы 36px и волна 62px поднимали текст над собой на разную высоту - подписи
   в соседних карточках расходились на 27px. Фиксируем высоту полосы, содержимое
   прижимаем к её низу. */
.wc--keys .wc-strip,
.wc--gpu .wc-strip,
.wc--replay .wc-strip { display: flex; align-items: flex-end; height: 62px; }

/* --- 7 колонок: пилюля как объект, в покое и в записи --- */
.wc-viz {
  flex: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  padding-block: 30px 34px;
}
.wc-viz-pill .pill { font-size: 13px; }

/* --- 5 колонок: единственная акцентная цифра секции --- */
.wc--price .wc-num { color: var(--accent-soft); }
.wc--price .wc-unit {
  margin-left: .08em;
  font-size: .5em;
  vertical-align: .2em;
  color: inherit;
}

/* --- 4 колонки: полоса из трёх мониторов (мок .mon переиспользован) --- */
/* Три экрана разного размера - настольный, рабочий, ноутбук. Одинаковые
   квадраты с галочкой читались бы как чекбоксы, разный размер сразу говорит
   «три разных устройства». */
.wc-mons { display: flex; align-items: flex-end; gap: 12px; }
.wc-mons .mon-screen {
  display: flex;
  align-items: center;
  justify-content: center;
}
.wc-mons .mon:nth-child(1) .mon-screen { width: 88px; height: 55px; }
.wc-mons .mon:nth-child(2) .mon-screen { width: 76px; height: 47px; }
.wc-mons .mon:nth-child(3) .mon-screen { width: 64px; height: 40px; }
.wc-mons .mon-screen .ic { width: 18px; height: 18px; color: var(--accent-soft); }
.wc-mons .mon-base { width: 32%; height: 6px; background: var(--line-strong); }

/* --- 4 колонки: чипы вместо цифры, факт важнее числа --- */
.wc-chips { display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-end; }
.wc-chip {
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--tr-text);
  color: var(--ink-dim);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}

/* --- 4 колонки: живая волна буфера, тот же трек, что в highlights --- */
.wc--replay .replay-track { height: 62px; padding: 10px; }

/* --- 12 колонок: горизонтальная полоса платформ --- */
.wc--os {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  padding: 30px 34px;
}
/* Текст тянется, плитки держат свою ширину: иначе плитки съедали полосу
   и текст сворачивался в узкий столбик. */
.wc-os-txt { flex: 1 1 280px; max-width: 46ch; min-width: 0; }
/* В горизонтальной полосе ширину держит колонка текста, не сама строка */
.wc--os .wc-cap,
.wc--os .wc-note { max-width: none; }
.wc--os .wc-val { margin-top: 16px; }
/* Плитки обязаны сжиматься. Раньше стояло flex: 0 0 254px и nowrap: две
   плитки по 254px плюс gap плюс колонка текста в 46ch давали больше ширины
   карточки, и лишнее вылезало за её скруглённый край. Теперь они делят
   свободное место и переносятся, если его не хватает. */
.wc-os-tiles {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 14px;
  min-width: 0;
}
.wc-os {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1 1 220px;
  max-width: 280px;
  min-width: 0;
  padding: 16px 18px;
  border-radius: var(--r-md);
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.wc-os-logo { width: 22px; height: 22px; flex: none; color: var(--ink-dim); }
.wc-os-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.wc-os-t b { font-size: 15px; font-weight: 600; }
.wc-os-t > span { font-size: 12px; line-height: 1.35; color: var(--ink-mute); overflow-wrap: anywhere; }

@media (hover: hover) and (pointer: fine) {
  .wc { transition: border-color var(--dur-hover) var(--ease-io); }
  .wc:hover { border-color: var(--line-strong); }
}

/* ============================================================================
   18. INSTALL - 4 шага
   ============================================================================ */
.install { padding-block: var(--section-y); }
/* minmax(0,1fr): иначе неразрывные .kbd внутри шагов раздувают колонки
   до min-content и ряд перестаёт быть равномерным. */
.install-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--grid-gap); }
.install-step {
  display: flex;
  flex-direction: column;
  min-height: 190px;
  padding: 24px 24px 24px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
}
.step-num {
  display: block;
  margin-bottom: 12px;
  font-family: var(--mono);
  font-size: 38px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-mute);
}
.step-h { font-size: 21px; font-weight: 600; line-height: 1.2; letter-spacing: var(--tr-card); }
.step-t { margin-top: 8px; font-size: var(--t-body); line-height: 1.5; color: var(--ink-dim); }
.step-t b { color: var(--ink); font-weight: 600; }

.install-warn {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  max-width: calc(var(--maxw-text) + var(--pad) * 2);
  margin: 24px auto 0;
  padding: 18px 22px;
  border-radius: var(--r-lg);
  border: 1px solid rgba(245,158,11,.28);
  background: rgba(245,158,11,.08);
  font-size: 15px;
  line-height: 1.5;
  color: #f3c98a;
}
.install-warn .ic { width: 20px; height: 20px; margin-top: 1px; color: var(--warn); }
.install-warn b { color: #f7d9a3; font-weight: 700; }

/* ============================================================================
   19. FAQ
   ============================================================================ */
.faq { padding-block: var(--section-y); }
.faq .sec-head { margin-bottom: 48px; }
.faq-list {
  width: 100%;
  max-width: calc(800px + var(--pad) * 2);
  margin-inline: auto;
  padding-inline: var(--pad);
}
.faq-item { border-top: 1px solid var(--line); }
.faq-item:last-child { border-bottom: 1px solid var(--line); }
.faq-q { font: inherit; font-weight: inherit; }
.faq-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  width: 100%;
  min-height: 72px;
  padding: 24px 0;
  text-align: left;
}
.faq-qt {
  font-size: 21px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: var(--tr-card);
  color: var(--ink);
}
.faq-btn[aria-expanded="true"] .faq-plus { transform: rotate(45deg); color: var(--ink); }

.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-switch) var(--ease);
}
.faq-a-in { overflow: hidden; min-height: 0; }
.faq-a-in p {
  max-width: 680px;
  padding-bottom: 24px;
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--ink-dim);
  opacity: 0;
  transition: opacity var(--dur-icon) var(--ease-io);
}
/* Открытое состояние: и через aria-expanded, и через класс на пункте */
.faq-q:has(.faq-btn[aria-expanded="true"]) + .faq-a,
.faq-item.is-open .faq-a { grid-template-rows: 1fr; }
.faq-q:has(.faq-btn[aria-expanded="true"]) + .faq-a .faq-a-in p,
.faq-item.is-open .faq-a-in p { opacity: 1; transition-delay: 100ms; }

@media (hover: hover) and (pointer: fine) {
  .faq-btn:hover .faq-qt, .closer-head:hover .closer-title { color: var(--ink); }
  .faq-btn:hover .faq-plus, .closer-head:hover .closer-plus { color: var(--ink); }
}

/* ============================================================================
   20. DOWNLOAD - финальный CTA
   ============================================================================ */
.dl { padding-block: var(--section-y); }
.dl-inner { text-align: center; }
.dl-pill { display: flex; justify-content: center; margin-bottom: 32px; }
.dl-pill .pill { font-size: 12px; }
.dl-inner .h2 { margin-inline: auto; }
.dl-price { margin: 20px auto 0; }
.dl-price b { color: var(--ink); font-weight: 700; }
.dl-cta { margin-top: 32px; }
.dl-buy { margin-top: 20px; }
.dl-note { margin-top: 20px; }
.dl-note b { color: var(--ink-dim); font-weight: 600; }

/* ============================================================================
   21. FOOTER
   ============================================================================ */
.foot { border-top: 1px solid var(--line); padding: 64px 0 40px; }
.foot-grid { display: grid; grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); }
.foot-brand { max-width: 340px; }
.foot-logo { display: inline-flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 700; letter-spacing: var(--tr-text); }
.foot-logo img { width: 24px; height: 24px; }
.foot-about { margin-top: 14px; font-size: var(--t-caption); line-height: 1.55; color: var(--ink-dim); }
.foot-col { display: flex; flex-direction: column; }
.foot-ct {
  margin-bottom: 10px;
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.foot-link { font-size: var(--t-caption); line-height: 2; color: var(--ink-dim); transition: color 200ms var(--ease-io); }

.foot-bottom {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px 20px;
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--line-2);
}
.foot-ver {
  font-family: var(--mono);
  font-size: var(--t-label);
  color: var(--ink-mute);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 3px 8px;
}
.foot-disclaimer { flex: 1 1 380px; font-size: var(--t-label); line-height: 1.5; color: var(--ink-mute); }
.foot-byline { font-family: var(--mono); font-size: var(--t-label); letter-spacing: .04em; color: var(--ink-mute); }
.foot-byline b { color: var(--accent-soft); font-weight: 600; }

@media (hover: hover) and (pointer: fine) {
  .foot-link:hover { color: var(--ink); }
}

/* ============================================================================
   22. МОДАЛКА ПОКУПКИ (создаётся landing.js, разметка из v1 без изменений)
   ============================================================================ */
.buyModal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px; }
.buyModal[hidden] { display: none; }
.buyModal-bg { position: absolute; inset: 0; background: rgba(6,7,9,.74); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.buyModal-card {
  position: relative; z-index: 1;
  width: 100%; max-width: 400px;
  padding: 30px 26px 22px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  text-align: center;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.7);
  animation: buyPop 260ms var(--ease);
}
@keyframes buyPop { from { opacity: 0; transform: translateY(12px) scale(.98); } }
.buyModal-x {
  position: absolute; top: 10px; right: 12px;
  padding: 4px 8px;
  font-size: 26px; line-height: 1; color: var(--ink-mute);
  transition: color 150ms var(--ease-io);
}
.buyModal-x:hover { color: var(--ink); }
.buyModal-title { display: inline-flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 20px; font-weight: 700; color: #fff; }
.buyModal-lead { margin-bottom: 18px; font-size: 14.5px; line-height: 1.5; color: var(--ink-dim); }
.buyModal-input {
  width: 100%; height: 48px; padding: 0 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--ink);
  font-family: inherit; font-size: 15.5px;
  outline: none;
  transition: border-color 150ms var(--ease-io);
}
.buyModal-input:focus { border-color: var(--buy); }
.buyModal-input::placeholder { color: var(--ink-mute); }
.buyModal-err { min-height: 17px; margin: 7px 2px 0; text-align: left; font-size: 13px; color: var(--rec); }
.buyModal-go { width: 100%; margin-top: 6px; }
.buyModal-note { margin-top: 13px; font-size: 12.5px; color: var(--ink-mute); }

/* ============================================================================
   23. ПОЯВЛЕНИЕ ПРИ СКРОЛЛЕ
   ============================================================================ */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.reveal.in, .reveal.is-in, .reveal.is-visible { opacity: 1; transform: none; }

/* Тяжёлые кадры не едут: только прозрачность и микро-приближение.
   Окна библиотеки здесь нет: у него своя постановка, блок 14.55. */
.aot-figure.reveal, .cmp-media.reveal {
  transform: scale(.985);
  transition-duration: 900ms;
}
.aot-figure.reveal.in, .cmp-media.reveal.in,
.aot-figure.reveal.is-in, .cmp-media.reveal.is-in { transform: none; }

/* Если скрипты выключены - показываем всё сразу */
@media (scripting: none) {
  .reveal { opacity: 1; transform: none; }
}

/* ============================================================================
   24. АДАПТИВ - две колонки Closer look держатся только пока стейджу хватает
   ширины на читаемые подписи плиток (стейдж = 2/3 контейнера).
   ============================================================================ */
@media (max-width: 1160px) {
  .closer-grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .closer-stage { position: static; }
  .closer-stage-in { max-width: 900px; margin-inline: auto; }
}

/* Три пилюли в ряд просят 580px (129 + 168 + 247 и два зазора). В окне
   1001-1160 карточка 7/12 столько не даёт, и третья пилюля падала на вторую
   строку одна. Ниже 1000 карточка снова во всю ширину - там ряд помещается,
   поэтому правило заперто с обеих сторон. Второй такой участок - телефон,
   он закрыт в блоке <= 640. */
@media (min-width: 1001px) and (max-width: 1160px) {
  .wc-viz-pill { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* На планшете три кнопки в шапке не уживаются с якорями: якоря важнее,
   скачивание дублируется в hero и в финальном CTA. */
@media (max-width: 900px) {
  .nav-btn-glass { display: none; }
}

/* ============================================================================
   25. АДАПТИВ <= 1000px
   ============================================================================ */
@media (max-width: 1000px) {
  :root { --pad: 24px; }

  .hero-product { margin-top: 40px; }
  /* Воздух по бокам панели ужимаем до 20px: на планшете каждый процент важен */

  /* На планшете экран ниже и уже: карточка идёт от ширины, но не выше 56vh */
  .hl-track { --hl-h: min(56vh, 520px); --hl-card: min(calc(var(--hl-h) * 1.6), 86vw); }
  .hl-cap { left: 28px; right: 28px; top: 28px; }
  .hl-media { left: 28px; right: 28px; top: 124px; bottom: 28px; }
  .hl-media-desk { left: 20px; right: 20px; top: 116px; bottom: 0; }

  /* Кадр на планшете тех же пропорций, но меньше: кегль сцены поднимаем по
     ширине - высота остаётся ограничителем, иначе содержимое не влезает.
     Вес клипа в библиотеке убираем: имя файла важнее и должно остаться
     читаемым, а на два ряда по четыре превью высоты уже не хватает. */
  .hstage { font-size: min(1.62cqw, 2.9cqh); }

  .cmp-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; }
  .cmp-text { max-width: none; }

  .feat-head { gap: 28px; }

  /* Бенто «стоит ли ставить» на планшете: сетка сжимается с 12 колонок до 6.
     Ритм остаётся читаемым - широкая карточка, каре 2x2, широкая полоса.
     Поясняющий текст уходит под заголовок и выравнивается влево. */
  .why-head { flex-direction: column; align-items: flex-start; gap: 14px; }
  .why-sub { max-width: none; text-align: left; }
  .why-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .wc--free { grid-column: span 6; min-height: 300px; }
  .wc--price,
  .wc--keys,
  .wc--gpu,
  .wc--replay { grid-column: span 3; min-height: 284px; }
  .wc--os { grid-column: span 6; flex-direction: column; align-items: stretch; gap: 26px; padding: 28px; }
  .wc-os-txt { max-width: none; }

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

  .foot-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px var(--grid-gap); }
  .foot-brand { grid-column: 1 / -1; max-width: none; }
}

/* ============================================================================
   26. АДАПТИВ <= 640px
   ============================================================================ */
@media (max-width: 640px) {
  html { scroll-padding-top: 60px; }

  /* --- nav --- */
  .nav-links { display: none; }
  .nav-inner { justify-content: space-between; }
  .nav-actions { margin-left: auto; }
  .nav-btn-glass { display: none; }

  /* --- hero --- */
  .hero { padding-top: 40px; }
  .hero-cta { flex-direction: column; align-items: stretch; }
  .hero-cta .btn { width: 100%; }
  .hero-product { margin-top: 40px; }
  .hero-screen { gap: 12px; }
  .hero-screen-top { min-height: 0; }
  .hero-pillbox .pill { font-size: 8.5px; }

  /* Панель в одну строку на телефоне нечитаема: раскладываем в три ряда
     и поднимаем базовый кегль. */
  .hero-screen .cbar,
  .closer-stage-in .cbar {
    flex-wrap: wrap;
    width: 48.9em;
    height: auto;
    padding: 2em;
    border-radius: 2em;
  }
  .hero-screen .cbar { font-size: 1.95cqw; }
  .closer-stage-in .cbar { font-size: 1.95cqw; }
  .hero-screen .cb-id, .closer-stage-in .cb-id,
  .hero-screen .cb-lib, .closer-stage-in .cb-lib { flex: 1 1 23.4em; }
  .hero-screen .cb-audio, .closer-stage-in .cb-audio,
  .hero-screen .cb-lib, .closer-stage-in .cb-lib { margin-left: 0; }
  .hero-screen .cb-id, .closer-stage-in .cb-id { min-height: 19em; }
  .hero-screen .cb-act, .closer-stage-in .cb-act { min-height: 15em; }
  .hero-screen .cb-mini, .closer-stage-in .cb-mini { align-self: stretch; }

  /* --- highlights --- */
  /* На телефоне высоту снова диктует пропорция, а не экран: height: auto
     нужен, иначе фиксированная высота гасит aspect-ratio. */
  .hl-track { --hl-card: 88vw; }
  .hl-card { height: auto; aspect-ratio: 3 / 4; }
  .hl-cap { left: 24px; right: 24px; top: 24px; font-size: 23px; max-width: none; }
  .hl-media { left: 24px; right: 24px; top: 124px; bottom: 24px; }
  .hl-media-desk { left: 18px; right: 18px; top: 118px; bottom: 0; }
  /* Кадр на телефоне почти квадратный: кегль сцены теперь ограничивает ширина,
     поэтому ряды в четыре колонки перестраиваем в два, а карточку отправки
     ставим в столбик. Иначе герои схлопываются до нечитаемых. */
  .hstage { font-size: min(3.1cqw, 2.9cqh); }
  .hsp-pill { top: 3em; right: 2.2em; font-size: 1.9em; }
  .hsp-note { left: 2.2em; right: 2.2em; bottom: 2.2em; }
  .hpn-ok { display: none; }
  .hpn-acts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hpn-act { padding: 1.2em; gap: .4em; }
  .hpn-act .ic { width: 2.4em; height: 2.4em; margin-bottom: .4em; }
  .hlb-cnt, .hlb-find { display: none; }
  .hlb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hlb-meta { display: block; }
  .hlb-card:nth-child(n+5) { display: none; }
  /* Три подписи шкалы в узкий кадр не встают - оставляем края */
  .hrp-scale .mid { display: none; }
  /* Карточка отправки в столбик: превью сверху, действия под ним. Подпись под
     карточкой убираем, иначе блок не влезает в почти квадратный кадр. */
  .hsn-card { flex-direction: column; gap: 1.2em; padding: 1.4em; }
  .hsn-thumb { width: 100%; aspect-ratio: 12 / 5; }
  .hsn-body { gap: .5em; }
  .hsn-to { padding: .7em 1em; }
  .hsn-btn { padding: .85em 0; }
  .hsn-done { display: none; }

  /* --- малая лента библиотеки: три ширины схлопываются в одну --- */
  .lbc-track { padding-inline: var(--pad); scroll-padding-inline: var(--pad); }
  .lbc-track .hl-card,
  .lbc-track .hl-card--wide,
  .lbc-track .hl-card--narrow { width: min(84vw, 344px); height: 332px; }
  .lbc-track .hl-cap { left: 22px; right: 22px; top: 22px; font-size: 19px; line-height: 1.26; }
  .lbc-track .hl-media { left: 22px; right: 22px; top: 112px; bottom: 22px; }
  .lbc-track .lpl-stage { height: 124px; }
  .lbc-track .ltr-track { height: 92px; }

  /* --- always on top --- */


  /* --- closer --- */
  .closer-stage-in {
    aspect-ratio: auto;
    padding: 20px;
    border-radius: var(--r-lg);
  }
  /* Панель перестроена в три ряда, проценты подсветки к ней не применимы */
  .spot, .closer-callout { display: none; }
  .closer-title { font-size: 21px; }

  /* --- compress --- */
  .cmp-grid { grid-template-columns: 1fr; gap: 32px; }
  .cmp-frame { aspect-ratio: 4 / 3; padding: 24px; }

  /* --- features --- */
  /* Стрелки на телефоне лишние: лента листается пальцем */
  .crs-arrows { display: none; }
  /* На телефоне карточка выше, чем шире: моки собраны в столбик, и квадрат
     их уже не вмещает. min-height страхует совсем узкие экраны, где даже
     вертикальная пропорция даёт меньше высоты, чем нужно мокам. */
  .feat-card,
  .feat-card--wide,
  .feat-card--mid,
  .feat-card--narrow { width: min(84vw, 360px); min-width: 0; }
  .feat-media { height: auto; aspect-ratio: 5 / 6; min-height: 360px; padding: 50px 20px 22px; }
  .feat-badge { left: 16px; top: 16px; }
  .feat-cap { margin-top: 16px; }
  .feat-mock.monmock { gap: 18px; }
  .feat-mock.monmock .mon-1 .mon-screen { width: 128px; height: 78px; }
  .feat-mock.monmock .mon-2 .mon-screen { width: 96px; height: 60px; }
  .rbuf-ring { width: 140px; height: 140px; }
  .rbuf-val b { font-size: 38px; }

  /* --- why --- */
  /* Одна колонка: модификаторы ширины гасим, высоту задаёт содержимое. */
  .why-grid { grid-template-columns: minmax(0, 1fr); }
  .wc { padding: 24px 22px; }
  .wc--free,
  .wc--price,
  .wc--keys,
  .wc--gpu,
  .wc--replay,
  .wc--os { grid-column: 1 / -1; min-height: 0; }
  .wc--os { padding: 24px 22px; gap: 22px; }
  /* На узком экране плитки переносятся: в одну строку они сжимались до 142px
     и текст в них разъезжался на четыре строки. */
  .wc-os-tiles { flex-wrap: wrap; }
  .wc-bot { padding-top: 26px; }
  .wc-viz { gap: 14px; padding-block: 24px 26px; }
  .wc-viz-pill { flex-direction: column; align-items: flex-start; gap: 10px; }
  .wc-viz-pill .pill { font-size: 11.5px; }
  .wc-strip { margin-top: 20px; }
  .wc-mons { gap: 10px; }
  .wc-mons .mon:nth-child(1) .mon-screen { width: 74px; height: 46px; }
  .wc-mons .mon:nth-child(2) .mon-screen { width: 64px; height: 40px; }
  .wc-mons .mon:nth-child(3) .mon-screen { width: 54px; height: 34px; }
  .wc-os { flex: 1 1 200px; }

  /* --- install --- */
  .install-grid { grid-template-columns: 1fr; }
  .install-step { min-height: 0; padding: 20px; }
  .step-num { margin-bottom: 12px; font-size: 36px; }
  .install-warn { padding: 16px 18px; font-size: 14px; }

  /* --- faq --- */
  .faq-btn { min-height: 64px; padding: 20px 0; }
  .faq-qt { font-size: 19px; }

  /* --- cta --- */
  .dl-cta { flex-direction: column; align-items: stretch; }
  .dl-cta .btn { width: 100%; }
  .dl-buy .btn-buy { width: 100%; }
  .dl-pill .pill { font-size: 10px; }

  /* --- footer --- */
  .foot { padding: 48px 0 32px; }
  .foot-grid { grid-template-columns: 1fr; gap: 32px; }
  .foot-brand { grid-column: auto; }
  .foot-bottom { margin-top: 32px; }
}

/* Очень узкие экраны: карточки карусели не должны прилипать к краю */
@media (max-width: 380px) {
  .hl-cap { font-size: 21px; }
  /* На 320px подпись малой карточки уходит в четвёртую строку - двигаем мок
     ниже и добираем высоту, вместо того чтобы резать текст ещё раз. */
  .lbc-track .hl-cap { font-size: 17px; }
  .lbc-track .hl-card { height: 340px; }
  .lbc-track .hl-media { top: 126px; }
  .feat-media { min-height: 380px; }
  .btn-os { min-width: 0; }
}

/* ============================================================================
   27. PREFERS-REDUCED-MOTION
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0ms !important;
    transition-delay: 0ms !important;
    animation-duration: 0ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  .closer-text, .faq-a-in p { opacity: 1 !important; }
  /* Гид без движения: камера не наезжает, текст и каллаут на местах, зону
     показывает статичная рамка .spot (кольцо само не зажигается - оно висит
     на .is-cam). Приглушение соседей оставляем: это статика, а не движение,
     и оно помогает читать панель. */
  .is-guide { transform: none !important; }
  .closer-text { transform: none !important; }
  .closer-text .dim { opacity: 1 !important; }
  .cal-l { transform: none !important; }
  .closer-progress { animation: none !important; }
  .pill .dot::after { animation: none !important; }
  .hl-track, .feat-track { scroll-behavior: auto; }
  /* Карусели показывают текст и кадры сразу, автопоказ не запускается вовсе */
  .crs-anim .hl-cap, .crs-anim .feat-cap { opacity: 1 !important; transform: none !important; }
  .crs-anim .hl-cap .dim, .crs-anim .feat-cap .dim { opacity: 1 !important; }
  .crs-anim .hl-media > *, .crs-anim .feat-mock { transform: none !important; }
  /* Кольцо буфера не крутится вовсе: дуга просто стоит на месте */
  .rbuf-arc { animation: none !important; }
  /* Библиотека: детали и сетка появляются без движения */
  .lw-di { animation: none !important; }
  .lw-main.is-fresh .lw-card:not(.is-sel) { animation: none !important; }
  .lw-card.is-sel { transform: none !important; }
  /* Постановки появления окна нет вовсе: JS её не заводит, а если класс всё же
     оказался на разметке - окно всё равно видно и стоит на месте */
  .lw.is-armed { opacity: 1 !important; }
  .lw.is-cast, .lw.is-cast * { animation: none !important; will-change: auto !important; }
}
