/* =========================================================
   noumy.ai — hero: ИИ-аватар проводит интервью за вас,
   вы выбираете лучших
   ========================================================= */

/* Цвета — переменные из макета (Figma → get_variable_defs), без своих
   выдумок: в проекте больше нет ни #090909, ни #2e2824, ни #2f342e. */
:root {
  --ink: #353535;            /* Accent dark — весь текст, рамки и тени кнопок */
  --text: #353535;
  --muted: #6D6A66;          /* Secondary text */
  --divider: #B4B4B3;        /* Stroke light */
  --bg: #E9E8E4;             /* Bg */
  --accent: #0F3DF2;         /* Primary/default */
  --accent-ink: #E9E8E4;     /* текст на синей кнопке — это Bg, а не белый */
  --white: #FFFFFF;

  /* Кнопки в макете БЕЗ скругления, с жёсткой тенью-подложкой:
     обычное состояние 4px, hover 6px (кнопка не двигается),
     click — тени нет, кнопка уезжает на её место.
     Цвет фона на всех трёх состояниях один и тот же — в макете он
     менялся (Primary/hover #0002DF у синей, Bg у белой), но по решению
     от 8 сентября 2026 наведение показываем только тенью. */
  --btn-shadow: 4px 4px 0 var(--ink);
  --btn-shadow-hover: 6px 6px 0 var(--ink);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ============================ HERO SHELL ============================ */

.hero {
  position: relative;
  background: var(--bg);
  isolation: isolate;
  overflow: hidden;
}

.hero__inner {
  position: relative;
  z-index: 4;
  max-width: 1440px;
  margin: 0 auto;
  padding: 16px 40px 0;
}

/* ============================ NAV ============================ */

/* по макету: логотип и кнопка 49px высотой, пункты меню 45px, всё
   выровнено по ВЕРХУ строки (в Figma все три лежат на y = 16) */
.nav {
  display: flex;
  align-items: flex-start;
  gap: 32px;          /* от блока пунктов до кнопки «Запросить демо» */
  padding: 0 0 16px;
}

.logo {
  display: block;
  margin-right: auto;
  line-height: 0;
}
.logo__mark { display: block; width: 114px; height: 49px; }

.nav__links {
  display: flex;
  align-items: flex-start;
  gap: 24px;          /* по макету между пунктами ровно 24 */
  margin: 0;
  padding: 0;
  list-style: none;
  white-space: nowrap;
}

/* ---------- компонент «пункт меню» ----------
   Три состояния из макета (frame «menu btn»):
     default   — обычный тёмный текст;
     hover     — текст синим;
     selected  — синий текст + подчёркивание маркером (.is-selected).
   Пункты пока ни к чему не привязаны: у каждого пустой data-target,
   обработчик в app.js на пустом значении просто ничего не делает.
   Когда появятся блоки — проставить им id и подставить сюда. */

.menu-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  appearance: none;
  border: 0;
  background: none;
  margin: 0;
  padding: 12px 8px 3px;     /* по макету */
  font: inherit;
  font-size: 16px;
  font-weight: 500;          /* Inter Medium */
  line-height: 1.3;
  letter-spacing: -0.02em;   /* -0.32px при 16px */
  color: var(--ink);
  cursor: pointer;
  transition: color .14s ease;
}
.menu-btn:hover,
.menu-btn:focus-visible,
.menu-btn.is-selected { color: var(--accent); }
.menu-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Подчёркивание «маркером» — три синие полосы по 6px из макета
   (22:1701/1702/1703): 27px в позиции 0,0 · 36px в 16,3 · 43px в 49,0.
   Рисуем тремя градиентами на одном элементе, чтобы не плодить разметку.
   Слот 9×92 держит место всегда — в остальных состояниях он пустой,
   поэтому при наведении и выборе строка не дёргается. */
.menu-btn__mark {
  display: block;
  width: 92px;
  height: 9px;
  background-repeat: no-repeat;
  background-image: none;
}
.menu-btn.is-selected .menu-btn__mark {
  background-image:
    linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent)),
    linear-gradient(var(--accent), var(--accent));
  background-size: 27px 6px, 36px 6px, 43px 6px;
  background-position: 0 0, 16px 3px, 49px 0;
}

/* ============================ BUTTONS ============================ */

/* Кнопка из макета (компонент «btn», варианты sm / lg × Default/Hover/Click).
   Ключевое, чего не было раньше:
     · углы НЕ скруглены — radius 0;
     · рамка 2px сплошным #353535 — в том числе у синей кнопки;
     · тень — не «мягкий» offset, а подложка того же #353535: 4px в покое,
       6px на hover (сама кнопка при этом НЕ съезжает — в макете растёт
       только подложка), 0 на нажатии, и кнопка уезжает на её место;
     · внутренние отступы в Figma 14/16 считаются ВМЕСТЕ с рамкой,
       поэтому в CSS (border-box) это padding 12/14 + border 2. Именно
       12, а не 10: при 10 кнопки выходили 45 и 50 вместо 49 и 54. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  border: 2px solid var(--ink);
  border-radius: 0;
  font-weight: 500;          /* Inter Medium */
  line-height: 1.3;
  letter-spacing: -0.02em;
  text-decoration: none;
  box-shadow: var(--btn-shadow);
  transition: box-shadow .12s ease, transform .12s ease;
  white-space: nowrap;
}
.btn:hover,
.btn:focus-visible { box-shadow: var(--btn-shadow-hover); }
.btn:active { box-shadow: none; transform: translate(4px, 4px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.btn__arrow { flex: none; display: block; }

/* sm — в шапке: 193×49 при тексте 16px и стрелке 23×19 */
.btn--sm {
  font-size: 16px;
  background: var(--white);
  color: var(--ink);
}

/* lg — главный CTA: 228×54 при тексте 20px и стрелке 27×22 */
.btn--lg {
  flex: none;
  font-size: 20px;
  letter-spacing: -0.02em;   /* -0.4px при 20px */
  background: var(--accent);
  color: var(--accent-ink);
}

/* ============================ TITLE / COPY ============================ */

/* Заголовок: Inter Regular 80px, интерлиньяж 0.93, трекинг -4.8px
   (это -0.06em, а не -0.035em, как было), цвет #353535.

   Кегль по макету жёстко привязан к брейкпоинтам, а не к вьюпорту:
   80px держится до 1200 включительно (фреймы «1140» и «1440-1200»),
   ниже — плавно съезжает к 64px на 900 (см. адаптив внизу файла).
   Прежний clamp(48, 5.56vw, 80) давал на 1200 всего 67px. */
.hero__title {
  margin: 135px 0 0;
  max-width: 1244px;
  font-size: 80px;
  line-height: 0.93;
  font-weight: 400;
  letter-spacing: -0.06em;
  color: var(--ink);
}
.accent { color: var(--accent); }

/* Кнопка в макете выровнена с абзацем не по центру, а по НИЖНЕЙ кромке:
   низ кнопки (482) совпадает с низом текста (482) */
.hero__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  margin: 40px 0 0;
  /* НЕ wrap: на 900–1200 абзац и кнопка помещаются в строку впритык
     (551 + 40 + 228 = 819 при колонке 820), и перенос сработал бы
     от одного лишнего пикселя. Вместо переноса ужимается абзац. */
  flex-wrap: nowrap;
}

.hero__sub {
  margin: 0;
  min-width: 0;
  flex: 0 1 608px;
  max-width: 608px;
  font-size: 20px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: -0.04em;   /* -0.8px при 20px */
  color: var(--muted);
}

/* ============================ ПОЛОСА ПРЕИМУЩЕСТВ / БЕГУЩАЯ СТРОКА ============
   Десктоп (>=1200px): четыре пункта, разнесённые по ширине колонки,
   между ними «/».
   Ниже 1200px: та же полоса становится бегущей строкой во всю ширину
   экрана — дорожка .ticker содержит ДВЕ одинаковые копии списка и едет
   влево ровно на половину своей ширины, поэтому шов не заметен.
   Порог именно 1200, а не 900: на 1199 четыре пункта уже не помещаются
   в строку, и нельзя допустить состояния «текст не влез, а бегущая
   строка ещё не включилась» (так и нарисовано в макете — фрейм
   «1200-900» уже с бегущей строкой).
   ============================================================================ */

.hero__features {
  margin: 40px 0 0;
  padding: 24px 0;
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
  overflow: hidden;
}

.ticker { display: block; }

.ticker__list {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 16px;
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--ink);
  white-space: nowrap;
}
.ticker__list .sep { color: var(--divider); }
.ticker__list--clone { display: none; }
/* «/» на стыке двух копий списка — нужен только в режиме бегущей строки */
.ticker__list .sep--loop { display: none; }

@keyframes tickerMove {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* ============================ СЦЕНА ============================
   Одна общая сцена: сверху полоса, где человечки бегают вокруг
   работающего за столом HR, ниже — ИИ-аватар и HR, которая выносит
   вердикт. Всё в одной системе координат, позиции расставляет JS
   через transform. Раскладка (где полоса, где робот, где HR)
   считается в app.js и на мобильном другая — вертикальная.
   ============================================================== */

.stage {
  position: relative;
  /* Высота фиксированная и от экрана не зависит: это сумма постоянных
     отступов раскладки, её считает measure() в app.js и сама же ставит
     в style.height. Здесь то же число — чтобы до запуска скрипта блок
     не прыгал. Меняете отступы в app.js — поправьте и эти числа. */
  height: 692px;
  margin-top: 0;
  overflow: hidden;
}

.stage__layer { position: absolute; inset: 0; }

/* невидимая зона вокруг робота — по ней ловим появление робота в кадре.
   Размер и место ставит app.js (layoutFixed) от реальных координат робота,
   потому что на десктопе и на мобильном он стоит в разных местах. */
.stage__sentinel {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
}

/* ============================ ПИКСЕЛЬНЫЕ ПЕРСОНАЖИ ============================
   Спрайты 20×27 (у робота 25×27). Анимация покадровая: пиксели нельзя
   вращать, поэтому вместо поворота конечностей CSS переключает готовые
   кадры через steps().
   ============================================================================ */

.ch {
  display: block;
  height: var(--h, 120px);
  width: auto;
  image-rendering: pixelated;
}

.flipper { display: block; }
.flip .flipper { transform: scaleX(-1); }
.bob { display: block; }

/* кадры кандидатов: по умолчанию видна стойка */
.px .pxf { opacity: 0; }
.px .pxf--idle { opacity: 1; }

/* идёт — два кадра шага по очереди. Темп шага задаёт app.js через
   --walk-ms (он же PACE): если разогнать бег, не тронув ноги, персонаж
   начинает «скользить» — ноги в прежнем ритме, а сам едет быстрее. */
.walk .px .pxf--idle { opacity: 0; }
.walk .px .pxf--a { animation: pxFrameA var(--walk-ms, .34s) steps(1, end) infinite; }
.walk .px .pxf--b { animation: pxFrameB var(--walk-ms, .34s) steps(1, end) infinite; }

/* робот и HR за столом не ходят — у каждого свой двухкадровый цикл,
   который крутится постоянно, темп — свой у каждого */
.two .pxf { opacity: 0; }
.two .pxf--a { animation: pxFrameA var(--ms, .5s) steps(1, end) infinite; }
.two .pxf--b { animation: pxFrameB var(--ms, .5s) steps(1, end) infinite; }

/* HR-вердикт — единственная, у кого цикл НЕ крутится постоянно: она просто
   стоит в первичной позе (кадр a, руки по швам), а разводит руками ровно
   один раз — в момент своей реплики, когда к ней подошёл кандидат, и так
   на КАЖДОГО подошедшего.

   Здесь только поза покоя. Сам круг жеста CSS больше не рисует: он живёт
   в gesture() в app.js на Web Animations API — CSS-анимация с
   fill-mode: none отыгрывала один раз и переставала перезапускаться,
   поэтому руками разводили только перед первым кандидатом. Подробности
   там же, в комментарии к gesture(). */
.two-once .pxf { opacity: 0; }
.two-once .pxf--a { opacity: 1; }

.actor--ai   { --ms: .46s; }
.actor--desk { --ms: 1.4s; }

@keyframes pxFrameA { 0%, 49.9% { opacity: 1 } 50%, 100% { opacity: 0 } }
@keyframes pxFrameB { 0%, 49.9% { opacity: 0 } 50%, 100% { opacity: 1 } }

/* ============================ ОБЛАЧКО РЕПЛИКИ ============================
   Фиксированный размер (макет Figma, sprites-ui.js: bubbleFrameSVG()).
   Размер и фон .bubble выставляются один раз при создании актёра
   (setupBubble() в app.js) — .bubble__bg и .bubble__t внутри
   позиционируются абсолютно, обе на свои фиксированные места.

   Хвостик у макета не по центру прямоугольника, поэтому наводим на
   говорящего не центр баблика, а именно кончик хвостика: --anchor —
   его смещение от левого края, app.js считает его в setupBubble().

   БЕЗ ПОВОРОТА: для пиксель-арта поворот даже на полтора градуса
   пересчитывает картинку с антиалиасингом и замыливает ступеньки
   обводки. В анимации появления остались только сдвиг и масштаб.
   ============================================================ */

.bubble {
  position: absolute;
  left: 50%;
  bottom: calc(100% - 4px);   /* точный нахлёст ставит app.js: BUBBLE_OVERLAP */
  --anchor: -50%;
  transform: translate(var(--anchor), 6px) scale(.4);
  transform-origin: 50% 115%;
  opacity: 0;
  transition: transform .26s cubic-bezier(.2, 1.5, .4, 1), opacity .18s ease;
  pointer-events: none;
  z-index: 20;
}
.bubble.show { opacity: 1; transform: translate(var(--anchor), 0) scale(1); }

.bubble__bg { position: absolute; inset: 0; z-index: 0; }
.bubble__bg svg { display: block; width: 100%; height: 100%; image-rendering: pixelated; }

.bubble__t {
  position: absolute;
  left: 50%;
  z-index: 1;
  transform: translate(-50%, -50%);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  white-space: normal;
  word-break: break-word;
  text-align: center;
  font-weight: 500;
  /* кегль и число строк ставит app.js (setupBubble) — они зависят от
     масштаба баблика; здесь только запасное значение */
  font-size: 13px;
  line-height: 1.2;
  letter-spacing: -0.02em;   /* как в макете: -0.32px при 16px */
  color: #353535;
  padding: 0 4px;
}

/* ---------- значок вердикта в реплике HR-женщины ----------
   Вместо системных эмодзи ✅ ❌ — пиксельный SVG (verdictMarkSVG),
   он одинаков во всех ОС и не выбивается из арта. .bubble__nb держит
   последнее слово и значок вместе, чтобы значок не уехал один на
   новую строку. Ширина значка задана в em, поэтому он масштабируется
   вместе с кеглем реплики (кегль ставит app.js от размера баблика). */
.bubble__nb { white-space: nowrap; }

.bubble__mark {
  display: inline-block;
  height: .85em;            /* ширину берём от пропорций значка: галочка
                               шире крестика, а высота у них одна */
  margin-left: .28em;
  vertical-align: -.04em;
}
.bubble__mark svg { display: block; height: 100%; width: auto; image-rendering: pixelated; }

/* ---------- баблик HR за столом: ВСЕГДА ПОВЕРХ остальных ----------
   Он единственный висит постоянно, поэтому его нельзя перекрывать
   чужими репликами. Раньше он жил внутри .actor, а у .actor z-index
   считается от Y (кто ниже — тот выше), да и сам .actor с z-index
   создаёт стекинг-контекст, из которого баблику не выбраться: любой
   кандидат ниже стола накрывал его своей репликой.
   Поэтому баблик стола вынесен из актёра в собственный слой
   .bubble-host — пустой блок нулевой ширины и ростом со спрайт,
   который app.js ставит ровно в точку стола. Внутри него .bubble
   ведёт себя точно так же, как внутри актёра (left: 50% от нулевой
   ширины = та же точка, bottom: 100% = макушка), но z-index у слоя
   заведомо выше всех актёров, включая .speaking. */
.bubble-host {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: var(--h, 120px);
  z-index: 900;
  pointer-events: none;
}

/* актёры — позицию задаёт JS через transform: translate(x, y) translate(-50%, -100%) */
.actor {
  position: absolute;
  left: 0;
  top: 0;
  will-change: transform;
}
.actor.hidden { opacity: 0; }
.actor.speaking { z-index: 800 !important; }

/* появление из кучи — мигание, как в восьмибитных играх */
.actor.pop .flipper { animation: pxBlink .16s steps(1, end) 4; }
@keyframes pxBlink { 0%, 49.9% { opacity: 1 } 50%, 100% { opacity: .2 } }

/* «оглушён» — подрагивание на целый пиксель, без поворота */
.actor.dizzy .bob { animation: pxJitter .16s steps(1, end) infinite; }
@keyframes pxJitter {
  0%, 49.9% { transform: translateX(-2px) }
  50%, 100% { transform: translateX(2px) }
}

.puff { position: absolute; left: 0; top: 0; z-index: 700; }
.puff i {
  display: block;
  width: 22px; height: 22px;
  border: 2px solid rgba(9, 9, 9, .35);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(.3);
  animation: puff .7s ease-out forwards;
}
@keyframes puff {
  to { transform: translate(-50%, -140%) scale(1.6); opacity: 0; }
}

/* ============================ ДРАКА ============================ */

.fight {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 750;
  pointer-events: none;
}
.fight__pop {
  transform: scale(0);
  transform-origin: 50% 100%;
  transition: transform .2s steps(3, end);
}
.fight.on .fight__pop { transform: scale(1); }

.fight .ch { height: auto; width: 100%; }
/* облако дрожит теми же двумя кадрами; период ставит app.js из FIGHT_PACE */
.fight .pxf--a { animation: pxFrameA var(--fight-frame-ms, .16s) steps(1, end) infinite; }
.fight .pxf--b { animation: pxFrameB var(--fight-frame-ms, .16s) steps(1, end) infinite; }

.boom { position: absolute; left: 0; top: 0; z-index: 800; }
.boom span {
  display: block;
  transform: translate(-50%, -50%) scale(0) rotate(var(--rot, -8deg));
  color: inherit;
  font-size: clamp(16px, 2.4vw, 28px);
  font-weight: 700;
  letter-spacing: .01em;
  text-transform: uppercase;
  white-space: nowrap;
  -webkit-text-stroke: 2px var(--ink);
  paint-order: stroke fill;
  animation: boom .8s cubic-bezier(.2, 1.5, .4, 1) forwards;
}
@keyframes boom {
  0%   { transform: translate(-50%, -50%) scale(0) rotate(var(--rot)); opacity: 0; }
  30%  { transform: translate(-50%, -50%) scale(1.15) rotate(var(--rot)); opacity: 1; }
  70%  { transform: translate(-50%, -62%) scale(1) rotate(var(--rot)); opacity: 1; }
  100% { transform: translate(-50%, -90%) scale(.9) rotate(var(--rot)); opacity: 0; }
}

/* ============================ ОЦЕНКА ============================
   Плашка — тот же приём, что у баблика: фон рисует scoreSVG
   (пиксельный пилл, красный/зелёный из sprites-ui.js), текст поверх. */

.score {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, 10px) scale(.2);
  opacity: 0;
  transition: transform .3s cubic-bezier(.2, 1.6, .4, 1), opacity .2s ease;
  z-index: 15;
}
.score.show { opacity: 1; transform: translate(-50%, 0) scale(1); }

.score__bg { position: absolute; inset: 0; z-index: 0; }
.score__bg svg { display: block; width: 100%; height: 100%; image-rendering: pixelated; }

.score__t {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  color: #fff;
  /* кегль ставит app.js (fitScore) от масштаба плашки; здесь запасное */
  font-size: 16px;
  font-weight: 700;
  padding: 0 3px;
}
.score__t small { font-size: 11px; font-weight: 600; opacity: .85; margin-left: 2px; }

/* фон плашки оценки — не персонаж и не ходит: у неё всегда один кадр 'a'.
   Но pxSVG() ставит на него те же классы pxf/pxf--a, что и на кадры
   персонажа, а .score__bg лежит внутри .actor с классом .walk/.two/.fight —
   поэтому общие правила анимации кадров невольно попадали и на неё, и
   плашка мигала в такт шагам/циклу актёра. Гасим это здесь. У баблика
   реплики той же проблемы нет — bubbleFrameSVG() рисует готовые <rect>
   напрямую, без классов pxf. */
.score__bg .pxf { animation: none !important; opacity: 1 !important; }

/* Подвал переехал в claude/footer.css (блок 8, класс .ftr) —
   прежняя временная плашка .footer удалена вместе со стилями. */

/* ============================ АДАПТИВ ============================ */

/* Брейкпоинты взяты из имён фреймов макета:
     «1140» / «1440-1200» → 1200px и шире
     «1200-900»           → 900–1199
     «900-760»            → 760–899
     «iPhone 16»          → уже 760
   Всё, что ниже, — только про хиро; сцена с анимацией не трогается,
   её правило осталось на прежнем пороге 900px в самом низу файла. */

/* ---------- 900–1199: колонка та же (отступы 40, меню на месте),
     но заголовок съезжает 80 → 64, абзац становится 16px,
     а полоса преимуществ превращается в бегущую строку ---------- */
@media (max-width: 1199px) {
  /* 80px на 1200 → 64px на 900, линейно: 16 + 5.333vw */
  .hero__title {
    margin-top: 100px;      /* в макете 181 − 81 (высота шапки) */
    max-width: none;
    font-size: calc(16px + 5.333vw);
  }

  .nav { gap: 24px; }
  .nav__links { gap: 16px; }

  .hero__row { margin-top: 32px; }
  .hero__sub { flex-basis: 551px; max-width: 551px; font-size: 16px; }

  /* --- бегущая строка: включается сразу с 1199, чтобы не было
     состояния «четыре пункта уже не влезли, а строка ещё стоит» --- */
  .hero__features {
    /* во всю ширину экрана, за пределы боковых отступов hero__inner */
    margin: 32px -40px 0;
    padding: 24px 0;
  }
  .ticker {
    display: flex;
    width: max-content;
    animation: tickerMove 30s linear infinite;
  }
  .ticker__list {
    width: auto;
    flex: none;
    justify-content: flex-start;
    gap: 22px;
    padding-right: 22px;
  }
  .ticker__list--clone { display: flex; }
  .ticker__list .sep--loop { display: block; }
}

/* ---------- 760–899: шапка сжимается (меню прячется, лого 83×35),
     кнопка уходит под абзац ---------- */
@media (max-width: 899px) {
  .hero__inner { padding: 12px 16px 0; }

  /* лого и кнопка теперь разной высоты (35 и 49) — в макете они
     выровнены по центру строки, а не по верху, как на десктопе */
  .nav { align-items: center; gap: 12px; padding: 0 0 12px; }
  .nav__links { display: none; }
  .logo__mark { width: 83px; height: 35px; }

  .hero__title { margin-top: 40px; font-size: 64px; }

  .hero__row { flex-direction: column; align-items: flex-start; gap: 32px; margin-top: 24px; }
  /* кнопка того же размера, что на десктопе (228×54 в макете) —
     не растягивается на всю ширину и стоит слева */
  .hero__sub { flex-basis: auto; }

  .hero__features { margin: 40px -16px 0; padding: 16px 0; }
}

/* ---------- уже 760: макет iPhone ---------- */
@media (max-width: 759px) {
  .hero__inner { padding: 12px 12px 0; }

  /* 64px на 760 → 48px на 393, линейно; ниже 393 ужимается дальше */
  .hero__title { font-size: clamp(34px, calc(30.9px + 4.36vw), 64px); }

  .hero__sub { max-width: none; }

  .hero__features { margin: 40px -12px 0; }
  .ticker__list { font-size: 14px; }
}

/* сцена на мобильном вертикальная: полоса бега сверху, робот ниже
   слева, HR-вердикт в самом низу справа. Высота — сумма фиксированных
   отступов из measure() в app.js, у телефонов и планшетов она разная,
   потому что там разный размер пикселя. Он ещё и подгоняется под
   плотность экрана (snapPx), поэтому здесь значения для ретины ×2,
   а точную высоту скрипт ставит сам — на ×3 она на пару пикселей другая.
   Порог оставлен прежним (900) — к хиро это правило не относится. */
@media (max-width: 900px) {
  .stage {
    height: 831px;   /* спрайт ~148px (планшеты 600-900) — см. measure() */
  }
}
@media (max-width: 599px) {
  .stage {
    height: 680px;   /* спрайт ~121px (телефоны) — см. measure() */
  }
}

@media (prefers-reduced-motion: reduce) {
  /* жест HR-вердикта тут не перечислен: он не CSS-анимация, а WAAPI,
     и gesture() в app.js сам не запускается при reduced-motion */
  .px .pxf--a, .px .pxf--b,
  .two .pxf--a, .two .pxf--b,
  .fight .pxf--a, .fight .pxf--b,
  .actor.pop .flipper, .actor.dizzy .bob { animation: none !important; }
  .px .pxf--idle { opacity: 1; }
  /* .walk переопределяет --idle до 0 (см. выше) сильнее, чем базовое
     правило .px .pxf--idle — без этой строки идущий кандидат станет
     невидимым, раз кадры a/b тоже перестали анимироваться */
  .walk .px .pxf--idle { opacity: 1; }
  .two .pxf--a { opacity: 1; }
  .ticker { animation: none !important; }
  html { scroll-behavior: auto; }
}
