/* ============================================================
   TONY SOPRANO ICT — V3 DRAFT: сборка по скринам владельца.
   Шрифт: Inter (variable, локально). Заголовки — плотный гротеск
   900 с тесным трекингом, палитра INSTITUTIONAL NOIR.
   Подключается ПОСЛЕ main.css и переопределяет его.
   ============================================================ */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/Inter-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/Inter-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Шрифтовая система: гротеск вместо серифа ---------- */

:root {
  --serif: 'Inter', system-ui, sans-serif;
  --sans: 'Inter', 'Manrope', system-ui, sans-serif;
  /* Трекинг крупных заголовков (правка владельца 2026-07-30: «буквы
     слишком тесно друг к другу»). Было −0.055em, а часть заголовков
     держала ещё более тесные −0.06em. При весе 900 и кириллическом
     капсе это за гранью: знаки физически касаются — у «Ц», «Д», «Щ»
     выносные элементы наезжают на соседнюю букву.
     −0.025em оставляет заголовки плотными и «дисплейными», но каждая
     буква стоит отдельно. Значение живёт в одном месте — все крупные
     заголовки ссылаются на этот токен.

     ВТОРАЯ ПРАВКА 2026-08-06 (владелец: «чтобы каждая буква полностью и
     ОТДЕЛЬНО»). −0.025em всё ещё стягивал знаки на крупных кеглях: при
     160px это −4px на каждый межбуквенный просвет, и у соседних круглых
     («о», «с», «е») контуры почти смыкаются. Ослаблено до −0.008em:
     плотность подачи сохраняется, но просвет между буквами перестаёт
     съедаться. */
  --head-track: -0.008em;
  /* Интерлиньяж крупных заголовков. Было 0.88–0.92 — строки физически
     наезжали друг на друга: у Inter зазор между свесом верхней строки и
     прописными нижней равен `интерлиньяж − 0.969em`, то есть при 0.9 он
     ОТРИЦАТЕЛЬНЫЙ (−0.069em ≈ 3px на кегле 45). Замер подтвердил: боксы
     строк стояли вплотную, зазор 0, а глифы выходят за боксы.
     1.0 даёт небольшой положительный зазор и сохраняет плотную подачу.

     ВТОРАЯ ПРАВКА 2026-08-06 (владелец: «текст заголовков урезается»).
     1.0 закрыл наложение СТРОК, но не свес последней. Замер на 1985px:
     строчный бокс свисает ниже бокса элемента на (1.21 − 1.0)/2 ≈ 0.105em —
     это 3px у h3, 8px у .t1-title и 29px у .manifest-line. Там живут
     хвосты «у», «р», «д», «ц», «щ». Предки их не срезают (проверил: ноль
     реально срезанных), но следующий элемент начинается ВНУТРИ этого
     свеса: у «База. Новости…» лид заходит на 29px, у «Сигналы не делают
     трейдера» — на 34px, у «Приватная группа» — на 37px. Хвосты букв
     оказываются в одной полосе с текстом абзаца.
     1.12 убирает свес почти полностью (остаётся 0.045em) и разводит
     заголовок с подзаголовком. Подача остаётся плотной. */
  --head-leading: 1.12;
}

body { font-family: var(--sans); }

.manifest-line,
.final-line {
  font-family: 'Inter', sans-serif;
  font-weight: 900;
  letter-spacing: var(--head-track);
}

.manifest-line {
  font-size: clamp(3rem, 7.6vw, 7.6rem);
  line-height: var(--head-leading);
}
.final-line {
  /* потолок поднят с 7rem (правка владельца 2026-07-31: «увеличить масштаб»);
     8.2rem — предел, при котором строка ещё умещается в карточку финала
     одной строкой на широком окне */
  font-size: clamp(3rem, 7.4vw, 8.2rem);
  line-height: var(--head-leading);
}
.manifest-line .gold-grad,
.t1-title .gold-grad,
.t6-box h2 .gold-grad {
  background: linear-gradient(180deg, #fdf6e6 0%, #d4af37 55%, #6e5a2c 115%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* line-height обязателен: без него заголовок наследовал книжные ~1.6, и
   двухстрочная «ТОРГОВЛЯ НА НОВОСТЯХ» занимала 108px вместо 71 — карточка
   витрины II переставала помещаться в пинный кадр и срезалась сверху
   (правка владельца 2026-07-31). 1.06, а не токен 1.0: у прописной
   кириллицы Д/Ц/Щ есть подстрочные хвосты. */
.reel-title { font-family: 'Inter', sans-serif; font-weight: 900; font-size: clamp(2.1rem, 2.9vw, 3.6rem); letter-spacing: -0.04em; line-height: 1.06; }
.reel-roman, .tariff-roman, .index-roman { font-family: 'Inter', sans-serif; font-weight: 900; letter-spacing: var(--head-track); }
.header-wordmark { font-family: 'Inter', sans-serif; font-weight: 800; letter-spacing: 0.14em; }
.reel-price { font-family: 'Inter', sans-serif; font-weight: 800; letter-spacing: -0.03em; }
.quote-main { font-family: 'Inter', sans-serif; font-weight: 600; font-style: normal; letter-spacing: -0.02em; }
.preloader-letter { font-family: 'Inter', sans-serif; font-weight: 900; letter-spacing: -0.04em; }
.btn { font-weight: 800; }
.section-label { font-weight: 800; }

/* ============================================================
   Блоки-шаблоны из второго сайта (Mentorship / Oryzo)
   ============================================================ */

/* ---------- Шаблон 1: hero «Не просто курс» + 3D-монета ---------- */

.s-t1 { position: relative; padding: 16vh 0 6vh; overflow: hidden; }
.t1-inner {
  width: min(1280px, 94vw); margin: 0 auto;
  display: grid; grid-template-columns: 1.02fr 0.98fr;
  align-items: center; gap: 46px;
}
.t1-title {
  font-family: 'Inter', sans-serif; font-weight: 900;
  font-size: clamp(3rem, 6.4vw, 6.6rem);
  line-height: var(--head-leading); letter-spacing: var(--head-track);
  margin: 1.4rem 0 1.4rem;
}
.t1-lead { max-width: 620px; color: rgba(244,240,234,0.6); font-size: clamp(1rem, 1.15vw, 1.3rem); line-height: 1.55; margin: 0 0 1.8rem; }
.t1-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.t1-stats { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 10px; margin-top: 2.4rem; max-width: 640px; }

.t1-visual { position: relative; min-height: 560px; perspective: 1200px; display: flex; align-items: center; justify-content: center; }
.t1-orbit {
  position: absolute; width: min(480px, 80vw); height: min(480px, 80vw);
  border: 1px solid rgba(212,175,55,0.16); border-radius: 50%;
  animation: t1orbit 20s linear infinite;
  box-shadow: inset 0 0 80px rgba(212,175,55,0.04), 0 0 100px rgba(212,175,55,0.04);
}
.t1-orbit::before, .t1-orbit::after {
  content: ""; position: absolute; inset: 44px; border-radius: 50%;
  border: 1px dashed rgba(244,240,234,0.12);
}
.t1-orbit::after { inset: 88px; animation: t1orbit 13s linear infinite reverse; }
@keyframes t1orbit { to { transform: rotate(360deg); } }
.t1-coin-stage {
  position: relative; width: min(380px, 68vw); height: min(380px, 68vw);
  transform-style: preserve-3d; animation: t1floaty 7s ease-in-out infinite;
}
@keyframes t1floaty {
  0%, 100% { transform: translateY(0) rotateX(8deg) rotateY(-14deg); }
  50% { transform: translateY(-18px) rotateX(-4deg) rotateY(12deg); }
}
.t1-coin { position: absolute; inset: 0; border-radius: 50%; }
/* --gb / --gs ведёт модуль 7d: когда луч ловит поверхность, металл сам
   разгорается и насыщается. Это читается лучше, чем одно пятно на тонком
   кружеве гравировки. */
.t1-coin img {
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 30px 70px rgba(0,0,0,0.7))
          drop-shadow(0 0 calc(40px * var(--gb, 1)) rgba(212,175,55,calc(0.16 * var(--gb, 1))))
          brightness(var(--gb, 1)) saturate(var(--gs, 1));
}
/* Блик луча по золоту (модуль 7d, правка владельца 2026-07-31).
   Маска — сам файл герба: свет ложится строго на металл, фон остаётся
   чистым. Позиция пятна (--gx/--gy) и его сила (--gi) приходят из JS и
   зависят от угла между лучом и поверхностью плашки. screen — блик
   складывается со светом гравировки, не забивая её. */
.t1-gleam {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 1;
  /* Солнечный луч, а не круглое пятно (правка владельца 2026-07-31):
     эллипс вытянут поперёк — свет ложится полосой и скользит по щиту, когда
     плашка качается. Сила убавлена второй раз: 0.62/0.46/0.24 → 0.42/0.30/0.15. */
  background: radial-gradient(ellipse 58% 34% at var(--gx, 50%) var(--gy, 42%),
    rgba(255, 252, 242, calc(var(--gi, 0.25) * 0.42)) 0%,
    rgba(255, 240, 198, calc(var(--gi, 0.25) * 0.30)) 26%,
    rgba(232, 196, 92, calc(var(--gi, 0.25) * 0.15)) 52%,
    transparent 80%);
  /* .webp вместо .png (2026-08-05): 68 КБ вместо 486. Маска режет по
     альфа-каналу — проверено, что конвертация его сохранила (чанк ALPH
     на месте), иначе блик лёг бы на весь прямоугольник вместо золота. */
  -webkit-mask-image: url('../assets/img/crest.webp');
          mask-image: url('../assets/img/crest.webp');
  -webkit-mask-size: contain;    mask-size: contain;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  mix-blend-mode: screen;
}
@media (prefers-reduced-motion: reduce) { .t1-gleam { display: none; } }

.t1-coin::before {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  background: conic-gradient(from 40deg, transparent, rgba(232,207,142,0.5), transparent, rgba(110,90,44,0.55), transparent);
  z-index: -1; filter: blur(1px);
  animation: t1shine 6s linear infinite;
}
@keyframes t1shine { to { transform: rotate(360deg); } }

/* HUD-чипы шаблона 1 (плейсхолдер-аватар удалён по приказу) */
.hud-chip {
  position: absolute;
  z-index: 4;
  border: 1px solid rgba(244,240,234,0.1);
  background: rgba(10,9,8,0.62);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-radius: 12px;
  padding: 13px 15px;
  min-width: 168px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
  animation: hudFloat 6s ease-in-out infinite;
  pointer-events: none;
}
.hud-chip small { display: block; color: var(--graphite); text-transform: uppercase; letter-spacing: 0.16em; font-size: 10px; margin-bottom: 6px; }
.hud-chip strong { font-size: 19px; font-weight: 900; letter-spacing: -0.02em; }
.hud-chip em { display: block; color: var(--gold); font-style: normal; font-size: 11px; margin-top: 4px; }
.hud-t1a { top: 40px; right: -6px; }
.hud-t1b { left: -10px; top: 150px; animation-delay: -1.8s; }
.hud-t1c { right: 20px; bottom: 90px; animation-delay: -3.2s; }
@keyframes hudFloat { 50% { transform: translateY(-16px); } }

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 14px;
  border: 1px solid rgba(244,240,234,0.12);
  border-radius: 999px;
  background: rgba(255,255,255,0.04);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--gold);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.pulse-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: #96ffbf;
  box-shadow: 0 0 14px rgba(150,255,191,0.9);
  animation: v2pulse 1.5s ease-in-out infinite;
}
@keyframes v2pulse { 50% { transform: scale(1.7); opacity: 0.5; } }

/* ---------- Тёмные стеклянные пластины: ВРЕМЯ / КОНТЕКСТ / ВХОД ----------
   Restrained luxury (люкс-часы / институциональный терминал): объём даёт
   МАТЕРИАЛ карточки — тонкий верхний кант, длинный рассеянный свет от
   верхнего левого края, мягкое затемнение нижней грани. Никакого bevel,
   яркого центрального пятна и тяжёлых теней на буквах. */
.hero-stat {
  --tilt-x: 0deg;
  --tilt-y: 0deg;
  --glare-mx: 25%;
  position: relative;
  padding: 22px 20px 18px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.14);
  background: linear-gradient(180deg,
    rgba(255,255,255,0.11) 0%,
    rgba(255,255,255,0.035) 25%,
    rgba(15,16,17,0.78) 58%,
    rgba(4,5,6,0.94) 100%);
  backdrop-filter: blur(16px) saturate(115%);
  -webkit-backdrop-filter: blur(16px) saturate(115%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    inset 0 -10px 20px rgba(0,0,0,0.52),
    0 12px 28px rgba(0,0,0,0.48);
  text-align: left;
  overflow: hidden;
  transform: perspective(700px) rotateX(var(--tilt-x)) rotateY(var(--tilt-y));
  transform-style: preserve-3d;
  transition:
    transform 420ms cubic-bezier(0.22, 1, 0.36, 1),
    border-color 420ms ease,
    box-shadow 420ms ease;
  will-change: transform;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero-stat { background: linear-gradient(180deg, #1e1d1b 0%, #121110 40%, #08090a 100%); }
}
/* Широкий рассеянный световой рефлекс от верхнего левого края —
   вместо яркого белого пятна; чуть смещается за курсором (--glare-mx) */
.hero-stat::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(ellipse at var(--glare-mx) 0%,
    rgba(255,255,255,0.20) 0%,
    rgba(255,255,255,0.07) 32%,
    transparent 68%);
  filter: blur(12px);
  opacity: 0.16;
  transition: opacity 420ms ease;
  pointer-events: none; z-index: 0;
}
/* Едва заметное зерно стекла — без золотых рефлексов */
.hero-stat::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background-image: var(--glass-grain);
  background-size: 110px 110px;
  opacity: 0.35;
  pointer-events: none; z-index: 0;
}
.hero-stat:hover {
  transform: perspective(700px) rotateX(var(--tilt-x)) rotateY(var(--tilt-y)) translateY(-2.5px);
  border-color: rgba(255,255,255,0.22);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.26),
    inset 0 -10px 20px rgba(0,0,0,0.55),
    0 16px 34px rgba(0,0,0,0.55);
}
.hero-stat:hover::before { opacity: 0.22; }
@media (prefers-reduced-motion: reduce) {
  .hero-stat { transition: border-color 0.3s ease, box-shadow 0.3s ease; }
  .hero-stat, .hero-stat:hover { transform: none; }
}
/* Базовая раскладка текста (премиальная типографика — ниже, только под
   модификатором .principle-card--premium) */
.hero-stat strong {
  display: block; font-size: clamp(14px, 1.05vw, 19px); font-weight: 800;
  letter-spacing: 0.05em; white-space: nowrap;
  position: relative; z-index: 4;
  color: #ece5d3;
  text-shadow: 0 1px 0 rgba(255,255,255,0.10), 0 2px 5px rgba(0,0,0,0.55);
}
.hero-stat span {
  display: block; color: rgba(225,220,207,0.78); font-size: 11px; line-height: 1.45; margin-top: 12px;
  font-weight: 400;
  position: relative; z-index: 3;
  text-shadow: 0 1px 2px rgba(0,0,0,0.75);
}

/* ---------- .principle-card--premium: авторская типографика ВРЕМЯ/КОНТЕКСТ/ВХОД ----------
   Строго локально (только 3 карточки шаблона 2, класс больше нигде не
   используется). Заголовок — металлик-градиент text-clip (гравировка на
   стекле), описание — тёплый серо-белый с приглушённым золотым словом.
   translateZ на title/description работает в 3D-пространстве, которое уже
   задаёт .hero-stat (perspective + preserve-3d из наклона за курсором). */
/* Заголовок — тонкая champagne-gold маркировка под стеклом: один чистый
   градиент + одна деликатная тень. Никакого bevel/emboss/контура/свечения —
   дорогой дизайн строится точностью, материалом и светом. */
.hero-stat.principle-card--premium .card-title {
  background: linear-gradient(180deg,
    #f4e7bd 0%,
    #d7bd73 42%,
    #a8873c 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow:
    0 1px 0 rgba(255,255,255,0.10),
    0 2px 5px rgba(0,0,0,0.55);
  transition: filter 420ms cubic-bezier(0.22, 1, 0.36, 1);
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .hero-stat.principle-card--premium .card-title { color: #d7bd73; -webkit-text-fill-color: initial; text-shadow: 0 2px 5px rgba(0,0,0,0.55); }
}
.hero-stat.principle-card--premium .card-description {
  transition: color 420ms ease;
}
.hero-stat.principle-card--premium:hover .card-title {
  filter: brightness(1.05) saturate(1.1); /* золото чуть теплее, без свечения */
}
.hero-stat.principle-card--premium:hover .card-description {
  color: rgba(236,230,210,0.88);
}

/* ---------- Диагональная лента: термины + котировки ---------- */

.tape-wrap {
  border-top: 1px solid rgba(244,240,234,0.1);
  border-bottom: 1px solid rgba(244,240,234,0.1);
  overflow: hidden;
  background: rgba(12,12,11,0.75);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transform: rotate(-2.6deg) scale(1.06);
  margin: 40px 0 60px;
  position: relative; z-index: 6;
}
.tape { display: flex; width: max-content; animation: tapeMove 34s linear infinite; }
.tape span {
  padding: 16px 26px; color: rgba(244,240,234,0.55);
  font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase;
  font-size: 12px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tape b { color: var(--gold); font-weight: 900; }
.tape .up { color: #96ffbf; }
.tape .down { color: #ff9c96; }
@keyframes tapeMove { to { transform: translateX(-50%); } }

/* ---------- Общие заголовки секций-шаблонов ---------- */

.tpl-kicker { color: var(--gold); text-transform: uppercase; letter-spacing: 0.16em; font-size: 12px; font-weight: 900; margin-bottom: 14px; }
.tpl-title {
  font-family: 'Inter', sans-serif; font-weight: 900;
  font-size: clamp(2.6rem, 5.4vw, 5.6rem);
  line-height: var(--head-leading); letter-spacing: var(--head-track); margin: 0 0 20px;
}
.tpl-title .dim { color: rgba(244,240,234,0.32); }
.tpl-lead { max-width: 760px; color: rgba(244,240,234,0.6); font-size: clamp(1rem, 1.1vw, 1.25rem); line-height: 1.6; margin: 0; }

/* ---------- Шаблон 2: massive card + модули ---------- */

.s-t2 { padding: 14vh 0; }
.t2-inner { width: min(1280px, 94vw); margin: 0 auto; }
.t2-grid { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: 22px; margin-top: 46px; align-items: stretch; }
.t2-massive {
  min-height: 500px; padding: 30px;
  display: flex; flex-direction: column; justify-content: space-between;
  position: relative; overflow: hidden;
  border-radius: 18px;
}
.t2-massive::before {
  content: ""; position: absolute; inset: -20%;
  background: radial-gradient(circle at 50% 30%, rgba(212,175,55,0.16), transparent 38%);
}
/* .t2-label удалён 2026-08-05 вместе со служебной маркировкой в шапке
   большой карточки шаблона 6 (команда владельца). */
.t2-mark { position: relative; z-index: 1; width: 250px; height: 250px; margin: auto; display: grid; place-items: center; animation: t1floatyMini 6s ease-in-out infinite; }
.t2-mark img { width: 210px; height: 210px; object-fit: contain; filter: drop-shadow(0 30px 60px rgba(0,0,0,0.55)); }
@keyframes t1floatyMini { 50% { transform: translateY(-14px) rotate(3deg); } }
.t2-copy { position: relative; z-index: 1; }
.t2-copy h3 { font-weight: 900; letter-spacing: -0.04em; font-size: clamp(1.8rem, 2.4vw, 2.6rem); margin: 0 0 10px; line-height: 1; }
.t2-copy p { color: rgba(244,240,234,0.6); line-height: 1.6; margin: 0; font-size: 0.9rem; }
.t2-features { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 16px; }
.t2-feature {
  min-height: 230px; padding: 22px; border-radius: 14px;
  position: relative; overflow: hidden;
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease;
}
.t2-feature:hover { transform: translateY(-8px); border-color: rgba(212,175,55,0.32); }
.t2-feature::after {
  content: ""; position: absolute; right: -50px; top: -50px;
  width: 160px; height: 160px; border-radius: 50%;
  background: radial-gradient(circle, rgba(212,175,55,0.16), transparent 68%);
}
.t2-feature small { color: var(--gold); font-size: 10px; letter-spacing: 0.15em; text-transform: uppercase; font-weight: 900; }
.t2-feature h3 { font-weight: 900; letter-spacing: -0.03em; font-size: clamp(1.3rem, 1.6vw, 1.8rem); margin: 12px 0 8px; line-height: 1; }
.t2-feature p { color: rgba(244,240,234,0.6); line-height: 1.5; margin: 0; font-size: 0.86rem; }
.temp-row { display: flex; gap: 8px; margin-top: 18px; }
.temp-row span { flex: 1; padding: 10px 6px; border: 1px solid rgba(244,240,234,0.1); border-radius: 8px; color: var(--graphite); font-size: 11px; text-align: center; background: rgba(0,0,0,0.22); }

/* ---------- Шаблон 3 + наставник: терминал, радар, шаги ---------- */

.s-t3 { padding: 14vh 0; }
.t3-inner { width: min(1280px, 94vw); margin: 0 auto; }
.t3-grid-a { display: grid; grid-template-columns: 0.9fr 1.3fr; gap: 22px; margin-top: 46px; align-items: stretch; }
.t3-mentor { padding: 26px; border-radius: 18px; display: flex; flex-direction: column; gap: 1.4rem; }
/* margin-inline: auto — портрет по центру карточки (правка владельца
   2026-07-31): при заданном max-width он прижимался влево, слева оставалось
   33px, справа 186px. */
.t3-mentor .holo-frame { max-width: 300px; margin-inline: auto; }
.t3-mentor-lines { list-style: none; margin: 0; padding: 0; }
.t3-mentor-lines li {
  font-family: 'Inter', sans-serif; font-weight: 700; letter-spacing: -0.02em;
  font-size: clamp(1rem, 1.2vw, 1.3rem); line-height: 1.4;
  padding: 0.8rem 0; border-bottom: 1px solid rgba(244,240,234,0.08);
}
.t3-mentor-lines li:first-child { border-top: 1px solid rgba(244,240,234,0.08); }
/* Терминал `.t3-terminal` с чек-листом сделки удалён 2026-07-30: владелец —
   «содержимое карточки справа не совпадает с контекстом блока». Вместе с ним
   ушли `.t3-terminal-top`, `.t3-lines`, `.t3-line`. На его месте `.voices`. */

/* ============================================================
   НАСТАВНИК: голоса трейдеров + портрет аудитории (2026-07-30)
   Материал — контент-база (экспорты открытого канала, закрытой группы,
   Discord «о себе»). Отзывы взяты те, что НЕ стоят в секции #results.
   ============================================================ */

/* Подпись под портретом: имя крупно, роль волоском ниже */
.mentor-id {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-bottom: clamp(14px, 1.2vw, 20px);
  border-bottom: 1px solid rgba(244,240,234,0.1);
}
.mentor-id b {
  font-weight: 900;
  letter-spacing: -0.03em;
  font-size: clamp(1.5rem, 1.9vw, 2.4rem);
  line-height: 1;
  color: var(--white);
}
.mentor-id span {
  font-size: clamp(0.66rem, 0.78vw, 0.92rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.45);
}

.voices {
  border-radius: 18px;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 1.6vw, 30px);
}
/* Тот же угловой отблеск, что был у терминала — он держал карточку
   и не даёт стеклу читаться плоским */
.voices::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 84% 6%, rgba(212,175,55,0.12), transparent 40%);
  pointer-events: none;
}

.voices-head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding-bottom: clamp(14px, 1.2vw, 20px);
  border-bottom: 1px solid rgba(244,240,234,0.1);
}
.voices-label {
  font-weight: 700;
  font-size: clamp(0.7rem, 0.82vw, 1rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.82);
}
.voices-src {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: clamp(0.6rem, 0.7vw, 0.8rem);
  letter-spacing: 0.1em;
  color: rgba(244,240,234,0.38);
}

/* Строки РАВНОЙ высоты (4 × 1fr) — не косметика, а защита от рывка:
   замер до правки показал ноль свободного запаса в списке, и цитата на
   строку длиннее растянула бы карточку, а вместе с ней (align-items:
   stretch) и левую. Скрытые `hidden` не занимают строк, поэтому в сетке
   всегда ровно 4 видимых. */
.voices-list {
  /* Кегль цитаты вынесен в переменную, чтобы от него же считать запас
     высоты строки. Замер показал: без запаса `1fr` не выравнивает —
     содержимое заполняет список целиком, свободного места нет, и строки
     остаются по контенту (116/116/116/91). Тогда подмена однострочной
     цитаты на двухстрочную дёргала бы карточку.
     8.4em на строку = 3 строки цитаты (4.5em) + подпись + отбивки, с
     запасом. Пропорция держится на любой ширине окна, потому что и
     кегль, и запас идут от одной величины. */
  --vq: clamp(0.95rem, 1.15vw, 1.45rem);
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-rows: repeat(4, minmax(0, 1fr));
  min-height: calc(4 * 8.4 * var(--vq));
  flex: 1;
  /* счётчик даёт индекс цитаты — нумерация не декор, а порядок в архиве */
  counter-reset: voice;
}

/* ---- Соло-режим: одна цитата в боксе карточки «Наставник» ----
   Перестановка колонок 2026-08-03. Базовые правила выше рассчитаны на
   колонку из нескольких цитат: жёсткие 4 строки грида и min-height под
   них. В боксе цитата одна и высота идёт по её содержимому, иначе бокс
   раздувался бы под несуществующие соседние строки.
   Резерв высоты остаётся (min-height в em), но всего на одну цитату —
   без него подмена однострочной цитаты на двухстрочную дёргала бы
   карточку, а её высота посчитана под экран снапа. */
/* Селектор задвоен намеренно: ниже по файлу, в десктопном блоке, стоит
   одноклассовое `.voices-list` с тремя строками грида и min-height под
   них — по порядку оно бы победило и раздуло бокс до 459px. */
.voices-list.voices-list--solo {
  grid-template-rows: minmax(0, 1fr);
  min-height: calc(5.6 * var(--vq));
  flex: none;
}
.voices-list--solo .voice {
  padding: clamp(12px, 1.6vh, 20px) clamp(14px, 1.2vw, 20px);
  border-top: 0;
}
.voices-list--solo .voice::before { top: clamp(12px, 1.6vh, 20px); }

/* Цитата как карточка архива: слева золотой волосок-корешок, который
   при наведении выезжает в полную высоту. Порядковый номер — из счётчика,
   поэтому при добавлении цитаты нумерация не рассыпается. */
.voice {
  counter-increment: voice;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(16px, 1.4vw, 26px) 0 clamp(16px, 1.4vw, 26px) clamp(30px, 2.4vw, 46px);
  border-bottom: 1px solid rgba(244,240,234,0.07);
  /* Смена цитаты: уходит вверх с растворением, приходит снизу.
     `:last-child` под запретом — при ротации последним в DOM может
     оказаться скрытый элемент, и линия-разделитель пропала бы у
     видимого. Нижнюю границу оставляем всем, а двойную линию перед
     подвалом снимаем у самого подвала. */
  transition:
    padding-left 0.45s var(--ease-out),
    opacity 0.42s var(--ease-out),
    transform 0.42s var(--ease-out);
}
/* ОБЯЗАТЕЛЬНО после `display: flex` выше. Атрибут `hidden` скрывает
   через `display: none` в стилях БРАУЗЕРА, а любое авторское правило
   `display` его перебивает — независимо от специфичности. Без этой строки
   в карточке рисовались все девять цитат вместо четырёх (поймано замером:
   `grid-template-rows` показал 9 дорожек). */
.voice[hidden] { display: none; }

.voice.is-out { opacity: 0; transform: translateY(-14px); }
.voice.is-in  { opacity: 0; transform: translateY(14px); }
.voice::before {
  content: counter(voice, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: clamp(18px, 1.5vw, 28px);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: clamp(0.6rem, 0.68vw, 0.78rem);
  color: rgba(212,175,55,0.55);
  transition: color 0.35s ease;
}
/* Корешок: тонкая золотая черта, растёт снизу вверх */
.voice::after {
  content: "";
  position: absolute;
  left: clamp(15px, 1.2vw, 23px);
  top: clamp(18px, 1.5vw, 28px);
  bottom: clamp(16px, 1.4vw, 26px);
  width: 1px;
  background: linear-gradient(180deg, var(--gold), rgba(212,175,55,0.1));
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 0.5s var(--ease-out);
}
.voice:hover { padding-left: clamp(36px, 2.9vw, 56px); }
.voice:hover::after { transform: scaleY(1); }
.voice:hover::before { color: var(--gold); }

.voice p {
  margin: 0 0 8px;
  font-size: var(--vq, clamp(0.95rem, 1.15vw, 1.45rem));
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: rgba(244,240,234,0.92);
  text-shadow: 0 0 14px rgba(6,6,7,0.9);
}
.voice small {
  font-size: clamp(0.62rem, 0.72vw, 0.84rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.4);
}

/* --- Портрет аудитории --- */

/* Границы у подвала нет: разделителем служит нижняя линия последней
   видимой цитаты — иначе на стыке рисовались бы две линии */
/* Биография в правой панели (перестановка колонок 2026-08-03). Ширина
   строки ограничена ~92 знаками: панель широкая, и без этого абзацы
   читались бы как газетная полоса. */
.mentor-bio {
  position: relative;
  z-index: 1;
  flex: 1;
  display: grid;
  align-content: start;
  gap: clamp(0.6rem, 1.1vh, 1rem);
  /* 62ch откачены обратно к 92ch (решение владельца 2026-08-05): сужение
     колонки ему не подошло. Причину решаем не мерой строки, а стеклом —
     см. правило .voices.glass в конце файла. */
  max-width: 92ch;
}
.mentor-bio p {
  margin: 0;
  font-size: clamp(0.92rem, min(1.05vw, 1.7vh), 1.2rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.72);
}
/* Первый абзац — лид: светлее и крупнее, он держит вход в текст */
.mentor-bio p:first-child {
  font-size: clamp(0.98rem, min(1.15vw, 1.85vh), 1.32rem);
  color: rgba(244,240,234,0.86);
}
/* Последний — вывод: золотой волосок слева, как у цитат витрины */
.mentor-bio p:last-child {
  margin-top: clamp(0.2rem, 0.5vh, 0.5rem);
  padding-left: 0.9rem;
  border-left: 2px solid rgba(212,175,55,0.5);
  color: rgba(244,240,234,0.82);
}

.voices-foot {
  position: relative;
  z-index: 1;
  padding-top: clamp(16px, 1.4vw, 26px);
  display: grid;
  gap: clamp(16px, 1.4vw, 26px);
}

/* ============================================================
   ЛУЧ ПРОЖЕКТОРА НА ЗАГОЛОВКЕ (2026-07-30)

   Портировано из лаборатории `CLAUDE безумные сайты/v1-noir` (блок
   `.colossus`, «наведи луч — рынок виден только в свете»).
   Механика оригинала сохранена: два слоя одного текста, у верхнего
   маска-круг в позиции `--bx/--by`, плюс отдельный слой видимого
   конуса света. Позицию ведёт JS с инерцией.

   Что изменено под наш проект:
   · палитра — у оригинала красные рефлексы (#FF1744), здесь золото;
   · подложка полупрозрачная, а не глухая: под секцией идёт видео с
     быком, и глухой фон оригинала закрыл бы его;
   · шрифт наш (Inter 900), а не сериф оригинала.
   ============================================================ */

.colossus {
  position: relative;
  isolation: isolate;
  /* Конус света лежит с полями inset −16%/−8% — без обрезки он вылезал
     за правый край окна на 76px и давал горизонтальный скролл всей
     странице (поймано при синхронизации в прод, 2026-07-31). Обрезка
     ничего не отнимает визуально: градиент конуса растворяется к 62%,
     а у блока свои скругления и полупрозрачная подложка. */
  overflow: hidden;
  --bx: 50%;
  --by: 42%;
  padding: clamp(18px, 2vw, 40px) clamp(16px, 2vw, 44px) clamp(20px, 2.2vw, 46px);
  margin: 0 clamp(-16px, -2vw, -44px);
  border-radius: 20px;
  /* Тёмная подложка нужна, чтобы базовый (тёмный) слой букв читался как
     форма. Полупрозрачная и с растворением к краям — бык остаётся виден */
  background: radial-gradient(120% 150% at 50% 45%,
    rgba(5,5,6,0.92) 0%,
    rgba(8,8,9,0.72) 46%,
    rgba(10,10,10,0.34) 74%,
    transparent 100%);
}

/* Видимый конус света — то, что «падает на экран» вокруг букв */
.colossus-cone {
  position: absolute;
  inset: -16% -8%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(circle 20vw at var(--bx) var(--by),
    rgba(244,240,234,0.10) 0%,
    rgba(212,175,55,0.06) 32%,
    transparent 62%);
}

.colossus-title { position: relative; }

.colossus-layer { display: block; }

/* Базовый слой: буквы почти сливаются с фоном, но форма читается.
   Обводка убрана (правка владельца 2026-07-31): -webkit-text-stroke кладёт
   линию ПО ЦЕНТРУ контура, и у Inter 900 она съедала внутренние просветы
   кириллицы — «у», «н», «ж» теряли форму без луча. Латиница переживала это
   легче, поэтому дефект и читался как «кривая кириллица». Контур держит
   сам цвет: тёплый графит светлее подложки. */
.colossus-layer--base {
  color: #2a2620;
}

/* Слой света: тот же текст белым, виден ТОЛЬКО внутри пятна луча */
.colossus-layer--beam {
  position: absolute;
  inset: 0;
  color: var(--white);
  -webkit-text-stroke: 1px rgba(212,175,55,0.38);
  -webkit-mask-image: radial-gradient(circle 24vw at var(--bx) var(--by),
    #000 0%, rgba(0,0,0,0.55) 34%, transparent 62%);
          mask-image: radial-gradient(circle 24vw at var(--bx) var(--by),
    #000 0%, rgba(0,0,0,0.55) 34%, transparent 62%);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

.colossus-note {
  margin: clamp(14px, 1.4vw, 24px) 0 0;
  font-size: clamp(0.58rem, 0.68vw, 0.76rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.34);
}

/* Без JS, при `prefers-reduced-motion` и на тач-устройствах имя обязано
   читаться целиком: маска снимается, остаётся мягкое свечение. Класс
   ставит JS; правило `:where` держит специфичность низкой. */
.colossus.is-lit .colossus-layer--beam {
  -webkit-mask-image: none;
          mask-image: none;
  -webkit-text-stroke: 1px rgba(212,175,55,0.28);
}
.colossus.is-lit .colossus-cone { opacity: 0.45; }
/* Подсказка про луч — только там, где луч ведёт рука */
.colossus.is-lit .colossus-note,
.colossus:not([data-colossus-ready]) .colossus-note { display: none; }

@media (prefers-reduced-motion: reduce) {
  .colossus-cone { opacity: 0.4; }
}

/* Строка-выходные данные под заголовком: масштаб доверия цифрами, а не
   словами о доверии. Приём тот же, что у `.faq-note` — золотой волосок
   сверху, — чтобы разделы читались одной семьёй. Цифры золотом: они и
   есть содержание строки. Шкала возраста `.aud-scale` из правой карточки
   удалена — эти данные теперь здесь, дублировать их незачем. */
.mentor-span {
  margin: clamp(20px, 1.8vw, 34px) 0 0;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: clamp(12px, 1.2vw, 22px);
  font-size: clamp(0.66rem, 0.8vw, 0.95rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.5);
  text-shadow: 0 0 14px rgba(6,6,7,0.9);
}
.mentor-span::before {
  content: "";
  flex: none;
  width: 100%;
  height: 1px;
  margin-bottom: clamp(14px, 1.3vw, 22px);
  background: linear-gradient(90deg, var(--gold), transparent 42%);
}
.mentor-span b {
  font-weight: 700;
  font-size: 1.28em;
  letter-spacing: 0.04em;
  color: var(--gold);
}
/* Разделитель между половинами строки — золотой волосок, не точка */
.mentor-span i {
  flex: none;
  width: clamp(26px, 3vw, 54px);
  height: 1px;
  background: rgba(212,175,55,0.5);
  transform: translateY(-0.3em);
}

.aud-facts {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.1vw, 22px);
}
.aud-facts dt {
  font-weight: 900;
  letter-spacing: -0.02em;
  font-size: clamp(1rem, 1.25vw, 1.6rem);
  line-height: 1.05;
  color: var(--gold);
}
.aud-facts dd {
  margin: 6px 0 0;
  font-size: clamp(0.66rem, 0.78vw, 0.92rem);
  line-height: 1.4;
  color: rgba(244,240,234,0.5);
}

@media (max-width: 560px) {
  .aud-facts { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .voice, .voice::before, .voice::after { transition: none; }
}
/* Блок `.t3-grid-b` (радар ликвидности + 4 шага) удалён по команде
   владельца 2026-07-30 — вместе с ним ушли `.t3-radar*`, `.t3-points`,
   `.t3-steps`, `.t3-step`, `@keyframes t3scan` и `t3ping`.

   Побочный эффект, поймано замером: `.t3-inner` — обычный блок, и весь
   отступ перед главой «[ 02 ] Приватная группа» держался на
   `margin-top` удалённого блока. После удаления зазор стал 0 px —
   глава упиралась в сетку наставника. Возвращаю отступ явно, крупнее
   карточного: это переход к новой главе внутри секции, а не соседний
   ряд. Правило скоупнуто на `.s-t3` — та же `.brut-head` стоит ещё
   в «Методе» и в FAQ, там своя вертикальная логика. */
.s-t3 .brut-head { margin-top: clamp(56px, 6vw, 110px); }

/* ---------- Шаблон 4 + ICT: pricing + цитаты ---------- */

.s-t4 { padding: 14vh 0; }
.t4-inner { width: min(1400px, 95vw); margin: 0 auto; }
.t4-grid { display: grid; grid-template-columns: 1.7fr 0.9fr; gap: 26px; margin-top: 46px; align-items: start; }
.t4-pricing { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.t4-card {
  border-radius: 18px; padding: 24px;
  position: relative; overflow: hidden;
  transition: transform 0.45s var(--ease-out), border-color 0.45s ease;
  display: flex; flex-direction: column;
}
.t4-card:hover { transform: translateY(-8px); border-color: rgba(212,175,55,0.35); }
.t4-card.featured { background: linear-gradient(150deg, rgba(212,175,55,0.14), rgba(255,255,255,0.05)); border-color: rgba(212,175,55,0.4); }
.t4-badge { display: inline-flex; align-self: flex-start; padding: 6px 10px; border-radius: 6px; background: rgba(212,175,55,0.12); color: var(--gold); border: 1px solid rgba(212,175,55,0.24); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; font-weight: 900; }
.t4-card h3 { font-weight: 900; letter-spacing: -0.04em; font-size: clamp(1.6rem, 2vw, 2.2rem); margin: 18px 0 6px; line-height: 1; }
.t4-card > p { color: rgba(244,240,234,0.6); line-height: 1.5; font-size: 0.86rem; margin: 0 0 4px; min-height: 56px; }
.t4-list { display: grid; gap: 9px; margin: 16px 0 20px; padding: 0; list-style: none; flex: 1; }
.t4-list li { display: flex; gap: 9px; color: rgba(244,240,234,0.62); line-height: 1.4; font-size: 0.84rem; }
.t4-list li::before { content: "✦"; color: var(--gold); flex: none; }
.t4-price { font-weight: 900; letter-spacing: -0.03em; font-size: clamp(1.6rem, 2vw, 2.2rem); color: var(--gold); margin-bottom: 16px; }

/* Строка объёма курса под названием («11 блоков · 6 недель»), правка
   2026-08-04. Селектор с двумя классами намеренно: одноклассовый `.t4-meta`
   проигрывает по весу правилу `.t4-card > p` с его `min-height:56px`, и под
   короткой строкой повисал бы пустой блок в полсотни пикселей. */
.t4-card > p.t4-meta {
  min-height: 0;
  margin: 0 0 10px;
  font-size: clamp(10px, 0.72vw, 14px);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-weight: 900;
  color: rgba(212,175,55,0.82);
}

/* Колонка тарифов = карточки + строка под ними. Обёртка нужна, чтобы
   .t4-grid оставался двухэлементным (карточки | портрет ICT). */
.t4-col { display: grid; }
.t4-note {
  margin: clamp(14px, 1.4vw, 22px) 0 0;
  font-size: clamp(0.86rem, 0.95vw, 1.1rem);
  line-height: 1.5;
  color: rgba(244,240,234,0.5);
  text-align: center;
}
.t4-card .btn { align-self: flex-start; }
.t4-ict { padding: 26px; border-radius: 18px; position: sticky; top: 110px; }
.t4-ict .holo-frame { max-width: 250px; margin-bottom: 1.6rem; }
.t4-quotes { display: grid; gap: 1.6rem; }
.t4-quotes .quote { border-left: 1px solid rgba(212,175,55,0.45); padding-left: 1.2rem; }
.t4-quotes .quote-main { font-size: clamp(0.95rem, 1.05vw, 1.15rem); line-height: 1.5; margin-bottom: 0.5rem; }
.t4-quotes cite { font-style: normal; font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(212,175,55,0.7); }

/* ---------- Шаблон 5: отзывы + paper ---------- */

.s-t5 { padding: 14vh 0; }
.t5-inner { width: min(1280px, 94vw); margin: 0 auto; }
.t5-reviews { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 46px; }
.t5-review { padding: 22px; border-radius: 14px; min-height: 240px; }
.t5-review p { color: #f4f0ea; line-height: 1.55; font-size: clamp(0.95rem, 1.05vw, 1.15rem); margin: 18px 0; }
.t5-review small { color: var(--graphite); font-size: 0.78rem; }
.stars { color: var(--gold); letter-spacing: 0.2em; font-size: 12px; }

.paper-block {
  margin-top: 3rem;
  border: 1px solid rgba(244,240,234,0.1);
  border-radius: 20px;
  background: #ece0cb;
  color: #18120b;
  padding: clamp(1.8rem, 3vw, 3rem);
  box-shadow: 0 26px 80px rgba(0,0,0,0.4);
  transform: rotate(0.6deg);
}
.paper-block .paper-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2.2rem; }
.paper-block small { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 10px; letter-spacing: 0.12em; color: rgba(24,18,11,0.75); } /* было 0.55 — ~2.9:1 на светлой бумаге, ниже WCAG AA */
.paper-block h3 { font-weight: 900; letter-spacing: -0.04em; font-size: clamp(1.8rem, 2.6vw, 2.6rem); margin: 0.6rem 0 0.8rem; }
.paper-block p { color: rgba(24,18,11,0.72); line-height: 1.65; margin: 0; font-size: 0.92rem; }
.paper-block pre {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  white-space: pre-wrap;
  padding: 1.1rem;
  background: rgba(0,0,0,0.07);
  border-radius: 12px;
  color: #3b2b18;
  font-size: 0.8rem;
  margin: 0;
  overflow: auto;
}

/* ---------- Шаблон 6: финальный CTA-box ---------- */

.s-t6 { padding: 12vh 0; display: grid; place-items: center; }
.t6-box {
  width: min(1180px, 94vw);
  border-radius: 24px;
  background: radial-gradient(circle at 50% 0%, rgba(212,175,55,0.16), transparent 42%), rgba(255,255,255,0.045);
  border: 1px solid rgba(244,240,234,0.1);
  padding: clamp(2.4rem, 6vw, 5rem);
  box-shadow: 0 24px 70px rgba(0,0,0,0.6);
  text-align: center; position: relative; overflow: hidden;
}
.t6-box img { width: 110px; height: 110px; object-fit: contain; margin: 0 auto 22px; filter: drop-shadow(0 0 20px rgba(244,240,234,0.25)); }
.t6-box h2 {
  font-family: 'Inter', sans-serif; font-weight: 900;
  font-size: clamp(2.6rem, 6.4vw, 6.4rem);
  line-height: var(--head-leading); letter-spacing: var(--head-track); margin: 0 0 20px;
}
.t6-box p { color: rgba(244,240,234,0.6); font-size: clamp(1rem, 1.15vw, 1.25rem); line-height: 1.6; max-width: 640px; margin: 0 auto 26px; }

/* Основной абзац призыва — тёмная плашка (правка владельца 2026-08-05,
   вариант «Б»). Три проблемы разом: цвет стоял на 60% прозрачности, тени
   не было, ширина 780px в карточке на 1338, и всё это ЛЕЖАЛО НА ВИДЕО
   (`cta-liquid-gold.mp4` крутится внутри бокса). Под видео подобрать цвет
   нельзя в принципе — фон меняется от кадра к кадру, поэтому владелец
   выбрал дать тексту собственную поверхность.

   `:not(.t6-micro)` обязателен: `.t6-box p` цепляет и служебную строку
   внизу («Telegram-канал открыт для всех…»), а она должна остаться тихой.

   Потолок кегля 1.875rem = 30px — ЗАМЕРЕНО на живой странице с УЧЁТОМ
   внутренних отступов плашки. Без плашки в две строки укладывался и 32px,
   но padding съедает 60px ширины, и на 32px строки становятся 1139 + 1224
   + хвост в 136px — рваный третий обрубок. На 30px выходит 1198 + 1153,
   то есть две почти равные строки. Выше не поднимать, не пересчитав
   переносы вместе с padding. */
.t6-box p:not(.t6-micro) {
  max-width: 1300px;
  font-size: clamp(1.05rem, 1.75vw, 1.875rem);
  color: #f4f0ea;
  background: rgba(10, 10, 10, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(244, 240, 234, 0.07);
  border-radius: 12px;
  padding: clamp(14px, 1.2vw, 22px) clamp(18px, 1.6vw, 30px);
  margin-bottom: clamp(22px, 2vw, 34px);
}
.t6-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }

/* ---------- Адаптив шаблонов ---------- */

@media (max-width: 980px) {
  /* minmax(0,1fr), не 1fr: иначе скролл-ряды внутри (статы, чипы) распирают
     трек до своего max-content и секция клипается за вьюпортом */
  .t1-inner, .t2-grid, .t3-grid-a, .t4-grid { grid-template-columns: minmax(0, 1fr); }
  .t1-visual { min-height: 0; flex-direction: column; gap: 26px; padding: 30px 0 10px; }
  .t4-ict { position: static; }
  .t5-reviews { grid-template-columns: 1fr; }
  .t1-stats { grid-template-columns: 1fr; }
  .paper-block .paper-grid { grid-template-columns: 1fr; }
  .paper-block { transform: none; }
}
@media (max-width: 560px) {
  .t1-coin-stage { width: 290px; height: 290px; }
  .t1-orbit { width: 330px; height: 330px; }
  /* На телефоне лента горизонтальная: наклон на узком экране съедает высоту
     и обрезает края */
  .tape-wrap { transform: none; }
}

/* ============================================================
   7-B/7-C — МОБИЛЬНЫЕ ПАТТЕРНЫ: свайп-карусели, sticky CTA,
   сжатая вертикальная композиция (телефон ≠ сжатый десктоп)
   ============================================================ */

@media (max-width: 767px) {
  /* Тарифы: свайп-карусель, рекомендуемый тариф первым */
  .t4-pricing {
    display: grid;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 80vw;
    gap: 14px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 4px 4px 18px;
    scrollbar-width: none;
  }
  .t4-pricing::-webkit-scrollbar { display: none; }
  .t4-card { scroll-snap-align: center; }
  .t4-card.featured { order: -1; }

  /* Отзывы: свайп-карусель по образцу тарифов */
  .t5-reviews {
    display: grid;
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 80vw;
    gap: 14px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 4px 4px 18px;
    scrollbar-width: none;
  }
  .t5-reviews::-webkit-scrollbar { display: none; }
  .t5-review { scroll-snap-align: center; min-height: 0; }

  /* Hero-статы: горизонтальный ряд вместо столбика */
  .t1-stats {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(200px, 64vw);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 12px;
    scrollbar-width: none;
    max-width: none;
  }
  .t1-stats::-webkit-scrollbar { display: none; }
  .hero-stat { scroll-snap-align: start; }

  /* Сжатая вертикаль: телефонная композиция плотнее десктопной */
  .s-t1 { padding: 9vh 0 4vh; }
  .s-t2, .s-t3, .s-t4, .s-t5 { padding: 8vh 0; }
  .s-t6 { padding: 8vh 0; }
  /* Лента без наклона на всём телефонном диапазоне (раньше — только ≤560) */
  .tape-wrap { transform: none; margin: 26px 0 36px; }

  /* Sticky CTA-бар: главный конверсионный элемент телефона */
  .mobile-cta {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
    background: rgba(10,10,10,0.82);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid rgba(244,240,234,0.1);
    transform: translateY(0);
    transition: transform 0.4s var(--ease-out);
  }
  .mobile-cta .btn {
    flex: 1;
    justify-content: center;
    min-height: 48px;
  }
  .mobile-cta.is-hidden { transform: translateY(105%); }

  /* Финал и футер не должны прятаться под баром */
  .site-footer { padding-bottom: calc(3rem + 74px); }
}

/* Бар — только телефон */
@media (min-width: 768px) {
  .mobile-cta { display: none; }
}

/* ============================================================
   V3.1 — АПСКЕЙЛ: шаблоны соразмерны большому окну (правка
   владельца: «всё мало, растянуть»). Контейнеры до ~1700px,
   типографика растёт от vw с высокими потолками.
   ============================================================ */

/* ---------- Hero: манифест шире и крупнее ---------- */

.manifest-inner { max-width: min(1680px, 94vw); }
.manifest-line { font-size: clamp(3.2rem, 8.4vw, 10rem); }
/* Золото вместо белого (правка владельца 2026-08-04, вариант «А»).
   Было `rgba(244,240,234,0.72)` — буквально цвет заголовка, выцветший до
   72%: глаз читал строку не как отдельный элемент, а как ослабевший хвост
   той же фразы. Прозрачностью это не лечится, нужен другой тон.
   Золото — не новый цвет, а возврат к правилу сайта: все строки этого вида
   (мелкие, капслоком, с широким трекингом) набраны им же — см. `.tpl-kicker`
   в кикерах всех остальных блоков. Серый на сайте закреплён за служебными
   подписями (`.corner-label`, `.section-label`), подводке манифеста он не
   по рангу. Белый сюда не возвращать. */
.manifest-sub {
  font-size: clamp(1rem, 1.5vw, 1.8rem);
  letter-spacing: 0.26em;
  color: var(--gold);
}
.btn { font-size: clamp(12px, 0.82vw, 17px); }
.manifest-cta { padding: 1.05em 2.8em; }

/* ---------- Контейнеры шаблонов ---------- */

/* Ультраширокие мониторы (правка владельца 2026-07-30: на 3440 по бокам
   секций оставались мёртвые поля ~28% с каждой стороны). До ~2020px
   формула ведёт себя В ТОЧНОСТИ как прежний min(1700px, 94vw):
   max(1700, 84vw) отдаёт 1700, пока 84vw его не перерастёт. Дальше
   контейнер держит 84% окна (поля по 8% читаются намеренным воздухом,
   а не пустотой) и упирается в 2600px — шире колонки текста и карточки
   становятся неприлично длинными. */
.t1-inner, .t2-inner, .t3-inner, .t5-inner { width: min(max(1700px, 84vw), 94vw, 2600px); }
.t4-inner { width: min(max(1780px, 84vw), 95vw, 2600px); }
.t6-box { width: min(max(1500px, 74vw), 94vw, 2200px); }

/* ---------- Шаблон 1: крупнее текст, монета, статы ---------- */

.t1-title { font-size: clamp(3.2rem, 5.8vw, 8.2rem); }
.t1-lead { max-width: 760px; font-size: clamp(1.05rem, 1.35vw, 1.7rem); }
.hero-eyebrow { font-size: clamp(11px, 0.8vw, 16px); padding: 10px 16px; }
.t1-stats { max-width: 780px; gap: 14px; }
/* Уже, чем раньше: при 38px «КОНТЕКСТ» вылезал за карточку на широких
   окнах — самое длинное слово тройки задаёт потолок для всех трёх */
/* Больше воздуха (брифинг «restrained luxury»): заголовок сдержанного
   размера, зазор заголовок↔описание 10–14px, текст не прижат к краям */
.hero-stat { padding: clamp(18px, 1.4vw, 26px) clamp(16px, 1.2vw, 22px) clamp(14px, 1.1vw, 20px); }
.hero-stat strong { font-size: clamp(14px, 1.1vw, 20px); }
/* Потолок поднят 13px → 16px (правка владельца 2026-08-05: «слишком мелкий»).
   Было: заголовок карточки упирался в 20px, а описание под ним — в 13px,
   и на широком мониторе оно выглядело сноской, хотя это основной смысл
   карточки. Множитель 0.78vw → 0.95vw, чтобы потолок достигался уже около
   1700px, а не 2050.
   16px — ПРЕДЕЛ, а не произвольное число: замерено на живой странице, при
   17px описание средней карточки («Сценарий важнее отдельного сигнала»)
   ломается на третью строку, и три карточки разъезжаются по высоте.
   Выше 16 не поднимать, не проверив все три строки на перенос. */
.hero-stat span { font-size: clamp(11px, 0.95vw, 16px); margin-top: clamp(10px, 0.8vw, 14px); }
.t1-visual { min-height: clamp(560px, 42vw, 820px); }
.t1-coin-stage { width: clamp(380px, 27vw, 560px); height: clamp(380px, 27vw, 560px); }
.t1-orbit { width: clamp(480px, 35vw, 720px); height: clamp(480px, 35vw, 720px); }
.tape span { font-size: clamp(12px, 0.85vw, 17px); padding: clamp(16px, 1.2vw, 24px) clamp(26px, 1.8vw, 38px); }

/* ---------- Орбиты HUD-чипов: планеты вокруг герба ---------- */

.hud-orbit {
  position: absolute;
  top: 50%; left: 50%;
  width: 0; height: 0;
  z-index: 4;
  animation: hudOrbit var(--T, 26s) linear infinite;
  animation-delay: var(--D, 0s);
  pointer-events: none;
}
@keyframes hudOrbit { to { transform: rotate(360deg); } }
.hud-orbit .hud-chip {
  position: absolute;
  top: 0; left: var(--R, 260px);
  /* Контр-вращение: чип едет по орбите, но текст остаётся прямым */
  animation: hudCounter var(--T, 26s) linear infinite;
  animation-delay: var(--D, 0s);
}
@keyframes hudCounter {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(-360deg); }
}
/* Собственное вращение вокруг своей оси — мягкое покачивание */
.hud-chip-in { animation: hudSway 5.5s ease-in-out infinite; }
@keyframes hudSway { 50% { transform: rotate(6deg) translateY(-6px); } }

.hud-chip { min-width: clamp(168px, 13vw, 250px); padding: clamp(13px, 1vw, 20px) clamp(15px, 1.1vw, 22px); }
.hud-chip strong { font-size: clamp(19px, 1.4vw, 28px); }
.hud-chip small { font-size: clamp(9px, 0.65vw, 12px); }
.hud-chip em { font-size: clamp(11px, 0.8vw, 15px); }

/* ---------- HUD-монеты: чипы → реалистичные 3D-монеты ----------
   Наклон за курсором (--rx/--ry ставит JS, main.js «HUD-монеты»),
   спекулярный блик едет за курсором (--mx/--my), «солнечная» полоса
   меняет угол вместе с наклоном монеты. */

/* Прямоугольная карточка выключается — весь визуал несёт .hud-coin */
.hud-orbit .hud-chip {
  border: 0; background: none; backdrop-filter: none;
  border-radius: 50%; padding: 0; min-width: 0;
  box-shadow: none;
  pointer-events: auto; /* монета ловит курсор для наклона */
}

.hud-coin {
  --rx: 0deg; --ry: 0deg; --mx: 50%; --my: 40%;
  width: clamp(120px, 9vw, 156px);
  aspect-ratio: 1;
  border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  padding: 13%;
  position: relative;
  transform: perspective(520px) rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform 0.18s ease-out;
  will-change: transform;
  background: radial-gradient(circle at 32% 28%, rgba(66,60,48,0.96), rgba(18,17,15,0.98) 64%);
  box-shadow:
    inset 0 0 0 1px rgba(212,175,55,0.45),
    inset 0 0 0 5px rgba(24,22,19,1),
    inset 0 0 0 6px rgba(212,175,55,0.16),
    inset 0 14px 22px -10px rgba(255,246,220,0.10),
    inset 0 -16px 24px -10px rgba(0,0,0,0.75),
    0 18px 40px rgba(0,0,0,0.6);
}
/* Гурт — ребристый кант по окружности, как у настоящей монеты */
.hud-coin::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  padding: 3px;
  background: repeating-conic-gradient(rgba(212,175,55,0.55) 0deg 2.5deg, rgba(64,52,24,0.7) 2.5deg 5deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
/* Блик: точечный спекуляр под курсором + луч, зависящий от угла наклона */
.hud-shine {
  position: absolute; inset: 2px; border-radius: 50%;
  pointer-events: none;
  background:
    radial-gradient(circle at var(--mx, 50%) var(--my, 40%), rgba(255,250,235,0.30), transparent 36%),
    linear-gradient(calc(118deg + var(--ry, 0deg) * 2.6), transparent 40%, rgba(255,246,215,0.22) 50%, transparent 60%);
  mix-blend-mode: screen;
  opacity: 0.5;
  transition: opacity 0.4s;
}
.hud-chip:hover .hud-shine { opacity: 1; }

/* Типографика в круге (перебивает прямоугольные clamp-размеры выше).
   Размер главного слова рассчитан на самое длинное — «ДИСЦИПЛИНА»
   (10 букв капсом Inter 900) во внутренних ~78% диаметра монеты */
.hud-coin { padding: 11%; }
.hud-coin small { margin-bottom: 4px; font-size: clamp(8px, 0.62vw, 10px); letter-spacing: 0.18em; }
.hud-coin strong { font-size: clamp(13px, 0.95vw, 17px); letter-spacing: -0.03em; line-height: 1.05; white-space: nowrap; }
.hud-coin em { font-size: clamp(9px, 0.72vw, 12px); margin-top: 4px; line-height: 1.25; }

/* Пока курсор на монете — покачивание замирает, монета слушается руки */
.hud-chip:hover .hud-chip-in { animation-play-state: paused; }

/* ---------- Общие заголовки шаблонов ---------- */

.tpl-kicker { font-size: clamp(12px, 0.85vw, 17px); }
.tpl-title { font-size: clamp(2.8rem, 5.8vw, 7.4rem); }
.tpl-lead { max-width: 900px; font-size: clamp(1rem, 1.25vw, 1.55rem); }
.section-label { font-size: clamp(11px, 0.78vw, 15px); }

/* ---------- Шаблон 2: massive card + модули ---------- */

.t2-grid { gap: clamp(22px, 1.8vw, 34px); }
.t2-massive { min-height: clamp(500px, 38vw, 700px); padding: clamp(30px, 2.4vw, 46px); }
.t2-mark { width: clamp(250px, 19vw, 380px); height: clamp(250px, 19vw, 380px); }
.t2-mark img { width: 84%; height: 84%; }
/* (апскейл .t2-label снят — элемент удалён 2026-08-05) */
.t2-copy h3 { font-size: clamp(1.8rem, 2.5vw, 3.4rem); }
.t2-copy p { font-size: clamp(0.9rem, 1.05vw, 1.3rem); }
.t2-features { gap: clamp(16px, 1.3vw, 24px); }
.t2-feature { min-height: clamp(230px, 17vw, 320px); padding: clamp(22px, 1.8vw, 34px); }
.t2-feature small { font-size: clamp(10px, 0.72vw, 14px); }
.t2-feature h3 { font-size: clamp(1.3rem, 1.75vw, 2.4rem); }
.t2-feature p { font-size: clamp(0.86rem, 1vw, 1.25rem); }
.temp-row span { font-size: clamp(11px, 0.8vw, 15px); padding: clamp(10px, 0.85vw, 16px) 6px; }

/* ---------- Шаблон 3: наставник и голоса трейдеров ---------- */

.t3-grid-a { gap: clamp(22px, 1.8vw, 34px); }
.t3-mentor, .voices { padding: clamp(26px, 2vw, 40px); }
.t3-mentor .holo-frame { max-width: clamp(300px, 24vw, 460px); }
.t3-mentor-lines li { font-size: clamp(1rem, 1.3vw, 1.65rem); }

/* ---------- Шаблон 4: pricing + ICT ---------- */

.t4-grid { gap: clamp(26px, 2vw, 40px); }
.t4-pricing { gap: clamp(16px, 1.3vw, 24px); }
.t4-card { padding: clamp(24px, 2vw, 38px); }
.t4-badge { font-size: clamp(10px, 0.72vw, 14px); }
.t4-card h3 { font-size: clamp(1.6rem, 2.1vw, 2.9rem); }
.t4-card > p { font-size: clamp(0.86rem, 1vw, 1.25rem); min-height: auto; }
.t4-list { gap: clamp(9px, 0.8vw, 14px); }
.t4-list li { font-size: clamp(0.84rem, 0.98vw, 1.2rem); }
.t4-price { font-size: clamp(1.6rem, 2.1vw, 2.9rem); }
.t4-ict { padding: clamp(26px, 2vw, 40px); }
.t4-ict .holo-frame { max-width: clamp(250px, 19vw, 360px); }
.t4-quotes .quote-main { font-size: clamp(0.95rem, 1.15vw, 1.45rem); }
.t4-quotes cite { font-size: clamp(10px, 0.7vw, 13px); }

/* ---------- Шаблон 5: отзывы + paper ---------- */

.t5-reviews { gap: clamp(16px, 1.3vw, 24px); }
.t5-review { min-height: clamp(240px, 18vw, 320px); padding: clamp(22px, 1.8vw, 34px); }
.t5-review p { font-size: clamp(0.95rem, 1.2vw, 1.5rem); }
.t5-review small { font-size: clamp(0.78rem, 0.85vw, 1rem); }
.stars { font-size: clamp(12px, 0.9vw, 17px); }
.paper-block h3 { font-size: clamp(1.8rem, 2.8vw, 3.8rem); }
.paper-block p { font-size: clamp(0.92rem, 1.1vw, 1.35rem); }
.paper-block pre { font-size: clamp(0.8rem, 0.9vw, 1.05rem); }
.paper-block small { font-size: clamp(10px, 0.72vw, 14px); }

/* ---------- Шаблон 6: CTA ---------- */

.t6-box h2 { font-size: clamp(2.8rem, 6.6vw, 8rem); }
.t6-box p { max-width: 780px; font-size: clamp(1rem, 1.3vw, 1.6rem); }
.t6-box img { width: clamp(110px, 9vw, 170px); height: clamp(110px, 9vw, 170px); }

/* ---------- Мобайл: чипы — горизонтальный свайп-ряд под монетой вместо орбит ---------- */

/* Обёртка чипов: на десктопе не создаёт бокса — absolute-орбиты
   позиционируются от .t1-visual как раньше */
.hud-row { display: contents; }

@media (max-width: 980px) {
  .hud-row {
    display: flex;
    gap: 12px;
    width: 100%;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding: 4px 4px 14px;
    scrollbar-width: none;
  }
  .hud-row::-webkit-scrollbar { display: none; }
  .hud-orbit {
    position: static;
    width: auto; height: auto;
    animation: none;
    flex: 0 0 auto;
    scroll-snap-align: start;
  }
  .hud-orbit .hud-chip {
    position: static;
    animation: none;
    min-width: 0; /* монета сама держит размер — растяжка не нужна */
  }
  .hud-chip-in { animation: none; }
  .hud-coin { width: clamp(112px, 31vw, 136px); } /* компактнее в свайп-ряду */
}

/* ---------- Шаблон 2: трёхчастная симметрия «текст | бык | герб» ----------
   Бык (фоновый слой) стоит по центру вьюпорта — колонки раздвинуты к краям,
   центральный column-gap = свободный коридор для фигуры. Композиция:
   ~треть текст · ~треть бык · ~треть герб с монетами. */
@media (min-width: 981px) {
  .t1-inner {
    /* До ~2238px — прежний min(1880px, 96vw); дальше растёт до 84vw
       (потолок 2750): трёхчастная симметрия сохраняется, просто текст
       и герб раздвигаются к краям окна, а коридор быка дышит шире
       (правка владельца 2026-07-30 про пустые поля на 3440) */
    width: min(max(1880px, 84vw), 96vw, 2750px);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(240px, 26vw, 540px);
  }
  /* Было жёстко 580px при грид-колонке 1105 на ультрашироком мониторе:
     заголовок ломался по одному слову в строку (6 строк, 787px высоты) и
     блок вместе с бегущей лентой не влезал в окно. Даём колонке дышать до
     1080 — строки встают по предложениям («Не просто курс.» / «Система» /
     «чтения рынка.»), высота заголовка падает до 394px. Коридор быка и
     колонка герба не двигаются: 1080 < 1105. */
  .t1-copy { max-width: min(100%, 1080px); }
  .t1-orbit { width: clamp(440px, 30vw, 600px); height: clamp(440px, 30vw, 600px); }
  .t1-coin-stage { width: clamp(340px, 24vw, 500px); height: clamp(340px, 24vw, 500px); }
}

/* ============================================================
   FRESH WEB v4 — люкс-апгрейд (черновик, 2026-07-28).
   Блок стоит ПОСЛЕ апскейл-блока V3.1 намеренно: поздние правила
   перекрывают его переопределения (грабли базового проекта).
   ============================================================ */

/* --- Витрина курсов: мета, программа, «кому» --- */

.reel-meta {
  font-size: clamp(0.68rem, 0.8vw, 0.95rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.45);
  margin: -0.3rem 0 1.1rem;
}
.reel-list {
  list-style: none;
  margin: 0 0 1.2rem;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}
.reel-list li {
  position: relative;
  padding-left: 1.15em;
  font-size: clamp(0.85rem, 1vw, 1.25rem);
  line-height: 1.5;
  color: rgba(244,240,234,0.78);
}
.reel-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.68em;
  width: 0.5em; height: 1px;
  background: var(--gold);
  opacity: 0.85;
}
.reel-for {
  font-size: clamp(0.8rem, 0.92vw, 1.15rem);
  font-style: italic;
  color: rgba(244,240,234,0.5);
  margin: 0 0 1.4rem;
}

/* Витрина 2026-08-02: слайд перестал быть вторым прайсом (цена и кнопка
   убраны) и стал редакционным — цитата автора задаёт тон, нумерованная
   программа отвечает на «что я реально пройду», сноска даёт сквозной
   контекст. Состав и порядок — из references/tg-content-base.md. */
.reel-quote {
  margin: 0 0 1.15rem;
  padding-left: 0.95rem;
  border-left: 2px solid rgba(212,175,55,0.55);
  font-style: italic;
  font-size: clamp(0.9rem, 1.05vw, 1.3rem);
  line-height: 1.45;
  color: rgba(244,240,234,0.74);
}
.reel-prog {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  counter-reset: prog;
}
.reel-prog li {
  counter-increment: prog;
  position: relative;
  padding-left: 2.2em;
  font-size: clamp(0.85rem, 1vw, 1.25rem);
  line-height: 1.45;
  color: rgba(244,240,234,0.8);
}
/* Нумерация 01…06 — тем же золотом, что и штрихи в прежнем списке */
.reel-prog li::before {
  content: counter(prog, decimal-leading-zero);
  position: absolute;
  left: 0; top: 0.12em;
  font-weight: 800;
  font-size: 0.76em;
  letter-spacing: 0.04em;
  color: var(--gold);
  opacity: 0.9;
}
.reel-note {
  margin: 0 0 0.95rem;
  font-size: clamp(0.78rem, 0.9vw, 1.05rem);
  line-height: 1.5;
  color: rgba(244,240,234,0.5);
}

/* «В стоимости» — то, что человек получает сверх уроков. Подсвечен слабой
   золотой подложкой: ценностный аргумент должен читаться как отдельный
   пункт сделки, а не теряться в сноске. */
.reel-incl {
  margin: 0 0 0.9rem;
  padding: 0.62em 0.9em;
  border-left: 2px solid rgba(212,175,55,0.55);
  border-radius: 0 6px 6px 0;
  background: rgba(212,175,55,0.06);
  font-size: clamp(0.78rem, 0.9vw, 1.05rem);
  line-height: 1.45;
  color: rgba(244,240,234,0.72);
}
.reel-incl b {
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #e8d9a8;
}

/* --- Упаковка «паспорт продукта» (правка владельца 2026-08-02) ---------
   Карточка витрины собрана как этикетка премиального товара: коллекционная
   бирка, золотой волосок по верхней кромке, зона «Программа», подвал с
   тихим ходом в тарифы и тиснёная печать-герб. Толстых рамок и неона нет —
   материал держит стекло, золото работает только волосками. */
.reel-card::after {
  content: "";
  position: absolute;
  left: 8%; right: 8%; top: 0; height: 1px;
  background: linear-gradient(90deg,
    transparent, rgba(244,231,189,0.55) 30%, rgba(168,135,60,0.3) 70%, transparent);
  pointer-events: none;
}
.reel-chip {
  position: absolute;
  top: clamp(1.1rem, 1.6vw, 2rem);
  right: clamp(1.2rem, 1.8vw, 2.2rem);
  padding: 0.45em 1em;
  font-size: clamp(0.56rem, 0.62vw, 0.72rem);
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #e8d9a8;
  border: 1px solid rgba(212,175,55,0.32);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(212,175,55,0.1), rgba(212,175,55,0.02));
}
.reel-zone {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 0.75rem;
  font-size: clamp(0.56rem, 0.62vw, 0.7rem);
  font-weight: 800;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(212,175,55,0.78);
}
.reel-zone::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(212,175,55,0.35), transparent);
}
/* Итог — тот же ярлык, но воздух сверху: это смысловой водораздел карточки */
.reel-zone--result { margin-top: 0.35rem; }
/* «Ответ автора» — мост между разрывом и цитатой: делает причинную связь
   видимой (боль ← ответ). Отступ меньше обычной зоны: он льнёт к цитате. */
.reel-zone--answer { margin-bottom: 0.45rem; }
/* РАЗРЫВ: строка боли до метода. Набрана крупнее программы и белее —
   это первое, что человек читает после названия курса. */
.reel-hook {
  margin: 0 0 0.95rem;
  font-size: clamp(0.95rem, 1.12vw, 1.35rem);
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: rgba(244,240,234,0.94);
  text-wrap: balance;
}
.reel-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px 18px;
  flex-wrap: wrap;
  margin-top: 0.2rem;
  padding-top: 0.9rem;
  border-top: 1px solid rgba(212,175,55,0.16);
}
.reel-foot .reel-for { margin: 0; flex: 1 1 260px; }
.reel-for-label {
  font-style: normal;
  font-weight: 800;
  font-size: 0.72em;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin-right: 0.7em;
}
/* Тихая дорога к покупке: не кнопка (кнопки живут в тарифах), а гравировка */
.reel-link {
  font-size: clamp(0.6rem, 0.68vw, 0.74rem);
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(212,175,55,0.9);
  text-decoration: none;
  transition: color 0.35s var(--ease-out);
}
.reel-link::after {
  content: "→";
  display: inline-block;
  margin-left: 0.5em;
  transition: transform 0.35s var(--ease-out);
}
.reel-link:hover { color: #f4e7bd; }
.reel-link:hover::after { transform: translateX(4px); }
.reel-link:focus-visible { outline: 1px solid rgba(212,175,55,0.6); outline-offset: 4px; }
/* Печать-герб: едва заметное тиснение над подвалом карточки */
.reel-seal {
  position: absolute;
  right: clamp(1rem, 1.6vw, 2rem);
  bottom: clamp(3.4rem, 5vh, 4.6rem);
  width: clamp(56px, 6.5vh, 92px);
  height: auto;
  opacity: 0.07;
  pointer-events: none;
  user-select: none;
}
.reel-card .reel-roman { margin-bottom: 0.9rem; }
.reel-card .reel-desc { margin-bottom: 1.2rem; }
.reel-card .reel-price { margin-bottom: 1.4rem; }

@media (max-height: 760px) and (min-width: 768px) {
  .reel-roman { font-size: 3.2rem; margin-bottom: 0.5rem; }
  .reel-card { padding: 2rem 2.4rem; }
}
@media (max-width: 767px) {
  .reel-meta { margin-bottom: 0.8rem; }
  .reel-list { gap: 0.4rem; }
  .reel-for { margin-bottom: 1rem; }
  /* Карточка выросла (программа курса) — absolute-раскладка базы клипала её
     верх внутри слайда 480px. Делаем карточку статичной: слайд растёт под
     контент, видео остаётся подложкой, верхний отступ — «окно» на видео. */
  .reel-slide { min-height: 0; }
  .reel-card {
    position: static;
    padding-top: clamp(200px, 52vw, 280px);
  }
}
@media (max-width: 560px) {
  .reel-roman { display: none; }
  /* padding-top = «окно» на видео курса (правило ниже ≤767-блока — держим и тут).
     Уменьшено 50vw → 32vw (аудит 2026-08-05, жалоба владельца «витрины не
     полностью отображаются»). Замер на 390px: карточка была 991px при
     доступных 826 — на 165px выше экрана, из них 195 занимало это окно.
     Свайпать вбок и одновременно скроллить вниз внутри одной карточки —
     худший из возможных жестов. Видео остаётся видно, просто полосой ниже. */
  .reel-card { padding: clamp(80px, 22vw, 150px) 1.4rem 1.7rem; }

  /* Внутренние отступы карточки: суммарно они давали около 140px на 12 блоков.
     Поджимаем примерно на треть — текст не трогаем, кегли остаются те,
     что подняты в блоке читаемости ниже по файлу. */
  .reel-title { margin-bottom: 12px; }
  .reel-hook  { margin-bottom: 10px; }
  .reel-quote { margin-bottom: 12px; }
  .reel-prog  { margin-bottom: 10px; }
  .reel-note  { margin-bottom: 10px; }
  .reel-zone  { margin-bottom: 7px; }
  /* Римская цифра скрыта строкой выше, но её нижний отступ оставался
     и держал 14px пустоты. */
  .reel-roman { margin-bottom: 0; }

  /* Программа курса — самый тяжёлый блок карточки: 276px, шесть пунктов
     по две строки. Поджимаем зазор и межстрочный, кегль не трогаем —
     он поднят в блоке читаемости ради телефона. */
  .reel-prog     { gap: 5px; }
  .reel-prog li  { line-height: 1.32; }
  .reel-incl     { margin-bottom: 10px; }
  .reel-list li { font-size: 0.82rem; }
  .reel-for { display: none; }
  /* Печать и бирка на телефоне только шумят */
  .reel-seal { display: none; }
  .reel-chip { top: 0.9rem; right: 0.9rem; font-size: 0.52rem; }
}

/* --- Наставник: цитата из интро студентов --- */

.t3-mentor-quote {
  margin: 1.1rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid rgba(244,240,234,0.1);
  font-size: clamp(0.85rem, 1vw, 1.2rem);
  line-height: 1.55;
  font-style: italic;
  color: rgba(244,240,234,0.66);
}
.t3-mentor-quote span {
  display: block;
  margin-top: 0.45rem;
  font-style: normal;
  font-size: 0.85em;
  letter-spacing: 0.08em;
  color: rgba(244,240,234,0.38);
}

/* Доводка радара ликвидности (метки пулов `fw-ping`/`fw-label`, статусная
   строка, пульс точки) удалена вместе с блоком `.t3-grid-b` по команде
   владельца 2026-07-30. Это была задача B6 бэклога — снимаю её оттуда. */

/* --- Амбиент-видео секций (Seedance): деликатные подложки --- */

.ambient-video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.4s ease;
  z-index: 0;
}
.ambient-video.is-on { opacity: var(--ambient-op, 0.16); }
.ambient-model { --ambient-op: 0.14; mix-blend-mode: screen; }
.ambient-cta { --ambient-op: 0.22; mix-blend-mode: screen; }

.s-t2 { position: relative; overflow: hidden; }
.s-t2 .t2-inner { position: relative; z-index: 1; }
.t6-box { position: relative; overflow: hidden; }
.t6-box > *:not(.ambient-video) { position: relative; z-index: 1; }

/* --- Split-заголовки: слова из-под маски --- */

/* ГЛАВНАЯ ПРИЧИНА СРЕЗАННЫХ БУКВ (правка владельца 2026-07-30).
   Маска прячет слово до появления, но при интерлиньяже 0.88–0.92 строчный
   бокс НИЖЕ самих глифов: у Inter 900 подъём ≈0.97em плюс свес ≈0.24em,
   итого ≈1.21em. Разницу `overflow: hidden` срезал — замер показал обрезку
   у ВСЕХ 42 слов на странице (от 5 до 11px на слово, «Ц», «Д», «Щ», «р»,
   «у» теряли выносные элементы).
   Поле сверху и снизу даёт глифам место, равный отрицательный отступ
   возвращает раскладку — высота заголовков не меняется ни на пиксель. */
[data-reveal="split"] .rw {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-block: 0.18em;
  margin-block: -0.18em;
}
[data-reveal="split"] .rw-in {
  display: inline-block;
  will-change: transform;
}

/* ГРАБЛЯ, пойманная 2026-07-30 (владелец: «куда пропала часть текста?»):
   у сплит-заголовка золотая часть переставала рисоваться — место в
   раскладке занято (замер: span 295×214, opacity 1), а глифов нет.

   Причина. `.gold-grad` красит текст приёмом «градиент + обрезка по
   буквам» (`background-clip: text` + `color: transparent`). Split-reveal
   оборачивает КАЖДОЕ слово внутри этого span в `.rw-in`, и GSAP вешает
   на них `transform` (после анимации остаётся `matrix(1,0,0,1,0,0)` —
   то есть навсегда). Трансформированный потомок рисуется в собственном
   контексте и НЕ попадает в область обрезки предка, поэтому градиент
   предка обрезается в ничто. Подтверждено кадрами: снятие transform у
   слов возвращает золото.

   Лечение — ДОБАВИТЬ градиент самим словам, а у предка ничего не
   отнимать. Элемент со своим же transform обрезает себя корректно.
   Правило намеренно аддитивное: без GSAP и при `prefers-reduced-motion`
   split не выполняется вовсе, слов `.rw-in` не существует — и золото
   красит предок, как раньше. Убери у предка градиент «для чистоты» —
   в этих двух случаях текст исчезнет совсем. */
[data-reveal="split"] .gold-grad .rw-in {
  background: linear-gradient(180deg, #fdf6e6 0%, #d4af37 55%, #6e5a2c 115%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}

/* --- Reduced motion: весь новый мотор отключается --- */

@media (prefers-reduced-motion: reduce) {
  .ambient-video { display: none; }
}

/* ============================================================
   ПРИБОРНЫЕ ПАНЕЛИ КУРСОВ (.reel-hud) — правая половина витрины.
   Один фирменный интерактив на слайд в общем стеклянном корпусе
   (урок разбора победителей Awwwards: research/awwwards-winners.md).
   ============================================================ */

.reel-hud {
  position: relative;
  z-index: 2;
  margin-left: auto;
  /* Ширина в точности как у карточки слева (правка владельца 2026-07-30:
     «масштаб этой карточки должен быть равен карточке слева»). Прежние
     clamp(300px, 26vw, 440px) давали 374px против 518px — панель читалась
     младшей по значению. Формула повторяет `.reel-card` буквально,
     поэтому пара остаётся равной на любой ширине окна. */
  --hud-w: clamp(480px, 36vw, 820px);
  width: var(--hud-w);
  max-width: 92vw;
  /* Отбивка подросла вместе с корпусом — иначе прибор упирался в стекло */
  padding: clamp(24px, 2.2vw, 40px);
  border-radius: 18px;
  border: 1px solid var(--glass-edge-light);
  background:
    linear-gradient(180deg,
      var(--glass-top) 0%,
      var(--glass-top-mid) 18%,
      var(--glass-mid) 48%,
      var(--glass-base) 100%);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.28),
    inset 0 -10px 18px rgba(0,0,0,0.7),
    0 0 0 1px rgba(0,0,0,0.5),
    0 14px 32px rgba(0,0,0,0.6),
    0 0 24px var(--glass-gold-reflect);
  /* Появление синхронно с активацией слайда */
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.8s var(--ease-out), transform 1s var(--ease-out);
}
.reel-slide.is-active .reel-hud { opacity: 1; transform: translateY(0); }

.hud-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 10px;
  margin-bottom: clamp(14px, 1.2vw, 22px);
  border-bottom: 1px solid rgba(244,240,234,0.1);
}
.hud-idx {
  font-weight: 900;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  color: var(--gold);
}
.hud-name {
  font-size: clamp(0.66rem, 0.75vw, 0.85rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.55);
}

.hud-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 900px;
}

.hud-foot { margin-top: clamp(14px, 1.2vw, 22px); }
.hud-line {
  margin: 0 0 12px;
  font-size: clamp(0.78rem, 0.88vw, 1rem);
  line-height: 1.55;
  color: rgba(244,240,234,0.62);
}
/* Строка про индикаторы в панели: тот же кегль, но с золотой чертой —
   это не описание прибора, а то, что покупатель получает в руки. */
.hud-line--incl {
  padding-left: 0.75em;
  border-left: 2px solid rgba(212,175,55,0.5);
  color: rgba(244,240,234,0.72);
}
.hud-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.hud-stats span {
  padding: 4px 10px;
  border-radius: 100px;
  border: 1px solid rgba(244,240,234,0.12);
  font-size: clamp(0.6rem, 0.68vw, 0.76rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.72);
}

/* --- Панель I: пирамида таймфреймов --- */

.tf-stack {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(8px, 0.7vw, 13px);
  transform-style: preserve-3d;
  transform: rotateX(calc(11deg + var(--hx, 0deg))) rotateY(calc(-15deg + var(--hy, 0deg)));
  transition: transform 0.5s var(--ease-out);
}
/* .tf-plane — позиция и глубина слоя (вход), .tf-slab — сам поворот на 360°,
   .tf-face — две грани физической пластины. Разнесено по элементам, чтобы
   transition входа и infinite-анимация вращения не спорили за transform. */
.tf-plane {
  --tz: calc((4 - var(--i)) * 13px);
  width: calc(100% - var(--i) * 8%);
  margin-left: calc(var(--i) * 4%);
  transform-style: preserve-3d;
  opacity: 0;
  transform: translateZ(var(--tz)) translateY(22px);
  transition: opacity 0.7s var(--ease-out), transform 0.9s var(--ease-out);
}
.reel-slide.is-active .tf-plane {
  opacity: 1;
  transform: translateZ(var(--tz)) translateY(0);
  transition-delay: calc(var(--i) * 0.085s + 0.2s);
}

/* --- Индивидуальный наклон плоскости за курсором (правка владельца
   2026-07-30: «при наведении на один из столбцов он вращался, реагируя
   на курсор») ---
   Отдельный слой МЕЖДУ .tf-plane и .tf-slab намеренно: у .tf-plane уже
   есть transition+delay для входа (задержка по каскаду, calc(i*0.085s)),
   у .tf-slab — keyframe-анимация автооборота. Повесь наклон на любой из
   них — он либо унаследует чужую задержку входа, либо будет драться за
   transform с keyframe-анимацией (она полностью перекрывает inline-стиль
   на том же свойстве). Здесь же transform свободен: своя, быстрая
   transition, без задержки, не участвует ни во входе, ни в обороте. */
.tf-tilt {
  transform-style: preserve-3d;
  transform: rotateX(var(--trx, 0deg)) rotateY(var(--try, 0deg));
  transition: transform 0.45s var(--ease-out);
}

/* Пока курсор ведёт конкретную плоскость — лёгкий золотой отклик:
   подтверждает, что реагирует именно ЭТА плоскость, а не вся стопка */
.tf-plane.is-hot .tf-face--front {
  border-color: rgba(212,175,55,0.5);
  box-shadow: 0 10px 22px rgba(0,0,0,0.5), 0 0 20px rgba(212,175,55,0.2);
  transition: border-color 0.35s ease, box-shadow 0.35s ease;
}

.tf-slab {
  position: relative;
  transform-style: preserve-3d;
}
/* Торец пластины: полоса, развёрнутая на 90° к граням. Пока пластина
   смотрит на зрителя — она невидима (стоит ребром), а в момент поворота
   на 90°/270°, когда обе грани скрыты, вспыхивает золотом. */
.tf-slab::before {
  content: "";
  position: absolute;
  top: 1px; bottom: 1px; left: 50%;
  width: 3px;
  margin-left: -1.5px;
  border-radius: 2px;
  transform: rotateY(90deg);
  background: linear-gradient(180deg,
    rgba(255,241,196,0.15), rgba(212,175,55,0.95) 45%, rgba(138,114,63,0.8) 100%);
  box-shadow: 0 0 16px rgba(212,175,55,0.65);
  pointer-events: none;
}
/* Оборот вокруг собственной ВЕРТИКАЛЬНОЙ оси: пластина всё время лежит
   горизонтально, а концы уходят в глубину — долгая выдержка лицом
   к зрителю → тяжёлый поворот на 360° → снова выдержка. Каскад по стопке. */
.reel-slide.is-active .tf-slab {
  animation: tf-flip 9s linear infinite;
  animation-delay: calc(var(--i) * 0.35s + 1.1s);
}
/* Кривая живёт НА кадре 24% — значит действует только на сегменте поворота
   24%→56% (2.9 с). Симметричный разгон-торможение: на границах скорость = 0,
   поэтому выход из покоя и возврат в него без рывка. */
@keyframes tf-flip {
  0%   { transform: rotateY(0deg); }
  24%  { transform: rotateY(0deg); animation-timing-function: cubic-bezier(0.55, 0, 0.45, 1); }
  56%  { transform: rotateY(360deg); }
  100% { transform: rotateY(360deg); }
}

.tf-face {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: clamp(7px, 0.6vw, 11px) clamp(11px, 0.9vw, 16px);
  border-radius: 8px;
  border: 1px solid rgba(244,240,234,0.13);
  box-shadow: 0 6px 14px rgba(0,0,0,0.45);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  overflow: hidden;
  /* Забираем задержку у .tf-slab, чтобы блик ::after шёл строго в такт
     повороту (animation-delay не наследуется сам — только явным inherit) */
  animation-delay: inherit;
}
/* Лицевая грань задаёт высоту, обратная лежит поверх и развёрнута на 180° */
.tf-face--front {
  position: relative;
  background: linear-gradient(180deg, rgba(255,255,255,0.07), rgba(10,10,10,0.55));
}
.tf-face--back {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  background:
    linear-gradient(100deg,
      rgba(10,10,10,0.72) 0%,
      rgba(212,175,55,0.30) 34%,
      rgba(244,240,234,0.16) 48%,
      rgba(138,114,63,0.26) 62%,
      rgba(10,10,10,0.75) 100%);
  border-color: rgba(212,175,55,0.32);
}
/* Тонкая гравировка на обороте — пластина не пустая, но и не кричит */
/* Гравировка убрана 2026-08-06: линия шла ровно по центру грани, и это
   имело смысл, пока оборот был ПУСТЫМ. Теперь там та же подпись, что и на
   лице, — линия её перечёркивала (замер: линия на y=3141, строка «МЕСЯЦ»
   занимала 3123..3146). */
.tf-face--back::before { content: none; }

/* Перелив: широкая мягкая волна золотого света медленно идёт по грани.
   Работает ТОЛЬКО пока пластина стоит лицом к зрителю; на время оборота
   гаснет (иначе блик спорит с вращением). */
.tf-face::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 62%;
  background: linear-gradient(105deg,
    transparent 0%,
    rgba(255,255,255,0.05) 22%,
    rgba(255,241,196,0.20) 42%,
    rgba(255,247,214,0.34) 52%,
    rgba(212,175,55,0.16) 66%,
    transparent 100%);
  opacity: 0;
  pointer-events: none;
}
.reel-slide.is-active .tf-face::after {
  animation: tf-sheen 9s linear infinite;
  animation-delay: inherit;
}
/* Фаза покоя разорвана границей цикла: 56%→100% и 0%→24% — это один
   непрерывный проход волны (6.1 с). Позиция на кадре 0% (152%) равна
   позиции на 100% — стык невидим. Окно оборота 24%→56% волна пропускает. */
@keyframes tf-sheen {
  0%   { opacity: 1; transform: translateX(152%); }
  19%  { opacity: 1; transform: translateX(269%); }
  24%  { opacity: 0; transform: translateX(300%); }
  56%  { opacity: 0; transform: translateX(-120%); }
  61%  { opacity: 1; transform: translateX(-89%); }
  100% { opacity: 1; transform: translateX(152%); }
}
/* filter на гранях не используем намеренно: он ломает backface-visibility
   в Chrome — свет даёт блик ::after и золотой оборот пластины. */

.tf-face b {
  font-weight: 800;
  font-size: clamp(0.72rem, 0.8vw, 0.92rem);
  letter-spacing: 0.08em;
}
.tf-face i {
  font-style: normal;
  font-size: clamp(0.58rem, 0.65vw, 0.74rem);
  letter-spacing: 0.04em;
  color: rgba(244,240,234,0.45);
}
/* Нижняя плоскость — точка исполнения, единственный золотой акцент стопки */
.tf-plane--exec .tf-face--front {
  border-color: rgba(212,175,55,0.5);
  background: linear-gradient(180deg, rgba(212,175,55,0.16), rgba(10,10,10,0.6));
}
.tf-plane--exec .tf-face--front b { color: var(--gold); }

/* --- Панель II: хронометр релиза --- */

/* Красный — намеренно только внутри этой панели: новости = зона риска.
   Остальной сайт остаётся золотым. */
[data-hud="clock"] { --nr: 198, 38, 52; }

.dial {
  position: relative;
  width: 92%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 1px solid rgba(var(--nr), 0.22);
  background:
    radial-gradient(circle at 50% 50%,
      rgba(var(--nr), 0.035) 0%,
      rgba(11,8,9,0.8) 62%,
      rgba(6,6,7,0.94) 100%);
  box-shadow:
    inset 0 0 42px rgba(var(--nr), 0.07),
    inset 0 0 0 1px rgba(0,0,0,0.6),
    0 0 22px rgba(var(--nr), 0.07);
  overflow: hidden;
}

/* Кольца дальности + перекрестие — сетка настоящего прибора */
.dial-grid {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side, transparent calc(32% - 1px), rgba(var(--nr), 0.17) calc(32% - 1px), rgba(var(--nr), 0.17) 32%, transparent 32%),
    radial-gradient(circle closest-side, transparent calc(64% - 1px), rgba(var(--nr), 0.12) calc(64% - 1px), rgba(var(--nr), 0.12) 64%, transparent 64%);
}
.dial-grid::before,
.dial-grid::after {
  content: "";
  position: absolute;
  background: rgba(var(--nr), 0.12);
}
.dial-grid::before { left: 6%; right: 6%; top: 50%; height: 1px; }
.dial-grid::after { top: 6%; bottom: 6%; left: 50%; width: 1px; }

.dial-ticks {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(var(--nr), 0.26) 0deg 0.5deg, transparent 0.5deg 7.5deg);
  /* closest-side по той же причине, что и у колец панели III: иначе полоса
     насечек уезжает внутрь и занимает четверть циферблата вместо ободка */
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(100% - 14px), #000 calc(100% - 14px), #000 100%, transparent 100%);
  mask: radial-gradient(circle closest-side, transparent calc(100% - 14px), #000 calc(100% - 14px), #000 100%, transparent 100%);
}

/* Луч: яркая передняя кромка + длинный затухающий след ПОЗАДИ неё.
   Отсчёт градиента сдвинут на -130°, поэтому самый плотный край
   приходится ровно на 0° (вверх), а хвост уходит против хода. */
.dial-sweep {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  background: conic-gradient(from -104deg,
    transparent 0deg,
    rgba(var(--nr), 0.02) 34deg,
    rgba(var(--nr), 0.055) 66deg,
    rgba(var(--nr), 0.12) 90deg,
    rgba(var(--nr), 0.24) 104deg);
  will-change: transform;
}
.dial-edge {
  position: absolute;
  left: 50%; top: 0; bottom: 50%;
  width: 2px;
  margin-left: -1px;
  background: linear-gradient(180deg, rgba(var(--nr), 0.05), rgba(var(--nr), 0.95));
  box-shadow: 0 0 14px rgba(var(--nr), 0.75);
}

/* Метки: место и свежесть задаёт JS (--a, --r, --k).
   Без JS остаются на исходных местах в полную яркость. */
.dial-marks { list-style: none; margin: 0; padding: 0; }
.dial-marks li {
  --k: 1;
  position: absolute;
  top: calc(50% - cos(calc(var(--a) * 1deg)) * var(--r));
  left: calc(50% + sin(calc(var(--a) * 1deg)) * var(--r));
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}
.dial-marks i {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: rgb(var(--nr));
  opacity: calc(0.22 + var(--k) * 0.78);
  box-shadow: 0 0 calc(4px + var(--k) * 14px) rgba(var(--nr), calc(var(--k) * 0.9));
}
/* Расходящееся кольцо отклика — шире и глуше по мере угасания метки */
.dial-marks li::after {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  width: 7px; height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  border: 1px solid rgba(var(--nr), 0.85);
  transform: scale(calc(1 + (1 - var(--k)) * 3.4));
  opacity: calc(var(--k) * 0.55);
  pointer-events: none;
}
.dial-marks span {
  font-size: clamp(0.52rem, 0.6vw, 0.68rem);
  font-weight: 700;
  letter-spacing: 0.11em;
  white-space: nowrap;
  color: rgba(244,240,234, calc(0.3 + var(--k) * 0.6));
  text-shadow: 0 0 8px rgba(6,6,7,0.98), 0 0 3px rgba(6,6,7,0.9);
}

.dial-core {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 58%;
}
.dial-core b {
  display: block;
  font-weight: 900;
  font-size: clamp(1.3rem, 1.75vw, 2.2rem);
  letter-spacing: 0.02em;
  line-height: 1;
  text-shadow: 0 0 18px rgba(var(--nr), 0.45);
}
.dial-core i {
  display: block;
  margin-top: 6px;
  font-style: normal;
  font-size: clamp(0.55rem, 0.62vw, 0.7rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.42);
}

/* Строка отклика: что луч нашёл прямо сейчас */
.dial-readout {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(244,240,234,0.08);
  font-size: clamp(0.6rem, 0.68vw, 0.76rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.6);
  min-height: 1em;
}
.dial-readout-dot {
  flex: none;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgb(var(--nr));
  box-shadow: 0 0 9px rgba(var(--nr), 0.9);
}

@keyframes hud-spin { to { transform: rotate(360deg); } }

/* --- Панель III: вложенные циклы 20 / 40 / 60 дней --- */

.cyc {
  position: relative;
  width: 94%;
  aspect-ratio: 1 / 1;
  transform-style: preserve-3d;
  /* Наклон всей системы колец за курсором — тот же жест, что у стопки
     таймфреймов в панели I (модуль 16b main.js) */
  transform: rotateX(var(--hx, 0deg)) rotateY(var(--hy, 0deg));
  transition: transform 0.5s var(--ease-out);
}
.cyc-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(244,240,234,0.12);
  opacity: 0;
  transform: scale(0.88);
  transition: opacity 0.8s var(--ease-out), transform 1s var(--ease-out);
}
.reel-slide.is-active .cyc-ring { opacity: 1; transform: scale(1); }
/* --t — период золотой дуги, --tl — период орбиты подписи (намеренно разные:
   дуга периодически догоняет подпись), --la — стартовый угол подписи. */
/* Скорости разведены по орбитам: чем дальше кольцо, тем медленнее тела.
   Оба метеора дальней орбиты (44 и 56 с) заметно медленнее метеоров
   средней (31 с) и внутренней (21 с) — иначе соседние дуги идут почти
   синхронно и читаются парой на одном кольце. */
.cyc-ring--60 { inset: 0;   --t: 44s; --t2: 56s; --tl: 64s; --la: 0deg; }
.cyc-ring--40 { inset: 14%; --t: 31s; --tl: 46s; --la: 118deg; }
.cyc-ring--20 { inset: 22%; --t: 21s; --tl: 33s; --la: 242deg; }
.reel-slide.is-active .cyc-ring--60 { transition-delay: 0.2s; }
.reel-slide.is-active .cyc-ring--40 { transition-delay: 0.32s; }
.reel-slide.is-active .cyc-ring--20 { transition-delay: 0.44s; }

/* Метеор активной фазы бежит по кольцу ПО ЧАСОВОЙ (hud-spin = rotate +360°).
   Голова сидит на 0°, хвост тянется НАЗАД, против хода: отсчёт градиента
   сдвинут на −74°, поэтому прозрачное начало приходится на −74°, а полная
   заливка — ровно на 0°. Сразу за головой (75°) обрыв в прозрачность,
   иначе последний стоп залил бы весь круг золотом. */
.cyc-ring::before,
.cyc-meteor {
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  /* ВАЖНО: circle closest-side. Без указания размера радиальный градиент
     считается от farthest-corner, и его 100% упирается в УГОЛ квадрата —
     тогда «50%» = 0.354 ширины, и метеор рисуется на радиусе соседнего
     внутреннего кольца. С closest-side 100% = ровно половина стороны,
     то есть радиус самого кольца. */
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(100% - 2px), #000 calc(100% - 2px), #000 100%, transparent 100%);
  mask: radial-gradient(circle closest-side, transparent calc(100% - 2px), #000 calc(100% - 2px), #000 100%, transparent 100%);
}
.cyc-ring::before {
  content: "";
  background: conic-gradient(from -74deg,
    rgba(212,175,55,0) 0deg,
    rgba(212,175,55,0.5) 55deg,
    var(--gold) 74deg,
    rgba(212,175,55,0) 75deg);
  animation: hud-spin var(--t) linear infinite;
}
/* Второй метеор на дальней орбите: короче хвост, тише свет и своя скорость —
   тела периодически догоняют друг друга, узор не зацикливается */
.cyc-meteor {
  background: conic-gradient(from -50deg,
    rgba(212,175,55,0) 0deg,
    rgba(212,175,55,0.3) 36deg,
    rgba(212,175,55,0.72) 50deg,
    rgba(212,175,55,0) 51deg);
  animation: hud-spin var(--t2, 33s) linear infinite;
  animation-delay: calc(var(--t2, 33s) * -0.45);
}
/* Насечки делений цикла — кольцо перестаёт быть голой линией */
.cyc-ring::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(244,240,234,0.26) 0deg 0.4deg, transparent 0.4deg 12deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(100% - 6px), #000 calc(100% - 6px), #000 100%, transparent 100%);
  mask: radial-gradient(circle closest-side, transparent calc(100% - 6px), #000 calc(100% - 6px), #000 100%, transparent 100%);
}

/* Подпись плывёт по своей орбите: внешний слой крутит систему координат,
   внутренний крутится ровно навстречу — текст всегда остаётся прямым
   (тот же приём, что у монет-планет вокруг герба в секции «Система»). */
.cyc-tag {
  position: absolute;
  inset: 0;
  /* Выше герба: у подписи своя плашка, поэтому на пересечении с ним
     она читается, а не тонет под подложкой */
  z-index: 3;
  animation: cyc-orbit var(--tl) linear infinite;
}
.cyc-tag-pos {
  position: absolute;
  left: 50%; top: 0;
  transform: translate(-50%, -50%);
}
.cyc-tag i {
  display: block;
  padding: 2px 7px;
  border-radius: 4px;
  background: rgba(10,10,10,0.92);
  font-style: normal;
  font-size: clamp(0.55rem, 0.63vw, 0.72rem);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.78);
  white-space: nowrap;
  animation: cyc-orbit-rev var(--tl) linear infinite;
}
@keyframes cyc-orbit {
  from { transform: rotate(var(--la)); }
  to   { transform: rotate(calc(var(--la) + 360deg)); }
}
@keyframes cyc-orbit-rev {
  from { transform: rotate(calc(var(--la) * -1)); }
  to   { transform: rotate(calc(var(--la) * -1 - 360deg)); }
}

/* Импульс от центра — цикл «выдыхает» наружу раз в 7 с */
.cyc-pulse {
  position: absolute;
  left: 50%; top: 50%;
  width: 34%; height: 34%;
  margin: -17% 0 0 -17%;
  border-radius: 50%;
  border: 1px solid rgba(212,175,55,0.55);
  opacity: 0;
  animation: cyc-pulse 7s ease-out infinite;
}
@keyframes cyc-pulse {
  0%   { transform: scale(0.6); opacity: 0; }
  14%  { opacity: 0.5; }
  72%  { transform: scale(2.75); opacity: 0; }
  100% { transform: scale(2.75); opacity: 0; }
}

.cyc-core {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 36%;
  z-index: 2;
}
/* Тёмная подложка: снимает с герба шум фонового видео, детали читаются */
.cyc-core::before {
  content: "";
  position: absolute;
  inset: -14%;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(8,8,9,0.94) 52%,
    rgba(8,8,9,0.55) 78%,
    transparent 100%);
}
/* Ореол за гербом: дышит, отделяет знак от колец и вытягивает детали */
.cyc-halo {
  position: absolute;
  inset: -34%;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(212,175,55,0.26) 0%,
    rgba(212,175,55,0.07) 52%,
    transparent 72%);
  animation: cyc-breathe 6.5s ease-in-out infinite;
}
@keyframes cyc-breathe {
  50% { opacity: 0.5; transform: scale(1.09); }
}
.cyc-core img {
  position: relative;
  display: block;
  width: 100%;
  filter:
    drop-shadow(0 0 20px rgba(212,175,55,0.5))
    drop-shadow(0 2px 6px rgba(0,0,0,0.9))
    contrast(1.12) saturate(1.08) brightness(1.12);
}

/* ============================================================
   ПОДАЧА ИЗ v3-BRUTALISM (перенос по просьбе владельца 2026-07-28):
   скобочный индекс секции, крупный титул слева + пронумерованные
   абзацы справа, бокс с шапкой-плашкой. Взята ТИПОГРАФИКА и структура —
   палитра остаётся нуар+золото, кремовый фон оригинала не переносим.
   ============================================================ */

.brut-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding-bottom: 12px;
  margin-bottom: clamp(28px, 3vw, 56px);
  border-bottom: 1px solid rgba(244,240,234,0.14);
  font-size: clamp(0.62rem, 0.72vw, 0.84rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.brut-idx { color: var(--gold); font-weight: 700; }
.brut-name { color: rgba(244,240,234,0.82); font-weight: 700; }
.brut-meta { margin-left: auto; color: rgba(244,240,234,0.4); }

.brut-split {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(28px, 4vw, 88px);
  align-items: start;
  margin-bottom: clamp(36px, 4vw, 72px);
}

/* Титул «Приватная группа» набран от КОЛОНКИ, а не от окна.
   Замер до правки на окне 1050: колонка 24…426, а слово «ПРИВАТНАЯ»
   доезжало до 493 — вылет 67px, и оно заезжало на стеклянную плашку
   списка (плашка начинается с 468). Базовые 7.5vw давали 78.75px при
   колонке 402px: девять капсов физически не влезают.
   Та же ошибка, что была в FAQ (этап 9.3) — лечится так же. */
.brut-split .brut-display { font-size: clamp(2.2rem, 4.6vw, 6.4rem); }

.brut-display {
  font-weight: 900;
  font-size: clamp(3rem, 7.5vw, 8.5rem);
  line-height: var(--head-leading);
  letter-spacing: var(--head-track);
  text-transform: uppercase;
  margin: 0;
}

/* Секции идут поверх видеофона: мягкий тёмный ореол держит читаемость
   на светлых кадрах (тот же приём, что у подписей радара). */
.brut-head, .brut-display, .brut-lead, .brut-list p, .brut-list i {
  text-shadow: 0 0 14px rgba(6,6,7,0.9), 0 1px 3px rgba(6,6,7,0.8);
}

.brut-lead {
  margin: clamp(20px, 2vw, 32px) 0 0;
  font-size: clamp(0.95rem, 1.12vw, 1.35rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.8);
  max-width: 34em;
}
.brut-lead b { color: var(--white); font-weight: 700; }

.brut-cta { display: inline-block; margin-top: clamp(20px, 2vw, 32px); }

/* Пронумерованные абзацы: номер вынесен на поля, между пунктами — волосок */
.brut-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.brut-list li {
  display: grid;
  grid-template-columns: clamp(28px, 2.6vw, 44px) minmax(0, 1fr);
  gap: clamp(10px, 1vw, 18px);
  padding: clamp(18px, 1.8vw, 30px) 0;
  border-top: 1px solid rgba(244,240,234,0.1);
}
.brut-list li:first-child { border-top: 0; padding-top: 0; }
.brut-list li:last-child { border-bottom: 1px solid rgba(244,240,234,0.1); }
.brut-list i {
  font-style: normal;
  font-weight: 700;
  font-size: clamp(0.6rem, 0.7vw, 0.8rem);
  letter-spacing: 0.1em;
  color: var(--gold);
  padding-top: 0.35em;
}
.brut-list p {
  margin: 0;
  font-size: clamp(0.95rem, 1.1vw, 1.32rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.88);
}
.brut-list b { color: var(--white); font-weight: 700; }
.brut-list--tight p { font-size: clamp(0.9rem, 1.02vw, 1.2rem); }
.brut-list--tight li { padding: clamp(13px, 1.3vw, 20px) 0; }

/* ============================================================
   СПИСОК «ПРИВАТНАЯ ГРУППА» НА СТЕКЛЕ (2026-07-30)

   Владелец: «текст сложно читать, он прямо над анимацией быка».
   Замер: под строками лежит `video.layer-video` — полноэкранное фоновое
   видео ПОД всей страницей (не фон секции), поэтому трогать его нельзя.
   Читаемость держал только тёмный ореол на буквах, и на светлых кадрах
   каркаса быка его не хватало.

   Выбор владельца — стеклянная плашка: тот же материал, что у карточек
   наставника и голосов, поэтому секция не выбивается из языка сайта.
   Материал взят токенами `--glass-*`, а не подобран на глаз.
   ============================================================ */

.brut-list--glass {
  padding: clamp(20px, 1.8vw, 34px) clamp(22px, 2vw, 38px);
  border: 1px solid var(--glass-edge-light);
  border-radius: 16px;
  background:
    linear-gradient(180deg,
      var(--glass-top) 0%,
      var(--glass-top-mid) 18%,
      var(--glass-mid) 48%,
      var(--glass-base) 100%);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.28),
    inset 0 -10px 18px rgba(0,0,0,0.7),
    0 0 0 1px rgba(0,0,0,0.5),
    0 18px 40px rgba(0,0,0,0.6),
    0 0 24px var(--glass-gold-reflect);
  /* Своя плоскость: без этого blur иногда считается от неверного слоя,
     когда под элементом лежит `position: fixed` видео (грабля проекта) */
  transform: translateZ(0);
}

/* Первый пункт больше не прижат к верху: у плашки своя отбивка, и
   `padding-top: 0` из базового правила оставлял бы букву на кромке */
.brut-list--glass li:first-child { padding-top: 0; }
.brut-list--glass li:last-child { border-bottom: 0; padding-bottom: 0; }

/* На стекле ореол больше не нужен — он был костылём для чтения поверх
   видео. Снимаем: без него буквы чище, а контраст даёт сама плашка. */
.brut-list--glass p {
  color: var(--white);
  text-shadow: none;
}
.brut-list--glass i { text-shadow: none; }

/* Если браузер не умеет backdrop-filter — плашка становится плотной,
   читаемость не зависит от размытия */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .brut-list--glass {
    background: linear-gradient(180deg, rgba(20,21,23,0.95), rgba(6,7,8,0.97));
  }
}

/* Бокс «Об авторе»: плашка-шапка + тело, как в оригинале */
.brut-box {
  margin-top: clamp(16px, 1.6vw, 26px);
  border: 1px solid rgba(244,240,234,0.16);
  border-radius: 6px;
  overflow: hidden;
}
.brut-box-bar {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px clamp(12px, 1vw, 18px);
  background: rgba(244,240,234,0.07);
  border-bottom: 1px solid rgba(244,240,234,0.12);
  font-size: clamp(0.58rem, 0.66vw, 0.74rem);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.brut-box-bar span:first-child { color: rgba(244,240,234,0.72); }
.brut-box-bar span:last-child { color: var(--gold); }
.brut-box-body {
  margin: 0;
  padding: clamp(14px, 1.2vw, 22px) clamp(12px, 1vw, 18px);
  font-size: clamp(0.85rem, 0.98vw, 1.15rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.7);
}

@media (max-width: 900px) {
  .brut-split { grid-template-columns: minmax(0, 1fr); gap: clamp(24px, 4vw, 40px); }
  .brut-display { font-size: clamp(2.6rem, 12vw, 4.6rem); }
  .brut-head { flex-wrap: wrap; }
  .brut-meta { margin-left: 0; width: 100%; }
}

/* Микротекст под кнопками призыва: снимает ощущение платного порога */
.t6-micro {
  margin: clamp(18px, 1.6vw, 28px) auto 0;
  max-width: 46ch;
  font-size: clamp(0.72rem, 0.82vw, 0.95rem);
  letter-spacing: 0.02em;
  line-height: 1.6;
  color: rgba(244,240,234,0.45);
}

/* ============================================================
   FAQ — снимает возражения перед финальным призывом.
   Аккордеон на нативных <details>: работает с клавиатуры и без JS.
   ============================================================ */

.s-faq { padding: 14vh 0; }
/* Та же логика, что у контейнеров V3.1 (правка владельца 2026-07-30 про
   пустые поля): до ~1600px — прежние min(1280px, 94vw), дальше 80% окна,
   потолок 2400 — FAQ читают, строки длиннее нельзя */
.faq-inner { width: min(max(1280px, 80vw), 94vw, 2400px); margin: 0 auto; }

.faq-split {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(32px, 5vw, 120px);
  align-items: start;
}

/* Левая колонка липкая: титул и визитка остаются в кадре, пока читатель
   идёт по вопросам. Только десктоп — на мобиле колонка в потоке. */
@media (min-width: 901px) {
  .faq-side {
    position: sticky;
    top: clamp(84px, 14vh, 170px);
  }
  /* Кегль титула считан от КОЛОНКИ (≈42.5% контейнера), а не от окна:
     прежний clamp(3rem, 7.5vw, 8.5rem) на широких мониторах давал слово
     «ВОПРОСЫ» шире своей колонки — буквы наезжали на список. Замер:
     8 капсов Inter 900 ≈ 4.96em; колонка на 1440 — 515px, на 2400-м
     контейнере — 980px. Потолок 7rem держит слово в 555px. */
  .faq-split .brut-display {
    font-size: clamp(2.8rem, 5vw, 7rem);
    line-height: 0.98;
  }
}

/* Подпись под титулом: короткий факт, отбитый золотым волоском */
.faq-note {
  margin: clamp(22px, 2vw, 36px) 0 0;
  max-width: 30ch;
  font-size: clamp(0.92rem, 1.05vw, 1.25rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.55);
  text-shadow: 0 0 14px rgba(6,6,7,0.9);
}
.faq-note::before {
  content: "";
  display: block;
  width: 44px;
  height: 1px;
  margin-bottom: clamp(14px, 1.3vw, 22px);
  background: linear-gradient(90deg, var(--gold), transparent);
}

/* Визитка «не нашёл вопрос»: стеклянный чип с контактом. Ссылка
   разрешённая — контакт @tony_ict (правила контента, CLAUDE.md §4) */
.faq-ask {
  display: inline-flex;
  flex-direction: column;
  gap: 6px;
  margin-top: clamp(24px, 2.2vw, 40px);
  padding: clamp(16px, 1.5vw, 26px) clamp(20px, 1.8vw, 32px);
  border: 1px solid var(--glass-edge-light);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--glass-top), var(--glass-base));
  text-decoration: none;
  transition: border-color 0.4s ease, box-shadow 0.4s ease, transform 0.4s var(--ease-out);
}
.faq-ask span {
  font-size: clamp(0.62rem, 0.72vw, 0.8rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244,240,234,0.45);
}
.faq-ask b {
  font-size: clamp(0.95rem, 1.1vw, 1.3rem);
  font-weight: 700;
  color: var(--white);
  transition: color 0.35s ease;
}
.faq-ask i {
  font-style: normal;
  display: inline-block;
  margin-left: 6px;
  color: var(--gold);
  transition: transform 0.35s var(--ease-out);
}
.faq-ask:hover {
  border-color: rgba(212,175,55,0.45);
  box-shadow: 0 12px 32px rgba(0,0,0,0.5), 0 0 24px rgba(212,175,55,0.12);
  transform: translateY(-2px);
}
.faq-ask:hover b { color: var(--gold); }
.faq-ask:hover i { transform: translateX(5px); }
.faq-ask:focus-visible {
  outline: 1px solid rgba(212,175,55,0.7);
  outline-offset: 4px;
}

.faq-item {
  border-top: 1px solid rgba(244,240,234,0.12);
}
.faq-item:last-child { border-bottom: 1px solid rgba(244,240,234,0.12); }

.faq-item summary {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(16px, 1.6vw, 28px);
  padding: clamp(20px, 2vw, 34px) 0;
  cursor: pointer;
  list-style: none;
  font-weight: 700;
  font-size: clamp(1rem, 1.28vw, 1.6rem);
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: rgba(244,240,234,0.9);
  text-shadow: 0 0 14px rgba(6,6,7,0.9);
  transition: color 0.35s var(--ease-out), padding-left 0.4s var(--ease-out);
}

/* Золотая черта-акцент: выдвигается слева при наведении и у открытого
   вопроса, строка уступает ей место — кинетика вместо шаблонного ховера */
.faq-item summary::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: clamp(18px, 1.6vw, 30px);
  height: 1.5px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 0;
  transition: transform 0.4s var(--ease-out), opacity 0.3s ease;
}
.faq-item summary:hover,
.faq-item[open] summary { padding-left: clamp(30px, 2.6vw, 48px); }
.faq-item summary:hover::before,
.faq-item[open] summary::before { transform: scaleX(1); opacity: 1; }
/* Убираем родные маркеры раскрытия у Chrome и Safari */
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::marker { content: ""; }
.faq-item summary:hover { color: var(--gold); }
.faq-item summary:focus-visible {
  outline: 1px solid rgba(212,175,55,0.7);
  outline-offset: 4px;
}

/* Знак «+» из модулей-принципов: тот же жест, поворот в «×» при раскрытии */
.faq-item summary i {
  flex: none;
  margin-left: auto;
  position: relative;
  width: clamp(24px, 1.9vw, 32px);
  height: clamp(24px, 1.9vw, 32px);
  border: 1px solid rgba(212,175,55,0.45);
  border-radius: 6px;
  transition: transform 0.4s var(--ease-out), background 0.4s ease, border-color 0.4s ease;
}
.faq-item summary i::before,
.faq-item summary i::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  background: var(--gold);
  transition: background 0.4s ease;
}
.faq-item summary i::before { width: 44%; height: 1.5px; transform: translate(-50%, -50%); }
.faq-item summary i::after  { width: 1.5px; height: 44%; transform: translate(-50%, -50%); }
.faq-item[open] summary i {
  transform: rotate(135deg);
  background: var(--gold);
  border-color: var(--gold);
}
.faq-item[open] summary i::before,
.faq-item[open] summary i::after { background: #0a0a0a; }
.faq-item[open] summary { color: var(--gold); }

/* Ответ отбит на ту же величину, что и сдвиг открытого вопроса —
   вопрос и ответ стоят на одной вертикали */
.faq-body { padding: 0 clamp(40px, 3vw, 52px) clamp(20px, 1.8vw, 32px) clamp(30px, 2.6vw, 48px); }
.faq-body p {
  margin: 0;
  max-width: 68ch;
  font-size: clamp(0.92rem, 1.08vw, 1.3rem);
  line-height: 1.65;
  color: rgba(244,240,234,0.68);
  text-shadow: 0 0 14px rgba(6,6,7,0.9);
}
/* <details> не рендерит содержимое в закрытом виде, поэтому высоту
   не анимируем — ответ мягко проявляется уже отрисованным. */
.faq-item[open] .faq-body { animation: faq-in 0.45s var(--ease-out); }
@keyframes faq-in {
  from { opacity: 0; transform: translateY(-10px); }
}

@media (max-width: 900px) {
  .faq-split { grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 4vw, 36px); }
  .faq-note { max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
  .faq-item summary i { transition: none; }
  .faq-item[open] .faq-body { animation: none; }
  .faq-item summary,
  .faq-item summary::before,
  .faq-ask, .faq-ask b, .faq-ask i { transition: none; }
}

/* ============================================================
   QT-ДИСК — фирменный знак в секции «Система» (2026-07-29).
   Механика — референс steven.com (диск с кольцевой типографикой),
   содержание — диаграмма владельца: QT ⊃ (IPDA · PO3 · MMXM), SMT
   в пересечении. Всё в нуар+золото, никакого копирования референса.
   Маски колец — ТОЛЬКО `circle closest-side` (грабли farthest-corner).
   ============================================================ */




/* Золотой ореол снят (ахроматизация); заземление даёт подиум-тень —
   гигантское мягкое затемнение вокруг колеса, как студия референса */



/* Тёмное лицо диска: гасит видеофон под кругами (нейтральное, без тепла) */
/* Лицо диска — глубокая матовая чернь. Гасит видеофон полностью,
   чтобы металл и подписи читались по чистому, а не «сквозь дымку». */

/* Спекуляр: узкий мягкий луч света медленно обходит диск */


/* Обод: металл с минутными насечками и двумя золотыми волосками */


/* Кольцевая типографика в ободе, медленно плывёт против хода тройки */



/* Золотой метеор бежит по внутренней кромке обода (хвост сзади) */


/* Тройка кругов: медленное вращение системы, текст держится прямым
   контрвращением (приём орбит), пересечения светлеют сами — альфы
   полупрозрачных стёкол складываются, тройное пересечение самое светлое */

/* Венн НЕ вращается: в любой момент он должен стоять симметрично.
   Дрейф вращения читался как перекос («масштаб не симметричен»). */



/* Классический симметричный венн: три круга по 120°, чёткие кольца */



/* SMT — точка пересечения: единственный золотой акцент центра */




/* Застёжка QT внизу обода — как заводная головка часов */



/* --- Сегментное колесо (механика референса steven.com, сборка своя) ---
   4 дуги-сегмента; колесо проворачивается тяжёлым ходом, ставя активный
   сегмент в «прожектор» на правом боку; активный выпирает наружу
   (translate по нормали сегмента), утолщается и вспыхивает, его круг
   в схеме загорается золотом. Надписи лежат дугой ПО кольцу — внизу
   переворачиваются, как у референса: это честная механика круга. */


/* Внешнее статичное кольцо — внешний круг логотипа (QT) */

/* Крупно и контрастно: на 300–450px мелкий тусклый шрифт читается
   грязью, а не гравировкой */

/* Внутреннее кольцо: подложка под сегментами */

/* Ахроматизация (пункт 8 сравнения): металл без тепла, золото живёт
   только в центре (SMT и его отклики) */




/* Гравированные стрелки хода между сегментами */

/* Волосковые дуги-трассы снаружи колеса */


/* Стеклянная сфера — доминанта центра (40% колеса, как у референса).
   Свет: верхний полумесяц-софит, нижний отражённый, краевая рефракция. */

/* Мир внутри линзы: круглая маска собственным радиусом, приглушён и
   утоплен виньеткой — контент «внутри шара», а не наклейка */


/* Венн переезжает внутрь сферы — компактные переопределения */



/* --- Появление (механика референса): кольца въезжают вращением
   с тяжёлым торможением навстречу друг другу, сфера растёт из точки --- */






/* Кольцо статично, как у референса: живут сегменты и центр, не колесо */


/* Полосы — заливные кольцевые секторы с радиальным градиентом поперёк:
   настоящая выпуклость (тёмная кромка → хромовый гребень → тёмная кромка) */
/* Фильтр света снят: он размывал форму, чтобы посчитать блик, и мылил
   кромки. На нашем размере решает ЧЁТКАЯ геометрия, а не псевдорендер. */







/* Вспышка активного сегмента — белая накладка той же геометрии */


/* Выступ: масштаб от центра колеса двигает сектор наружу по радиусу
   и утолщает полосу — как выдвинутый сегмент референса */
/* 1.16: сектор выезжает наружу, ПЕРЕКРЫВАЯ внешнее кольцо — как у
   референса; подпись растёт вместе с ним */





/* --- Абзацы «Метода» переехали внутрь карточки Tony-1 ---
   Титул секции стал широким, знак уменьшен, чтобы три абзаца помещались
   в карточку без обрезки (у .t2-massive стоит overflow:hidden). */

.brut-display--wide {
  margin-bottom: clamp(24px, 2.4vw, 44px);
  max-width: 14ch;
}

/* Ядро метода — единственный абзац карточки, поэтому набран крупнее
   модулей справа: это заявление, а не пункт списка. */
.t2-core {
  position: relative;
  z-index: 1;
  margin: 0;
  padding-top: clamp(16px, 1.5vw, 26px);
  border-top: 1px solid rgba(244,240,234,0.14);
  font-size: clamp(0.9rem, 1.05vw, 1.28rem);
  line-height: 1.6;
  color: rgba(244,240,234,0.78);
}
.t2-core b { color: var(--white); font-weight: 700; }

/* Знак — единственный визуал карточки, поэтому крупный: карточка тянется
   по высоте трёх рядов модулей, мелкий герб в ней терялся */
.t2-massive .t2-mark {
  width: clamp(200px, 22vw, 400px);
  height: clamp(200px, 22vw, 400px);
  margin: clamp(14px, 1.4vw, 26px) auto;
}

/* Выделения внутри модулей + их поведение при инверсии */
.t2-feature p b { color: rgba(244,240,234,0.92); font-weight: 700; }
.t2-feature:hover p b,
.t2-feature:has(:focus-visible) p b { color: #0a0a0a; }

@media (max-width: 900px) {
  .brut-display--wide { max-width: none; }
}

/* --- Модули-принципы: крупный номер + инверсия карточки при наведении ---
   Жест из v3-brutalism: там выделенная строка переворачивалась в чёрное.
   У нас фон уже тёмный, поэтому инверсия идёт в другую сторону — карточка
   наливается тёплым белым, текст становится чёрным. */

.t2-feature {
  display: flex;
  flex-direction: column;
  cursor: default;
  transition:
    transform 0.45s var(--ease-out),
    background 0.5s var(--ease-out),
    border-color 0.45s ease,
    box-shadow 0.5s var(--ease-out);
}
.t2-num {
  display: block;
  font-weight: 900;
  font-size: clamp(2.1rem, 3vw, 3.6rem);
  line-height: 0.9;
  letter-spacing: var(--head-track);
  color: var(--gold);
  margin-bottom: clamp(10px, 1vw, 18px);
  transition: color 0.5s var(--ease-out);
}
.t2-feature h3 { transition: color 0.5s var(--ease-out); }
.t2-feature p  { transition: color 0.5s var(--ease-out); }

.t2-plus {
  position: absolute;
  right: clamp(16px, 1.3vw, 24px);
  bottom: clamp(16px, 1.3vw, 24px);
  width: clamp(28px, 2.2vw, 38px);
  height: clamp(28px, 2.2vw, 38px);
  display: grid;
  place-items: center;
  border-radius: 6px;
  background: var(--gold);
  color: #0a0a0a;
  font-weight: 900;
  font-size: clamp(1rem, 1.2vw, 1.4rem);
  line-height: 1;
  opacity: 0;
  transform: scale(0.6) rotate(-45deg);
  transition: opacity 0.4s var(--ease-out), transform 0.5s var(--ease-out);
  z-index: 2;
}

.t2-feature:hover,
.t2-feature:focus-visible,
.t2-feature:has(:focus-visible) {
  transform: translateY(-8px);
  background: linear-gradient(180deg, #f6f2ec 0%, #e4dbcb 100%);
  border-color: rgba(212,175,55,0.75);
  box-shadow: 0 20px 46px rgba(0,0,0,0.62), 0 0 0 1px rgba(212,175,55,0.32);
  outline: none;
}
.t2-feature:hover h3,
.t2-feature:has(:focus-visible) h3 { color: #0a0a0a; }
.t2-feature:hover p,
.t2-feature:has(:focus-visible) p { color: rgba(10,10,10,0.7); }
.t2-feature:hover .t2-num,
.t2-feature:has(:focus-visible) .t2-num { color: rgba(138,114,63,0.85); }
.t2-feature:hover .t2-plus,
.t2-feature:has(:focus-visible) .t2-plus { opacity: 1; transform: scale(1) rotate(0deg); }
/* Золотой блик в углу мешает на светлой заливке — гасим */
.t2-feature:hover::after,
.t2-feature:has(:focus-visible)::after { opacity: 0; }
.t2-feature::after { transition: opacity 0.4s ease; }

@media (prefers-reduced-motion: reduce) {
  .t2-feature, .t2-plus { transition: none; }
  .t2-feature:hover, .t2-feature:has(:focus-visible) { transform: none; }
  .t2-plus { transform: none; }
}

/* --- Карточки тарифов: та же инверсия, что у модулей «Метода» ---
   Правка владельца 2026-07-30: «надо чтоб эти карточки меняли цвет при
   наведении так же, как в блоке МЕТОД выше».

   Отличие от `.t2-feature`: у тарифов висит `data-tilt`, и модуль наклона
   пишет `transform` и `box-shadow` ИНЛАЙНОМ, а инлайн перебивает любое
   правило CSS. Поэтому здесь меняется только цвет: сдвиг и тень уже даёт
   наклон, дублировать их в CSS бессмысленно — они бы не применились.

   Блок стоит ПОСЛЕ `.t4-card.featured` (строка ~768) намеренно: у обоих
   селекторов одинаковая специфичность, и побеждает поздний — иначе
   золотая заливка «рекомендуем» не пускала бы светлую. */

.t4-card,
.t4-badge,
.t4-card h3,
.t4-card > p,
.t4-list li,
.t4-list li::before,
.t4-price,
.t4-card .btn {
  transition-property: background, border-color, color, box-shadow;
  transition-duration: 0.5s;
  transition-timing-function: var(--ease-out);
}

.t4-card:hover,
/* БАГ И ПОЧЕМУ ЗДЕСЬ `:has(:focus-visible)`, А НЕ `:focus-within`
   (найдено по скриншоту владельца 2026-08-04).
   Все кнопки тарифов ведут в Telegram с `target="_blank"`: вкладка с
   сайтом остаётся открытой, а фокус — на нажатой кнопке. `:focus-within`
   срабатывает от ЛЮБОГО фокуса, включая мышиный, поэтому нажатая
   карточка оставалась светлой навсегда. Наводишь курсор на соседнюю —
   светятся две сразу, и блок выглядит сломанным.
   `:focus-visible` браузер ставит ссылке только при переходе с
   клавиатуры, а после клика мышью — нет. Клавиатурная доступность
   сохранена, залипание после клика ушло.
   Если браузер не знает `:has()` — правило просто не применится:
   подсветка с клавиатуры пропадёт, но ничего не сломается. */
.t4-card:has(:focus-visible) {
  background: linear-gradient(180deg, #f6f2ec 0%, #e4dbcb 100%);
  border-color: rgba(212,175,55,0.75);
  box-shadow: 0 20px 46px rgba(0,0,0,0.62), 0 0 0 1px rgba(212,175,55,0.32);
}
.t4-card:hover h3,
.t4-card:has(:focus-visible) h3 { color: #0a0a0a; }
.t4-card:hover > p,
.t4-card:has(:focus-visible) > p { color: rgba(10,10,10,0.7); }
.t4-card:hover .t4-list li,
.t4-card:has(:focus-visible) .t4-list li { color: rgba(10,10,10,0.72); }
/* Золото на светлой заливке слепнет — уводим в бронзу */
.t4-card:hover .t4-list li::before,
.t4-card:has(:focus-visible) .t4-list li::before,
.t4-card:hover .t4-price,
.t4-card:has(:focus-visible) .t4-price { color: rgba(138,114,63,0.95); }
.t4-card:hover .t4-badge,
.t4-card:has(:focus-visible) .t4-badge {
  background: rgba(138,114,63,0.16);
  border-color: rgba(138,114,63,0.42);
  color: rgba(28,22,8,0.92);
}
/* Кнопка: белый текст и светлая рамка на светлой заливке исчезли бы */
.t4-card:hover .btn,
.t4-card:has(:focus-visible) .btn {
  border-color: rgba(10,10,10,0.38);
  color: #0a0a0a;
}
.t4-card:hover .btn:hover,
.t4-card:has(:focus-visible) .btn:hover {
  border-color: #0a0a0a;
  background: rgba(10,10,10,0.06);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .t4-card, .t4-badge, .t4-card h3, .t4-card > p,
  .t4-list li, .t4-price, .t4-card .btn { transition: none; }
}

/* --- Адаптив: панель живёт только там, где справа реально есть место --- */

@media (max-width: 1180px) {
  .reel-hud { display: none; }
}

/* ============================================================
   ЗНАК В КОРПУСЕ ОБЪЕКТИВА (2026-07-29) — замена герба

   Шаблон — фирменный знак владельца: QT ⊃ (IPDA · PO3 · MMXM),
   SMT в пересечении. Корпус и механика сняты с объектива
   steven.com (ролик research/REF.mkv): матовый ахроматический
   металл с широкими мягкими переходами, обод с именем, повторённым
   сверху и снизу, кольцо из трёх сегментов, стекло в центре,
   наезд камеры и выступ сегмента при наведении.
   Скопировано ПОВЕДЕНИЕ — файлы, код и графика steven.com не
   использовались (граница исключения, CLAUDE.md §5).

   Урок этапа 7.7 («дёшево, размыто, тускло») учтён буквально:
   слоёв мало, у каждого ЧЁТКАЯ кромка. Полупрозрачных вуалей
   друг на друге нет — на 400px они съедают контраст, а не
   добавляют материал. Никаких фототекстур и SVG-фильтров.

   Слои: опора → безель (CSS-металл) → лицо со знаком (SVG) → стекло.
   Все круглые маски — только `circle closest-side` (грабля проекта).
   ============================================================ */

/* Крупнее прежнего герба: три кольца требуют места. Потолок 430px —
   ровно ширина контента карточки на 1440 (замер: 432px), поэтому
   30vw безопасно упирается в него и не вылезает на широких окнах. */
.t2-massive .t2-mark {
  width: clamp(240px, 30vw, 430px);
  height: clamp(240px, 30vw, 430px);
  animation: lensFloat 6.5s ease-in-out infinite;
}

/* Прежнее парение `t1floatyMini` доворачивало знак на 3°. Точёному
   прибору качание не идёт (у референса объект не вращается), а
   повёрнутый габарит съедал 21px ширины карточки: 430 × (cos3°+sin3°)
   = 452 при внутренней ширине 462. Дыхание оставлено, поворот снят. */
@keyframes lensFloat { 50% { transform: translateY(-12px); } }

/* Опора: объект стоит на плоскости, а не висит в воздухе */
.t2-mark::after {
  content: "";
  position: absolute;
  z-index: 0;
  left: 8%; right: 8%; bottom: -4%; height: 22%;
  border-radius: 50%;
  background: radial-gradient(ellipse closest-side, rgba(0,0,0,0.6), transparent 74%);
  filter: blur(9px);
}

/* Наезд камеры: при наведении на сегмент вся сцена приближается */
.lens {
  position: absolute;
  inset: 0;
  transform: scale(var(--zm, 1));
  transition: transform 0.55s var(--ease-out);
}

.lens-bezel,
.lens-face,
.lens-glass {
  position: absolute;
  inset: 0;
}
.lens-bezel,
.lens-glass { border-radius: 50%; pointer-events: none; }

/* --- Безель: полированный хром (правка владельца 2026-07-30) ---
   Хром держится НЕ на узком ярком гребне — на нём погорела сборка
   этапа 7.3, гребень читался неоновой трубкой. Настоящий хром — это
   (а) большой динамический диапазон: почти белое #e8ecf3 рядом с
   почти чёрным #0a0b0e; (б) ДВА софита в противоположных лобах и
   две глубокие тени между ними; (в) жёсткая линия горизонта — резкий
   стык отражения «неба» и «земли» на середине полосы. Переходы
   короткие и чёткие, размытых вуалей по-прежнему нет. */
.lens-bezel {
  z-index: 1;
  background:
    /* 1. Луч за курсором: узкое ядро + широкий спад — зеркальный
          отклик хрома, а не матовый шин */
    conic-gradient(from calc(var(--lens-a, 208deg) - 46deg),
      transparent          0deg,
      rgba(255,255,255,0.05)  20deg,
      rgba(255,255,255,0.28)  40deg,
      rgba(255,255,255,0.52)  46deg,
      rgba(255,255,255,0.24)  53deg,
      rgba(255,255,255,0.04)  74deg,
      transparent          92deg),
    /* 2. Линия горизонта: верх ловит «небо», низ — «землю»,
          стык резкий на 47% — главный признак полированного металла */
    linear-gradient(177deg,
      rgba(255,255,255,0.13) 0%,
      rgba(255,255,255,0.03) 40%,
      rgba(255,255,255,0.07) 46.4%,
      rgba(0,0,0,0.20)       47.6%,
      rgba(0,0,0,0.30)       74%,
      rgba(0,0,0,0.42)      100%),
    /* 3. Сама хромировка: главный софит на 318° (лево-верх, согласован
          с бликом стекла), отражённый на 145° (право-низ), глубокая
          чернь на 34° и 216°. Подъёмы к пикам короткие (12–14°) —
          у полировки переход резкий; растянутые переходы читались
          матовым анодированием, а не хромом. */
    conic-gradient(from 0deg,
      #262b33   0deg,
      #0f1116  14deg,
      #0a0b0e  34deg,
      #0c0e12  52deg,
      #1a1e25  70deg,
      #363c46  92deg,
      #7b8390 116deg,
      #aeb6c3 134deg,
      #c3cbd7 145deg,
      #8f97a4 158deg,
      #414753 172deg,
      #14171d 192deg,
      #0b0c10 216deg,
      #0d0f14 238deg,
      #232830 258deg,
      #5d6573 280deg,
      #a8b0bd 300deg,
      #dde3ed 312deg,
      #eef2f8 318deg,
      #b4bcc9 328deg,
      #565c68 340deg,
      #262b33 360deg);
  box-shadow:
    0 30px 58px -22px rgba(0,0,0,0.9),
    inset 0 -2px 7px rgba(0,0,0,0.6);
}

/* Фаска внешней кромки: тонкое кольцо, светится ТОЛЬКО там, куда
   попадает свет. Ровное белое кольцо по всей кромке читалось бы
   дешёвой обводкой — здесь оно гаснет в теневых лобах. */
.lens-bezel::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    rgba(255,255,255,0.26)   0deg,
    rgba(255,255,255,0.03)  34deg,
    rgba(255,255,255,0.10)  84deg,
    rgba(255,255,255,0.60) 145deg,
    rgba(255,255,255,0.09) 190deg,
    rgba(255,255,255,0.02) 216deg,
    rgba(255,255,255,0.30) 292deg,
    rgba(255,255,255,0.88) 318deg,
    rgba(255,255,255,0.20) 344deg,
    rgba(255,255,255,0.26) 360deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 98.2%, #000 98.8% 99.7%, transparent 100%);
          mask: radial-gradient(circle closest-side, transparent 0 98.2%, #000 98.8% 99.7%, transparent 100%);
}

/* Насечка по кромке — 90 штрихов. Даёт масштаб: по ней глаз
   понимает, что объект точёный, а не нарисованный градиентом.
   У каждого штриха своя тень сразу за ним: одними светлыми
   штрихами насечка тонула в светлой полосе хрома, а на паре
   «свет + тень» читается на любом фоне — как настоящая накатка. */
.lens-bezel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
    rgba(255,255,255,0.17) 0deg 1.1deg,
    rgba(0,0,0,0.30)     1.1deg 2.3deg,
    transparent          2.3deg 4deg);
  /* Накатка живёт у самой кромки — как хват на оправе объектива. Начало
     полосы 93.5% выбрано замером: марка QT дотягивается до r92.4,
     гравировка имени до r89.7 — штрихи их больше не режут. */
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 93.5%, #000 94.1% 98.4%, transparent 99.2%);
          mask: radial-gradient(circle closest-side, transparent 0 93.5%, #000 94.1% 98.4%, transparent 99.2%);
}

/* --- Лицо со знаком --- */
.lens-face {
  z-index: 2;
  font-family: inherit;
  overflow: visible;
  /* глифы позиционируются точно, без округления к пикселю — на кольцевом
     тексте это заметно: буквы перестают «дышать» по дуге */
  text-rendering: geometricPrecision;
}

/* Полоса маркировки. Тонкая светлая ступень по её кромке — стык
   сатиновой полосы и хромового кольца хвата; на точёной вещи такой
   переход всегда виден как отдельная фаска. */
.lens-collar {
  stroke: rgba(255,255,255,0.20);
  stroke-width: 0.7;
  pointer-events: none;
}

/* Рельеф гравировки: тёмная копия сдвинута вниз — это тень в канавке,
   светлая лежит поверх. Отсюда «богатый» вид и, главное, читаемость:
   у надписи есть контраст и по светлому, и по тёмному соседству. */
.lens-t-shadow {
  fill: rgba(0,0,0,0.8) !important;
  pointer-events: none;
}

/* Лицо гасит видеофон секции. Золотой волосок на кромке — единственное
   золото корпуса, кроме ядра SMT */
.lens-plate {
  stroke: rgba(212,175,55,0.30);
  stroke-width: 0.8;
  pointer-events: none;
}

/* Гравировка светлая и плотная: раньше она была полупрозрачной (0.46) и
   лежала на хроме — в световой полосе буквы исчезали совсем. Теперь под
   ними сатиновая полоса, поэтому можно взять плотный светлый тон. */
.lens-brand {
  fill: #dfe4ec;
  font-size: 6.9px;
  font-weight: 600;
  letter-spacing: 2.3px;
  pointer-events: none;
}

/* --- ОБОРОТ СЕГМЕНТОВ ПО ЦИКЛУ (правка владельца 2026-07-30) ---
   Три сегмента проворачиваются по часовой на 120° — каждый встаёт на
   место соседа. Дуги сегментов ротационно симметричны (0° / 120° / 240°),
   поэтому после поворота текст ложится ровно на дугу нового места и
   читается так же, как читался там сосед.

   Характер «трансформер»: кривая с жёстким разгоном и доводкой
   (0.72, 0, 0.16, 1.06) — в конце лёгкий перелёт и защёлкивание, как у
   механизма, а не плавное скольжение. Плюс сегменты трогаются НЕ разом:
   задержка 90 мс на каждый следующий. Разъезд на доли секунды и есть
   то, что читается механикой, а не вращением цельного кольца. */
.lens-seg-orbit {
  transform-origin: 100px 100px;
  transform: rotate(var(--seg-rot, 0deg));
  transition: transform 0.92s cubic-bezier(0.72, 0, 0.16, 1.06);
  transition-delay: calc(var(--i) * 90ms);
}

/* Сегменты: выступ наружу — scale от ЦЕНТРА колеса, то есть сектор
   уходит по радиусу и утолщается, как выдвинутый сегмент референса */
.lens-seg {
  transform-origin: 100px 100px;
  transition: transform 0.5s var(--ease-out);
  cursor: default;
}
.lens-seg.is-on { transform: scale(1.085); }

/* Секторы — тоже металл: радиальный градиент с тем же направлением
   света, что у обода (софит в левом верху). Плоская заливка читалась
   картоном рядом с хромом.
   Активный сектор светлеет через `brightness`, а не сменой заливки:
   переход между двумя градиентами CSS не тваинит. */
.lens-seg-body {
  fill: url(#lensSegG);
  stroke: rgba(244,240,234,0.13);
  stroke-width: 0.6;
  transition: filter 0.45s var(--ease-out);
}
.lens-seg.is-on .lens-seg-body { filter: brightness(1.8); }

.lens-seg-label {
  fill: rgba(244,240,234,0.78);
  font-size: 8.2px;
  font-weight: 700;
  letter-spacing: 1.8px;
  pointer-events: none;
  transition: fill 0.4s ease;
}
.lens-seg.is-on .lens-seg-label { fill: var(--white); }

/* Рамка видоискателя: дуга длиной 166.1 (117.5° при r=81) разбита
   так, что рисуются только два уголка по 16 на концах сегмента */
.lens-seg-trace {
  fill: none;
  stroke: rgba(244,240,234,0.85);
  stroke-width: 0.9;
  stroke-linecap: round;
  stroke-dasharray: 16 134.1 16;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.lens-seg.is-on .lens-seg-trace { opacity: 1; }

.lens-pupil { pointer-events: none; }

/* --- Живое стекло (переработка 2026-07-30 по замечанию владельца) ---
   Вращающийся спекуляр и дрейф каустики удалены: их полосы пересекали
   отверстие по диагонали и ломали симметрию. Жизнь в куполе теперь
   дают дыхание каустики (в такт ореолу, 5.6 с) и блик бегущего луча
   `.lens-spot` — оба радиально согласованы с геометрией. */
.lens-live { pointer-events: none; }

.lens-caustic { animation: lensCausticPulse 5.6s ease-in-out infinite; }
@keyframes lensCausticPulse {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 1; }
}

/* Дыхание ореола ведёт ТОЛЬКО масштаб. Прозрачность оставлена под
   управление затвору: анимация перебивает transition, и при закрытой
   диафрагме ореол не удалось бы погасить. */
.lens-core-glow {
  pointer-events: none;
  transform-origin: 100px 100px;
  opacity: 0.78;
  animation: lensBreath 5.6s ease-in-out infinite;
  transition: opacity 0.45s var(--ease-out) 0.2s;
}
@keyframes lensBreath {
  0%, 100% { transform: scale(0.94); }
  50%      { transform: scale(1.1); }
}
.lens.is-shut .lens-core-glow {
  opacity: 0;
  transition: opacity 0.16s ease;
}

/* --- ДИАФРАГМА-ЗАТВОР (правка владельца 2026-07-30) ---
   Отвод лепестка от центра = вписанный радиус отверстия. Отсюда вся
   механика на одном значении: 30 — открыто, 0 — смыкание ПОЛНОЕ.
   Прежняя версия была контуром семигранника со швами-линиями: она
   физически не могла закрыться, только уменьшиться.

   Тайминги направленные, как у настоящего затвора: закрытие короткое и
   разгоняющееся (0.24 с), открытие длиннее и с оттяжкой (0.62 с).
   Правило `.is-shut` стоит ПОСЛЕ `.is-focus` — при затворе отвод обязан
   быть нулевым, даже если курсор держит фокус. */
.lens-iris { pointer-events: none; }

/* Каждый лепесток подрезан СВОИМ клином 1/7 круга (`#lensBladeClip`).
   Замечание владельца 2026-07-30: при смыкании один лепесток вставал
   диагональю и накрывал половину объектива, а три нижних упирались в
   него. Причина — порядок отрисовки: лепестки были полудисками и
   свободно наезжали друг на друга, последний закрывал предыдущие.
   Клин отвечает ровно за свой сектор, поэтому при любом положении
   видны все семь.

   Геометрия сходится: точка вне отверстия нарушает полуплоскость
   ИМЕННО ближайшей грани, а её клин эту точку содержит — значит клип
   не меняет ни площадь покрытия, ни радиус отверстия, ни полное
   смыкание. Проверено замером отверстия в обоих состояниях. */
.lens-blade {
  transform: translateY(-30px);
  transition: transform 0.62s var(--ease-out);
}
.lens.is-focus .lens-blade { transform: translateY(-24px); }
.lens.is-shut .lens-blade {
  transform: translateY(0);
  transition: transform 0.24s cubic-bezier(0.5, 0, 0.9, 0.55);
}

.lens-blade-face {
  fill: url(#lensBladeG);
  /* передняя кромка лепестка ловит свет: семь кромок и рисуют
     семигранник отверстия */
  stroke: rgba(214,222,234,0.45);
  stroke-width: 0.7;
  transition: stroke 0.4s ease;
}

/* Шов между соседними лепестками. Идёт из вершины клина наружу, поэтому
   при полном смыкании все семь сходятся в центре ровным веером — это и
   есть симметрия, которую просил владелец. */
.lens-blade-seam {
  stroke: rgba(219,227,239,0.46);
  stroke-width: 0.65;
  transition: stroke 0.4s ease;
}

/* Курсор на центре — диафрагма поджимается на ступень (30 → 24), кромки
   и швы светлеют: механизм отвечает на руку */
.lens.is-focus .lens-blade-face { stroke: rgba(236,242,250,0.75); }
.lens.is-focus .lens-blade-seam { stroke: rgba(236,242,250,0.6); }

/* Пока сегменты едут — их тела светлеют, а уголки видоискателя
   приоткрываются: механизм видно в работе, а не просто поворот */
.lens.is-turning .lens-seg-body { filter: brightness(1.4); }
.lens.is-turning .lens-seg-trace { opacity: 0.5; }

/* Цель для курсора на центре — прозрачная, r44 (вне сегментов r62–77,
   поэтому их наведение она не перехватывает) */
.lens-hit { pointer-events: auto; }

/* Ядро знака — пересечение трёх кругов шаблона.
   Проявление после открытия затвора: надпись не просто «включается», а
   собирается — выходит из разреженного трекинга и подрастает в масштабе,
   с задержкой 0.24 с, когда лепестки уже пошли в стороны. Читается как
   изображение, всплывающее НА линзе. */
.lens-core {
  fill: var(--gold);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 1.4px;
  pointer-events: none;
  transform-origin: 100px 100px;
  transition:
    opacity 0.52s var(--ease-out) 0.24s,
    transform 0.66s var(--ease-out) 0.24s,
    letter-spacing 0.66s var(--ease-out) 0.24s,
    fill 0.5s ease;
}
.lens.is-focus .lens-core { fill: #f2dfa4; }

.lens.is-shut .lens-core {
  opacity: 0;
  transform: scale(0.8);
  letter-spacing: 5.2px;
  transition: opacity 0.15s ease, transform 0.22s ease, letter-spacing 0.22s ease;
}

/* QT — марка внизу обода. Крупнее гравировки имени, но всё ещё
   гравировка: кегль 11 при полосе обода 21 ед. (r79–100) даёт
   высоту прописной ~8 ед., текст сидит по центру полосы. */
.lens-qt {
  fill: #eef2f8;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: 4px;
  pointer-events: none;
}

/* --- Стекло над ядром: кромка + рефракция к краю ---
   Диаметр 44% корпуса = зрачок r44 в системе SVG */
/* Выпуклость (доработка 2026-07-30: «линза вообще не заметна»).
   ОШИБКА прошлой версии, найденная разбором: каустика лежала на 93.5%
   стекла (r41), точка софита на r31 — а лепестки закрывают всё, что
   дальше r30. Признаки купола сидели там, где их физически не видно.
   Теперь ВСЕ признаки сжаты внутрь отверстия (r < 30 в системе SVG):
   тело купола, точка софита, два полумесяца на пседоэлементах, тёмная
   кромка кривизны. Стекло стоит НАД лепестками (z 3 против SVG z 2) —
   это правильно: передняя линза, диафрагма за ней. */
.lens-glass {
  inset: 28%;
  z-index: 3;
  background:
    /* Жёсткая точка софита переехала в `.lens-spot` — правка владельца
       2026-07-30: при сомкнутом затворе бликов быть не должно, а слой
       фона погасить по отдельности нельзя, только целиком. В `.lens-spot`
       она гаснет вместе с бегущим бликом одним переходом. */
    /* тело купола: свет в верхнем левом */
    radial-gradient(circle closest-side at 37% 27%,
      rgba(255,255,255,0.17),
      rgba(255,255,255,0.05) 40%,
      transparent 62%),
    /* кривизна: чернение к кромке купола поверх зоны лепестков —
       читается толщей стекла */
    radial-gradient(circle closest-side,
      transparent 0 68%,
      rgba(0,0,0,0.24) 86%,
      rgba(0,0,0,0.48) 97%,
      rgba(0,0,0,0.54) 100%);
  box-shadow:
    inset 0 0 0 1px rgba(244,240,234,0.20),
    inset 0 2px 1px -1px rgba(255,255,255,0.32),
    inset 0 0 0 3.5px rgba(0,0,0,0.42),
    inset 0 0 20px 7px rgba(0,0,0,0.45);
  transition: box-shadow 0.5s var(--ease-out);
}

/* Верхний полумесяц купола: дуга с чёткой кромкой на r23.5–27.7 —
   внутри отверстия. Тот же приём, что на стекле герба этапа 8:
   резкость дуги и есть «стекло» на мелком масштабе. */
/* Прежняя пара полумесяцев (маски 50–63%) удалена: ниже в файле стоят
   такие же селекторы с масками 85–95%, они полностью перекрывали эти —
   правила были мёртвыми и только путали при чтении. */

/* Отражение бегущего луча на куполе. Отдельным слоем НАМЕРЕННО: позиция
   считается через sin/cos от угла луча, и если браузер их не понимает,
   ломается только этот блик — статичная точка софита в `.lens-glass`
   остаётся на месте. Блик ходит по куполу вместе со светом на ободе —
   для глаза это и есть доказательство, что поверхность выпуклая. */
.lens-spot {
  position: absolute;
  inset: 28%;
  z-index: 4;
  border-radius: 50%;
  pointer-events: none;
  background:
    /* радиус хода 24% (r ≈ 21) — блик не заходит под лепестки даже при
       поджатой до r24 диафрагме */
    radial-gradient(circle closest-side
      at calc(50% + 24% * sin(var(--lens-a, 208deg)))
         calc(50% - 24% * cos(var(--lens-a, 208deg))),
      rgba(255,255,255,0.85) 0 3.6%,
      rgba(255,255,255,0.22) 7%,
      transparent 11%),
    /* статичная точка софита — переехала сюда из `.lens-glass`, чтобы
       гаснуть вместе с бегущей при закрытом затворе */
    radial-gradient(circle closest-side at 32% 24%,
      rgba(255,255,255,0.95) 0 3%, rgba(255,255,255,0.3) 4.8%, transparent 7.6%);
  transition: opacity 0.32s var(--ease-out);
}

/* --- Затвор сомкнут — бликов нет (правка владельца 2026-07-30) ---
   Стекло стоит НАД лепестками (передняя линза, диафрагма за ней), и
   физически отражения на нём остались бы. Но владелец прав по картинке:
   две светлые точки на глухом затворе читались грязью, а не стеклом.
   Гаснут обе точки софита и оба полумесяца; кромка стекла остаётся —
   без неё закрытый затвор выглядел бы дырой, а не линзой. */
.lens.is-shut .lens-spot,
.lens.is-shut .lens-glass::before,
.lens.is-shut .lens-glass::after { opacity: 0; }

.lens-glass::before,
.lens-glass::after { transition: opacity 0.32s var(--ease-out); }

/* Верхняя фаска купола тоже гаснет: на сомкнутых лепестках она читалась
   яркой дугой. Обводка кромки в 1px остаётся. */
.lens.is-shut .lens-glass {
  box-shadow:
    inset 0 0 0 1px rgba(244,240,234,0.14),
    inset 0 0 0 3.5px rgba(0,0,0,0.42),
    inset 0 0 20px 7px rgba(0,0,0,0.5);
}

/* Касание центра «просветляет» стекло: кромка ярче, рефракция мягче —
   как будто объектив навёлся */
.lens.is-focus .lens-glass {
  box-shadow:
    inset 0 0 0 1px rgba(244,240,234,0.30),
    inset 0 2px 1px -1px rgba(255,255,255,0.4),
    inset 0 0 0 3.5px rgba(0,0,0,0.38),
    inset 0 0 20px 7px rgba(0,0,0,0.38);
}

/* Верхний блик — отражение софита. Дуга с чёткой кромкой, а не пятно:
   именно резкость дуги читается стеклом на мелком масштабе */
.lens-glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 268deg,
    transparent 0 10deg,
    rgba(255,255,255,0.55) 34deg,
    rgba(255,255,255,0.92) 52deg,
    rgba(255,255,255,0.42) 70deg,
    transparent 96deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 84%, #000 85.5% 95%, transparent 96.5%);
          mask: radial-gradient(circle closest-side, transparent 0 84%, #000 85.5% 95%, transparent 96.5%);
}

/* Нижний блик — отражённый от стола, втрое тише верхнего */
.lens-glass::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 110deg,
    transparent 0 8deg,
    rgba(255,255,255,0.16) 26deg,
    rgba(255,255,255,0.30) 40deg,
    rgba(255,255,255,0.12) 56deg,
    transparent 76deg);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 86%, #000 87.5% 95%, transparent 96.5%);
          mask: radial-gradient(circle closest-side, transparent 0 86%, #000 87.5% 95%, transparent 96.5%);
}

@media (prefers-reduced-motion: reduce) {
  .t2-mark { animation: none; }
  .lens, .lens-seg, .lens-seg-body, .lens-seg-label, .lens-seg-trace,
  .lens-blade, .lens-blade-face, .lens-blade-seam,
  .lens-core, .lens-core-glow, .lens-glass { transition: none; }
  .lens-caustic, .lens-core-glow { animation: none; }
  /* Цикл оборота не запускается вовсе (модуль 10b), но снимаем и переход,
     чтобы случайная смена переменной не дала движения */
  .lens-seg-orbit { transition: none; }
  /* Свет внутри купола остаётся, но замирает на выразительной фазе */
  .lens-caustic { opacity: 0.85; }
  .lens-core-glow { opacity: 0.7; }
}

/* ============================================================
   УЛЬТРАШИРОКИЕ ОКНА ≥1980px (2026-07-30) — контейнеры выше уже
   растянуты до 84vw (блок V3.1); здесь сетки перестраиваются, чтобы
   заполнить ширину ПЛОТНОСТЬЮ, а не раздуванием карточек.
   Блок стоит в конце файла намеренно: поздние правила перекрывают
   V3.1 (главная грабля проекта работает на нас).
   ============================================================ */

@media (min-width: 1980px) {
  /* Метод: 6 модулей в 3 колонки × 2 ряда вместо 2×3 — карточки
     держат прежнюю ширину ~350–500px, а не растягиваются вдвое */
  .t2-features { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Карточка Tony-1 стала шире — знак-объектив дорастает до 520px,
     иначе тонет в стекле (прежний потолок 430 считан с окна 1440) */
  .t2-massive .t2-mark {
    width: clamp(240px, 30vw, 520px);
    height: clamp(240px, 30vw, 520px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reel-hud, .reel-slide .tf-plane, .cyc-ring { opacity: 1; transform: none; transition: none; }
  .tf-plane { transform: none; }
  .reel-slide.is-active .tf-slab,
  .reel-slide.is-active .tf-face::after,
  .dial-sweep, .dial-marks li, .dial-marks li::after,
  .cyc-ring::before, .cyc-meteor, .cyc-pulse, .cyc-halo { animation: none; }
  .tf-slab { transform: none; }
  .tf-tilt { transform: none; transition: none; }
  .tf-plane.is-hot .tf-face--front { transition: none; }
  .dial-marks li { opacity: 1; }
  .cyc-pulse { opacity: 0; }
  /* Орбиты стоят, но подписи остаются разведёнными по кольцу */
  .cyc-tag { animation: none; transform: rotate(var(--la)); }
  .cyc-tag i { animation: none; transform: rotate(calc(var(--la) * -1)); }
}

/* ============================================================
   ТИПОГРАФИКА ПРИБОРОВ — доля от ширины корпуса (2026-07-30)

   После приравнивания панели к левой карточке сцена прибора выросла
   с 331 до 453px, а подписи остались на прежних vw-кегель: замер дал
   1.9–2.0% ширины сцены против прежних 2.6–2.75%. Панель читалась
   увеличенной рамкой с мелким содержимым.

   Кегли переведены на долю от `--hud-w`, поэтому текст растёт ровно
   вместе с корпусом на любой ширине окна — и на 480px floor, и на
   820px cap. Коэффициенты подобраны так, чтобы вернуть оптические
   пропорции, которые были до укрупнения.
   Внутренние отбивки переведены в `em` — растут за кеглем сами.
   ============================================================ */

.hud-name      { font-size: calc(var(--hud-w) * 0.025); }
.hud-idx       { font-size: calc(var(--hud-w) * 0.028); }
.hud-line      { font-size: calc(var(--hud-w) * 0.029); }
.hud-stats span { font-size: calc(var(--hud-w) * 0.023); padding: 0.34em 0.85em; }

/* I · Карта таймфреймов */
.tf-face { font-size: calc(var(--hud-w) * 0.042); }

/* II · Хронометр релиза */
.dial-marks span { font-size: calc(var(--hud-w) * 0.023); }
.dial-core b     { font-size: calc(var(--hud-w) * 0.058); }
.dial-core i     { font-size: calc(var(--hud-w) * 0.024); }
.dial-readout    { font-size: calc(var(--hud-w) * 0.026); }

/* III · Календарь циклов */
.cyc-tag i { font-size: calc(var(--hud-w) * 0.024); padding: 0.2em 0.62em; }

/* --- Не только кегли: остальная мелочь внутри панели ---
   Найдена сравнением снимков computed-стилей на 1440 и 1920: всё, что
   не изменилось при росте окна на 33%, сидело на жёстких пикселях и
   после укрупнения корпуса стало мельче положенного. Волосковые линии
   в 1px и радиусы в % сознательно НЕ трогаем — они обязаны такими быть.
   Коэффициенты — доля от `--hud-w`, множитель роста сцены 453/331. */

/* Отбивки строк головы и подвала */
.hud-head       { gap: calc(var(--hud-w) * 0.0264); padding-bottom: calc(var(--hud-w) * 0.0264); }
.hud-line       { margin-bottom: calc(var(--hud-w) * 0.0317); }
.hud-stats      { gap: calc(var(--hud-w) * 0.0158); }

/* I · Карта таймфреймов: зазор внутри грани и её скругление */
.tf-face        { gap: calc(var(--hud-w) * 0.0264); border-radius: calc(var(--hud-w) * 0.0212); }

/* ============================================================
   ПАНЕЛЬ I — УКРУПНЕНИЕ ПЛОСКОСТЕЙ (правка владельца 2026-07-30:
   «увеличить эти столбцы по размеру»)

   Замер до правки: сцена (квадрат) 565×565, стопка из пяти плоскостей
   занимала только 566×306 — 259px высоты пустовали. Причина: подписи
   `<b>`/`<i>` сидели на vw-клампах у самого потолка диапазона (0.8vw/
   0.65vw, 1440px viewport давал 11.5px/9.36px — почти на минимуме
   clamp) и не были привязаны к ширине панели вовсе, а `.tf-face`
   padding и `.tf-stack` gap — на узких vw-клампах из старой вёрстки.

   Все четыре величины переведены на долю от `--hud-w`, поэтому растут
   строго вместе с корпусом панели (та же переменная, что и у ширины
   самой панели) на любом окне — не только на 1440. */
.tf-stack       { gap: calc(var(--hud-w) * 0.024); }
.tf-face        { padding: calc(var(--hud-w) * 0.032) calc(var(--hud-w) * 0.048); }
.tf-face b      { font-size: calc(var(--hud-w) * 0.036); }
.tf-face i      { font-size: calc(var(--hud-w) * 0.027); }

/* II · Хронометр релиза: метка = точка + подпись, кромка луча, строка отклика */
.dial-marks li  { gap: calc(var(--hud-w) * 0.0132); }
.dial-marks i {
  width: calc(var(--hud-w) * 0.0185);
  height: calc(var(--hud-w) * 0.0185);
}
/* Расходящееся кольцо отклика повторяет размер точки, поэтому и сдвиг
   на половину считается от того же значения */
.dial-marks li::after {
  width: calc(var(--hud-w) * 0.0185);
  height: calc(var(--hud-w) * 0.0185);
  margin-left: calc(var(--hud-w) * -0.00925);
}
/* Кромка центрируется сдвигом ровно на свою половину — иначе луч
   уезжает на пиксель при росте панели */
.dial-edge {
  width: calc(var(--hud-w) * 0.0053);
  margin-left: calc(var(--hud-w) * -0.00265);
}
.dial-core i    { margin-top: calc(var(--hud-w) * 0.0158); }
.dial-readout {
  gap: calc(var(--hud-w) * 0.0212);
  margin-bottom: calc(var(--hud-w) * 0.0317);
  padding-bottom: calc(var(--hud-w) * 0.0264);
}
.dial-readout-dot {
  width: calc(var(--hud-w) * 0.0158);
  height: calc(var(--hud-w) * 0.0158);
}

/* III · Скругление плашки подписи — за своим кеглем */
.cyc-tag i      { border-radius: 0.45em; }

/* ==========================================================================
   ЕДИНАЯ ПЛАВНОСТЬ ПЕРЕХОДА НА СВЕТЛЫЙ ФОН (правка владельца 2026-08-01)
   Светлая заливка есть в двух местах — карточки тарифов и карточки «МЕТОД».
   Тайминги там разошлись (0.45/0.5с), а стеклянный блюр под заливкой не
   анимировался вовсе и снимался рывком. Сводим к одной длительности и
   добавляем блюр в переход, чтобы стекло растворялось вместе с фоном.
   ========================================================================== */
/* ГЛАВНОЕ ПРО РЫВОК (правка владельца 2026-08-01, найдено замером):
   у карточки в покое `background-image: none`, а на наведении — градиент.
   Переход от «ничего» к градиенту браузер анимировать НЕ УМЕЕТ и меняет
   мгновенно — сколько длительность ни ставь. Даём базовый градиент той же
   структуры (то же направление, те же две точки), но полностью прозрачный:
   теперь это интерполяция цвета, и заливка наплывает плавно.
   Фон-подложку `.glass` не трогаем — она живёт в background-color. */
.t4-card, .t2-feature {
  background-image: linear-gradient(180deg, rgba(246, 242, 236, 0) 0%, rgba(228, 219, 203, 0) 100%);
}
/* «Рекомендуем» сохраняет свою золотую подсветку, но уже двумя точками —
   иначе она снова упрётся в несовпадение структуры. */
.t4-card.featured {
  background-image: linear-gradient(150deg, rgba(212, 175, 55, 0.14) 0%, rgba(255, 255, 255, 0.05) 100%);
}
/* А это правило ОБЯЗАНО идти после: у `.t4-card.featured` и `.t4-card:hover`
   одинаковая специфичность, и без него позднее базовое правило перебивало
   наведение — ICT PRO не белела, а текст уже уходил в тёмный, и карточка
   становилась нечитаемой (правка владельца 2026-08-01). */
.t4-card.featured:hover,
.t4-card.featured:has(:focus-visible) {
  background-image: linear-gradient(180deg, #f6f2ec 0%, #e4dbcb 100%);
}

/* 0.85с вместо 0.55 и задержка 0.14с на ВХОДЕ (правка владельца 2026-08-01:
   «резкая смена цвета при переходе курсора с окошка на окошко раздражает»).
   Задержка гасит именно эту проблему: беглый проход мимо карточки не успевает
   запустить заливку. Уход — без задержки, чтобы карточка не «залипала». */
.t4-card, .t2-feature,
.t4-card *, .t2-feature * {
  transition-duration: 1.2s;          /* 0.55 → 0.85 → 1.2: владельцу всё ещё резко */
  transition-timing-function: cubic-bezier(0.33, 0, 0.2, 1);
  transition-delay: 0s;
}
.t4-card:hover, .t4-card:hover *,
.t4-card:has(:focus-visible), .t4-card:has(:focus-visible) *,
.t2-feature:hover, .t2-feature:hover *,
.t2-feature:has(:focus-visible), .t2-feature:has(:focus-visible) * {
  transition-delay: 0.14s;
}
.t4-card, .t2-feature {
  transition-property: background, border-color, color, box-shadow, backdrop-filter, -webkit-backdrop-filter;
}
.t4-card:hover, .t4-card:has(:focus-visible),
.t2-feature:hover, .t2-feature:has(:focus-visible),
.t2-feature:focus-visible {
  -webkit-backdrop-filter: blur(0px);
          backdrop-filter: blur(0px);
}
/* золотой плюс в «МЕТОД» — единственный элемент без перехода цвета */
.t2-plus { transition: opacity 0.4s var(--ease-out), transform 0.5s var(--ease-out),
                       background 0.55s var(--ease-out), color 0.55s var(--ease-out); }

/* ==========================================================================
   КОМПАКТНАЯ ВЕРТИКАЛЬ (правка владельца 2026-08-01)
   Замер: «Наставник» занимал 3.62 экрана, «Тарифы» 2.08 — блоки разъезжались
   через границу окна. Ужимаем поля, отступы и внутренние паддинги; тексты и
   структуру не трогаем. Только десктоп: у мобильной свои правила.
   ========================================================================== */
@media (min-width: 768px) {
  /* 14vh с каждой стороны = 252px на секцию только на воздух */
  .s-t2, .s-t3, .s-t4, .s-t5, .s-faq { padding: clamp(46px, 7vh, 86px) 0; }

  /* ---- Секция обязана дотягиваться до нижнего края окна ----
     Правка владельца 2026-08-02: «надо растянуть чуть ниже, нижний блок
     всплывает вверх». Снап ставит верх КОНТЕНТА под шапку, то есть
     прокрутка = верх_секции + свой padding-top − 88 − 12. Значит низ
     секции на экране = высота_секции − padding-top + 100. Чтобы соседняя
     секция не заглядывала снизу, нужно ≥ 100vh, откуда при border-box:

         min-height = 100vh − 100px + собственный padding-top

     Секциям, которые и так выше окна (Манифест, Витрина, Наставник),
     правило ничего не меняет — их высоту диктует содержимое. */
  .s-t2, .s-t3, .s-t4, .s-t5, .s-faq { min-height: calc(100vh - 100px + clamp(46px, 7vh, 86px)); }

  /* Манифест стоял на 140vh — 40vh сверх экрана были пустой беговой
     дорожкой: контента там всего 561px, а слой с быком и так ровно 100vh.
     При снапе в этой пустоте можно было запарковаться между блоками.
     Ровно 100vh: padding-top 88 + .manifest-inner (100vh − 88) = 100vh,
     низ секции совпадает с нижней кромкой окна. Общая формула секций
     здесь не годится — точка снапа у первой секции упирается в 0. */
  .s-manifest { min-height: 100vh; }
  .s-t1    { min-height: calc(100vh - 100px + 16vh); }
  .s-t6    { min-height: calc(100vh - 100px + 12vh); }
  .s-final { min-height: calc(100vh - 100px + 88px + clamp(12px, 2vh, 28px)); }

  /* Шаблон 2: блок вместе с бегущей лентой должен читаться одним экраном
     (правка владельца 2026-08-02). Та же болезнь, что была у отзывов —
     размеры считались ТОЛЬКО от ширины окна и не реагировали на высоту:
     колонка герба держала min-height 42vw (806px при окне 955), заголовок
     упирался в 5.8vw. Добавляем вертикальные члены. Потолки подобраны так,
     чтобы на ультрашироком мониторе (3440×1250) композиция не менялась. */
  .t1-visual { min-height: clamp(400px, min(42vw, 66vh), 820px); }
  /* 5.8vw давало 5 строк по одному слову: колонка текста — это примерно
     35vw (полвина сетки за вычетом коридора быка), а на 3 строки по
     предложениям нужен кегль не больше ширины_колонки/8.43. Отсюда 4vw. */
  .t1-title  { font-size: clamp(2.2rem, min(4vw, 9.2vh), 8.2rem); }
  .t1-lead   { margin-bottom: clamp(14px, 1.8vh, 29px); }

  /* Глобус + «Приватная группа» — отдельный экран снапа (data-snap на
     .t3-geo). Между ними стояло 166px чистого воздуха: `.s-t3 .brut-head`
     держала margin-top до 110px и margin-bottom 56, и низ «Приватной
     группы» уходил за границу окна на 27px. Селектор с `.s-t3` —
     одноклассовый проиграл бы по весу раннему правилу (строка 803). */
  .s-t3 .brut-head { margin-top: clamp(28px, 4vh, 70px); margin-bottom: clamp(18px, 2.4vh, 40px); }


  /* ---- Тарифы: заголовок + четыре карточки + портрет ICT одним экраном
     (правка владельца 2026-08-02: «заголовок не влезает при снапе»).
     Правила стояли в блоке для коротких окон и на высоком мониторе не
     работали вовсе — блок перерастал экран на 351px. Кегли и поля считаем
     от МЕНЬШЕГО из ширины и высоты, потолки сбиты под окно 1250. ---- */
  .t4-grid    { gap: 18px; margin-top: clamp(10px, 0.8vh, 24px); align-items: stretch; }
  .t4-pricing { gap: 12px; }
  /* Колонка портрета была `position: sticky` и во время прокрутки уезжала
     на 7–8px, из-за чего нижний край «плавал». Без залипания работает
     stretch: обе колонки тянутся до общей высоты. */
  .t4-ict     { position: static; display: flex; flex-direction: column; }
  /* цитаты забирают остаток высоты — под портретом не остаётся пустоты */
  .t4-ict .t4-quotes { margin-top: auto; }

  .s-t4 .tpl-title  { font-size: clamp(1.8rem, min(5.8vw, 6.2vh), 5rem); margin-bottom: clamp(4px, 0.5vh, 18px); }
  /* 720px здесь резали ширину строки под старую короткую подводку. Новая
     (2026-08-04) на этой ширине ломается на две строки и съедает 29px
     высоты — при том что кегль оставляет запас по длине строки.
     Замер: строке нужно 1179px. 1200px на окне 1250 держит её в одну
     строку — длинно для абзаца, но это одна служебная фраза, а не текст
     для чтения. У родителя 2600px, места хватает с избытком. */
  .s-t4 .tpl-lead   { font-size: clamp(0.92rem, min(1.25vw, 1.6vh), 1.15rem); max-width: 1200px; }
  .s-t4 .tpl-kicker { margin-bottom: clamp(4px, 0.55vh, 12px); }

  /* Поля пережаты ещё раз 2026-08-04: копия тарифов выросла на 136px
     (строка объёма в каждой карточке, пятый пункт в 1-ON-1, строка про
     Telegram под сеткой) и блок перерос снап-экран. Резан ТОЛЬКО воздух,
     ни одна строка текста не убрана. Кегли не тронуты. */
  .t4-card    { padding: clamp(16px, min(2vw, 1.7vh), 28px); }
  .t4-card h3 { font-size: clamp(1.3rem, min(2.1vw, 3vh), 2.3rem); margin: clamp(6px, 0.6vh, 14px) 0 4px; }
  /* min-height в две строки (2 × line-height 1.4 = 2.8em). Базовый CSS держал
     для этого `min-height: 56px`, но апскейл V3.1 сбил его в `auto` — и когда
     описание ICT NEWS стало однострочным (правка владельца 2026-08-04), список
     в этой карточке поехал на 18px выше соседней. Цена и кнопка выровнены
     всегда: их держит `flex: 1` у списка. В em, а не в px, чтобы правило
     работало на всех кеглях от 1280 до ультрашироких. */
  .t4-card > p { font-size: clamp(0.86rem, min(0.98vw, 1.5vh), 1.05rem); line-height: 1.4; min-height: 2.8em; }
  .t4-card > p.t4-meta { margin-bottom: clamp(3px, 0.4vh, 8px); }
  .t4-list     { gap: clamp(4px, 0.45vh, 11px); margin: clamp(8px, 0.9vh, 16px) 0 clamp(8px, 0.9vh, 18px); }
  .t4-list li  { font-size: clamp(0.8rem, min(0.98vw, 1.45vh), 1rem); }
  .t4-price    { font-size: clamp(1.3rem, min(2.1vw, 3vh), 2.3rem); margin-bottom: clamp(6px, 0.8vh, 14px); }
  .t4-note     { margin-top: clamp(6px, 0.7vh, 16px); }
  .t4-card .btn { padding: 0.6em 1.5em; }
  .t4-badge    { font-size: clamp(0.62rem, min(0.8vw, 1vh), 0.78rem); }

  .t4-ict .tilt-scene    { width: clamp(180px, 77%, 430px); }
  .t4-ict .quote         { font-size: clamp(0.82rem, min(0.95vw, 1.25vh), 0.98rem); }
  .t4-quotes             { gap: clamp(0.6rem, 1.2vh, 1.2rem); }
  .t4-ict .section-label { margin-bottom: 8px; }
  .t4-ict     { padding: clamp(18px, 2.2vh, 32px); }
  .t1-stats  { margin-top: clamp(16px, 2.2vh, 38px); }
  .tape-wrap { margin: clamp(18px, 2.6vh, 40px) 0 clamp(22px, 3.2vh, 60px); }

  /* Наставник: заголовок + карточки одним экраном (правка владельца
     2026-08-01). Замер: вместе 1718px при окне 955 — не хватало 763.
     Резать пришлось много, поэтому кегли считаем и от ВЫСОТЫ окна:
     на широком мониторе шрифт иначе растёт, а места по вертикали нет. */
  .t3-grid-a { gap: 16px; margin-top: clamp(8px, 1.2vh, 16px); }
  .t3-mentor { padding: clamp(11px, 1.5vh, 18px); gap: clamp(0.5rem, 0.9vh, 0.8rem); }

  .colossus { padding: clamp(10px, 1.2vh, 20px) clamp(16px, 2vw, 44px) clamp(10px, 1.3vh, 22px); }

  /* Имя по центру карточки, поля слева и справа симметричные (правка
     владельца 2026-08-02). Потолок был 4rem = 64px: на ультрашироком
     мониторе строка занимала 39.7% от 2544px внутренней ширины и жалась
     влево. Замер: при кегле 64px текст 1010px, значит на 82% ширины нужно
     ~4.15vw. Вертикальный член 10.6vh держит строку в высоте окна. */
  .colossus { text-align: center; }
  .colossus .mentor-span { justify-content: center; }
  .colossus .tpl-title { font-size: clamp(1.7rem, min(4.15vw, 10.6vh), 190px); }
  .colossus .tpl-kicker { margin-bottom: clamp(4px, 0.8vh, 12px); }
  .colossus .colossus-title { margin-bottom: clamp(6px, 1vh, 14px); }
  .colossus .mentor-span { margin-top: clamp(6px, 0.9vh, 12px); }
  .colossus .mentor-span::before { margin-bottom: clamp(8px, 1vh, 14px); }
  .colossus-note { margin-top: clamp(4px, 0.8vh, 11px); }

  /* Портрет квадратный, и он — главный вклад в высоту карточки. Жёсткий
     потолок держать нельзя: на ультрашироком мониторе (3440×1250) он
     оставлял 243px пустого места, на ноутбуке — не влезал.
     Считаем БЮДЖЕТ: всё остальное в блоке растёт примерно как 0.18·vh+482,
     под шапку уходит 88 — значит портрету достаётся ~0.82·vh − 570.
     Минус 15px страховки. Потолок 460px — исходный размер портрета. */
  .t3-mentor .holo-frame { max-width: clamp(120px, calc(82vh - 652px), 400px); }

  /* ---- Авторские индикаторы рядом с портретом (правка владельца
     2026-08-03) ----
     На высоком окне портрет центрирован и уже своей колонки — справа от
     него оставалось мёртвое поле. Ставим карточку в грид: портрет слева,
     список индикаторов в этом поле. Высота карточки не растёт: список
     (4 пункта ≈ 110px) заведомо ниже портрета.
     Селекторы через `>` повторяют компактную ветку ≤870px, чтобы правила
     двух раскладок не спорили. */
  .t3-mentor {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-content: start;
    column-gap: clamp(16px, 2vw, 34px);
  }
  .t3-mentor > .section-label,
  .t3-mentor > .mentor-id,
  .t3-mentor > .brut-box,
  .t3-mentor > .t3-mentor-quote { grid-column: 1 / -1; }
  .t3-mentor > .holo-frame  { grid-column: 1; }
  .t3-mentor > .mentor-tools { grid-column: 2; align-self: center; }

  .mentor-tools-head {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: clamp(8px, 1vh, 14px);
    font-size: clamp(0.56rem, min(0.66vw, 1.1vh), 0.74rem);
    font-weight: 800; letter-spacing: 0.24em; text-transform: uppercase;
    color: rgba(212,175,55,0.82);
  }
  .mentor-tools-head::after {
    content: ""; flex: 1; height: 1px;
    background: linear-gradient(90deg, rgba(212,175,55,0.35), transparent);
  }
  .mentor-tools-list {
    list-style: none; margin: 0; padding: 0;
    display: grid; gap: clamp(5px, 0.9vh, 10px);
    counter-reset: mt;
  }
  .mentor-tools-list li {
    counter-increment: mt;
    position: relative; padding-left: 2.1em;
    font-size: clamp(0.8rem, min(0.98vw, 1.6vh), 1.05rem);
    line-height: 1.35;
    color: rgba(244,240,234,0.86);
  }
  .mentor-tools-list li::before {
    content: counter(mt, decimal-leading-zero);
    position: absolute; left: 0; top: 0.1em;
    font-weight: 800; font-size: 0.76em; letter-spacing: 0.04em;
    color: var(--gold); opacity: 0.9;
  }
  .mentor-tools-note {
    margin: clamp(8px, 1vh, 14px) 0 0;
    font-size: clamp(0.72rem, min(0.88vw, 1.45vh), 0.95rem);
    line-height: 1.45;
    color: rgba(244,240,234,0.5);
  }

  /* Линия обучения — второй блок в той же колонке. Маркер штрихом, а не
     номером: нумерация уже занята списком индикаторов над ним, и два
     нумерованных списка подряд читались бы как одна сплошная опись. */
  /* Текст «Об авторе» вырос на строку (сборка владельца 2026-08-03), и на
     1920×955 экран «Наставника» вылез на 2px. Поля бокса — от высоты окна:
     на высоком мониторе не меняются, на среднем отдают ~15px. */
  .t3-mentor .brut-box-body { padding-block: clamp(10px, 1.4vh, 20px); }
  /* gap здесь НЕ трогать: карточка — grid, и шорткат затирает широкий
     column-gap колонок (проверено 2026-08-03 — карточка от этого росла). */

  /* Правая колонка вмещает оба блока, только если портрет достаточно высок.
     Портрет считается как 82vh − 652 (бюджет высоты), а два блока просят
     ~370px — значит вместе они помещаются лишь при окне выше ~1250px.
     Ниже этого порога колонка отдаётся линии обучения: индикаторы уже
     названы в витрине III дважды, а линия обучения больше нигде не звучит. */
  .mentor-lineage { margin-top: clamp(14px, 2.2vh, 26px); }
  .mentor-lineage:first-child { margin-top: 0; }
  .mentor-lineage-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: clamp(5px, 0.9vh, 10px);
  }
  .mentor-lineage-list li {
    position: relative;
    padding-left: 1.15em;
    font-size: clamp(0.8rem, min(0.98vw, 1.6vh), 1.05rem);
    line-height: 1.35;
    color: rgba(244,240,234,0.86);
  }
  .mentor-lineage-list li::before {
    content: "";
    position: absolute;
    left: 0; top: 0.62em;
    width: 0.5em; height: 1px;
    background: var(--gold);
    opacity: 0.85;
  }
  .t3-mentor .mentor-id { padding-bottom: clamp(7px, 1vh, 14px); gap: 2px; }
  .t3-mentor .mentor-id b { font-size: clamp(1.1rem, min(1.4vw, 2.1vh), 1.55rem); }
  .t3-mentor .brut-box-body { font-size: clamp(0.76rem, min(0.95vw, 1.5vh), 1rem); }
  .t3-mentor .brut-box-bar  { padding: clamp(4px, 0.6vh, 8px) 12px; }
  .t3-mentor-quote { font-size: clamp(0.78rem, min(0.95vw, 1.45vh), 1rem); }
  .t3-mentor .brut-box-body { line-height: 1.38; }

  /* Вертикальные отступы внутри карточки: у метки «НАСТАВНИК» было 3rem
     воздуха под собой, у боксов — по 22px полей. Режем воздух, а не текст. */
  .t3-mentor .section-label { margin-bottom: clamp(6px, 0.85vh, 16px); }
  .t3-mentor .brut-box { margin-top: clamp(6px, 1vh, 18px); }
  .t3-mentor .brut-box-body { padding: clamp(7px, 1.1vh, 16px) clamp(12px, 1vw, 18px); }
  .t3-mentor-quote { margin-top: clamp(5px, 0.85vh, 14px); padding-top: clamp(5px, 0.85vh, 14px); }
  .voices-list .voice p { font-size: clamp(0.9rem, min(1.05vw, 1.7vh), 1.15rem); }
  /* Список был жёстко расчерчен под 4 цитаты и держал min-height под них —
     из-за этого смена SLOTS на 3 сама по себе ничего не дала. */
  .voices-list {
    /* --vq считался только от ширины (1.15vw) — на широком, но невысоком
       окне колонка не ужималась и одна держала высоту всей строки грида.
       Добавляем вертикальный член: теперь она реагирует на высоту окна. */
    --vq: clamp(0.9rem, min(1.15vw, 1.95vh), 1.45rem);
    grid-template-rows: repeat(3, minmax(0, 1fr));
    min-height: calc(3 * 6.6 * var(--vq));
  }
  /* Колонка — flex со своим gap 30px, который ложился ПОВЕРХ margin'ов
     шапки и подвала: воздух считался дважды. Именно она диктовала высоту
     всей строки грида (наставнику хватало 622). */
  .voices { padding: 18px; gap: 12px; }
  .voices-list .voice {
    padding: clamp(10px, 1.4vh, 18px) 0 clamp(10px, 1.4vh, 18px) clamp(26px, 2vw, 40px);
  }
  .voices-head { margin-bottom: 4px; }
  .voices-foot { margin-top: clamp(6px, 0.9vh, 12px); }
}

/* Короткие окна (ноутбуки 1280×700 и ниже): даже на минимальном портрете
   стопка «портрет → имя → бокс → цитата» перерастает экран. Ставим портрет
   и имя в один ряд — это возвращает ~60px, не отнимая ни строчки текста.
   Перестановка чисто на гриде: разметку не трогаем. */
/* ---- Отзывы: секция одним экраном на НЕВЫСОКОМ окне ----
   Замер на 1600×960: контент занимал 986 при доступных 860. Причина —
   не высота окна сама по себе, а узкие карточки: при ширине 1600 колонка
   отзыва 487px, и текст переносится на шесть строк вместо четырёх.
   Плюс заголовок 92.8px в две строки (186px) и фиксированные 46px над
   сеткой — всё считалось только от ШИРИНЫ окна.

   Правила заперты в `max-height: 1000px` намеренно. Первая версия правки
   считала кегли от меньшей стороны окна безусловно — и ужала секцию на
   ультрашироком мониторе (3440×1250) с 1112 до 855px, чего владелец не
   просил. Здесь высокое окно не трогаем вовсе. */
@media (min-width: 768px) and (max-height: 1000px) {
  /* Биография в правой панели: на невысоком окне колонка ещё и узкая,
     текст переливается на лишние строки. Кегль и межабзацный воздух —
     от высоты окна; на 1250+ размеры не меняются. */
  .mentor-bio { gap: clamp(0.4rem, 0.8vh, 1rem); }
  .mentor-bio p { font-size: clamp(0.84rem, min(1.05vw, 1.5vh), 1.2rem); line-height: 1.5; }
  .mentor-bio p:first-child { font-size: clamp(0.88rem, min(1.15vw, 1.62vh), 1.32rem); }

  /* «Об авторе» вырос на строку (сборка владельца 2026-08-03) — на средних
     окнах карточка наставника вылезала на 2px. Режем воздух цитаты и бокса,
     не текст; на 1250+ эти правила не действуют. */
  .t3-mentor .brut-box { margin-top: clamp(8px, 1.2vh, 16px); }
  .t3-mentor .t3-mentor-quote { margin-top: clamp(6px, 1vh, 12px); padding-top: clamp(6px, 1vh, 12px); }
  .t3-mentor .mentor-id { padding-bottom: clamp(8px, 1vh, 14px); }

  .s-t5 .tpl-title  { font-size: clamp(1.8rem, min(5.2vw, 5.9vh), 4.6rem); margin-bottom: clamp(8px, 1.2vh, 20px); }
  .s-t5 .tpl-kicker { margin-bottom: clamp(6px, 0.9vh, 14px); }
  .s-t5 .tpl-lead   { font-size: clamp(0.92rem, min(1.2vw, 1.7vh), 1.25rem); }

  .t5-reviews  { margin-top: clamp(10px, 1.6vh, 40px); gap: clamp(10px, 1.6vh, 24px); }
  /* min-height считался от ширины (18vw = 288px при окне 1600) и держал
     карточку выше, чем нужно её собственному тексту */
  .t5-review   { min-height: clamp(150px, min(18vw, 24vh), 320px); padding: clamp(13px, min(1.8vw, 2.3vh), 34px); }
  .t5-review p { font-size: clamp(0.88rem, min(1.2vw, 2.05vh), 1.5rem); margin: clamp(6px, 1.1vh, 18px) 0; line-height: 1.4; }
}

/* Ниже 1250px портрет мельче и правая колонка карточки «Наставник» вмещает
   только один блок. Уступаем его линии обучения — она нигде больше не
   звучит, тогда как индикаторы названы в витрине III дважды. */
@media (min-width: 768px) and (max-height: 1249px) {
  .mentor-instr { display: none; }
}

/* «Разрыв» уходит раньше остальной компактной раскладки: строка выросла до
   трёх строк (правка владельца 2026-08-03), и в полосе 871–895px карточка
   переставала влезать в пинный кадр. Порог свой, отдельным правилом —
   иначе пришлось бы двигать всю компактную раскладку «Наставника».
   Из трёх тактов карточки «разрыв» наименее обязателен: программа и итог
   продают и без него. */
@media (min-width: 768px) and (max-height: 895px) {
  /* Метка «Ответ автора» уходит вместе с разрывом: без вопроса ответ
     повисает в воздухе. */
  .reel-hook, .reel-zone--answer { display: none; }
}

@media (min-width: 768px) and (max-height: 870px) {
  .t3-mentor {
    display: grid;
    grid-template-columns: clamp(96px, 24%, 132px) minmax(0, 1fr);
    align-content: start;
    column-gap: clamp(12px, 1.4vw, 20px);
  }
  /* Блок индикаторов уходит: на коротком окне колонка справа занята именем,
     и список выталкивал карточку за пределы экрана снапа. Индикаторы
     остаются в витрине III («В стоимости» и строка в панели). */
  .t3-mentor > .mentor-tools { display: none; }

  .t3-mentor > .section-label,
  .t3-mentor > .brut-box,
  .t3-mentor > .t3-mentor-quote { grid-column: 1 / -1; }
  .t3-mentor > .holo-frame {
    grid-column: 1;
    align-self: start;
    margin-inline: 0;
    max-width: 100%;
  }
  .t3-mentor > .mentor-id {
    grid-column: 2;
    align-self: center;
    padding-bottom: 0;
    border-bottom: 0;
  }

  /* Имя раскрываем и здесь, но вертикальный член ниже: на коротком окне
     высота строки дороже. Заполнение выходит ~70% вместо 82%. */
  .colossus .tpl-title { font-size: clamp(1.5rem, min(4.7vw, 7.6vh), 4.6rem); }
  .t3-mentor .brut-box-body { font-size: clamp(0.72rem, min(0.95vw, 1.5vh), 1rem); }

  /* Колонка отзывов на таком экране становится второй по высоте — снимаем
     с неё те же лишние поля. */
  .voices { padding: 12px; }
  .voices-list { min-height: calc(3 * 5.8 * var(--vq)); }
  .voices-list .voice { padding-block: clamp(6px, 1vh, 12px); }
  .voices-head { margin-bottom: 0; }
  .voices-foot { margin-top: 6px; padding-top: clamp(10px, 1.4vh, 20px); gap: clamp(10px, 1.4vh, 20px); }
  /* Биография на коротком окне: пол кегля ниже и воздух между абзацами
     срезан. Текст не сокращаем — только поля. */
  .mentor-bio { gap: 0.3rem; }
  .mentor-bio p { font-size: clamp(0.78rem, min(1.05vw, 1.5vh), 1.2rem); }
  .mentor-bio p:first-child { font-size: clamp(0.82rem, min(1.15vw, 1.62vh), 1.32rem); }

  /* Глобус + «Приватная группа» должны читаться одним экраном (правка
     владельца 2026-08-01). Замер: вместе с отступами они занимали 1072px
     при окне 955 — не хватало ~120px. Ужимаем оба блока и промежутки. */
  .t3-geo    { margin-top: 12px; padding: 16px; }
  /* `.t3-geo .geo-globe`, а не просто `.geo-globe`: ниже по файлу есть
     правило с max-width 420px, и по одному классу оно бы победило. */
  .t3-geo .geo-globe { max-width: clamp(220px, 26vh, 340px); }
  .geo-lead  { margin: 0.7rem 0 1rem; }
  .geo-list  { gap: 7px; }
  .geo-note  { margin-top: 0.9rem; }

  /* `.s-t3`, чтобы не проиграть по весу правилу в общем десктопном блоке */
  .s-t3 .brut-head { margin-top: clamp(24px, 3.2vh, 44px); margin-bottom: clamp(14px, 2vh, 24px); }
  .brut-split { margin-bottom: clamp(18px, 3vh, 36px); }
  /* через `.brut-split`, иначе одноклассовое правило проиграет по весу
     более раннему `.brut-split .brut-display` */
  .brut-split .brut-display { font-size: clamp(2.4rem, min(5.4vw, 8vh), 5.4rem); }
  .brut-lead    { font-size: clamp(0.92rem, min(1.1vw, 1.75vh), 1.2rem); }
  .brut-list li { padding: clamp(10px, 1.5vh, 18px) clamp(14px, 1.2vw, 22px); }
  .brut-list li p { font-size: clamp(0.88rem, min(1vw, 1.6vh), 1.05rem); }

  /* Тарифы. Замер на 100% масштабе (1920×955): секция занимала 1738px и
     заголовок уезжал за верх экрана. Ужимаем заголовок и карточки —
     кегли считаем и от ВЫСОТЫ окна, иначе на широком мониторе шрифт растёт,
     а места по вертикали не прибавляется. */
  /* Низ карточки портрета вровень с тарифами (правка владельца 2026-08-01).
     Подгонять размер портретом бессмысленно: колонка была `position: sticky`
     и во время прокрутки уезжала на 7–8px, поэтому край «плавал». Снимаем
     залипание — тогда работает stretch, и обе колонки тянутся до общей
     высоты: верх и низ совпадают на любом экране и при любой прокрутке.
     Цена решения: портрет больше не следует за прокруткой. */
}

/* ==========================================================================
   ВИТРИНА I · КАРТА ТАЙМФРЕЙМОВ — равные карточки, ровная стопка
   (правка владельца 2026-08-01)
   ========================================================================== */
@media (min-width: 768px) {
  /* 1. Стоят ровно, а не по диагонали: базовый разворот (11°/−15°) снят,
        наклон за курсором (--hx/--hy) сохранён. */
  .tf-stack { transform: rotateX(var(--hx, 0deg)) rotateY(var(--hy, 0deg)); }

  /* 2. Одинаковый размер. Причин было ДВЕ: ступенчатая ширина
        (каждая пластина на 8% уже предыдущей со сдвигом влево) и разная
        глубина — под перспективой ближний слой выглядел крупнее дальнего.
        Снято и то и другое; вход и оборот пластин не затронуты. */
  .tf-plane { --tz: 0px; width: 100%; margin-left: 0; }

  /* 3. Описание — строго в правой половине. Было space-between: подпись
        улетала к правому краю и пересекала центральный шов грани. Теперь
        две колонки: описание начинается от середины и выровнено по левому
        краю, поэтому у всех пластин стартует на одной вертикали. */
  .tf-face {
    display: grid;
    grid-template-columns: 44% 1fr;
    align-items: baseline;
    gap: 0;
  }
  .tf-face i { text-align: left; }
}

/* Мягкая подмена отзывов (модуль 18d). Классы навешиваются, только когда
   отзывов в разметке больше шести — сейчас ротация спит, работает лишь
   случайный порядок. Ритм тот же, что у голосов в «Наставнике». */
.t5-review { transition: opacity 0.42s var(--ease-out), transform 0.42s var(--ease-out); }
.t5-review.is-out { opacity: 0; transform: translateY(-14px); }
.t5-review.is-in  { opacity: 0; transform: translateY(14px); }

/* ==========================================================================
   ШАБЛОН 3–5 · ВИТРИНА: карточка и панель — равная пара внутри кадра
   (правка владельца 2026-07-31)

   Высоту правой панели задавал КВАДРАТ внутри неё: `aspect-ratio` считается
   от ширины, поэтому на широком невысоком окне сторона доходила до 684px,
   панель вырастала до 968px при кадре 612px — верх уезжал под шапку, а пара
   «карточка / панель» читалась разнокалиберной.

   Теперь кадр задаёт сам слайд (падинги под шапку), обе колонки тянутся на
   его высоту — значит равны всегда, — а квадрат забирает лишь остаток после
   шапки и подвала панели. Кегли внутри карточки считаются от МЕНЬШЕЙ из
   сторон окна: на широком мониторе шрифт больше не растёт в ущерб высоте.
   ========================================================================== */

@media (min-width: 768px) {
  .reel-slide {
    align-items: stretch;                       /* обе колонки одной высоты */
    padding: calc(88px + 2.4vh) 8vw 2.4vh;      /* 88px — фиксированная шапка */
  }

  .reel-card, .reel-hud { max-height: 100%; }

  .reel-card {
    display: flex; flex-direction: column; justify-content: center;
    overflow: hidden;
    padding: clamp(1.4rem, min(3.6vw, 4.4vh), 5rem) clamp(1.8rem, min(4vw, 5vh), 5.4rem);
  }
  /* Кегли подняты по высотному коэффициенту (правка владельца 2026-08-01:
     «текст витрин чуть-чуть увеличить»). Ширина по-прежнему ограничивает —
     карточка считается от МЕНЬШЕЙ стороны окна и остаётся в пинном кадре. */
  .reel-roman { font-size: clamp(2.3rem, min(6.2vw, 8.4vh), 8.6rem); }
  .reel-title { font-size: clamp(1.6rem, min(3.1vw, 4.8vh), 3.6rem); }
  .reel-desc  { font-size: clamp(0.95rem, min(1.2vw, 2.1vh), 1.3rem); }
  .reel-meta  { font-size: clamp(0.72rem, min(0.92vw, 1.7vh), 1rem); }
  .reel-for   { font-size: clamp(0.82rem, min(1.02vw, 1.8vh), 1.1rem); }
  .reel-price { font-size: clamp(1.7rem, min(2.8vw, 5vh), 3.3rem); }
  .reel-list  { font-size: clamp(0.86rem, min(1.08vw, 2vh), 1.15rem); gap: clamp(0.3rem, 0.9vh, 0.75rem); }
  .reel-quote { font-size: clamp(0.86rem, min(1.12vw, 2vh), 1.25rem); margin-bottom: clamp(0.25rem, 0.7vh, 0.9rem); }
  .reel-prog  { font-size: clamp(0.84rem, min(1.06vw, 1.95vh), 1.15rem); gap: clamp(0.18rem, 0.45vh, 0.7rem); margin-bottom: clamp(0.3rem, 0.8vh, 0.85rem); }
  .reel-note  { font-size: clamp(0.74rem, min(0.92vw, 1.65vh), 1rem); margin-bottom: clamp(0.3rem, 0.8vh, 0.8rem); }
  .reel-incl  { font-size: clamp(0.74rem, min(0.92vw, 1.6vh), 1rem); padding: clamp(0.34em, 0.7vh, 0.55em) 0.85em; margin-bottom: clamp(0.25rem, 0.7vh, 0.75rem); }
  .reel-meta  { margin-bottom: clamp(0.45rem, 1.1vh, 0.95rem); }
  /* Элементы упаковки — тоже от высоты окна */
  .reel-hook  { font-size: clamp(0.9rem, min(1.14vw, 2vh), 1.3rem); margin-bottom: clamp(0.3rem, 0.8vh, 0.8rem); }
  .reel-zone--answer { margin-bottom: clamp(0.15rem, 0.4vh, 0.4rem); }
  .reel-chip  { font-size: clamp(0.52rem, min(0.6vw, 1.05vh), 0.7rem); top: clamp(0.9rem, 2.2vh, 2rem); right: clamp(1rem, 2vw, 2.2rem); }
  .reel-zone  { font-size: clamp(0.52rem, min(0.6vw, 1vh), 0.68rem); margin-bottom: clamp(0.25rem, 0.7vh, 0.7rem); }
  .reel-foot  { padding-top: clamp(0.25rem, 0.7vh, 0.8rem); margin-top: 0; row-gap: 4px; }
  .reel-zone--result { margin-top: clamp(0.1rem, 0.3vh, 0.35rem); }
  .reel-link  { font-size: clamp(0.56rem, min(0.66vw, 1.1vh), 0.72rem); }
  .reel-seal  { width: clamp(44px, 6vh, 84px); bottom: clamp(2.8rem, 6vh, 4.4rem); }

  /* Вертикальный ритм тоже от высоты окна — иначе на низком экране
     фиксированные отступы съедали больше, чем сам текст. Специфичность
     0,2,0 повторяет ранние правила `.reel-card .reel-*`, блок ниже — значит
     побеждает. */
  .reel-card .reel-roman,
  .reel-card .reel-title,
  .reel-card .reel-meta,
  .reel-card .reel-desc,
  .reel-card .reel-list,
  .reel-card .reel-for,
  .reel-card .reel-price { margin-bottom: clamp(0.3rem, 0.85vh, 1rem); }

  /* Место под «разрыв» и «итог» освобождено сверху карточки: римская цифра
     была 8.4vh (76px при окне 900) — чистая декорация, дублирующая бирку и
     точки прогресса. Ужата до 5.8vh; освободившиеся ~40px ушли в смысл. */
  .reel-roman { font-size: clamp(2rem, min(5vw, 5.8vh), 6rem); }
  .reel-card { padding: clamp(1.2rem, min(3.2vw, 3.6vh), 4.2rem) clamp(1.8rem, min(4vw, 5vh), 5.4rem); }

  .reel-hud {
    display: flex; flex-direction: column;
    padding: clamp(1.2rem, min(2.2vw, 3.2vh), 2.5rem);
  }
  /* Квадрат больше не ведёт ширина: базис 0 — он забирает ровно остаток
     высоты и от него считает свою сторону, упираясь в ширину панели. */
  .hud-stage {
    flex: 1 1 0%;
    min-height: 0;
    width: auto;
    max-width: 100%;
    margin-inline: auto;
    container-type: size;
  }
  /* Начинка панели (стопка таймфреймов, радар, циферблаты) считается от
     `--hud-w`, то есть от ШИРИНЫ ПАНЕЛИ — на низком окне стопка занимала
     504px в боксе 317px и вылезала. Здесь переменная пересчитывается от
     стороны самого квадрата (`cqh`), поэтому содержимое всегда ему по
     размеру — и на низком окне, и на большом мониторе. На ширину панели
     это не влияет: она берёт `--hud-w` со своего уровня. */
  .hud-stage > * { --hud-w: 100cqh; }
}

/* ==========================================================================
   ШАБЛОН 7 · ГЕОГРАФИЯ СООБЩЕСТВА (глобус, 2026-07-31)
   Колонки повторяют .t3-grid-a (0.9fr / 1.3fr), чтобы блок встал в один
   ритм с карточками выше. Палитра глобуса задаётся в js/main.js теми же
   токенами: суша — тёплый белый, метки — золото, свечение — бронза.
   ========================================================================== */

.t3-geo {
  margin-top: 22px;
  padding: 26px;
  border-radius: 18px;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr);
  gap: clamp(18px, 2.4vw, 40px);
  align-items: center;
}

.geo-globe {
  position: relative;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  aspect-ratio: 1;
}
.geo-globe canvas {
  width: 100%; height: 100%; display: block;
  cursor: grab;
  opacity: 0;                        /* поднимается в JS, когда первый кадр готов */
  transition: opacity 1.2s var(--ease-out);
  touch-action: pan-y;               /* вертикальный скролл страницы не отбираем */
  contain: paint;
}
.geo-globe canvas.is-dragging { cursor: grabbing; }

/* Метка выбранной страны: красная, пульсирует (правка владельца 2026-08-01).
   Позицию по вертикали правит JS — у высоких широт наклон глобуса упирается
   в ограничитель, и точка садится чуть выше центра. */
.geo-pin {
  position: absolute;
  left: 50%; top: calc(50% + var(--pin-dy, 0px));
  width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 96, 72, 0.95) 0%, rgba(214, 48, 34, 0.55) 46%, transparent 72%);
  box-shadow: 0 0 12px rgba(255, 82, 58, 0.75);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease-out);
}
.geo-pin.is-on { animation: geoPinPulse 1.25s ease-in-out infinite; }
@keyframes geoPinPulse {
  0%, 100% { transform: scale(1);   filter: brightness(1); }
  50%      { transform: scale(1.55); filter: brightness(1.35); }
}
@media (prefers-reduced-motion: reduce) { .geo-pin.is-on { animation: none; } }

.geo-side { min-width: 0; }

/* Подпись «География сообщества»: крупнее и золотом (правка владельца
   2026-08-04). Было 13px графитом — то есть заголовок оказывался МЕЛЬЧЕ
   собственного лида под ним (17.6px) и самым тусклым элементом блока,
   поэтому читался как сноска, а не как название. Теперь он выше лида по
   кеглю и взят золотом — тем же, что кикеры блоков и подводка манифеста.

   Селектор нарочно ограничен `.geo-side`: класс `.section-label` живёт ещё
   в двух местах («НАСТАВНИК» в шаблоне 7, «ICT / КОРНИ МЕТОДА» в шаблоне 8),
   их владелец менять не просил. Двух классов хватает, чтобы перебить
   и базовое правило, и апскейл V3.1, где бы они ни стояли по порядку. */
.geo-side .section-label {
  /* Нижняя граница 11px, а не больше: у `.section-label` есть декоративная
     черта `::after` шириной 64px плюс gap 16px — на телефоне они съедают
     80px из 313, и тексту остаётся 233. Замер: при 12px строка просит 244
     и переносится на две. 11px (230px) — ровно то значение, под которое
     подпись и была подогнана изначально. Растём только там, где есть место. */
  font-size: clamp(11px, 1.2vw, 1.35rem);
  color: var(--gold);
}
/* Черта после подписи шла графитом и рядом с золотым текстом смотрелась
   обрубком от старой версии. Золото на 40% — читается как линейка, а не
   как второй золотой элемент, спорящий с текстом за внимание. */
.geo-side .section-label::after { background: rgba(212, 175, 55, 0.4); }

.geo-lead {
  margin: 0.9rem 0 1.4rem;
  color: rgba(244, 240, 234, 0.62);
  font-size: clamp(0.95rem, 1.05vw, 1.15rem);
  line-height: 1.6;
  max-width: 46ch;
}

.geo-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px;
}
.geo-city {
  font: inherit;
  font-size: clamp(0.78rem, 0.85vw, 0.95rem);
  letter-spacing: 0.02em;
  color: rgba(244, 240, 234, 0.74);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(244, 240, 234, 0.1);
  border-radius: 999px;
  padding: 0.55em 1.1em;
  cursor: pointer;
  transition: color 0.35s var(--ease-out), border-color 0.35s var(--ease-out),
              background 0.35s var(--ease-out), transform 0.35s var(--ease-out);
}
.geo-city:hover,
.geo-city:focus-visible,
.geo-city.is-active {
  color: var(--gold);
  border-color: rgba(212, 175, 55, 0.5);
  background: rgba(212, 175, 55, 0.08);
  transform: translateY(-1px);
}

.geo-note {
  margin: 1.3rem 0 0;
  font-size: 12px; letter-spacing: 0.24em; text-transform: uppercase;
  color: rgba(244, 240, 234, 0.3);
}
/* Подпись видна и на таче (возврат по команде владельца 2026-08-05:
   «под глобусом нет текста»). Прежнее скрытие исходило из того, что
   «наводить нечем», но у чипов есть click-обработчик: тап закрепляет
   страну, и глобус поворачивается к ней — подсказка честна и на пальце. */
body.is-touch .geo-note { display: block; }

@media (max-width: 900px) {
  .t3-geo { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .geo-globe { max-width: 320px; }
  .geo-side { text-align: center; }
  .geo-list { justify-content: center; }
  .geo-lead { margin-inline: auto; }
}

/* ==========================================================================
   ШАБЛОН 11 · ФИНАЛ-ГАЛАКТИКА (вариант Б + врата Г, выбор владельца 2026-07-31)
   Сцена: спираль-галактика на канвасе → «Остальное — внутри» распыляется
   в частицы → проявляются словомарка сверху и «Войти» по центру.
   Логика — модуль 19 js/main.js. Блок стоит В КОНЦЕ файла сознательно:
   поздние правила перекрывают апскейл-блок V3.1.
   ========================================================================== */

.s-final {
  position: relative;
  overflow: hidden;
  /* Поле сверху = высота фиксированной шапки + воздух (правка владельца
     2026-07-31). Прежние 27px были МЕНЬШЕ шапки (88px), и верх карточки
     уезжал под неё. Больше прежних 64–130px не берём: карточка и подвал
     обязаны оставаться на одном экране. */
  padding-top: calc(88px + clamp(12px, 2vh, 28px));
}

/* КАРТОЧКА-ЭКРАН. Габариты и обводка — один в один с CTA-боксом шаблона 10
   (.t6-box): та же формула ширины, радиус 24px, кромка, тень и золотое
   свечение от верхнего края. Пропорция 1.9 повторяет его сложение. */
.final-stage {
  position: relative;
  flex: none;
  align-self: center;
  width: min(max(1500px, 74vw), 94vw, 2200px);
  aspect-ratio: 1.82;
  /* Высота ужата (правка владельца 2026-07-31): при 82vh карточка вместе с
     подвалом не помещалась на экран — 1063px при кадре 780. Ширина осталась
     прежней (сложение .t6-box), иначе увеличенный заголовок не встал бы в
     одну строку. */
  /* Третий предел — остаток высоты после шапки и подвала. Связывает только
     на сильном масштабе браузера: при 150% (окно ~637px) секция вылезала
     на 28px, теперь укладывается. На обычных экранах правит по-прежнему 50vh. */
  max-height: min(50vh, 470px, calc(100vh - 360px));
  /* margin-top:auto забирает весь свободный воздух секции СВЕРХУ и опускает
     карточку к подвалу — в диапазон, который владелец расчертил 2026-07-31.
     Раньше `justify-content: space-between` прижимал её под самую шапку. */
  margin: auto auto clamp(10px, 2.5vh, 32px);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
}

/* Слой рамки: он появляется и испаряется, а текст живёт отдельно поверх.
   Нутро непрозрачно-чёрное — как в исходной анимации. */
.final-frame {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  border-radius: 24px;
  background: #000;
  border: 1px solid rgba(244, 240, 234, 0.1);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
}
/* золотое свечение от верхней кромки — поверх звёзд, как в .t6-box */
.final-frame::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  pointer-events: none; border-radius: inherit;
  background: radial-gradient(circle at 50% 0%, rgba(212, 175, 55, 0.16), transparent 42%);
}

.final-galaxy {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}

.final-inner, .s-final .site-footer { position: relative; z-index: 1; }

/* Подвал ужат, чтобы попадал на один экран с карточкой (правка владельца
   2026-07-31): было 424px, из них 176px — герб. Пропорции сохранены,
   уменьшен только масштаб. */
.s-final .site-footer {
  padding: clamp(1.6rem, 3vh, 2.6rem) 24px clamp(1.2rem, 2.4vh, 2rem);
  gap: clamp(0.7rem, 1.6vh, 1.4rem);
}
.s-final .footer-crest { width: clamp(78px, 11vh, 118px); height: auto; }
.final-inner { position: relative; }

/* канвас-пыль: распад заголовка живёт внутри карточки, испарение самой
   карточки — в секции (иначе пыль растворилась бы вместе с ней) */
.final-dust { position: absolute; z-index: 3; pointer-events: none; }

/* тексты лежат на звёздах — мягкая подложка тенью, без плашек */
.final-stage .final-line,
.final-gate-mark,
.final-enter { text-shadow: 0 2px 26px rgba(0, 0, 0, 0.85), 0 0 8px rgba(0, 0, 0, 0.6); }

.final-gate-mark {
  position: absolute; top: clamp(26px, 5vh, 54px); left: 0; right: 0; z-index: 2;
  margin: 0; text-align: center;
  font-size: clamp(0.72rem, 1vw, 0.95rem);
  font-weight: 700; letter-spacing: 0.42em; text-transform: uppercase;
  color: rgba(244, 240, 234, 0.9);
  opacity: 0; visibility: hidden;
}

.final-enter {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); z-index: 2;
  opacity: 0; visibility: hidden;
  font-size: clamp(1.15rem, 2.4vw, 1.6rem);
  font-weight: 200; letter-spacing: 0.4em; text-transform: uppercase;
  color: rgba(244, 240, 234, 0.92);
  padding: 0.6em 1.2em 0.6em 1.6em; /* слева больше: компенсация трекинга последней буквы */
  opacity: 0; pointer-events: none;
  transition: letter-spacing 0.5s var(--ease-out), color 0.5s var(--ease-out);
}
.final-enter:hover, .final-enter:focus-visible { letter-spacing: 0.48em; color: var(--gold); }
/* GSAP ставит opacity инлайном — visibility снимаем, когда врата открыты */
.final-gated .final-enter, .final-gated .final-gate-mark { visibility: visible; }

/* Пульсацию ведёт GSAP (модуль 19), а не CSS-keyframes: анимация CSS
   перебивает инлайновую opacity, и «Войти» не гасла вместе с карточкой. */
.final-gated .final-enter { pointer-events: auto; }

/* Статичный режим (reduced-motion / нет GSAP): без распада, всё видно сразу,
   «Войти» встаёт в поток под заголовком. */
.final-static .final-gate-mark,
.final-static .final-enter { opacity: 1; visibility: visible; }
.final-static .final-enter { position: static; transform: none; pointer-events: auto; }

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

/* ============================================================
   ШАБЛОН 8 — невысокие окна (2026-08-04)
   Блок не влезал в снап-экран на 1920x955 и до правки копии — на 94px.
   Корень: портрет ICT считал размер только от ШИРИНЫ (`clamp(180px, 77%,
   430px)`), и на коротком окне 430-пиксельный квадрат один съедал бюджет.
   Здесь размеры считаются от МЕНЬШЕГО из ширины и высоты — тот же приём,
   что уже применён к карточкам выше по файлу.
   Стоит в конце файла намеренно: апскейл V3.1 в середине по порядку
   победил бы эти правила.
   ============================================================ */

@media (min-width: 768px) and (max-height: 1000px) {
  .t4-ict .tilt-scene { width: clamp(150px, min(77%, 26vh), 430px); }
  .t4-ict { padding: clamp(14px, 1.8vh, 32px); }
  .t4-quotes { gap: clamp(0.5rem, 0.9vh, 1.2rem); }

  .s-t4 .tpl-title { font-size: clamp(1.6rem, min(5.8vw, 5vh), 5rem); }
  .s-t4 .tpl-kicker { margin-bottom: clamp(3px, 0.4vh, 12px); }

  .t4-card { padding: clamp(12px, min(2vw, 1.35vh), 28px); }
  .t4-card h3,
  .t4-price { font-size: clamp(1.1rem, min(2.1vw, 2.3vh), 2.3rem); }
  .t4-card h3 { margin: clamp(4px, 0.5vh, 14px) 0 3px; }
  .t4-price { margin-bottom: clamp(5px, 0.65vh, 14px); }
  .t4-card > p { font-size: clamp(0.78rem, min(0.98vw, 1.32vh), 1.05rem); }
  .t4-list { gap: clamp(3px, 0.35vh, 11px); margin: clamp(6px, 0.7vh, 16px) 0 clamp(6px, 0.7vh, 18px); }
  .t4-list li { font-size: clamp(0.74rem, min(0.98vw, 1.28vh), 1rem); }
  .t4-card .btn { padding: 0.5em 1.3em; }
  .t4-note { margin-top: clamp(5px, 0.6vh, 16px); font-size: clamp(0.78rem, 1.25vh, 1.1rem); }
}

/* ---- Шаблон 8, очень низкие окна (≤820px): четыре карточки в один ряд.
   Причина: высоту диктует КОЛОНКА КАРТОЧЕК (два ряда), а не портрет.
   Ужимать поля дальше некуда — кегли уже упёрлись в свои полы, ниже
   начинается нечитаемое. Поэтому меняем раскладку, а не размеры:
   один ряд вместо двух срезает половину высоты колонки.
   Портрет ICT снимается — он декоративный (герой методологии и две
   цитаты), решение о покупке принимают по карточкам. Тот же приём, что
   с индикаторами в «Наставнике»: на коротком окне уступает место
   тому, ради чего блок существует. ---- */
@media (min-width: 768px) and (max-height: 820px) {
  .t4-grid    { grid-template-columns: minmax(0, 1fr); }
  .t4-ict     { display: none; }
  .t4-pricing { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .t4-card    { padding: clamp(11px, 1.1vw, 20px); }
  .t4-list    { gap: clamp(3px, 0.4vh, 8px); }
}

/* ============================================================
   ЧИТАЕМОСТЬ НА ТЕЛЕФОНАХ И ПЛАНШЕТАХ (аудит 2026-08-05)
   Замер на 390px показал 59 элементов мельче 12px, худшие — 8px у подписей
   на монетах и 8.3px у чипов витрины. Всё это капслоком с широким трекингом,
   что читаемость дополнительно ухудшает.

   Порог 1024px, а не 767: на планшете (замер при 805px) обнаружились РОВНО
   ТЕ ЖЕ значения — 8px, 8.3px, 9px. iPad в портрете и альбоме попадает
   в диапазон 768–1024, и без этого порога он оставался бы без правки.
   На десктопе (шире 1024) кегли не меняются вообще.

   Блок стоит в КОНЦЕ файла намеренно: апскейл V3.1 в середине по порядку
   перебил бы эти правила.
   ============================================================ */
@media (max-width: 1024px) {
  /* было 8–9px: подписи и девизы на монетах шаблона 2 */
  .hud-coin small { font-size: 11px; }
  .hud-coin em    { font-size: 11.5px; }

  /* было 8.3–10.9px: витрина курсов */
  .reel-chip { font-size: 11px; }
  .reel-zone { font-size: 11px; }
  .reel-meta { font-size: 11.5px; }

  /* было 9.3–11.6px: блок «Наставник» */
  .brut-box-bar span      { font-size: 11px; }
  .voices-src             { font-size: 11px; }
  .voices-label           { font-size: 11.5px; }
  .voice small            { font-size: 11px; }
  .mentor-id span         { font-size: 11.5px; }
  .mentor-span span       { font-size: 11.5px; }
  .t3-mentor-quote span   { font-size: 11.5px; }
  .aud-facts dd           { font-size: 11.5px; }
  .section-label          { font-size: 11.5px; }

  /* было 9.9px: правые подписи блоков 6, 7 и FAQ */
  .brut-meta      { font-size: 11px; }
  .faq-ask span   { font-size: 11px; }

  /* было 10px: тарифы. Селектор с двумя классами обязателен: выше по файлу
     стоит `.t4-card > p.t4-meta`, и одноклассовое правило ему проигрывает. */
  .t4-badge              { font-size: 11px; }
  .t4-card > p.t4-meta   { font-size: 11px; }
  .t4-quotes cite        { font-size: 11px; }

  /* «Условия доступа — в тарифах»: было 9.6px и высота строки 15px —
     в такую цель пальцем почти не попасть. Кегль до 12px и вертикальные
     поля, чтобы зона нажатия дотянула до рекомендованных 44px.
     inline-block обязателен: у inline-элемента вертикальный padding
     не увеличивает область клика. */
  .reel-link {
    font-size: 12px;
    display: inline-block;
    padding-block: 13px;
  }

  /* было 11px: описания карточек шаблона 2 — основной смысл блока */
  .hero-stat span { font-size: 12.5px; }

  /* Эти две подписи видны только на планшете — на телефоне их блоки
     перестроены, поэтому в мобильном замере они не всплыли. */
  .reel-for-label     { font-size: 11px; }
  .mentor-tools-head  { font-size: 11px; }
  .colossus-note      { font-size: 11px; }

  /* Подписи ВНУТРИ графики витрины: метки на радаре новостей (слайд II)
     и на кольцах циклов (слайд III). Были 9.2px и 7.5px. Проверено
     замером: увеличение до 11/10 не добавляет вылезаний за пределы
     рисунка — две метки стоят на ободе по замыслу и при любом кегле.
     Выше не поднимать: подписи подогнаны под диаметр колец. */
  .dial-marks li span { font-size: 11px; }
  .dial-core i        { font-size: 11px; }
  .cyc-tag-pos i      { font-size: 10px; }

  /* ПУНКТЫ МЕНЮ НАМЕРЕННО НЕ ТРОГАЕМ. На планшете они 32px в высоту,
     меньше рекомендованных 44px. Чтобы дотянуть, нужно 13px полей вместо
     нынешних 7 — капсула меню заметно раздуется, а это центральный элемент
     шапки, который владелец долго доводил. Компенсация: цели широкие
     (86–116px), промахнуться по горизонтали сложно. Менять только по
     прямому решению владельца. */

  /* Чипы стран у глобуса были 36px в высоту — ниже рекомендованных 44px
     для пальца. На тач-устройствах у них нет наведения (глобус
     поворачивается по hover), но нажать по ним всё равно можно,
     и промах раздражает. Добавляем вертикальные поля, кегль не трогаем. */
  .geo-city { padding-block: 10px; }
}

/* ---- Финал на телефоне: «Остальное — внутри» (жалоба владельца 2026-08-05
   «сложно прочесть»). Причина двойная: кегль упирался в нижнюю границу
   clamp (48px на 390px — на телефоне мелко для главной фразы блока), и
   буквы лежат прямо поверх анимированного звёздного поля, из-за чего
   сливаются с ним. Поднимаем кегль и отделяем текст от фона тенью —
   она не читается как эффект, но даёт буквам контур на любом кадре
   анимации. Выше 767px правило не действует. ---- */
@media (max-width: 767px) {
  .final-line {
    /* 15vw → 11vw (правка владельца 2026-08-05: «слишком большой,
       соразмерно карточке»). На 390px это ~43px вместо 58.5 — заголовок
       перестаёт упираться в края карточки финала. Крупицы сборки следуют
       за кеглем автоматически: растр считается от DOM-шрифта. */
    font-size: clamp(2.5rem, 11vw, 3.2rem);
    text-shadow: 0 2px 18px rgba(6, 6, 7, 0.92), 0 1px 4px rgba(6, 6, 7, 0.85);
  }
  /* Метка врат «TONY SOPRANO ICT» в статичном режиме оставалась в центре
     сцены и ложилась прямо на заголовок (скриншот владельца 2026-08-05).
     На телефоне она декоративна и не нужна — заголовок и «Войти» несут
     всё сами. Десктоп не задет: там движок ведёт метку по прогрессу. */
  .final-static .final-gate-mark { display: none; }
}

/* ============================================================
   ВИТРИНА КУРСОВ НА ТЕЛЕФОНЕ — ВЕРТИКАЛЬНАЯ СТОПКА (2026-08-05)

   Что было не так. На мобиле витрина работала свайп-каруселью, а вместе
   с ней через `display: none` пропадали:
     · .reel-hud ×3 — «Карта таймфреймов», «Хронометр релиза»,
       «Календарь циклов». Правило скрывало их на ВСЁМ, что уже 1180px;
     · .reel-for ×3 — строки «Кому»;
     · .reel-progress — индикатор, единственный намёк, что курсов три.
   Плюс карточка была выше экрана, и приходилось свайпать вбок и
   скроллить вниз одновременно — худший из возможных жестов.

   Почему стопка, а не «вернуть панели в карусель». Панели весят
   551–668px. Пришив их к карточке в 850px, получаем слайд в полтора
   экрана внутри горизонтальной ленты — нечитаемо. Вертикально же всё
   раскладывается естественно: пролистал — увидел всё.

   Видео из фона слайда становится полосой-шапкой сверху: на телефоне
   оно всё равно не читалось как фон под текстом.

   ПОРОГ ПОДНЯТ 767 → 1180 (2026-08-05, второй заход). Причина серьёзнее
   вёрстки: на НАСТОЯЩЕМ планшете (тач) JS идёт по мобильной ветке и
   никогда не ставит слайдам `is-active`, а десктопный CSS в полосе
   768–1180 держит слайды с opacity:0 до этого класса. То есть на
   реальном iPad витрина была ПУСТЫМ ЧЁРНЫМ БЛОКОМ в два экрана.
   Скрытие .reel-hud на ≤1180 было заплаткой поверх этой дыры.
   Стопка ниже самодостаточна: она нейтрализует и карусельную базу ≤767
   из main.css, и десктопную (position:absolute; opacity:0) — поэтому
   работает в обеих полосах. Пин-режим JS отключён до 1181px тем же
   днём (см. js/main.js, модуль 3). ============================== */
@media (max-width: 1180px) {
  .s-showreel { height: auto; }

  .showreel-stage {
    position: static;
    height: auto;
    display: block;
    overflow: visible;
    overflow-x: visible;
    scroll-snap-type: none;
    padding: 6vh 18px;
  }

  .reel-slide {
    /* нейтрализация десктопной базы: слайды там absolute и невидимы
       до is-active, которого без пина никто не поставит */
    position: relative;
    inset: auto;
    opacity: 1;
    visibility: visible;
    display: block;
    flex: none;
    width: auto;
    max-width: 760px;
    min-height: 0;
    overflow: hidden;
    margin: 0 auto 28px;
    padding: 0;
    background: #0d0d0d;
    border-radius: 14px;
  }
  .reel-slide:last-child { margin-bottom: 0; }

  /* Точки прогресса — деталь пин-режима, в стопке бессмысленны */
  .reel-progress { display: none; }

  /* Видео — полоса-шапка вместо подложки под всей карточкой.
     bottom:auto обязателен: десктопная база задаёт inset:0, и без
     явного сброса низа полоса растянулась бы на весь слайд. */
  .reel-video,
  .reel-shade { position: absolute; top: 0; left: 0; right: 0; bottom: auto; height: 150px; }
  .reel-video { object-fit: cover; }

  /* Карточка возвращается в поток. padding-top держит полосу видео —
     он же заменяет прежнее «окно» из блока ≤560px. */
  .reel-card {
    position: relative;
    bottom: auto;
    padding-top: 130px;
  }

  /* Приборная панель курса: была скрыта правилом для ≤1180px.
     Возвращаем и кладём ПОД карточку. Правило стоит в конце файла,
     поэтому по порядку побеждает то `display: none`.
     --hud-w переопределяется сознательно: внутренние детали панелей
     (кольца, метки, стрелки) считают размеры от этой переменной через
     calc(var(--hud-w) * k). Задай мы ширину напрямую — коробка сжалась
     бы, а начинка осталась в масштабе 480px и вылезла из корпуса. */
  .reel-hud {
    display: block;
    position: relative;
    opacity: 1;
    transform: none;
    --hud-w: min(680px, calc(100vw - 72px));
    width: var(--hud-w);
    max-width: none;
    margin: 14px auto 0;
  }

  /* «Кому» — строка адресации, на телефоне она нужна не меньше */
  .reel-for { display: block; }
}

/* ============================================================
   ЖИЗНЬ ГЕРОЯ И ГЕРБА НА ТЕЛЕФОНЕ (2026-08-05, скриншоты владельца:
   «нет анимации на гербе», «не видно анимации быка, он урезается»).

   Бык. Десктопный герой — three.js-частицы и видеослои; на мобиле
   осознанно статичный кадр (решения владельца от 8 июля про фон и
   производительность не трогаем). Кадр 16:9 на портретном экране
   неизбежно режется — поэтому даём ему медленный кен-бёрнс: масштаб
   плывёт и кадр дрейфует, срез перестаёт читаться как «обрубили»,
   и герой живёт без единого килобайта видео.

   Герб. Качание t1floaty и блик-луч работают и на мобиле, но на
   290px их амплитуда физически незаметна. Ниже — усиленная мобильная
   версия качания и дыхание свечения, которое видно сразу.
   ============================================================ */
@keyframes bull-kenburns {
  0%   { transform: scale(1.06) translateX(0); }
  100% { transform: scale(1.18) translateX(-4.5%); }
}
@keyframes t1floaty-mobile {
  0%, 100% { transform: translateY(0) rotateX(9deg) rotateY(-17deg); }
  50%      { transform: translateY(-24px) rotateX(-6deg) rotateY(15deg); }
}
@keyframes coin-glow-breathe {
  0%, 100% { filter: drop-shadow(0 30px 70px rgba(0,0,0,0.7)) drop-shadow(0 0 26px rgba(212,175,55,0.10)); }
  50%      { filter: drop-shadow(0 30px 70px rgba(0,0,0,0.7)) drop-shadow(0 0 44px rgba(212,175,55,0.30)); }
}

@media (max-width: 767px) {
  .bull-static {
    animation: bull-kenburns 16s ease-in-out infinite alternate;
    transform-origin: 58% 42%; /* центр масс быка — дрейф вокруг него */
    will-change: transform;
  }
  .t1-coin-stage { animation: t1floaty-mobile 5.5s ease-in-out infinite; }
  .t1-coin img   { animation: coin-glow-breathe 4.2s ease-in-out infinite; }
}

@media (prefers-reduced-motion: reduce) {
  .bull-static, .t1-coin-stage, .t1-coin img { animation: none; }
}

/* ============================================================
   БЫК ЦЕЛИКОМ НА ТЕЛЕФОНЕ (2026-08-05, владелец: «он урезается,
   надо чтоб полностью отображался»).

   Что было. hero-bull-frame.png — ландшафтный кадр 2752×1536 (1.79:1),
   а бокс героя на телефоне портретный (390×844, 0.46:1). При
   object-fit: cover браузер показывал ВСЕГО 26% ШИРИНЫ кадра — от быка
   оставалась середина туши без головы и хвоста. Отсюда и претензия
   «непонятно, зачем он там».

   Жёсткий потолок, который надо понимать. Кадр 1.79:1 во всю ширину
   390px — это ровно 218px высоты. Больше не бывает: любая попытка
   сделать быка выше = снова обрезать его по бокам. Поэтому композиция
   строится вокруг полосы 218px, а не наоборот.

   Решение: contain + якорь книзу. Бык встаёт «постаментом» в нижней
   трети, заголовок работает над ним. Края растворяются маской — иначе
   прямоугольная кромка кадра читается как вставленная картинка
   (тот же приём, что у слоёв героя в модуле 2b main.css).
   ============================================================ */
@media (max-width: 767px) {
  .bull-static {
    object-fit: contain;
    /* 50% 88% — бык сидит низко, но не впритык к кромке экрана */
    object-position: 50% 88%;
    opacity: 0.92;
    /* Растушёвка: кадр вплывает из фона сверху и тает у нижней кромки.
       Проценты — по высоте БОКСА (844px), а не полосы быка: сама полоса
       живёт примерно в 62–88% этого диапазона. */
    -webkit-mask-image: linear-gradient(180deg,
      transparent 48%, rgba(0,0,0,0.55) 58%, #000 66%, #000 93%, transparent 100%);
    mask-image: linear-gradient(180deg,
      transparent 48%, rgba(0,0,0,0.55) 58%, #000 66%, #000 93%, transparent 100%);
    /* Кен-бёрнс переписан: прежний scale(1.06→1.18) увеличивал кадр и
       СНОВА его обрезал — ровно то, на что жаловался владелец. Теперь
       только горизонтальный дрейф, масштаб строго 1: бык всё время
       виден целиком. */
    animation: bull-drift-mobile 18s ease-in-out infinite alternate;
    transform-origin: 50% 88%;
  }
}
@keyframes bull-drift-mobile {
  0%   { transform: translateX(-1.6%); }
  100% { transform: translateX(1.6%); }
}
@media (prefers-reduced-motion: reduce) {
  .bull-static { animation: none; }
}

/* ============================================================
   ТРИ МОНЕТЫ ВРАЩАЮТСЯ ВОКРУГ ГЕРБА НА ТЕЛЕФОНЕ
   (2026-08-05, владелец: «три сферы не крутятся вокруг герба»).

   Что было. На <=980px орбиты глушились: .hud-orbit переводился в
   position: static с animation: none, и три монеты вставали
   горизонтальным свайп-рядом под гербом. Вращения не было вообще.

   Почему нельзя было просто вернуть орбиту. Замер на 390px: доступная
   полуширина 183px, а герб рисовался 374px (радиус 187) — он один
   занимал всю ширину. Причина — ГЛОБАЛЬНОЕ правило апскейл-блока V3.1
   (v3.css ~1173: .t1-coin-stage { width: clamp(380px,27vw,560px) }).
   Оно стоит ПОСЛЕ мобильного @media(max-width:560){ width:290px } и,
   не будучи ни в каком media, перебивало его на всех ширинах. Та самая
   ловушка из «Известных граблей» CLAUDE.md. Ринг .t1-orbit по той же
   причине рисовался 608px при экране 390 и обрезался секцией.

   Геометрия. Чтобы монета радиуса c ходила по орбите R СНАРУЖИ герба
   радиуса r и не вылезала за экран, нужно r + 2c <= 183. При читаемой
   монете (c=50) это дало бы герб радиусом всего 83px — мельче монет,
   композиция разваливается.

   Решение — ОРБИТА С ГЛУБИНОЙ. Монета на дальней дуге уходит ЗА герб
   (z-index ниже, масштаб 0.70, прозрачность 0.42), на ближней выходит
   вперёд и крупнее (1.08). Тогда орбита имеет право быть уже плоского
   минимума: лёгкое перекрытие читается не как наезд, а как объём —
   ровно так планета проходит за светилом. Числа: герб 176px (r=88),
   монета 100px (c=50), орбита R=128. Внешний край 178 < 183 — влезает.
   ============================================================ */
@media (max-width: 767px) {
  /* Апскейл-блок V3.1 перебиваем здесь — правило в конце файла */
  .t1-coin-stage { width: 176px; height: 176px; }
  .t1-orbit      { width: 300px; height: 300px; }
  /* Место под орбиту: радиус 128 + половина монеты 50 = 178 => 356px */
  .t1-visual     { min-height: 380px; }

  /* Ряд перестаёт быть свайп-лентой и снова становится прозрачным
     контейнером: position: static возвращает .hud-orbit привязку к
     .t1-visual, как на десктопе. */
  .hud-row {
    display: block; position: static;
    overflow: visible; padding: 0;
    height: 0;
  }

  .hud-orbit {
    position: absolute;
    top: 50%; left: 50%;
    width: 0; height: 0;
    --R: 128px;
    /* Две анимации на одном элементе: вращение трогает transform,
       смена слоя — только z-index, поэтому не конфликтуют. */
    animation: hudOrbit var(--T, 26s) linear infinite,
               hudDepthZ var(--T, 26s) linear infinite;
    animation-delay: var(--D, 0s), var(--D, 0s);
  }
  .hud-orbit .hud-chip {
    position: absolute;
    top: 0;
    min-width: 0;
    /* Контр-вращение: чип едет по кругу, текст остаётся прямым */
    animation: hudCounter var(--T, 26s) linear infinite;
    animation-delay: var(--D, 0s);
  }
  /* Радиус задаётся ЧИСЛОМ, а не через var(--R): --R прописан инлайном
     в index.html (200/225/212px под десктоп), а инлайн-стиль сильнее
     любого правила без !important. Числа разные — орбиты не сливаются
     в одну линию. Максимум 130 + половина монеты 48.5 = 178.5 < 183. */
  .hud-orbit:nth-child(1) .hud-chip { left: 118px; }
  .hud-orbit:nth-child(2) .hud-chip { left: 130px; }
  .hud-orbit:nth-child(3) .hud-chip { left: 124px; }
  /* Глубину даёт вложенный слой: transform у чипа уже занят
     контр-вращением, два animation не могут вести одно свойство. */
  .hud-chip-in {
    animation: hudDepth var(--T, 26s) linear infinite;
    animation-delay: var(--D, 0s);
  }
  .hud-coin { width: 100px; }
  /* Текст в уменьшенной монете — пол 10px из работы по читаемости держим */
  .hud-coin small  { font-size: 10px; letter-spacing: 0.1em; margin-bottom: 3px; }
  .hud-coin strong { font-size: 12px; }
  .hud-coin em     { font-size: 10px; margin-top: 2px; line-height: 1.25; }

  /* Герб — средний слой: дальняя дуга уходит под него, ближняя над */
  .t1-coin-stage { z-index: 3; }
}

/* 0% = 3 часа, 25% = 6 часов (ближняя точка, к зрителю),
   50% = 9 часов, 75% = 12 часов (дальняя точка, за гербом) */
@keyframes hudDepth {
  0%   { transform: scale(0.92); opacity: 0.85; }
  25%  { transform: scale(1.08); opacity: 1; }
  50%  { transform: scale(0.92); opacity: 0.85; }
  75%  { transform: scale(0.70); opacity: 0.42; }
  100% { transform: scale(0.92); opacity: 0.85; }
}
/* z-index переключается ступенькой — плавность тут не нужна и невозможна */
@keyframes hudDepthZ {
  0%,  61%  { z-index: 4; }
  62%, 88%  { z-index: 1; }
  89%, 100% { z-index: 4; }
}

@media (prefers-reduced-motion: reduce) {
  .hud-orbit, .hud-orbit .hud-chip, .hud-chip-in { animation: none; }
}

/* ============================================================
   ПЛАНШЕТЫ 768–980: ВЕРНУТЬ ОРБИТЫ (2026-08-05)

   Свайп-ряд включался с 980px и вниз — на планшете орбит тоже не было.
   Но там места хватает с запасом: при 805px полуширина .t1-visual 385px,
   герб радиусом 188, монета 121. Плоская геометрия (r + 2c = 308 < 385)
   сходится без трюка с глубиной, который понадобился телефону.

   Радиус задаём числом, а не var(--R): инлайн в разметке даёт 200px,
   и при гербе радиусом 188 монеты сидели бы прямо на щите. 250 ставит
   их вплотную к кромке герба, внешний край 310 < 385.
   ============================================================ */
@media (min-width: 768px) and (max-width: 980px) {
  .hud-row {
    display: block; position: static;
    overflow: visible; padding: 0; height: 0;
  }
  .hud-orbit {
    position: absolute;
    top: 50%; left: 50%;
    width: 0; height: 0;
    animation: hudOrbit var(--T, 26s) linear infinite;
    animation-delay: var(--D, 0s);
  }
  .hud-orbit .hud-chip {
    position: absolute;
    top: 0;
    animation: hudCounter var(--T, 26s) linear infinite;
    animation-delay: var(--D, 0s);
  }
  .hud-orbit:nth-child(1) .hud-chip { left: 250px; }
  .hud-orbit:nth-child(2) .hud-chip { left: 262px; }
  .hud-orbit:nth-child(3) .hud-chip { left: 256px; }
  .t1-visual { min-height: 640px; }
}

/* ============================================================
   БЫК ЦЕЛИКОМ И НА ПОРТРЕТНОМ ПЛАНШЕТЕ (2026-08-05)

   .bull-static показывается ТОЛЬКО на тач-устройствах (js/main.js,
   модуль быка: three.js достаётся десктопу, картинка — тачу). На
   реальном планшете 820×1180 портретный бокс 0.69:1 против кадра
   1.79:1 даёт те же 39% ширины — бык обрезан так же, как на телефоне.
   Планка 1024 берёт телефоны и портретные планшеты; в ландшафте
   планшета бокс уже близок к пропорции кадра, и cover там честен.
   ============================================================ */
@media (min-width: 768px) and (max-width: 1024px) {
  .bull-static {
    object-fit: contain;
    object-position: 50% 84%;
    opacity: 0.92;
    -webkit-mask-image: linear-gradient(180deg,
      transparent 40%, rgba(0,0,0,0.55) 52%, #000 60%, #000 94%, transparent 100%);
    mask-image: linear-gradient(180deg,
      transparent 40%, rgba(0,0,0,0.55) 52%, #000 60%, #000 94%, transparent 100%);
    animation: bull-drift-mobile 18s ease-in-out infinite alternate;
    transform-origin: 50% 84%;
  }
}

/* ============================================================
   БЫК НА ТЕЛЕФОНЕ: ОДИН, ЦЕЛИКОМ И КРУТИТСЯ (2026-08-05, второй заход
   по скриншотам владельца: «анимация бык+медведь урезается за текстом»
   и «добавь движение — чтоб он крутился»).

   Что вскрылось. Мой первый заход сделал .bull-static контейном и вывел
   его отдельной полосой. Но на мобиле поверх уже играл слой #scrub-video
   с hero-bull-bear-orbit-mobile.mp4 — то есть быков стало ДВА, между
   ними резкий шов (он и виден на скриншоте). Проверил кадры видео на
   0 / 7.5 / 12 секунде: они заметно различаются — видео РЕАЛЬНО
   анимировано, бык там уже вращается. Просьба «чтоб крутился» не требует
   нового ассета: нужно вынести это видео туда, где его видно.

   Решение. Статичная картинка снята (js/main.js оставляет её только для
   reduced-motion), а видеослой опущен из-за текста вниз — на то самое
   место, где владелец обвёл быка. object-position двигает кадр внутри
   бокса: 91% по вертикали ставит полосу под заголовок.

   Веса не прибавилось ни на байт: то же видео 2.3 МБ, просто видно.
   ============================================================ */
@media (max-width: 767px) {
  #scrub-video {
    /* Кадр 960x540 при ширине 390 даёт полосу 219px. Свободного места
       в боксе 495px — 91% опускают полосу под заголовок. */
    object-position: 50% 50%;
  }

  /* ---- ГЛАВНОЕ: полоса-фон под заголовком вместо кадра во весь экран.

     Почему прошлые заходы не сработали НА ТЕЛЕФОНЕ. База .layer-video —
     object-fit: cover во весь экран (main.css ~130), а contain включается
     правилом body:not(.is-touch) (~160). В панели превью тач не
     определяется, поэтому там кадр был contain, а на реальном телефоне —
     cover. Я калибровал object-position по превью, но при cover кадр
     растянут точно по высоте окна, вертикального запаса нет, и
     object-position по Y НЕ ДЕЛАЕТ НИЧЕГО. Отсюда «ничего не поменялось».

     При cover 390x844 кадр 960x540 масштабируется в 1500x844 — видно 26%
     ШИРИНЫ, то есть вертикальный срез через середину туши. Узнать в нём
     животное невозможно — отсюда «не отображается анимация».

     Приём: ограничиваем бокс полосой 40vh. Тогда cover масштабирует кадр
     не по высоте окна, а по высоте полосы: 340px => кадр 605x340 => видно
     64% ширины. Кропаются только БОКА (стены зала) — ровно тот замысел,
     что записан в комментарии базового правила. Полоса 340px ВЫШЕ
     заголовка (256px) и накрывает его целиком: анимация читается фоном,
     а не отдельной лентой. ---- */
  #scrub-video, #orbit-video, #bear-orbit-video {
    top: 28vh;
    height: 40vh;
    bottom: auto;
    object-fit: cover;
    object-position: 50% 50%;
    /* Кромки полосы растворяем сами: модуль 2b растушёвывает поля
       contain-кадра, а при cover полей нет — он корректно молчит. */
    -webkit-mask-image: linear-gradient(180deg,
      transparent 0%, #000 18%, #000 82%, transparent 100%);
    mask-image: linear-gradient(180deg,
      transparent 0%, #000 18%, #000 82%, transparent 100%);
  }
  /* Подложка приглушена, но не погашена: она даёт объём вокруг кадра,
     при этом не спорит с ним яркостью. */
  #scrub-bg { opacity: 0.5; }

  /* Заголовок теперь лежит на движущемся кадре — без подложки буквы
     тонут в светлых участках. Тень по краям глифов вместо плашки:
     плашка съела бы сам эффект «текст на анимации». */
  .manifest-line {
    text-shadow:
      0 2px 24px rgba(6, 6, 7, 0.92),
      0 1px 6px rgba(6, 6, 7, 0.88),
      0 0 2px rgba(6, 6, 7, 0.6);
  }
}

/* ============================================================
   РИМСКИЕ ЦИФРЫ В ВИТРИНЕ ВОЗВРАЩЕНЫ НА ТЕЛЕФОН
   (2026-08-05, владелец: «на моб версии не видно римских цифр»).

   Их скрывало `.reel-roman { display: none }` в блоке ≤560px. Правило
   ставили не от хорошей жизни: карточка тогда была свайп-слайдом и не
   влезала в экран — 991px при доступных 826, и цифру срезали как самое
   декоративное. Но витрина с тех пор переведена в вертикальную стопку
   (см. блок «ВИТРИНА КУРСОВ НА ТЕЛЕФОНЕ» выше): высота больше не в
   дефиците, и повод для скрытия отпал.

   Заодно возвращён нижний отступ — он был обнулён тем же заходом,
   потому что держал 14px пустоты под невидимым элементом.

   Правило стоит в КОНЦЕ файла осознанно: только так оно перебивает
   `display: none` из ≤560 (специфичность равная, решает порядок).
   ============================================================ */
@media (max-width: 560px) {
  .reel-roman {
    display: block;
    font-size: clamp(2rem, 10vw, 3.2rem);
    margin-bottom: 10px;
    /* Альфа поднята 0.16 → 0.34. Базовый цвет рассчитан на десктопный
       кегль 70–137px: на таком размере 16% читаются как водяной знак.
       На телефоне цифра 39px, и при 16% она физически неразличима —
       вернуть её на экран и оставить невидимой значило бы не выполнить
       правку. Чем мельче текст, тем больше ему нужно контраста;
       характер «подложки под заголовком» при 34% сохраняется. */
    color: rgba(244, 240, 234, 0.34);
  }
}

/* ============================================================
   СТЕКЛО КОЛОНКИ «ОБ АВТОРЕ» — ПРИГЛУШЕНО (2026-08-05)

   Владелец: «заднее стекло приглушить чуть-чуть, чтоб при движении
   анимации не сбивало при чтении». До этого пробовали сузить колонку
   (вариант Б) — не подошло, откачено, мера строки вернулась к 92ch.

   Что происходило. Базовое .glass — rgba(16,16,16,0.42), то есть фон
   просвечивал на 58%. Под карточкой играет видео со статуей: контраст
   под буквами меняется от кадра к кадру, и глаз ловит движение вместо
   строки. Сам контраст текста при этом в порядке — 11,2:1.

   Что сделано. Плотность 0.42 → 0.66: просвет падает с 58% до 34%,
   примерно вдвое. Блюр 18 → 24px: движение под стеклом размывается
   сильнее, детали перестают читаться как объект. Материал при этом
   остаётся стеклом — до глухой плашки далеко (в варианте «А» пробовали
   0.88, здесь сознательно мягче, как и просил владелец).

   Селектор из двух классов бьёт базовое .glass по специфичности, но
   правило всё равно стоит в конце файла — так надёжнее, учитывая
   апскейл-блок V3.1 в середине.
   ============================================================ */
.voices.glass {
  background: rgba(13, 13, 14, 0.66);
  backdrop-filter: blur(24px) saturate(1.05);
  -webkit-backdrop-filter: blur(24px) saturate(1.05);
}

/* ============================================================
   КОЛОНКА «ОБ АВТОРЕ»: ПУСТОТА СПРАВА И ЯРКОСТЬ СТЕКЛА
   (2026-08-05, владелец: «есть всё ещё пустота» + «стекло можно ещё
   тусклее, чтоб текст читался лучше»).

   ОТКУДА БРАЛАСЬ ПУСТОТА. Мера строки задана в `ch`, то есть привязана
   к кеглю. А кегль считался как min(1.05vw, 1.7vh) — из двух величин
   берётся МЕНЬШАЯ, и на широком, но невысоком окне побеждает высота.
   Замер на 2225x900: 1.05vw даёт 23.4px, 1.7vh — всего 15.3px, кегль
   зажимается в 14.58px, и 92ch = 929px. Карточка при этом растёт вместе
   с шириной окна до 1066px. Разница 138px и есть та пустота: карточка
   тянется за шириной, текст — за высотой.

   ПОЧЕМУ ЛЕЧИМ КЕГЛЕМ, А НЕ ШИРИНОЙ. Снять max-width значило бы пустить
   строку на 110+ знаков — нечитаемо. Но раз мера задана в `ch`, рост
   кегля растягивает колонку и НЕ меняет число знаков в строке: их так и
   остаётся ~88. То есть один параметр закрывает обе просьбы — пустота
   уходит, а текст становится крупнее и читается легче.

   Коэффициент высоты поднят 1.7vh → 2.05vh, потолок 1.2rem → 1.35rem.
   На 2225x900 кегль становится 18.5px, 92ch ≈ 1180px — упирается уже в
   карточку, а не в себя. Пустоты не остаётся.
   ============================================================ */
/* Кегль ставится на КОНТЕЙНЕР, а не на абзацы. Единица `ch` считается от
   шрифта того элемента, где написан max-width: у .mentor-bio он был 16px
   по наследству, и 92ch намертво равнялись 928px, сколько бы я ни поднимал
   кегль внутри. Первая попытка правки именно на это и напоролась —
   шрифт вырос, пустота осталась ровно та же, 138px. */
/* Только десктопная раскладка: пустота бывает лишь там, где карточка
   стоит второй колонкой и растёт вместе с окном. Ниже 981px блок
   одноколоночный, текст и так занимает всю ширину, а правило без медиа
   перебило бы адаптивные кегли из блоков ≤1024 и ≤короткое окно —
   те подобраны, чтобы биография влезала в экран целиком. */
@media (min-width: 981px) {
  .mentor-bio {
    font-size: clamp(0.95rem, min(1.05vw, 2.05vh), 1.35rem);
  }
  .mentor-bio p { font-size: inherit; }
  /* Лид крупнее остальных — соотношение из базового правила сохранено */
  .mentor-bio p:first-child { font-size: 1.07em; }
}

/* Стекло ещё тусклее: 0.66 → 0.78. Просвет фона падает с 34% до 22% —
   движение статуи под текстом становится почти неразличимым. Блюр
   24 → 30px. Это уже ближе к плашке, чем к стеклу, но владелец просил
   именно «чтоб текст читался лучше», и приоритет отдан читаемости. */
.voices.glass {
  background: rgba(12, 12, 13, 0.78);
  backdrop-filter: blur(30px) saturate(1.05);
  -webkit-backdrop-filter: blur(30px) saturate(1.05);
}

/* ============================================================
   ПЕРЕКЛЮЧАТЕЛЬ ЯЗЫКА RU | EN (2026-08-06)

   Живёт в шапке рядом с часами. Активный язык — <span>, а не ссылка:
   страница не ссылается сама на себя. Разделитель рисуется псевдо-
   элементом, а не символом в разметке, — иначе он попал бы в перевод
   и в чтение скринридером.

   На узких экранах часы уже скрыты (<=1180 и <=1023), переключатель
   остаётся: сменить язык нужнее, чем знать время в Токио.
   ============================================================ */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: clamp(14px, 1.4vw, 26px);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.lang-switch .lang-cur {
  color: var(--gold);
  font-weight: 700;
}
.lang-switch .lang-alt {
  position: relative;
  color: rgba(244, 240, 234, 0.42);
  text-decoration: none;
  padding: 6px 2px;          /* тап-зона по высоте, без сдвига макета */
  transition: color 0.3s var(--ease-out);
}
.lang-switch .lang-alt::before {
  content: '';
  position: absolute;
  left: -5px; top: 50%;
  width: 1px; height: 11px;
  transform: translateY(-50%);
  background: rgba(244, 240, 234, 0.18);
}
.lang-switch .lang-alt:hover,
.lang-switch .lang-alt:focus-visible { color: var(--white); }

@media (max-width: 767px) {
  /* В шапке телефона место занято гербом и бургером, поэтому в закрытом
     состоянии переключатель скрыт. При открытом меню он всплывает над
     часами — тем же приёмом, что и часы (position: fixed поверх
     оверлея). Прятать его совсем нельзя: сменить язык с телефона нужно
     не реже, чем с десктопа. */
  .lang-switch { display: none; }
  body.menu-open .lang-switch {
    display: flex;
    position: fixed;
    left: 0; right: 0;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    justify-content: center;
    font-size: 13px;
    z-index: 60;
  }
  /* 12px по вертикали, а не 10: с ними тап-зона выходит на 44px —
     стандарт, которого держится вся мобильная вёрстка проекта. */
  body.menu-open .lang-switch .lang-alt { padding: 12px 8px; }
  body.menu-open .lang-switch .lang-cur { padding: 12px 2px; }
}

/* ============================================================
   ПАНЕЛИ ВИТРИНЫ НА ТЕЛЕФОНЕ: ПОЛ КЕГЛЯ 10px (2026-08-06)

   Кегли внутри приборных панелей заданы долей от ширины самой панели:
   font-size: calc(var(--hud-w) * 0.025) и подобные. На десктопе панель
   820px, и это даёт нормальные 20px. Но на телефоне я ограничил её
   до min(680px, 100vw − 72px) = 318px, и та же формула выдала 7.3–9.2px.

   Почему это моя недоработка, а не старая болезнь сайта: панели на
   мобиле были СКРЫТЫ, и когда я поднимал читаемость мелкого текста
   (тот заход поднял 59 элементов до 10–12.5px), их в выборке просто не
   существовало. Открыл я их позже — и они приехали с кеглями, которых
   никто не проверял.

   Лечится max(): нижняя граница 10px, выше неё работает прежняя
   пропорция. На десктопе ничего не меняется — там доля и так больше пола.
   Заголовки внутри циферблата (0.036–0.058) не трогаю: они и на телефоне
   дают 11.4–18.4px.
   ============================================================ */
@media (max-width: 767px) {
  .hud-name       { font-size: max(10px, calc(var(--hud-w) * 0.025)); }
  .hud-idx        { font-size: max(10px, calc(var(--hud-w) * 0.028)); }
  .hud-line       { font-size: max(11px, calc(var(--hud-w) * 0.029)); }
  .hud-stats span { font-size: max(10px, calc(var(--hud-w) * 0.023)); }
  .dial-marks span { font-size: max(10px, calc(var(--hud-w) * 0.023)); }
  .dial-core i    { font-size: max(10px, calc(var(--hud-w) * 0.024)); }
  .dial-readout   { font-size: max(10px, calc(var(--hud-w) * 0.026)); }
  .cyc-tag i      { font-size: max(10px, calc(var(--hud-w) * 0.024)); }
  .tf-face i      { font-size: max(10px, calc(var(--hud-w) * 0.027)); }
}

/* ============================================================
   КНОПКИ ТАРИФОВ: ЗОЛОТАЯ ЗАЛИВКА СНИЗУ ПРИ НАВЕДЕНИИ
   (2026-08-06, вариант «В» с золотом — выбор владельца)

   Что было не так. Наводишь курсор на карточку — она целиком заливается
   светлым (#f6f2ec…#e4dbcb). А наведение на саму КНОПКУ внутри добавляло
   всего rgba(10,10,10,0.06), то есть 6% затемнения. На уже светлом фоне
   этого не видно: карточка и кнопка реагировали почти одинаково, и было
   непонятно, наведён курсор именно на кнопку или нет.

   Решение: золотая плашка выезжает снизу вверх за 0.35с, текст в этот
   момент уходит в чёрный. Движение мозг замечает быстрее, чем смену
   цвета, — понятно мгновенно и без периферийного зрения.

   ПОЧЕМУ z-index: -1, А НЕ ОБЁРТКА ТЕКСТА В <span>. Текст кнопки лежит
   голым узлом внутри <a>, поднять его над плашкой напрямую нельзя.
   Обёртка потребовала бы правки разметки в обеих версиях. Вместо этого
   плашка уходит ПОД содержимое, а isolation: isolate запирает её внутри
   кнопки — иначе при отрицательном z-index она провалилась бы под саму
   карточку и стала невидимой.

   Правило заперто в .t4-card: .btn — общий класс, он же у CTA и финала,
   и overflow: hidden на нём глобально мог бы срезать что-то ещё.
   ============================================================ */
.t4-card .btn {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.t4-card .btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--gold);
  transform: translateY(101%);   /* 101, а не 100: убирает щель от округления */
  transition: transform 0.35s var(--ease-out);
}
/* Заливка живёт только когда карточка уже подсвечена — как и весь
   остальной светлый режим карточки. */
.t4-card:hover .btn:hover::before,
.t4-card:has(:focus-visible) .btn:focus-visible::before {
  transform: translateY(0);
}
.t4-card:hover .btn:hover,
.t4-card:has(:focus-visible) .btn:focus-visible {
  border-color: var(--gold);
  color: #0a0a0a;
  background: none;              /* прежние 6% затемнения больше не нужны */
  box-shadow: 0 6px 20px rgba(212, 175, 55, 0.32);
}

@media (prefers-reduced-motion: reduce) {
  /* Без движения — просто мгновенная заливка, эффект сохраняется */
  .t4-card .btn::before { transition: none; }
}


/* ============================================================
   ГОРИЗОНТАЛЬНЫЕ КАРУСЕЛИ НА ТЕЛЕФОНЕ: НЕ ПЕРЕХВАТЫВАТЬ
   ВЕРТИКАЛЬНУЮ ПРОКРУТКУ
   (2026-08-06, отчёт тестировщика: «при попытке пролистать сам сайт
   сдвигается налево или направо, с первого раза не получается»)

   Три причины, каждая усиливает предыдущую.

   1. `scroll-snap-type: x mandatory` у тарифов и отзывов. Слово
      mandatory обязывает браузер ДОВЕСТИ прокрутку до ближайшей точки
      привязки, поэтому вертикальный свайп с малейшим горизонтальным
      уводом залипал в горизонтали: жест уходил в карусель, страница
      стояла. Отсюда и «с первого раза не получается» — вторая попытка
      удаётся, потому что палец уже идёт строго вниз.
      proximity привязывает мягко: близко к точке — доводит, далеко —
      оставляет как есть, и вертикаль проходит насквозь. У .t1-stats и
      .hud-row proximity стоял изначально, и на них никто не жаловался —
      это и подсказало причину.

   2. Не было `overscroll-behavior-x`. Дойдя до края карусели, браузер
      начинал цеплять прокрутку родителя и «дёргать» страницу вбок.
      contain обрывает эту цепочку на самой карусели.

   3. Не было `touch-action`. Явное `pan-x pan-y` разрешает обе оси и
      отдаёт браузеру выбор доминирующей по первому движению пальца —
      именно этот выбор и ломался снапом.
   ============================================================ */
@media (max-width: 767px) {
  .t4-pricing,
  .t5-reviews {
    scroll-snap-type: x proximity;
  }
  .t4-pricing,
  .t5-reviews,
  .t1-stats,
  .hud-row {
    overscroll-behavior-x: contain;
    touch-action: pan-x pan-y;
  }
}

/* ============================================================
   ПОДПИСЬ ПОД ТАРИФАМИ: УБРАТЬ ИЗ-ПОД НАКЛОНЁННЫХ КАРТОЧЕК
   (2026-08-06, тестировщик: «текст на карточки лезет… когда начинаете
   взаимодействовать с карточками такое происходит»)

   Замер на 1440x900: зазор между низом карточек и подписью — 6px.
   Карточка на наведении наклоняется (data-tilt, rotateX до 2°) и при
   высоте 339px её нижняя кромка уходит вниз примерно на те же 6px,
   плюс ложится тень 0 32px 80px. Подпись оказывается ПОД карточкой.

   Шесть пикселей взялись не из базового правила (там 14–22px), а из
   двух правил для коротких окон: clamp(6px, 0.7vh, 16px) и
   clamp(5px, 0.6vh, 16px). При высоте окна 900px обе дают ~6px.
   Поднимаем нижнюю границу до 22px — больше хода наклона с запасом.
   Потолок не трогаем: на высоких окнах отступ и так был нормальным.
   ============================================================ */
@media (min-width: 768px) {
  .t4-note { margin-top: clamp(22px, 1.4vw, 26px); }
}


/* ============================================================
   МОБИЛЬНОЕ МЕНЮ В СТИЛЕ САЙТА (2026-08-06, правка владельца:
   «сделать в стиле сайта и поработать над размером, сейчас в меню очень
   большие шрифты»)

   Что было. Кегль clamp(1.7rem, 8.5vw, 2.5rem) — это 33px на экране 390.
   Семь пунктов по 73px плюс зазоры занимали 642px при доступных 733, и
   последний пункт «X» наезжал на переключатель языка ровно на 9px
   (замер: пункт 741..814, переключатель 805..850). Именно эту накладку
   видно на скриншоте владельца.

   Кроме размера, меню выбивалось из языка сайта: тяжёлый вес 900 и
   заголовочная подача — тогда как вся навигация и метки разделов на
   сайте набраны мелким капслоком с широким трекингом (.section-label:
   11–13px, letter-spacing 0.28em). Меню было единственным местом с
   «плакатной» типографикой.

   Стало. Кегль 19–22px, капслок, трекинг 0.16em, вес 700 — та же система,
   что у меток разделов и десктопной навигации. Между пунктами волосяная
   линия, как разделитель в .section-label. Тап-зона держится на 52px:
   меньше кегль, но padding компенсирует, и палец не мельчит.

   Освободилось около 250px по высоте — накладка на переключатель ушла
   с запасом, а меню перестало быть стеной из букв.
   ============================================================ */
@media (max-width: 767px) {
  .site-nav {
    gap: 0;
    padding: 0 clamp(28px, 9vw, 56px);
  }

  /* ЗАКРЫТОЕ МЕНЮ НЕ ДОЛЖНО ЛОВИТЬ ПАЛЕЦ (2026-08-06, «меню исчезло»).

     У шапки есть backdrop-filter, а он делает её containing block для
     фиксированных потомков — это наш давний грабль, записанный в CLAUDE.md.
     Из-за него `inset: var(--header-h) 0 0 0` у меню считается не от экрана,
     а от 72-пиксельной шапки: top 72 + bottom 0 внутри высоты 72 дают высоту
     РОВНО НОЛЬ. Существующий фикс снимает backdrop-filter только у открытого
     меню, поэтому закрытое так и живёт нулевой высоты.

     Дальше цепочка: `transform: translateY(-102%)` от нулевой высоты — это
     сдвиг на ноль, меню никуда не уезжает. Пункты при justify-content:center
     вываливаются за его коробку симметрично вверх и вниз и ложатся поверх
     шапки. Текст их не виден, но ссылки исправно перехватывают нажатие —
     под бургером оказывался пункт «Наставник». Кнопка переставала
     открываться, и со стороны это читалось как «меню исчезло».

     Раньше беды не было, потому что пункты были шириной по тексту и до
     бургера в правом углу не дотягивались. Ширину 100% они получили вместе
     с плашками — так скрытый дефект и вышел наружу.

     Лечим следствие в одну строку: закрытое меню полностью выключено. */
  body:not(.menu-open) .site-nav {
    visibility: hidden;
    pointer-events: none;
  }

  /* Полоса под переключатель языков и часы: они висят фиксированно поверх
     меню, а меню центрировало пункты по всей своей высоте и заезжало под
     них — на 375×667 пункты налезали на переключатель на 22px.

     Отступ живёт ТОЛЬКО у открытого меню, и это не придирка к чистоте.
     Закрытое меню имеет высоту по содержимому и сдвинуто за экран на
     translateY(-102%) — то есть на свою же высоту. Пока высота нулевая,
     оно уезжает целиком. С отступом высота стала 118px, меню сдвигалось
     лишь на 120px и повисало невидимой плёнкой поверх шапки (−48..70),
     перехватывая нажатие на бургер: кнопка переставала открываться, и со
     стороны это выглядело как «меню исчезло». */
  body.menu-open .site-nav {
    padding-bottom: calc(118px + env(safe-area-inset-bottom, 0px));
  }
  .site-nav a {
    font-family: var(--sans);
    font-size: clamp(1.15rem, 5.2vw, 1.4rem);
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(244, 240, 234, 0.82);
    /* 15px сверху и снизу при кегле ~20px дают тап-зону 52px */
    padding: 15px 10px;
    width: 100%;
    text-align: center;
    position: relative;
  }
  /* ---- Вариант В (выбор владельца 2026-08-06) ----
     Волосяная линия между пунктами была почти не видна на телефоне:
     растушёванная к краям, она тонула в фоне. Разделяет теперь пустота —
     каждый пункт стал своей плашкой со стеклом, между ними живой зазор.
     Спутать соседние пункты нельзя даже краем глаза.

     Плата за это — высота: шесть зазоров прибавляют 60px. Помещается
     (замер ниже по коду проверял оба крайних экрана), но запас до
     переключателя языков стал меньше, поэтому на низких экранах зазор
     и вертикальные поля пунктов ужимаются. */
  .site-nav { gap: 10px; }

  /* Палец по пунктам не должен листать страницу под меню: оверлей просто
     лежит поверх документа, скролл сквозь него не заблокирован, и без
     этого подсветка скакала бы по уезжающим пунктам. Только у открытого —
     закрытое меню не должно перехватывать ничего вообще. */
  body.menu-open .site-nav { touch-action: none; }

  .site-nav a {
    border: 1px solid rgba(244, 240, 234, 0.10);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.035);
    transition:
      background 0.22s var(--ease-out),
      color 0.22s var(--ease-out),
      border-color 0.22s var(--ease-out);
  }

  /* Палец над пунктом. Класс вешает js/main.js (модуль 25): на тач-экране
     :hover не срабатывает при протягивании, а :active гаснет, как только
     палец поехал, — одним CSS отклик «за пальцем» не сделать. */
  .site-nav a.is-touched {
    border-color: rgba(212, 175, 55, 0.6);
    background: rgba(212, 175, 55, 0.07);
    color: var(--gold);
  }

  /* Нажатие — вспышка сильнее, чтобы касание было подтверждено до перехода */
  .site-nav a.is-pressed,
  .site-nav a:active {
    background: var(--gold);
    border-color: var(--gold);
    color: #0a0a0a;
  }

  /* Низкие экраны (iPhone SE и подобные): семь плашек с зазорами
     перестают помещаться над переключателем — ужимаем зазор и поля. */
  @media (max-height: 720px) {
    .site-nav { gap: 6px; }
    .site-nav a { padding: 11px 10px; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav a { transition: none; }
}

/* ============================================================
   ПОДСКАЗКА СВАЙПА для мобильных каруселей (2026-08-06)

   Первая версия стояла под лентой и указывала влево. Владелец прислал
   скриншоты с нарисованными стрелками и уточнил постановку: стрелки
   смотрят ВПРАВО и стоят У ПРАВОГО КРАЯ карточки, поверх ленты — там,
   где из-за края выглядывает следующая. Так подсказка отвечает на вопрос
   «а там что-то есть?», а не описывает движение пальца.

   Три шеврона бегут волной слева направо: у левого задержка 0, у правого
   0.3с — волна уходит туда же, куда указывают.

   Позиционирование. Подсказка идёт в потоке сразу за лентой, поэтому её
   собственный верх совпадает с низом ленты. Нулевая высота плюс подъём на
   22% высоты ленты ставит её на 78% — ровно туда, где нарисовал владелец,
   и при этом она не занимает места в потоке и не двигает соседей.
   Высоту ленты в CSS не вычислить, её отдаёт js/main.js (модуль 24) в
   переменной --rail-h.

   Стрелка ничего не перехватывает (pointer-events: none) и гаснет после
   первого живого свайпа — класс is-done вешает тот же модуль 24.

   На десктопе подсказки нет: там карточки лежат сеткой, свайпать нечего.
   ============================================================ */
.swipe-hint { display: none; }

@media (max-width: 767px) {
  .swipe-hint {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    position: relative;
    z-index: 4;
    height: 0;
    margin: 0;
    /* Правее и ниже (правка владельца 2026-08-06: «стрелка упирается в знак
       доллара»). На 78% стрелка стояла в одной полосе с ценами, и стоило
       соседней карточке выглянуть из-за края, её «$» приходил вплотную.

       Просветов в карточке почти нет — замер показал, что между ценой и
       кнопкой всего 16px при высоте шеврона 14px, а самая широкая свободная
       полоса (25px) лежит у самого низа. Выбрано 88.5%: это строка кнопки,
       справа от неё пусто, цена осталась выше. Проверено на положении с
       ленты, где соседняя карточка выглядывает на 60px — как на скриншоте
       владельца: пересечений с её содержимым нет.

       Отступ справа уменьшен с 16 до 4px. */
    padding-right: 4px;
    transform: translateY(calc(var(--rail-h, 420px) * -0.115));
    pointer-events: none;
    transition: opacity 0.5s var(--ease-out);
  }
  .swipe-hint.is-done { opacity: 0; }

  .swipe-hint span {
    width: 10px;
    height: 10px;
    /* Верхняя и правая грани, повёрнутые на 45° — шеврон смотрит вправо */
    border-top: 2px solid var(--gold);
    border-right: 2px solid var(--gold);
    /* Порядок важен: сдвиг применяется до поворота, поэтому translateX
       уводит шеврон вправо по экрану, а не вдоль его повёрнутой оси */
    transform: translateX(0) rotate(45deg);
    opacity: 0.3;
    /* Стрелки лежат поверх карточки, а не на пустом фоне: тёмный ореол
       отделяет их от текста и картинки под ними */
    filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.65));
    animation: swipeChevron 1.9s var(--ease-out) infinite;
  }
  .swipe-hint span:nth-child(1) { animation-delay: 0s;    }
  .swipe-hint span:nth-child(2) { animation-delay: 0.15s; }
  .swipe-hint span:nth-child(3) { animation-delay: 0.30s; }
}

@keyframes swipeChevron {
  0%, 55%, 100% { opacity: 0.3; transform: translateX(0)   rotate(45deg); }
  25%           { opacity: 1;   transform: translateX(4px) rotate(45deg); }
}

@media (prefers-reduced-motion: reduce) {
  .swipe-hint span { animation: none; opacity: 0.55; }
}

/* ============================================================
   ЛЮФТ В «НАСТАВНИКЕ» (та же правка владельца про качание влево-вправо).

   Корневой клип уже поставлен в main.css, но здесь был и настоящий
   геометрический вылет: световой конус .colossus-cone задан как
   inset: -16% -8%, то есть на 16% шире родителя — на узком экране это
   68px за краем, а сама секция выходила за экран на 4px. По вертикали
   запас конусу нужен (луч уходит вверх за кадр), по горизонтали — нет.
   ============================================================ */
@media (max-width: 767px) {
  .colossus-cone { inset: -16% 0; }
  /* Второй источник — отрицательные поля самого блока: margin 0 -16px при
     padding 16px выпускали свечение за контейнер. На десктопе это красиво
     и незаметно, на 390px даёт ровно те 4px, на которые секция шире
     экрана. Паддинг оставляем — текст внутри не должен упереться в край. */
  .colossus { margin-left: 0; margin-right: 0; }
}
