/* ============================================================
   BYTEWELL — студия разработки
   Дизайн-система лендинга.
   Сквозной градиент: тёмно-серый сверху → светло-голубой снизу.
   ============================================================ */

/* ---------- 1. Токены ---------- */
:root {
  /* Тёмная зона */
  --ink-900: #0e0f13;
  --ink-800: #14161c;
  --ink-700: #1c1f27;
  --ink-600: #262b36;
  --ink-500: #2f3644;

  /* Переход и светлая зона */
  --shift-1: #2f3644;
  --shift-2: #5d6d95;
  --sky-400: #8ea5d6;
  --sky-300: #aec1e8;
  --sky-200: #c8d7f3;
  --sky-100: #dde7fb;
  --sky-50:  #eef3fd;

  /* Контент */
  --paper: #ffffff;
  --text-strong: #12141a;
  --text-body: #4a5162;
  --text-muted: #7b8394;

  --on-dark: #ffffff;
  --on-dark-soft: rgba(255, 255, 255, 0.66);
  --on-dark-faint: rgba(255, 255, 255, 0.36);

  --accent: #a9c6ff;
  --brand: #2f6bff;
  --brand-ink: #1d4fd8;

  --line-dark: rgba(255, 255, 255, 0.14);
  --line-light: rgba(18, 20, 26, 0.10);

  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 26px;
  --r-xl: 34px;
  --r-pill: 999px;

  --shadow-card: 0 2px 4px rgba(16, 20, 34, .04), 0 12px 28px rgba(16, 20, 34, .10);
  --shadow-lift: 0 6px 12px rgba(16, 20, 34, .07), 0 26px 56px rgba(16, 20, 34, .18);
  --shadow-modal: 0 30px 90px rgba(8, 11, 20, .40);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);

  --shell: 1240px;
  /* широкая сетка — только для шапки: элементы должны стоять по краям экрана */
  --shell-wide: 1600px;
  /* подложка последней главы (продвижение + подвал) */
  --band: #b9c6ec;
  /* Еле заметное зерно. Длинная растяжка при 8 битах на канал неизбежно
     распадается на полосы; шум их разбивает. Лежит в том же background,
     что и градиент, то есть под содержимым, а не поверх него. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)' opacity='.06'/%3E%3C/svg%3E");
  --gut: 28px;

  --font: "Onest", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

/* ---------- 2. Сброс и база ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

/* авторские display-правила ниже перебивают браузерный [hidden] — возвращаем его */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--ink-900);
  /* Страховка от горизонтальной болтанки. То же правило стоит на body, но
     Safari переносит его с body на окно не всегда — а на корне оно работает
     везде, где вообще есть clip. Браузеры постарше значение просто не
     поймут и оставят как было: хуже не станет. */
  overflow-x: clip;
}

body {
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.55;
  color: var(--on-dark);
  background: var(--ink-900);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* clip, а не hidden: hidden сделал бы из body прокручиваемую область,
     и закреплённый внизу подвал считал бы «низом» её край, а не окна. */
  overflow-x: clip;
}

/* Замок прокрутки для окон поверх страницы. Класс висит и на html, и на
   body: с тех пор как у html появился overflow-x: clip, «главным» стал
   корень, и один только body окно уже не держит — рядом с полосой прокрутки
   открытой панели оставалась вторая, от самой страницы.
   Селектор с :has() — для браузеров, где класс на корень ещё не поставили. */
html.is-locked,
body.is-locked,
html:has(> body.is-locked) { overflow: hidden; }

img, video, svg { display: block; max-width: 100%; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--brand); color: #fff; }

/* Подсветка под пальцем.
   Мобильные браузеры сами рисуют серо-синий прямоугольник поверх всего, на
   что нажали, — и он ложится по рамке элемента, а не по его форме: под
   круглой кнопкой колоды появлялся квадрат, под галочкой согласия —
   прямоугольник во всю строку с текстом. У наших кнопок, карточек и полей
   свои состояния наведения и нажатия, так что системная подсветка только
   мешает. Свойство наследуется, поэтому одного правила на корень хватает.
   Клавиатурную обводку это не трогает: она отдельная, ниже, на
   :focus-visible — при нажатии пальцем браузер её не показывает. */
html { -webkit-tap-highlight-color: transparent; }

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

/* Размытая заглушка под обложкой.
   Пока настоящая картинка едет, на её месте стоит крошечный (24 px в ширину)
   кадр из манифеста копий — он приезжает строкой data: прямо в атрибуте
   style, отдельного запроса не делает. Браузер растягивает его на всю
   плитку со сглаживанием, получается мягкое пятно нужных цветов вместо
   пустого голубого прямоугольника. Гасить заглушку не нужно: готовая
   картинка непрозрачна и закрывает фон собой.
   Точка кадрирования у фона та же, что у самой картинки, иначе в момент
   подмены кадр заметно прыгает. */
.deck-art > img,
.case-stage > img,
.gallery-grid img {
  background-size: cover;
  background-repeat: no-repeat;
  background-position: var(--focus, 50% 50%);
}

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

/* Широкая сетка — для шапки: логотип и кнопки должны стоять ближе к краям
   экрана, иначе по бокам остаётся много воздуха и страница кажется узкой.
   Правило обязано идти ПОСЛЕ .shell: селекторы одной силы, побеждает
   последний, и в обратном порядке .shell возвращал бы ширину обратно. */
.shell-wide { max-width: var(--shell-wide); padding-inline: 34px; }

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

/* ---------- 3. Сцены: непрерывный градиент по странице ---------- */
/* Раньше каждая из трёх сцен несла свой градиент, и на стыках была видна
   «ступенька»: скорость изменения цвета менялась скачком, а весь путь от
   тёмного к светлому укладывался в 260 px переходной полосы. Теперь путь
   растянут через конец тёмной сцены, всю переходную полосу и начало светлой,
   стопы стоят часто и равномерно, а поверх лежит зерно против полос. */
/* Сцены лежат над подвалом и непрозрачны — именно поэтому он и открывается
   только в самом низу. Полотно страницы (html) тёмное, чтобы в вырезах под
   скруглением светлой части не проглядывал белый лист. */
.stage-dark, .stage-shift, .stage-light { position: relative; z-index: 1; }
/* Нижние углы скругляем и у самой сцены, а не только у блока вопросов внутри
   неё: иначе в вырезах остаётся видна её же светлая заливка — уголками
   «ступенькой». Скруглили обе — в вырезах тёмное полотно, как и подвал. */
.stage-light {
  margin-bottom: var(--footer-h, 420px);
  border-radius: 0 0 var(--r-xl) var(--r-xl);
}

.stage-dark {
  position: relative;
  background:
    var(--grain),
    linear-gradient(180deg,
      var(--ink-900)  0%,
      #101216        10%,
      var(--ink-800) 20%,
      #191c23        30%,
      #1f232c        40%,
      var(--ink-600) 48%,
      var(--shift-1) 56%,
      #394257        64%,
      #45506a        72%,
      #525e7f        80%,
      #5e6b90        88%,
      #65739b        94%,
      #6b7ba4       100%);
}

/* Полоса больше не тянет на самостоятельную секцию: в ней просто строка
   контактов, поэтому высота ровно под неё, без воздуха на две сотни
   пикселей сверху и снизу. Путь по цвету здесь короткий — основную
   часть перехода несут конец тёмной сцены и начало светлой. */
.stage-shift {
  height: 220px;
  display: flex;
  align-items: center;
  background:
    var(--grain),
    linear-gradient(180deg,
      #6b7ba4   0%,
      #6e7ea8  25%,
      #7182ad  50%,
      #7485b3  75%,
      #7688b8 100%);
}

.stage-light {
  background:
    var(--grain),
    linear-gradient(180deg,
      #7688b8         0%,
      #7c8ebe         7%,
      #8394c5        14%,
      #8a9ccd        21%,
      var(--sky-400) 28%,
      #9db2de        38%,
      var(--sky-300) 48%,
      #bdcdf0        58%,
      var(--sky-200) 68%,
      #d5e0f8        78%,
      var(--sky-100) 87%,
      #e8effd        94%,
      #f4f8ff       100%);
  color: var(--text-strong);
}

/* мягкое голубое свечение за героем */
.glow {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  /* Пятна свечения крупнее блока и упираются в его нижний край.
     Без маски срез читается прямой линией — особенно на телефоне,
     где герой низкий. Маска гасит свечение до края, а не на краю. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 100%);
}
.glow::before,
.glow::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .5;
}
.glow::before {
  width: 620px; height: 620px;
  top: -220px; left: 50%;
  transform: translateX(-58%);
  background: radial-gradient(circle, rgba(94, 124, 214, .58), transparent 68%);
}
.glow::after {
  width: 520px; height: 520px;
  top: 180px; right: -140px;
  background: radial-gradient(circle, rgba(126, 108, 200, .40), transparent 68%);
}

/* ---------- 3.5. Полоса прокрутки ---------- */
html {
  scrollbar-width: thin;
  scrollbar-color: rgba(93, 109, 149, .5) transparent;
}
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  /* прозрачная рамка + background-clip делают ползунок тоньше дорожки,
     поэтому он выглядит аккуратной пилюлей, а не полосой во всю ширину */
  background: rgba(93, 109, 149, .5);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover { background: rgba(93, 109, 149, .78); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ---------- 4. Типографика ---------- */
h1, h2, h3, h4 {
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.06;
}

.display {
  font-size: clamp(52px, 11.5vw, 132px);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 0.94;
}

.h-section {
  font-size: clamp(32px, 5vw, 58px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.04;
}

.lead {
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.55;
  font-weight: 400;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--on-dark-faint);
}
.eyebrow::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.stage-light .eyebrow { color: var(--text-muted); }
.stage-light .eyebrow::before { background: var(--brand); }

/* ---------- 5. Кнопки ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 54px;
  padding: 0 30px;
  border-radius: var(--r-pill);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transition: transform .32s var(--ease), background-color .22s, color .22s, box-shadow .32s var(--ease), border-color .22s;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn-light {
  background: var(--paper);
  color: var(--text-strong);
  box-shadow: 0 6px 20px rgba(6, 10, 22, .28);
}
.btn-light:hover { box-shadow: 0 12px 32px rgba(6, 10, 22, .38); }

.btn-dark {
  background: var(--text-strong);
  color: #fff;
  box-shadow: 0 6px 20px rgba(16, 22, 44, .22);
}
.btn-dark:hover { box-shadow: 0 12px 34px rgba(16, 22, 44, .30); }

.btn-ghost {
  border: 1px solid var(--line-dark);
  color: var(--on-dark);
  background: rgba(255, 255, 255, .04);
}
.btn-ghost:hover { background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .28); }

/* Обведённая кнопка — для второстепенного действия рядом с главным.
   Живёт в шапке, а шапка над голубой частью страницы становится светлой,
   поэтому у неё есть и светлый вариант (ниже, рядом с остальной шапкой). */
.btn-line {
  border: 1px solid var(--line-dark);
  color: var(--on-dark);
  background: transparent;
}
.btn-line:hover { background: rgba(255, 255, 255, .10); border-color: rgba(255, 255, 255, .30); }

.btn-sm { height: 44px; padding: 0 20px; font-size: 15px; }
.btn-full { width: 100%; }
.btn[disabled] { opacity: .55; pointer-events: none; }

.btn .arr { transition: transform .32s var(--ease); }
.btn:hover .arr { transform: translateX(4px); }

/* ---------- 6. Шапка ---------- */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  padding: 16px 0;
  transition: background-color .3s, backdrop-filter .3s, border-color .3s, padding .3s;
  border-bottom: 1px solid transparent;
}
.header.is-stuck {
  padding: 10px 0;
  background: rgba(14, 15, 19, .72);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  border-bottom-color: rgba(255, 255, 255, .08);
}
.header.on-light.is-stuck {
  background: rgba(238, 243, 253, .78);
  border-bottom-color: rgba(18, 20, 26, .08);
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.logo {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--on-dark);
  transition: color .3s;
}
.logo .dot { color: var(--accent); }
.header.on-light .logo { color: var(--text-strong); }
.header.on-light .logo .dot { color: var(--brand); }

.header-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}
.header-nav a {
  padding: 9px 16px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  color: var(--on-dark-soft);
  transition: color .2s, background-color .2s;
}
.header-nav a:hover { color: var(--on-dark); background: rgba(255, 255, 255, .09); }
.header.on-light .header-nav a { color: var(--text-body); }
.header.on-light .header-nav a:hover { color: var(--text-strong); background: rgba(18, 20, 26, .06); }

.header-cta { display: flex; align-items: center; gap: 10px; margin-left: 8px; }
.header .btn-light { box-shadow: none; }
.header.on-light .btn-light { background: var(--text-strong); color: #fff; }
.header.on-light .btn-line { border-color: rgba(18, 20, 26, .20); color: var(--text-strong); }
.header.on-light .btn-line:hover { background: rgba(18, 20, 26, .06); border-color: rgba(18, 20, 26, .34); }

.burger {
  display: none;
  width: 44px; height: 44px;
  border-radius: var(--r-pill);
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .10);
}
.burger span {
  display: block;
  width: 18px; height: 1.8px;
  background: currentColor;
  border-radius: 2px;
  transition: transform .3s var(--ease), opacity .2s;
}
.burger span + span { margin-top: 5px; }
.header.on-light .burger { background: rgba(18, 20, 26, .08); color: var(--text-strong); }
.burger.is-open span:nth-child(1) { transform: translateY(6.8px) rotate(45deg); }
.burger.is-open span:nth-child(2) { opacity: 0; }
.burger.is-open span:nth-child(3) { transform: translateY(-6.8px) rotate(-45deg); }

.drawer {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 55;
  padding: 92px 0 26px;
  background: rgba(14, 15, 19, .96);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  transform: translateY(-102%);
  transition: transform .44s var(--ease);
  border-bottom: 1px solid rgba(255, 255, 255, .10);
}
.drawer.is-open { transform: translateY(0); }
.drawer > .shell > a {
  display: block;
  padding: 15px 0;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}

/* Кнопки под пунктами меню: «написать нам» и вход в кабинет клиента. */
.drawer-actions {
  display: grid;
  gap: 10px;
  margin-top: 22px;
}
.drawer-portal svg { width: 19px; height: 19px; flex: none; }

/* Штора. Меню — это панель сверху, а не полный экран, поэтому под ним лежит
   отдельный слой на всё окно: он слегка размывает и притемняет страницу.
   visibility, а не только opacity: иначе закрытая штора продолжала бы
   перехватывать нажатия. z-index ниже меню (55) и ниже шапки (60). */
.drawer-veil {
  position: fixed;
  inset: 0;
  z-index: 54;
  background: rgba(9, 11, 17, .48);
  backdrop-filter: blur(7px) saturate(120%);
  -webkit-backdrop-filter: blur(7px) saturate(120%);
  opacity: 0;
  visibility: hidden;
  transition: opacity .38s var(--ease-soft), visibility .38s;
}
.drawer-veil.is-open { opacity: 1; visibility: visible; }

/* Пока меню открыто, шапка лежит поверх его тёмной панели. Светлый вариант
   (он включается над голубой частью страницы) выглядел бы на ней чужой
   полосой, поэтому на время меню шапка всегда тёмная и без подложки.
   Правила стоят ПОСЛЕ светлых: вес у селекторов одинаковый, решает порядок. */
body.menu-open .header,
body.menu-open .header.is-stuck,
body.menu-open .header.on-light.is-stuck {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}
body.menu-open .header .logo { color: var(--on-dark); }
body.menu-open .header .logo .dot { color: var(--accent); }
body.menu-open .header .burger { background: rgba(255, 255, 255, .10); color: var(--on-dark); }

/* ---------- 7. Герой ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: 150px 0 100px;
}
.hero-inner {
  position: relative;
  z-index: 2;
  max-width: 880px;
}
.hero .display { margin-bottom: 30px; }
.hero .display .soft { color: var(--accent); }

.hero-lead {
  max-width: 620px;
  font-size: clamp(18px, 2.1vw, 23px);
  line-height: 1.5;
  color: var(--on-dark-soft);
  margin-bottom: 40px;
  /* Эти две строки — плата за то, что теперь это h1. Общее правило
     «h1, h2, h3, h4» выше задаёт 700 и -0.025em; без возврата к 400 и normal
     фраза стала бы жирной и уплотнилась. Значения — те, что были у <p>. */
  font-weight: 400;
  letter-spacing: normal;
}
.hero-lead strong { color: var(--on-dark); font-weight: 600; }

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

.hero-note {
  margin-top: 46px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  font-size: 15px;
  color: var(--on-dark-faint);
}
.hero-note span { display: inline-flex; align-items: center; gap: 8px; }
.hero-note span::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
  opacity: .8;
}

/* ---------- 8. Портфолио ---------- */
.work { padding: 40px 0 44px; }

.section-head {
  max-width: 760px;
  margin-bottom: 52px;
}
.section-head .eyebrow { margin-bottom: 18px; }
.section-head .h-section { margin-bottom: 18px; }
.section-head .lead { color: var(--on-dark-soft); }
.stage-light .section-head .lead { color: var(--text-body); }

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.filter {
  height: 44px;
  padding: 0 20px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  color: var(--on-dark-soft);
  background: rgba(255, 255, 255, .07);
  border: 1px solid transparent;
  transition: background-color .2s, color .2s, border-color .2s;
}
.filter:hover { color: #fff; background: rgba(255, 255, 255, .13); }
.filter.is-on {
  background: var(--paper);
  color: var(--text-strong);
  font-weight: 600;
}

/* ---------- Выпадающий список (фильтр направлений и поле формы) ---------- */
.dd { position: relative; }

.dd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 44px;
  padding: 0 18px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  transition: background-color .2s, color .2s, border-color .2s, box-shadow .2s;
}
.dd-caret {
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-right: 1.8px solid currentColor;
  border-bottom: 1.8px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  opacity: .65;
  transition: transform .3s var(--ease);
}
.dd.is-open .dd-caret { transform: translateY(2px) rotate(-135deg); }

.dd-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 40;
  min-width: 100%;
  width: max-content;
  max-width: min(340px, 82vw);
  max-height: 316px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 7px;
  border-radius: 20px;
  background: var(--paper);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px) scale(.97);
  transform-origin: top left;
  transition: opacity .2s var(--ease-soft), transform .28s var(--ease), visibility .2s;
}
.dd.is-open .dd-menu { opacity: 1; visibility: visible; transform: none; }
.dd.dd--up .dd-menu {
  top: auto;
  bottom: calc(100% + 8px);
  transform-origin: bottom left;
}
.dd-menu::-webkit-scrollbar { width: 0; height: 0; }
.dd-menu { scrollbar-width: none; }

.dd-opt {
  display: block;
  width: 100%;
  text-align: left;
  padding: 11px 14px;
  border-radius: 13px;
  font-size: 15px;
  line-height: 1.35;
  color: var(--text-body);
  transition: background-color .16s, color .16s;
}
.dd-opt:hover, .dd-opt:focus-visible { background: rgba(18, 20, 26, .06); color: var(--text-strong); }
.dd-opt.is-cur { background: rgba(47, 107, 255, .10); color: var(--brand-ink); font-weight: 600; }

/* вариант на тёмном фоне — фильтр над колодой */
.dd--dark .dd-btn {
  color: var(--on-dark-soft);
  background: rgba(255, 255, 255, .07);
}
.dd--dark .dd-btn:hover { color: #fff; background: rgba(255, 255, 255, .13); }
.dd--dark.is-set .dd-btn {
  background: var(--paper);
  color: var(--text-strong);
  font-weight: 600;
}

/* вариант поля формы */
.dd--field { display: block; }
.dd--field .dd-btn {
  width: 100%;
  height: 54px;
  padding: 0 18px;
  border-radius: var(--r-md);
  border: 1.5px solid transparent;
  background: #f2f5fb;
  color: var(--text-strong);
  font-size: 16px;
  font-weight: 400;
}
.dd--field .dd-btn:hover { background: #eaeff8; }
.dd--field.is-open .dd-btn,
.dd--field .dd-btn:focus-visible {
  outline: none;
  background: #fff;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(47, 107, 255, .14);
}
/* в поле формы список ровно по ширине поля: left+right+width:auto,
   иначе длинный пункт растянул бы меню шире модалки */
.dd--field .dd-menu { right: 0; width: auto; max-width: none; }

/* ---------- Колода: карточки проектов стопкой ---------- */
.deck {
  /* смещение карточек в стопке: на десктопе вверх, на мобилке вправо.
     Масштаб сам опускает верхний край, поэтому --dy заметно больше видимого сдвига. */
  --dx: 0px;
  --dy: -33px;
  --ds: .07;
}

.deck-stage {
  position: relative;
  height: clamp(430px, 36vw, 466px);
  /* верхний отступ с запасом: задние карточки стопки поднимаются над сценой
     на 34px, и без запаса они почти упираются в фильтры */
  margin: 78px 0 26px;
  /* горизонтальные свайпы забирает скрипт, вертикальный скролл остаётся браузеру */
  touch-action: pan-y;
}

.deck-card {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 47% 53%;
  background: var(--paper);
  border-radius: var(--r-lg);
  overflow: hidden;
  color: var(--text-strong);
  box-shadow: 0 18px 44px rgba(6, 9, 20, .34);
  transform:
    translate3d(calc(var(--dx) * var(--d)), calc(var(--dy) * var(--d)), 0)
    scale(calc(1 - var(--ds) * var(--d)));
  transition: transform .58s var(--ease), opacity .42s var(--ease);
  will-change: transform, opacity;
}

/* в стопке (0 — передняя, 1–2 выглядывают сзади) */
.deck-card[data-pos="in"] { opacity: 1; }
/* ещё не в стопке — ждут за третьей позицией */
.deck-card[data-pos="far"] { opacity: 0; pointer-events: none; }
/* уже показаны — уходят вниз и растворяются */
.deck-card[data-pos="past"] {
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, 48px, 0) scale(.97);
}

.deck-face {
  grid-column: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  padding: 34px 34px 30px;
  min-width: 0;
}
.deck-num {
  display: block;
  font-size: 15px;
  color: var(--text-muted);
  margin-bottom: 6px;
  font-variant-numeric: tabular-nums;
}
.deck-name {
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.08;
}
.deck-client {
  display: block;
  margin-top: 8px;
  font-size: 15px;
  color: var(--text-muted);
}
.deck-desc {
  font-size: 17px;
  line-height: 1.5;
  color: var(--text-strong);
}
.deck-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 16px;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--text-muted);
  transition: color .2s, gap .3s var(--ease);
}
.deck-link:hover { color: var(--brand-ink); gap: 11px; }

.deck-art {
  grid-column: 2;
  position: relative;
  overflow: hidden;
  background: var(--sky-100);
  min-width: 0;
}
.deck-art > img, .deck-art > .cover {
  width: 100%; height: 100%;
  object-fit: cover;
  /* точка фокуса из админки приезжает в --focus прямо на теге картинки */
  object-position: var(--focus, 50% 50%);
  transition: transform .8s var(--ease);
}
.deck-card[data-pos="in"][data-d="0"]:hover .deck-art > img,
.deck-card[data-pos="in"][data-d="0"]:hover .deck-art > .cover { transform: scale(1.04); }

.deck-pills {
  position: absolute;
  inset: 20px 20px auto 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  /* индикатор готовности стоит в правом верхнем углу обложки */
  justify-content: flex-end;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 16px;
  border-radius: var(--r-pill);
  background: #fff;
  color: var(--text-strong);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  box-shadow: 0 2px 10px rgba(10, 14, 30, .14);
}
.pill i {
  width: 7px; height: 7px;
  border-radius: 50%;
  /* цвет всегда задаёт класс состояния; серый достаётся неизвестному статусу */
  background: var(--text-muted);
  font-style: normal;
}
.pill.is-live i { background: #35c47a; }   /* работает */
.pill.is-done i { background: #2f9fe0; }   /* готово */
.pill.is-dev  i { background: #f0a92e; }   /* в разработке */

/* управление колодой */
.deck-controls {
  display: flex;
  align-items: center;
  gap: 20px;
}
.deck-nav {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .10);
  color: #fff;
  font-size: 17px;
  transition: background-color .22s, opacity .22s, transform .3s var(--ease);
}
.deck-nav:hover:not([disabled]) { background: rgba(255, 255, 255, .2); }
.deck-nav[disabled] { opacity: .3; cursor: default; }
.deck-nav.prev:hover:not([disabled]) { transform: translateX(-3px); }
.deck-nav.next:hover:not([disabled]) { transform: translateX(3px); }

.deck-dots {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
}
.deck-dot {
  height: 7px;
  width: 7px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .34);
  transition: width .45s var(--ease), background-color .25s;
}
.deck-dot:hover { background: rgba(255, 255, 255, .55); }
.deck-dot.is-on {
  width: 96px;
  background: rgba(255, 255, 255, .62);
}

.deck-empty {
  display: grid;
  place-items: center;
  height: 100%;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .06);
  color: var(--on-dark-soft);
  text-align: center;
  padding: 30px;
}

/* сгенерированная «обложка», когда у кейса нет картинки */
.cover {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.cover-mono {
  position: relative;
  font-size: clamp(52px, 7vw, 82px);
  font-weight: 800;
  letter-spacing: -0.05em;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 4px 30px rgba(20, 26, 50, .22);
}
.cover-grain {
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 22% 26%, rgba(255,255,255,.34), transparent 46%),
    radial-gradient(circle at 78% 74%, rgba(255,255,255,.20), transparent 52%);
  mix-blend-mode: soft-light;
}

.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tag {
  height: 27px;
  padding: 0 11px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--r-pill);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-body);
  background: rgba(18, 20, 26, .055);
}

/* скелетон загрузки */
.skeleton {
  position: absolute;
  inset: 0;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .09), transparent);
  animation: shimmer 1.5s infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }

/* ---------- 9. Страница проекта ---------- */
.case {
  position: fixed;
  inset: 0;
  z-index: 90;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--sky-50);
  color: #fff;
  opacity: 0;
  visibility: hidden;
  transform: translateY(18px);
  transition: opacity .34s var(--ease), transform .44s var(--ease), visibility .34s;
}
.case.is-open { opacity: 1; visibility: visible; transform: none; }

/* Градиент задаётся секциями, а не фоном скролл-контейнера:
   фон контейнера с overflow не прокручивается вместе с содержимым. */
.case-dark {
  /* padding, а не margin у последнего блока: иначе margin схлопывается наружу
     и между тёмной секцией и переходом появляется светлая полоса */
  padding-bottom: 34px;
  background:
    var(--grain),
    linear-gradient(180deg,
      #12151c   0%,
      #161a21  12%,
      #1b1f28  22%,
      #22262f  30%,
      var(--ink-600) 38%,
      var(--shift-1) 48%,
      #363e51  58%,
      #3e4761  67%,
      #47526f  76%,
      #505c7e  84%,
      #5a678c  92%,
      #6b7ba4 100%);
}
.case-light {
  background:
    var(--grain),
    linear-gradient(180deg,
      var(--sky-400)  0%,
      #97acda        10%,
      #a2b6e0        18%,
      var(--sky-300) 25%,
      #bdcdf0        38%,
      var(--sky-200) 46%,
      #d5e0f8        62%,
      var(--sky-100) 76%,
      #e8effd        88%,
      var(--sky-50) 100%);
  color: var(--text-strong);
  padding: 34px 0 80px;
}

.case-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 14px 0;
  background: rgba(18, 21, 28, .74);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.case-bar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.case-back {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 42px;
  padding: 0 18px 0 14px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 600;
  background: rgba(255, 255, 255, .10);
  transition: background-color .22s, transform .3s var(--ease);
}
.case-back:hover { background: rgba(255, 255, 255, .18); transform: translateX(-3px); }

.case-hero { padding: 64px 0 44px; }
.case-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  background: rgba(255, 255, 255, .12);
  margin-bottom: 22px;
}
.case-status i { width: 6px; height: 6px; border-radius: 50%; background: var(--on-dark-faint); font-style: normal; }
/* те же три состояния, что и в .pill, но осветлённые:
   насыщенные #35c47a / #2f9fe0 / #f0a92e на тёмной шапке смотрятся грязно */
.case-status.is-live i { background: #6ee7a8; }   /* работает */
.case-status.is-done i { background: #7dd3fc; }   /* готово */
.case-status.is-dev  i { background: #ffc86b; }   /* в разработке */

.case-title {
  font-size: clamp(42px, 8vw, 86px);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: .98;
  margin-bottom: 20px;
}
.case-sub {
  max-width: 660px;
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.5;
  color: var(--on-dark-soft);
  margin-bottom: 30px;
}
.case-actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* Обложка слева, карточка с фактами справа — вместо широкой картинки на всю ширину */
.case-top {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: 26px;
  align-items: start;
}

.case-stage {
  aspect-ratio: 16 / 10;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lift);
  background: var(--ink-700);
}
.case-stage > * { width: 100%; height: 100%; object-fit: cover; object-position: var(--focus, 50% 50%); }

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

.case-prose {
  max-width: 780px;
  padding-bottom: 60px;
}
.case-prose h3 {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(18, 20, 26, .48);
  margin-bottom: 14px;
}
.case-prose p {
  font-size: 18px;
  line-height: 1.62;
  color: var(--text-strong);
}
.case-prose p + p { margin-top: 16px; }

/* Высоту перехода задаёт скрипт от размера блока с обложкой и фактами */
/* Полоса перехода в кейсе мостит конец .case-dark и начало .case-light.
   Диапазон здесь другой, чем на лендинге, потому что и соседи другие. */
.case .stage-shift {
  height: var(--case-shift, 150px);
  background:
    var(--grain),
    linear-gradient(180deg,
      #6b7ba4   0%,
      #7181aa  17%,
      #7787b1  34%,
      #7d8eb9  51%,
      #8394c2  68%,
      #899cca  84%,
      var(--sky-400) 100%);
}

.case-facts {
  background: var(--paper);
  border-radius: var(--r-lg);
  padding: 6px 24px 22px;
  box-shadow: 0 14px 38px rgba(6, 9, 20, .30);
  color: var(--text-strong);
}
.facts-toggle { display: none; }
.fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding: 15px 0;
  border-bottom: 1px solid var(--line-light);
}
.fact dt { font-size: 15px; color: var(--text-muted); }
.fact dd { font-size: 15.5px; font-weight: 600; text-align: right; }

/* теги живут внутри той же белой карточки, отделены линией */
.case-tags {
  padding-top: 18px;
  margin-top: 4px;
}
.facts-list .fact:last-of-type { border-bottom: 0; }
.case-facts .case-tags { border-top: 1px solid var(--line-light); }

.case-gallery { padding-bottom: 70px; }
.case-gallery h3 {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(18, 20, 26, .48);
  margin-bottom: 18px;
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px;
}
.gallery-grid figure {
  border-radius: var(--r-lg);
  overflow: hidden;
  background: rgba(255, 255, 255, .5);
  box-shadow: var(--shadow-card);
}
.gallery-grid img, .gallery-grid video { width: 100%; height: 100%; object-fit: cover; }

.gallery-dots { display: none; }

/* ---------- 9.1. Свой видеоплеер в галерее ----------
   Браузерный <video controls> в каждом браузере свой и рядом с карточками
   кейса выглядит чужеродно. Разметку собирает vplayerHtml(),
   поведение навешивает initVideoPlayer() (см. site.js). */
/* высоту ячейки задаёт сам ролик, но размеры кадра приезжают вместе
   с метаданными — до этого момента держим ячейку от схлопывания */
.gal-video { min-height: 200px; }

.vplayer {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  overflow: hidden;
  background: var(--ink-900);
  color: #fff;
  /* выделять внутри нечего, а при перетаскивании полосы выделение мешает */
  -webkit-user-select: none;
  user-select: none;
}
.vplayer > video {
  width: 100%;
  height: 100%;
  /* contain, а не cover: пропорции роликов заранее неизвестны и кадрировать их нельзя */
  object-fit: contain;
  background: var(--ink-900);
}

.vp-glyph { width: 18px; height: 18px; fill: currentColor; }
.vp-glyph .g-pause, .vp-glyph .g-off { display: none; }
.vplayer.is-playing .vp-glyph .g-play { display: none; }
.vplayer.is-playing .vp-glyph .g-pause { display: block; }
/* звук выключен — у динамика вместо волн крестик */
.vplayer:not(.is-sound) .vp-glyph .g-on { display: none; }
.vplayer:not(.is-sound) .vp-glyph .g-off { display: block; }

/* большая кнопка по центру */
.vp-big {
  position: absolute;
  top: 50%; left: 50%;
  width: 72px; height: 72px;
  margin: -36px 0 0 -36px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(14, 15, 19, .52);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 10px 30px rgba(6, 9, 20, .34);
  opacity: 0;
  transform: scale(.88);
  pointer-events: none;
  transition: opacity .24s var(--ease-soft), transform .32s var(--ease), background-color .2s;
}
.vp-big .vp-glyph { width: 30px; height: 30px; }
.vp-big:hover { background: rgba(14, 15, 19, .74); }
/* автозапуск не сработал — кнопку видно сразу и однозначно */
.vplayer.is-blocked .vp-big { background: var(--brand); box-shadow: 0 12px 34px rgba(47, 107, 255, .40); }

/* кнопка звука поверх кадра — пока ролик идёт молча */
.vp-sound {
  position: absolute;
  top: 14px; right: 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px 0 13px;
  border-radius: var(--r-pill);
  background: rgba(14, 15, 19, .58);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 6px 18px rgba(6, 9, 20, .28);
  color: #fff;
  font-size: 14.5px;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  transition: opacity .24s, transform .3s var(--ease), background-color .2s;
}
.vp-sound:hover { background: rgba(14, 15, 19, .78); transform: translateY(-1px); }
.vplayer.is-playing:not(.is-sound) .vp-sound { opacity: 1; pointer-events: auto; }

/* тонкая полоса — единственный след управления, когда панель спрятана */
.vp-line {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: rgba(255, 255, 255, .22);
  transition: opacity .24s;
}
.vp-line i { display: block; width: 0; height: 100%; background: var(--brand); }

/* нижняя панель */
.vp-bar {
  position: absolute;
  left: 12px; right: 12px; bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  background: rgba(14, 15, 19, .52);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  box-shadow: 0 10px 30px rgba(6, 9, 20, .30);
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity .26s var(--ease-soft), transform .36s var(--ease);
}

/* Панель и центральная кнопка держатся, пока с плеером работают: мышь рядом,
   ролик на паузе или фокус внутри (иначе управление с клавиатуры вслепую). */
.vplayer.is-ui .vp-bar,
.vplayer:not(.is-playing) .vp-bar,
.vplayer:focus-within .vp-bar { opacity: 1; transform: none; pointer-events: auto; }

.vplayer.is-ui .vp-big,
.vplayer:not(.is-playing) .vp-big,
.vplayer:focus-within .vp-big { opacity: 1; transform: none; pointer-events: auto; }

.vplayer.is-ui .vp-line,
.vplayer:not(.is-playing) .vp-line,
.vplayer:focus-within .vp-line { opacity: 0; }

.vp-btn {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  transition: background-color .2s;
}
.vp-btn:hover { background: rgba(255, 255, 255, .16); }

.vp-time {
  flex: 0 0 auto;
  display: inline-flex;
  gap: 5px;
  padding: 0 2px;
  font-size: 13.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, .82);
}
.vp-sep { opacity: .5; }

.vp-track {
  position: relative;
  flex: 1 1 auto;
  min-width: 60px;
  height: 26px;                 /* зона захвата заметно выше самой полосы */
  cursor: pointer;
  /* без этого перетаскивание пальцем листало бы карусель галереи */
  touch-action: none;
}
.vp-track::before {
  content: "";
  position: absolute;
  top: 50%; left: 0; right: 0;
  margin-top: -2.5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .24);
}
.vp-fill {
  position: absolute;
  top: 50%; left: 0;
  width: 0;
  margin-top: -2.5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--brand);
}
.vp-knob {
  position: absolute;
  top: 50%; left: 0;
  width: 13px; height: 13px;
  margin: -6.5px 0 0 -6.5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(6, 9, 20, .40);
  opacity: 0;
  transform: scale(.6);
  transition: opacity .2s, transform .2s var(--ease);
}
.vp-track:hover .vp-knob,
.vp-track:focus-visible .vp-knob,
.vp-track.is-drag .vp-knob { opacity: 1; transform: none; }

/* :fullscreen и :-webkit-full-screen — раздельными правилами:
   в одном списке незнакомый селектор уронил бы всё правило целиком */
.vplayer:fullscreen { border-radius: 0; background: #000; }
.vplayer:fullscreen > video { object-fit: contain; }
.vplayer:-webkit-full-screen { border-radius: 0; background: #000; }
.vplayer:-webkit-full-screen > video { object-fit: contain; }

.case-cta {
  padding: 46px 40px;
  border-radius: var(--r-xl);
  background: var(--paper);
  box-shadow: var(--shadow-card);
  color: var(--text-strong);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.case-cta h3 { font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.03em; margin-bottom: 8px; }
.case-cta p { color: var(--text-body); }

/* ---------- 10. Форма ---------- */
.form { display: grid; gap: 16px; }

.field { display: grid; gap: 8px; align-content: start; }
.field > label {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-strong);
}
/* пометка обязательности — красная, как в референсе */
.field .hint { font-size: 14px; color: #d9453f; font-weight: 500; }

.control {
  width: 100%;
  min-height: 54px;
  padding: 15px 18px;
  border-radius: var(--r-md);
  border: 1.5px solid transparent;
  background: #f2f5fb;
  color: var(--text-strong);
  font-size: 16px;
  transition: border-color .2s, box-shadow .2s, background-color .2s;
}
.control::placeholder { color: #97a0b2; }
.control:hover { background: #eaeff8; }
.control:focus {
  outline: none;
  background: #fff;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(47, 107, 255, .14);
}
textarea.control { min-height: 128px; resize: vertical; line-height: 1.5; }
.field.has-error .control { border-color: #e05252; }
.field.has-error .control:focus { box-shadow: 0 0 0 4px rgba(224, 82, 82, .16); }
.err {
  font-size: 13.5px;
  color: #cc3f3f;
  display: none;
}
.field.has-error .err { display: block; }

/* Селектор с двумя классами — иначе `.field > label` выше перебивает
   и размер, и цвет, и согласие выглядит как обычная подпись поля. */
.field > .consent {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  color: #949cad;
}
.consent input { position: absolute; opacity: 0; width: 0; height: 0; }
.consent .box {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  margin-top: 1px;
  border-radius: 7px;
  border: 1.5px solid rgba(18, 20, 26, .22);
  background: #fff;
  display: grid;
  place-items: center;
  transition: background-color .2s, border-color .2s;
}
.consent .box::after {
  content: "";
  width: 11px; height: 6px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg) scale(.5);
  opacity: 0;
  transition: opacity .18s, transform .18s var(--ease);
}
.consent input:checked + .box { background: var(--brand); border-color: var(--brand); }
.consent input:checked + .box::after { opacity: 1; transform: rotate(-45deg) scale(1); }
.consent input:focus-visible + .box { outline: 2px solid var(--brand); outline-offset: 3px; }
.consent a { color: #6f7a8f; text-decoration: underline; text-underline-offset: 2px; transition: color .2s; }
.consent a:hover { color: var(--brand-ink); }
.field.has-error .consent .box { border-color: #e05252; }

.form-foot {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.form-note { font-size: 13.5px; color: var(--text-muted); }

.form-alert {
  display: none;
  padding: 13px 16px;
  border-radius: var(--r-sm);
  background: rgba(224, 82, 82, .10);
  color: #b23636;
  font-size: 14.5px;
}
.form-alert.is-on { display: block; }

.form-done {
  display: none;
  text-align: center;
  padding: 30px 10px;
}
.form-done.is-on { display: block; animation: pop .5s var(--ease); }
.form-done .check {
  width: 62px; height: 62px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: rgba(47, 107, 255, .12);
  color: var(--brand);
  display: grid;
  place-items: center;
  font-size: 28px;
}
.form-done h3 { font-size: 25px; letter-spacing: -0.03em; margin-bottom: 10px; color: var(--text-strong); }
.form-done p { color: var(--text-body); font-size: 16px; }
@keyframes pop {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to { opacity: 1; transform: none; }
}
.form-wrap.is-done .form { display: none; }

/* ---------- Широкая раскладка формы (только пк) ----------
   Имя и контакт в две колонки, остальное на всю ширину.
   На телефоне форма остаётся одноколоночной — там ничего не меняем. */
@media (min-width: 861px) {
  .form {
    grid-template-columns: 1fr 1fr;
    gap: 20px 22px;
  }
  .form > [data-field="name"]    { grid-column: 1; }
  .form > [data-field="contact"] { grid-column: 2; }
  .form > [data-field="type"],
  .form > [data-field="description"],
  .form > [data-field="consent"],
  .form > .form-alert,
  .form > .form-foot { grid-column: 1 / -1; }

  .form > .form-foot { margin-top: 6px; }
  .form-foot .btn { min-width: 220px; }
}

/* ---------- 10.5. Контакты в переходной полосе ----------
   Между колодой и формой была пустая растяжка на две сотни пикселей.
   Теперь там короткая строка контактов: телефон, телеграм, почта.
   Ненавязчиво — прозрачные пилюли на градиенте, без рамок и заголовков. */
.contacts-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
}
.cs-item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 20px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .10);
  color: rgba(255, 255, 255, .82);
  font-size: 15.5px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color .22s, color .22s, transform .3s var(--ease);
}
.cs-item:hover {
  background: rgba(255, 255, 255, .92);
  color: var(--text-strong);
  transform: translateY(-2px);
}
.cs-item svg { width: 17px; height: 17px; flex: 0 0 auto; opacity: .78; }
.cs-item:hover svg { opacity: 1; }

/* ---------- 11. Секция контактов ---------- */
.contact { padding: 44px 0 104px; }

/* Заголовок вынесен над карточкой формы, как в референсе */
.contact-title {
  font-size: clamp(30px, 4vw, 46px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  /* Белым: заголовок стоит в самом верху светлой сцены, а там фон ещё
     тёмно-голубой — тёмный текст на нём глухой. */
  color: var(--on-dark);
  margin-bottom: 26px;
}

.form-card {
  background: var(--paper);
  border-radius: var(--r-xl);
  padding: 36px;
  box-shadow: var(--shadow-card);
}

/* ---------- 12. Модалка ---------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 24px;
  opacity: 0;
  visibility: hidden;
  transition: opacity .28s var(--ease-soft), visibility .28s;
}
.modal.is-open { opacity: 1; visibility: visible; }
.modal-veil {
  position: absolute;
  inset: 0;
  background: rgba(10, 13, 20, .58);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* Скругление живёт на самой карточке, а прокрутка — на внутреннем слое.
   Так углы остаются круглыми в любом положении скролла, а полоса прокрутки скрыта. */
.modal-card {
  position: relative;
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 48px);
  display: flex;
  background: var(--paper);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-modal);
  color: var(--text-strong);
  transform: translateY(20px) scale(.98);
  transition: transform .38s var(--ease);
}
.modal.is-open .modal-card { transform: none; }

.modal-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 34px;
  border-radius: inherit;
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* старый Edge */
}
.modal-scroll::-webkit-scrollbar { width: 0; height: 0; }

/* отступ справа — чтобы заголовок никогда не заезжал под крестик */
.modal-card h3 { font-size: 26px; letter-spacing: -0.032em; margin-bottom: 8px; padding-right: 44px; }
.modal-card .sub { font-size: 15.5px; color: var(--text-body); margin-bottom: 26px; }

/* Широкая модалка на пк — правило обязано стоять ПОСЛЕ базового .modal-card:
   медиазапрос не добавляет специфичности, решает порядок в файле. */
@media (min-width: 861px) {
  .modal-card { max-width: 720px; }
}
.modal-x {
  position: absolute;
  z-index: 2;
  top: 18px; right: 18px;
  width: 38px; height: 38px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(18, 20, 26, .06);
  color: var(--text-body);
  font-size: 17px;
  transition: background-color .2s, transform .3s var(--ease);
}
.modal-x:hover { background: rgba(18, 20, 26, .12); transform: rotate(90deg); }

/* ---------- 13. Подвал ---------- */
/* ---------- Подвал ----------
   Он того же цвета, что и самая верхняя точка страницы, и закреплён внизу
   окна ПОД остальным содержимым: светлая сцена со скруглённой нижней кромкой
   съезжает поверх него, и подвал открывается по мере прокрутки. Высоту
   меряет site.js и кладёт в --footer-h, чтобы страница заканчивалась ровно
   там, где подвал начинается. */
.footer {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 0;
  padding: 56px 0 46px;
  color: var(--on-dark-soft);
  background: var(--ink-900);
}
.footer-top {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  justify-content: space-between;
  padding-bottom: 30px;
  border-bottom: 1px solid var(--line-dark);
}
.footer .logo { color: var(--on-dark); }
.footer .logo .dot { color: var(--accent); }
.footer-brand p { font-size: 15px; margin-top: 12px; max-width: 280px; color: var(--on-dark-soft); }
.footer-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(150px, auto));
  gap: 30px 56px;
}
.footer-col h3 {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--on-dark-faint);
  margin-bottom: 12px;
}
.footer-col a {
  display: block;
  font-size: 15px;
  padding: 4px 0;
  color: var(--on-dark-soft);
  transition: color .2s;
}
.footer-col a:hover { color: var(--on-dark); }
.footer-bottom {
  padding-top: 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  justify-content: space-between;
  font-size: 14px;
  color: var(--on-dark-faint);
}

/* контакты в подвале: те же три, что и в переходной полосе, одним рядом */
.footer-contacts { display: inline-flex; flex-wrap: wrap; gap: 8px 18px; }
.footer-contacts a {
  color: var(--on-dark);
  font-weight: 600;
  border-bottom: 1px solid var(--line-dark);
  transition: color .2s, border-color .2s;
}
.footer-contacts a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- 14. Cookie-баннер ---------- */
/* Компактная плашка: белая пилюля с короткой фразой и кнопкой согласия.
   Кнопка отказа нарочно оставлена — согласие по 152-ФЗ должно быть
   осознанным и свободным, а свободного выбора без «нет» не бывает. Она
   тише по виду, но настоящая: тот же обработчик, что и раньше. */
.cookies {
  position: fixed;
  left: 16px; right: 16px; bottom: 18px;
  z-index: 80;
  width: max-content;
  max-width: calc(100% - 32px);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 10px 10px 10px 22px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 6px 18px rgba(10, 14, 30, .12), 0 18px 44px rgba(10, 14, 30, .18);
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1.4;
  transform: translateY(180%);
  transition: transform .5s var(--ease);
}
.cookies.is-on { transform: none; }

/* Пока открыто меню, баннер уезжает вниз: он лежит поверх всего (z-index 80)
   и на затемнённой странице остался бы единственным чётким пятном. */
body.menu-open .cookies.is-on { transform: translateY(180%); }

.cookies p { white-space: nowrap; }
.cookies a {
  color: var(--text-strong);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(18, 20, 26, .25);
  transition: text-decoration-color .2s;
}
.cookies a:hover { text-decoration-color: var(--brand); }

.cookies-actions { display: flex; align-items: center; gap: 6px; }
.cookies .btn { height: 40px; padding: 0 22px; font-size: 15px; }
/* Отказ — обычной строкой, чтобы не спорить с главной кнопкой, но рядом с ней. */
.cookies-no {
  height: 40px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: color .2s, background-color .2s;
}
.cookies-no:hover { color: var(--text-strong); background: rgba(18, 20, 26, .06); }

/* Узкий экран: пилюля превращается в прямоугольную карточку.
   Порог 760, а не 560: в одну строку плашка занимает около 470 px, и на
   экране уже 700 px она начинала переносить кнопки — а пилюля с двумя
   строками внутри выглядит нелепо, слишком круглые бока для такой высоты.
   Прямоугольник со скруглением как у карточек переносы держит спокойно. */
@media (max-width: 760px) {
  .cookies {
    width: auto;
    max-width: 560px;
    padding: 14px 16px 14px 20px;
    border-radius: var(--r-lg);
    font-size: 14.5px;
    justify-content: space-between;
    gap: 10px 14px;
  }
  .cookies p { white-space: normal; }
  .cookies .btn { height: 38px; padding: 0 20px; font-size: 14.5px; }
  .cookies-no { height: 38px; padding: 0 12px; font-size: 13.5px; }
}

/* Совсем узко — текст и кнопки в две строки, всё по центру. */
@media (max-width: 460px) {
  .cookies { padding: 14px 16px; }
  .cookies p { flex: 1 1 100%; text-align: center; }
  .cookies-actions { flex: 1 1 100%; justify-content: center; }
}

/* ---------- 15. Появление при скролле ---------- */
/* Прячем блоки только когда скрипт жив: без JS (или при его ошибке)
   страница обязана остаться читаемой, а не пустой. */
.js .rise {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js .rise.is-in { opacity: 1; transform: none; }
.rise-d1 { transition-delay: .07s; }
.rise-d2 { transition-delay: .14s; }
.rise-d3 { transition-delay: .21s; }

/* ---------- 16. Адаптив ---------- */
@media (max-width: 1080px) {
  .deck-card { grid-template-columns: 44% 56%; }
  .deck-face { padding: 28px 26px 26px; }
  .deck-desc { font-size: 16px; }
  .pill { height: 34px; padding: 0 13px; font-size: 14px; }
  .case-top { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 20px; }
}

@media (max-width: 860px) {
  :root { --gut: 20px; }
  .header-nav, .header-cta { display: none; }
  .burger { display: inline-flex; flex-direction: column; }

  /* Колода на телефоне: карточка вертикальная, обложка сверху,
     соседние карточки выглядывают справа. */
  .deck { --dx: 24px; --dy: 0px; --ds: .05; }
  .deck-stage {
    height: min(78vh, 620px);
    /* уводим сцену за правый отступ: карточка шире, а стопка уходит к краю экрана */
    margin: 26px calc(var(--gut) * -1) 22px 0;
  }
  .deck-card {
    inset: 0 34px 0 0;          /* справа место под выглядывающую стопку */
    grid-template-columns: 1fr;
    grid-template-rows: minmax(88px, 1fr) auto;
    transform-origin: 50% 50%;
  }
  .deck-art  { grid-column: 1; grid-row: 1; }
  .deck-face { grid-column: 1; grid-row: 2; padding: 24px 22px 26px; }
  .deck-face { justify-content: flex-start; gap: 18px; }
  .deck-name { font-size: 27px; }
  .deck-desc { font-size: 16px; }
  .deck-pills { inset: 14px 14px auto 14px; gap: 7px; }
  .pill { height: 33px; padding: 0 13px; font-size: 14px; }
  .deck-card[data-pos="past"] { transform: translate3d(-46px, 0, 0) scale(.97); }

  /* ПОЧЕМУ ЭТО ЗДЕСЬ.
     Карточки, которые ещё не вошли в стопку, ждут своей очереди на четвёртой
     позиции (--d: 3). Они прозрачные, но место в разметке занимают: сцена и
     так дотянута до правого края экрана, а четвёртая позиция уводит карточку
     ещё на ~14 px за него. Отсюда и брался горизонтальный люфт — страницу
     можно было двигать вбок, и она «съезжала». Пропадал он ровно тогда, когда
     до конца колоды оставалось меньше четырёх карточек: четвёртой позиции
     больше нет — и страница сама собой приходила в норму.
     Ставим ожидающие карточки на третью позицию (--d: 2), под ту, что уже
     видна. Видимые карточки (0, 1, 2) не сдвигаются ни на пиксель, а
     появление становится даже мягче: карточка не подъезжает, а проявляется. */
  .deck-card[data-pos="far"] {
    transform:
      translate3d(calc(var(--dx) * 2), calc(var(--dy) * 2), 0)
      scale(calc(1 - var(--ds) * 2));
  }
  .deck-dot.is-on { width: 74px; }
  .deck-controls { gap: 12px; }
  .filters { gap: 8px; }
  .filter, .dd--dark .dd-btn { height: 42px; padding: 0 16px; font-size: 14.5px; }
  .dd--dark .dd-menu { max-width: min(300px, calc(100vw - 40px)); }
  /* Первый экран занимает ровно экран и стоит по центру: человек заходит и
     видит только знак, фразу о том, чем мы занимаемся, и две кнопки. Раньше
     здесь стояло min-height: auto, герой сжимался по содержимому, и снизу
     уже лез заголовок «Наши кейсы» — начало страницы читалось как каша.
     Единица svh, а не vh: на телефоне адресная строка то появляется, то
     прячется, и vh считается по самому большому состоянию — низ блока
     оказывался под строкой. */
  .hero {
    min-height: 100svh;
    padding: 104px 0 40px;
  }
  .hero .display { margin-bottom: 22px; }
  .hero-note { display: none; }
  .work { padding: 20px 0 28px; }
  .stage-shift { height: 210px; }
  .section-head { margin-bottom: 34px; }
  .contact { padding: 28px 0 76px; }
  .contact-title { margin-bottom: 18px; }
  .form-card { padding: 26px 22px; }
  .modal-scroll { padding: 26px 22px; }
  .case-hero { padding: 44px 0 32px; }
  .case-dark { padding-bottom: 36px; }
  .case-light { padding: 36px 0 56px; }
  .case-top { grid-template-columns: 1fr; gap: 18px; }
  .case-stage { aspect-ratio: 4 / 3; }
  .case-prose { padding-bottom: 40px; }

  /* Факты свёрнуты до двух пунктов, остальное — по кнопке */
  .case-facts:not(.is-open) .fact:nth-of-type(n + 3),
  .case-facts:not(.is-open) .case-tags { display: none; }
  .case-facts:not(.is-open) .facts-list .fact:nth-of-type(2) { border-bottom: 0; }

  .facts-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding: 9px 16px;
    border-radius: var(--r-pill);
    background: rgba(18, 20, 26, .06);
    color: var(--text-strong);
    font-size: 15px;
    font-weight: 600;
    transition: background-color .2s;
  }
  .facts-toggle:hover { background: rgba(18, 20, 26, .11); }
  .facts-toggle .chev {
    width: 8px; height: 8px;
    border-right: 1.8px solid currentColor;
    border-bottom: 1.8px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .3s var(--ease);
  }
  .case-facts.is-open .facts-toggle .chev { transform: translateY(2px) rotate(-135deg); }

  /* Галерея — карусель со снапом вместо колонки */
  .gallery-grid {
    display: flex;
    grid-template-columns: none;
    gap: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-right: calc(var(--gut) * -1);
    padding-right: var(--gut);
  }
  .gallery-grid::-webkit-scrollbar { width: 0; height: 0; }
  .gallery-grid figure {
    flex: 0 0 84%;
    aspect-ratio: 4 / 3;
    scroll-snap-align: start;
  }
  .gallery-dots {
    display: flex;
    justify-content: center;
    gap: 7px;
    margin-top: 16px;
  }
  .gallery-dot {
    width: 7px; height: 7px;
    border-radius: var(--r-pill);
    background: rgba(18, 20, 26, .18);
    transition: width .35s var(--ease), background-color .25s;
  }
  .gallery-dot.is-on { width: 26px; background: rgba(18, 20, 26, .45); }

  /* плеер в узкой карточке карусели */
  .vp-bar { left: 8px; right: 8px; bottom: 8px; height: 46px; gap: 6px; padding: 0 7px; }
  .vp-btn { width: 32px; height: 32px; }
  .vp-big { width: 60px; height: 60px; margin: -30px 0 0 -30px; }
  .vp-big .vp-glyph { width: 25px; height: 25px; }
  .vp-time { font-size: 12.5px; gap: 4px; }
  .vp-sound { top: 10px; right: 10px; height: 36px; padding: 0 14px 0 11px; font-size: 13.5px; }

  .case-cta { padding: 32px 24px; }
  .footer-links { grid-template-columns: 1fr 1fr; gap: 24px; }
  /* Отступы и форма плашки куки заданы выше, в её собственных правилах для
     760 и 460 px. Здесь остаются только поля от краёв экрана. */
  .cookies { left: 12px; right: 12px; bottom: 12px; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .hero-actions .btn { width: 100%; }
  .case-actions .btn { width: 100%; }
  .form-foot .btn { width: 100%; }
  .gallery-grid { grid-template-columns: 1fr; }
}

/* ---------- 9.2. Просмотр фотографий кейса ----------
   Открывается по клику на фото в галерее. Управление своё, а не браузерное:
   разметку собирает lightboxHtml(), поведение навешивает initLightbox()
   (см. site.js). Живёт над страницей проекта, поэтому z-index выше её 90. */

/* подсказка «можно открыть» на самой плитке галереи */
.gal-photo { position: relative; cursor: zoom-in; }
.gal-photo img { transition: transform .5s var(--ease); }
.gal-photo:hover img { transform: scale(1.03); }
.gal-zoom {
  position: absolute; right: 12px; bottom: 12px;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(8, 11, 20, .55);
  color: #fff;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .28s var(--ease), transform .28s var(--ease);
  pointer-events: none;
}
.gal-zoom svg { width: 17px; height: 17px; }
.gal-photo:hover .gal-zoom, .gal-photo:focus-visible .gal-zoom { opacity: 1; transform: none; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  flex-direction: column;
  /* Подложка светлее, чем была, зато с настоящим размытием: страница за
     фотографией угадывается, но не мешает — при глухой заливке кадр
     смотрелся вырезанным из другого сайта. */
  background: rgba(12, 16, 26, .76);
  backdrop-filter: blur(20px) saturate(1.1);
  -webkit-backdrop-filter: blur(20px) saturate(1.1);
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s var(--ease-soft), visibility .3s;
  -webkit-user-select: none;
  user-select: none;
}
.lightbox.is-open { opacity: 1; visibility: visible; }

/* ── кадр ── */
/* Отступы кадра — это место под интерфейс: сверху крестик и счётчик,
   по бокам кнопки листания. Без них фотография уезжала под кнопки
   и часть её было не видно. */
.lb-stage {
  flex: 1 1 auto;
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 78px 96px 14px;
  touch-action: pan-y;
}
.lb-img {
  /* На широких экранах не растягиваем на всю доступную площадь: фотография
     во всю стену читается хуже, чем спокойный кадр по центру.
     Высоту считаем от экрана, а не в процентах: процент разрешается
     относительно площади grid, а та сама растёт под картинку — кадр
     переставал ограничиваться и залезал под ленту миниатюр.
     200px — это отступы кадра плюс лента миниатюр. */
  max-width: min(1080px, 100%);
  max-height: calc(100vh - 200px);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--r-md);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .55);
  opacity: 0;
  transition: opacity .26s var(--ease-soft), transform .26s var(--ease);
}
.lb-img.is-ready { opacity: 1; }
/* направление сдвига при перелистывании задаёт скрипт */
.lb-img.is-out-left  { opacity: 0; transform: translateX(-26px); }
.lb-img.is-out-right { opacity: 0; transform: translateX(26px); }

.lb-spin {
  position: absolute;
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, .22);
  border-top-color: #fff;
  animation: lbSpin .8s linear infinite;
  opacity: 0;
  transition: opacity .2s;
}
.lightbox.is-loading .lb-spin { opacity: 1; }
@keyframes lbSpin { to { transform: rotate(360deg); } }

/* ── кнопки ── */
.lb-btn {
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  transition: background-color .2s, transform .3s var(--ease), opacity .2s;
}
.lb-btn:hover { background: rgba(255, 255, 255, .24); }
.lb-btn svg { width: 18px; height: 18px; }

.lb-close {
  position: absolute; top: 16px; right: 18px; z-index: 3;
  width: 44px; height: 44px;
}
.lb-close:hover { transform: rotate(90deg); }

.lb-nav {
  position: absolute; top: 50%; z-index: 3;
  width: 50px; height: 50px;
  transform: translateY(-50%);
}
.lb-nav:hover { transform: translateY(-50%) scale(1.06); }
.lb-prev { left: 18px; }
.lb-next { right: 18px; }
.lb-nav[disabled] { opacity: .26; pointer-events: none; }

.lb-count {
  position: absolute; top: 22px; left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  height: 32px; padding: 0 15px;
  display: inline-flex; align-items: center;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .12);
  color: #fff;
  font-size: 14px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── лента миниатюр ── */
.lb-thumbs {
  flex: 0 0 auto;
  display: flex;
  gap: 9px;
  justify-content: center;
  padding: 12px 18px 20px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.lb-thumbs::-webkit-scrollbar { width: 0; height: 0; }
.lb-thumbs:empty { display: none; }
.lb-thumb {
  flex: 0 0 auto;
  width: 74px; height: 52px;
  padding: 0;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255, 255, 255, .08);
  opacity: .5;
  transition: opacity .22s, box-shadow .22s, transform .3s var(--ease);
}
.lb-thumb img { width: 100%; height: 100%; object-fit: cover; }
.lb-thumb:hover { opacity: .85; }
.lb-thumb.is-cur {
  opacity: 1;
  box-shadow: 0 0 0 2px var(--accent);
  transform: translateY(-2px);
}

@media (max-width: 860px) {
  .lb-stage { padding: 66px 62px 10px; }
  .lb-img { max-height: calc(100vh - 176px); }
  .lb-nav { width: 40px; height: 40px; }
  .lb-prev { left: 6px; }
  .lb-next { right: 6px; }
  .lb-close { top: 12px; right: 12px; width: 40px; height: 40px; }
  .lb-count { top: 18px; }
  .lb-thumbs { justify-content: flex-start; padding: 10px 12px 16px; }
  .lb-thumb { width: 62px; height: 44px; }
  /* на плитке галереи наводить нечем — значок открытия виден всегда */
  .lb-img { border-radius: var(--r-sm); }
}

@media (max-width: 620px) {
  /* кнопки по бокам съедали бы половину кадра — листаем свайпом и миниатюрами */
  .lb-nav { display: none; }
  .lb-stage { padding: 62px 10px 8px; }
  .lb-img { max-height: calc(100vh - 168px); }
  .gal-zoom { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .lb-img.is-out-left, .lb-img.is-out-right { transform: none; }
  .gal-photo:hover img { transform: none; }
  .lb-close:hover, .lb-nav:hover { transform: none; }
  .lb-nav:hover { transform: translateY(-50%); }
  .lb-spin { animation-duration: 2s; }
}

/* ---------- 16.4. Продвижение: «Запустили — а дальше?» ----------
   Последняя глава лежит на своей подложке во всю ширину, со скруглённой
   верхней кромкой. Подвал и блок вопросов держим того же цвета, чтобы кромка
   была одна и низ страницы читался как единое целое. */
.grow {
  position: relative;
  margin-top: 96px;
  padding: 74px 0 60px;
  background: var(--band);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
}

.grow .section-head { margin-bottom: 34px; }
.grow .section-head .lead { color: var(--text-body); }

/* ── Лента-гармошка ──
   В покое четыре карточки равной ширины, и видно только обложку с названием.
   Наведение (на телефоне — касание) разворачивает одну на всю ширину кадра:
   горизонтальное видео показывается целиком, под названием выезжает список.
   Ширину развёрнутой карточки задаёт --g: её считает site.js по настоящим
   пропорциям видео, чтобы кадр совпал с карточкой и ничего не обрезалось. */
/* Высоту ставит site.js: она выводится из пропорций самого широкого ролика,
   чтобы развёрнутая карточка уместила кадр целиком и полоскам осталось место.
   Значение в clamp() — запасное, на случай выключенного скрипта. */
.grow-strip {
  display: flex;
  gap: 12px;
  height: var(--gs-h, clamp(400px, 42vw, 520px));
  margin-bottom: 96px;
}

.gs-skeleton {
  flex: 1 1 0;
  border-radius: var(--r-lg);
  background: linear-gradient(100deg, rgba(255,255,255,.28), rgba(255,255,255,.5), rgba(255,255,255,.28));
  background-size: 300% 100%;
  animation: bw-shine 1.4s linear infinite;
}

/* Сворачивание нарочно медленнее раскрытия: раскрытие — ответ на движение
   мыши, его ждут сразу, а возврат в покой приятнее видеть неспешным. Базовое
   правило работает как раз на возврат; переход между соседними карточками
   остаётся быстрым. */
.gs-card {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--ink-700);
  box-shadow: var(--shadow-card);
  transition: flex-grow 1s var(--ease), box-shadow .5s var(--ease);
}
/* Пока одна карточка раскрыта, остальные ужимаются в полоски — как в колоде:
   внимание в один момент времени достаётся ровно одному кадру. */
.grow-strip.is-open .gs-card { flex-grow: .42; transition-duration: .62s, .4s; }
.grow-strip.is-open .gs-card.is-open { flex-grow: var(--g, 5); box-shadow: var(--shadow-lift); }

.gs-media { position: absolute; inset: 0; z-index: 0; background: var(--ink-800); }
/* Подложка и ролик лежат друг на друге: ролик появляется поверх кадра, когда
   карточку разворачивают, и кадр не мигает в момент подмены. */
.gs-media > * { position: absolute; inset: 0; }
.gs-media video,
.gs-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
  transition: object-position .62s var(--ease);
}
/* Развёрнутая карточка по ширине равна кадру, поэтому центр — это весь кадр. */
.gs-card.is-open .gs-media video,
.gs-card.is-open .gs-media img { object-position: 50% 50%; }

/* Заглушка, пока для карточки не загрузили видео */
.gs-fallback { position: absolute; inset: 0; }
.gs-card:nth-child(4n+1) .gs-fallback { background: linear-gradient(150deg, #2c3a63, #4b64ab); }
.gs-card:nth-child(4n+2) .gs-fallback { background: linear-gradient(150deg, #35335f, #6a5aa8); }
.gs-card:nth-child(4n+3) .gs-fallback { background: linear-gradient(150deg, #21454f, #3f8b98); }
.gs-card:nth-child(4n+4) .gs-fallback { background: linear-gradient(150deg, #3a2f4f, #7a5c8f); }
.gs-fallback::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--grain);
  opacity: .5;
}
/* Тот же значок, только огромный и еле заметный: без видео карточка иначе
   выглядит как кусок заливки, и непонятно, о чём она. */
.gs-fallback i {
  position: absolute;
  right: -7%; bottom: -9%;
  width: 54%;
  color: #fff;
  opacity: .11;
}
.gs-fallback svg { width: 100%; height: auto; stroke-width: 1; }

.gs-scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(10,13,22,0) 34%, rgba(10,13,22,.30) 62%, rgba(10,13,22,.78) 100%),
    linear-gradient(90deg, rgba(10,13,22,.45), rgba(10,13,22,0) 58%);
}

/* Прозрачная кнопка во всю карточку: на телефоне она раскрывает карточку
   касанием, с клавиатуры — фокусом, и она же держит aria-expanded. */
.gs-hit {
  position: absolute; inset: 0; z-index: 3;
  width: 100%; height: 100%;
  cursor: pointer;
}

/* Ширина текстового блока задана в пикселях и не меняется при анимации:
   иначе строки перевёрстывались бы на каждом кадре. Лишнее просто
   подрезается краем карточки. */
/* Название лежит в левом нижнем углу карточки, а «сверху» и «в середине» —
   это сдвиг от него; сам сдвиг проставляет site.js прямо в style, посчитав
   его по настоящим размерам. Через var() внутри transform не выйдет: Chrome
   не пересчитывает такое свойство при смене переменной, если на нём висит
   переход, — сдвиг молча остаётся нулевым. У развёрнутой карточки сдвига нет,
   и название плавно съезжает вниз, к списку. */
.gs-content {
  position: absolute;
  left: 0; bottom: 0; z-index: 2;
  padding: 26px 26px 24px;
  color: #fff;
  pointer-events: none;
  transition: transform 1s var(--ease), opacity .3s linear;
}
.gs-card.is-open .gs-content { transition-duration: .62s, .3s; }
/* Ширина по содержимому: блок с названием сам по себе становится «пятном»,
   которое можно двигать по карточке целиком (см. --tx/--ty ниже). */
.gs-head {
  display: flex;
  align-items: center;
  gap: 13px;
  width: max-content;
  max-width: 280px;
}
.gs-title {
  font-size: clamp(23px, 2.4vw, 31px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.1;
}

/* Список раскрывается ровно теми же длительностью и кривой, что и сдвиг
   названия, и без задержки. Тогда обе величины меняются по одной кривой, и
   название едет в конечную точку одним движением, а не «вниз, а потом рывком
   вверх», как было, пока у списка была своя скорость. */
.gs-panel {
  width: min(560px, 62vw);
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 1s var(--ease), opacity .35s linear;
}
.gs-panel > div { overflow: hidden; }
.gs-card.is-open .gs-panel {
  grid-template-rows: 1fr;
  opacity: 1;
  transition-duration: .62s, .3s;
}

.gs-list {
  list-style: none;
  display: grid;
  gap: 12px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, .24);
}
.gs-list li {
  position: relative;
  padding-left: 23px;
  font-size: 17.5px;
  line-height: 1.45;
  color: rgba(255, 255, 255, .9);
}
.gs-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 10px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #fff;
  opacity: .62;
}

/* Стрелка-подсказка и пилюля «Подробнее»: нужны только там, где нет
   наведения, то есть на телефоне. */
.gs-more, .gs-pill { display: none; }

/* Пока раскрыта соседняя карточка, название в полоске прячем —
   в 70 пикселях ширины от него всё равно ничего не прочитать. */
.grow-strip.is-open .gs-card:not(.is-open) .gs-content { opacity: 0; }

/* ── Бегущая строка «С чем работаем» ──
   Во всю ширину экрана, поэтому живёт вне .shell. Две строки навстречу
   друг другу: одна лента читалась бы как «уехавший» текст, две — как узор. */
.grow-marquee { margin: 0 0 96px; }
.grow-marquee-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-body);
  opacity: .72;
  text-align: center;
  margin-bottom: 16px;
}
.mq {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.mq + .mq { margin-top: 10px; }
.mq-track {
  display: flex;
  width: max-content;
  animation: mq-run var(--mq-time, 60s) linear infinite;
}
.mq--rev .mq-track { animation-direction: reverse; }
/* Навели — лента останавливается: иначе название не прочитать и не запомнить. */
.grow-marquee:hover .mq-track,
.grow-marquee:focus-within .mq-track { animation-play-state: paused; }
.mq-row { display: flex; align-items: center; gap: 10px; padding-right: 10px; list-style: none; }
@keyframes mq-run {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
@keyframes bw-shine {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}

.chip {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 18px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  color: var(--text-strong);
  background: rgba(255, 255, 255, .74);
  box-shadow: 0 1px 2px rgba(16, 20, 34, .06);
}

/* ── Полоса-призыв ── */
.grow-cta {
  padding: 34px 36px;
  border-radius: var(--r-xl);
  background: var(--paper);
  box-shadow: var(--shadow-card);
  color: var(--text-strong);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
}
.grow-cta h3 { font-size: clamp(21px, 2.4vw, 27px); letter-spacing: -0.03em; margin-bottom: 6px; }
.grow-cta p { color: var(--text-body); font-size: 15.5px; }

/* ---------- 16.45. Частые вопросы ----------
   Продолжение той же подложки: слева заголовок, справа список.
   Ответ раскрывается через grid-template-rows 0fr → 1fr — так высота
   анимируется без замеров в JS и без обрезки длинного текста. */
/* Нижняя кромка светлой части: под скруглением видно тёмное полотно
   страницы, из-под которого выезжает подвал. */
.faq {
  background: var(--band);
  padding: 36px 0 92px;
  border-radius: 0 0 var(--r-xl) var(--r-xl);
}
.faq-wrap {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.5fr);
  gap: 46px;
  align-items: start;
}
.faq-aside { position: sticky; top: 108px; }
.faq-aside .h-section { margin-bottom: 14px; }
.faq-aside .lead { color: var(--text-body); margin-bottom: 24px; }

.faq-list { display: grid; gap: 12px; }
.faq-skeleton {
  height: 74px;
  border-radius: var(--r-lg);
  background: linear-gradient(100deg, rgba(255,255,255,.34), rgba(255,255,255,.62), rgba(255,255,255,.34));
  background-size: 300% 100%;
  animation: bw-shine 1.4s linear infinite;
}

.faq-item {
  background: var(--paper);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  transition: box-shadow .3s var(--ease);
}
.faq-item.is-open { box-shadow: var(--shadow-lift); }

.faq-q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 24px;
  text-align: left;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.35;
  color: var(--text-strong);
}
.faq-sign {
  flex: none;
  position: relative;
  width: 30px; height: 30px;
  margin-top: 1px;
  border-radius: 50%;
  background: rgba(47, 107, 255, .10);
  color: var(--brand);
  transition: transform .42s var(--ease), background-color .22s, color .22s;
}
.faq-sign::before,
.faq-sign::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 12px; height: 2px;
  margin: -1px 0 0 -6px;
  border-radius: 2px;
  background: currentColor;
}
.faq-sign::after { transform: rotate(90deg); }
.faq-item.is-open .faq-sign { transform: rotate(135deg); background: var(--brand); color: #fff; }
.faq-q:hover .faq-sign { background: rgba(47, 107, 255, .18); }

.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .45s var(--ease);
}
.faq-item.is-open .faq-a { grid-template-rows: 1fr; }
.faq-a > div { overflow: hidden; }
.faq-a p {
  padding: 0 24px 22px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-body);
  max-width: 68ch;
}
.faq-a p + p { padding-top: 12px; }

@media (max-width: 1080px) {
  .grow-strip { height: var(--gs-h, clamp(360px, 46vw, 470px)); }
  .gs-head { width: 200px; }

  /* Одна колонка — и кнопка «задать вопрос» уезжает ПОД список вопросов:
     сначала человек читает готовые ответы, и только если своего вопроса там
     не нашлось — пишет нам. На широком экране кнопка остаётся в левой
     колонке, там она всё время на виду.

     Как это сделано без второго куска разметки: боковой колонке ставим
     display: contents — её собственная рамка исчезает, а заголовок, подпись и
     кнопка становятся прямыми детьми полосы и слушаются order. Отступы держим
     на margin, а не на gap: у блоков они разные. */
  .faq-wrap { display: flex; flex-direction: column; gap: 0; }
  .faq-aside { display: contents; }
  .faq-aside .h-section { order: 1; margin-bottom: 14px; }
  .faq-aside .lead { order: 2; margin-bottom: 26px; max-width: 62ch; }
  .faq-list { order: 3; }
  .faq-aside .btn { order: 4; margin-top: 26px; }
}

/* ── Узкий экран: карточки-фотографии ──
   Наведения нет, разворачивать некуда, а видео на маленьком экране только
   съедает трафик. Поэтому карточка — статичный квадрат с фотографией, имя
   сверху, внизу пилюля «Подробнее»; подробности открываются окном.
   Фотографию и её точку обрезки задают отдельно в админке (photo/photoFocus),
   а если её не загрузили — берём постер или кадр видео.

   Порог 1080, а не 900: у раскрытого складного телефона экран почти
   квадратный (около 850–970 точек в ширину), и лента-гармошка на нём не
   разворачивалась — четырём карточкам в ряд просто негде. Тот же порог, что
   у блока вопросов, чтобы «узкий экран» на всей странице означал одно и то же.
   ВАЖНО: это же число зашито в mqNarrow в site.js — менять их только вместе,
   иначе разметка будет статичной, а скрипт продолжит крутить ролики. */
@media (max-width: 1080px) {
  .grow-strip {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    height: auto;
  }
  /* Начиная с планшета и раскрытого фолда — по две в ряд: одна на всю
     ширину превращалась в квадрат на восемьсот точек. */
  @media (min-width: 620px) {
    .grow-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
  }
  .gs-skeleton { aspect-ratio: 1 / 1; }

  .gs-card {
    flex: none;
    aspect-ratio: 1 / 1;
    background: var(--ink-700);
    color: #fff;
  }
  .grow-strip.is-open .gs-card,
  .grow-strip.is-open .gs-card.is-open { flex-grow: 0; }

  .gs-media { position: absolute; inset: 0; }
  .gs-media video,
  .gs-media img { object-position: var(--focus-p, 50% 50%); }

  .gs-scrim {
    display: block;
    background:
      linear-gradient(180deg, rgba(10,13,22,.62) 0%, rgba(10,13,22,.12) 38%, rgba(10,13,22,0) 60%),
      linear-gradient(0deg, rgba(10,13,22,.55) 0%, rgba(10,13,22,0) 34%);
  }

  .gs-content {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: auto;
    padding: 22px 20px 0;
    color: #fff;
    text-align: center;
    opacity: 1 !important;
    transform: none;
  }
  .gs-head { width: 100%; max-width: none; justify-content: center; }
  .gs-title { font-size: clamp(26px, 7.4vw, 32px); }
  .gs-panel { display: none; }          /* список живёт в окне карточки */
  .gs-more { display: none; }

  .gs-pill {
    position: absolute;
    left: 20px; bottom: 20px; z-index: 2;
    display: inline-flex; align-items: center; gap: 8px;
    height: 42px; padding: 0 20px;
    border-radius: var(--r-pill);
    background: rgba(255, 255, 255, .92);
    color: var(--text-strong);
    font-size: 15px; font-weight: 600;
    box-shadow: 0 4px 16px rgba(8, 11, 20, .28);
  }
  .gs-pill .arr { transition: transform .3s var(--ease); }
  .gs-card:active .gs-pill .arr { transform: translateX(3px); }
}

/* ── Планшет и раскрытый складной телефон ──
   Экран уже широкий, но колонка всё ещё одна. Оба блока ниже на таком экране
   выглядели прижатыми к левому краю, а справа оставалась пустота. */
@media (min-width: 620px) and (max-width: 1080px) {

  /* Вопросы. Виновник прижатия — align-items: start: оно досталось полосе от
     двухколоночной сетки, а в колонке заставляет детей сжиматься по
     содержимому и липнуть к левому краю. Ставим по центру; список тянем на
     всю ширину, но не шире читаемой строки. Текст внутри карточек остаётся
     слева — вопрос по центру читался бы как лозунг. */
  .faq-wrap { align-items: center; text-align: center; }
  .faq-aside .lead { margin-inline: auto; }
  .faq-list {
    align-self: stretch;
    width: 100%;
    max-width: 760px;
    margin-inline: auto;
    text-align: left;
  }

  /* Подвал. Внутренняя сетка ссылок растворяется (display: contents), и
     «Разделы» с «Документами» становятся такими же опорами полосы, как
     логотип. Три опоры и space-between — текст расходится по всей ширине,
     а не жмётся к левому краю двумя кучками. */
  .footer-links { display: contents; }
  .footer-top { gap: 24px 32px; }
  .footer-brand { flex: 0 1 auto; }
  .footer-brand p { max-width: 240px; }
}

/* ── Окно карточки ── */
.cardm {
  position: fixed; inset: 0; z-index: 110;
  display: grid; place-items: end center;
  padding: 0;
}
.cardm-veil {
  position: absolute; inset: 0;
  background: rgba(8, 11, 20, .58);
  opacity: 0;
  transition: opacity .3s var(--ease-soft);
}
.cardm.is-open .cardm-veil { opacity: 1; }
.cardm-card {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 92vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--paper);
  color: var(--text-strong);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--shadow-modal);
  transform: translateY(100%);
  transition: transform .42s var(--ease);
}
.cardm.is-open .cardm-card { transform: none; }
.cardm-x {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: var(--text-strong);
  font-size: 15px;
  box-shadow: 0 2px 10px rgba(8, 11, 20, .2);
}
.cardm-media { position: relative; aspect-ratio: 16 / 9; background: var(--sky-100); overflow: hidden; }
.cardm-media:empty { display: none; }
.cardm-media img,
.cardm-media video { width: 100%; height: 100%; object-fit: cover; object-position: var(--focus-p, 50% 50%); }
.cardm-body { padding: 22px 24px 26px; }
.cardm-body h3 {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.035em;
  margin-bottom: 4px;
}
.cardm-list {
  list-style: none;
  display: grid;
  gap: 12px;
  margin: 18px 0 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line-light);
}
.cardm-list li {
  position: relative;
  padding-left: 23px;
  font-size: 16.5px;
  line-height: 1.45;
  color: var(--text-body);
}
.cardm-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 9px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand);
  opacity: .55;
}
@media (min-width: 560px) {
  .cardm { place-items: center; padding: 24px; }
  .cardm-card { border-radius: var(--r-xl); transform: translateY(24px) scale(.97); }
}

@media (max-width: 860px) {
  .grow { margin-top: 64px; padding: 52px 0 44px; border-radius: var(--r-lg) var(--r-lg) 0 0; }
  .grow-strip { margin-bottom: 44px; }
  .contacts-strip { gap: 8px; }
  .cs-item { height: 42px; padding: 0 16px; font-size: 14.5px; }

  .shell-wide { padding-inline: 20px; }
  .grow-cta { padding: 26px 22px; }
  .chip { height: 36px; padding: 0 15px; font-size: 14px; }
  .grow-marquee { margin-bottom: 44px; }
  .faq { padding-bottom: 64px; }
  .faq-q { padding: 18px 20px; font-size: 17px; }
  .faq-a p { padding: 0 20px 18px; font-size: 15.5px; }
}
@media (max-width: 620px) {
  .grow-cta .btn { width: 100%; }
  .faq-aside .btn { width: 100%; }

  /* Контакты на телефоне: телефон и телеграм делят строку пополам, почта —
     отдельной строкой под ними и по центру. Раскладка сеткой, а не потоком:
     иначе перенос зависел бы от длины номера, и почта то поднималась бы
     наверх, то уезжала вниз. justify-self: center оставляет почте её
     собственную ширину — на всю строку она не растягивается. */
  .contacts-strip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .cs-item { justify-content: center; padding: 0 10px; font-size: 13.5px; gap: 7px; }
  .cs-item svg { width: 16px; height: 16px; }
  .contacts-strip .cs-item:nth-child(3) {
    grid-column: 1 / -1;
    justify-self: center;
    padding: 0 18px;
  }
}

/* Меньше движения — меньше движения: лента стоит, кадры не разъезжаются. */
@media (prefers-reduced-motion: reduce) {
  .mq-track { animation: none; }
  .mq { overflow-x: auto; }
  .gs-card, .gs-media, .gs-panel, .faq-a, .faq-sign { transition-duration: .01ms; }
}

/* ---------- 16.5. Обложки на телефоне ----------
   Кадр карточки на компьютере почти квадратный, а на телефоне вытянут
   вертикально — одна точка фокуса на оба макета не годится. Поэтому
   на узких экранах берём отдельную мобильную точку, а если её не задали,
   откатываемся к обычной. */
@media (max-width: 860px) {
  .deck-art > img,
  .deck-art > .cover,
  .case-stage > * { object-position: var(--focus-m, var(--focus, 50% 50%)); }
  /* Заглушка кадрируется вместе с картинкой — см. раздел про размытую
     заглушку в начале файла. */
  .deck-art > img,
  .case-stage > img { background-position: var(--focus-m, var(--focus, 50% 50%)); }
}

/* ---------- 17. Уважение к настройкам движения ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js .rise { opacity: 1; transform: none; }
}
