/*
  Весь десктопный слой — фиксированный канвас 1440px (не тянется на всю
  ширину окна на широких мониторах и не садится дальше при её сужении
  вплоть до 1200px, где начинается адаптив). --u раньше пересчитывался из
  clientWidth в main.js (макет был нарисован на 1920 и масштабировался
  вместе с окном) — из-за этого при живом ресайзе окна шрифты и отступы
  непрерывно менялись («скакали»). Теперь --u — фиксированная константа
  1440/1920 = 0.75: те же формулы calc(N * var(--u)) держат исходные
  Figma-пропорции, но больше не зависят от ширины окна вообще.

  Внутри карточек размеры в cqw (контейнер — .case). Большинство значений
  (отступы, уголки, плюс, блок подробностей) считаны от исходной карточки
  Figma 503.33px (10 из 12 колонок при 1920) — их проценты друг к другу от
  этого не меняются, даже когда сама карточка потом стала уже. У
  card__cat/card__title/card__year база другая — 448px (карточка при текущей
  ширине блока кейсов, см. .cases__page: 1440px, минус паддинги и зазоры
  сетки, / 3), потому что для них указан конкретный размер в px и стоило
  посчитать точно, а не «примерно как раньше».

  Адаптив — в конце файла: 1200px (планшет) и 768px (телефон).
*/
:root {
  /* Фиксированная константа — см. комментарий выше. Не трогать через JS. */
  --u: 0.75px;
  --page-max: 1440px;
  --pad: 40px;
  --radius: 12px;

  /* Левый край 1-й колонки, правый край 5-й и правый край 12-й (последней)
     — чтобы меню и контакты (position: fixed, вне потока hero) могли
     встать вровень с сеткой в обоих своих положениях, стартовом и
     пристыкованном. Значения меряет main.js (syncGridAlign) по фактическому
     hero, а не
     пересчитывает параллельной формулой в CSS: у hero ширина — не всегда
     ровно --page-max (на десктопе почти всегда есть вертикальный
     скроллбар, а он не везде одинаково учитывается в 100vw), плюс сама
     раскладка 1fr-колонок в CSS Grid округляет дробные пиксели по-своему —
     проще один раз измерить реальный отрендеренный hero, чем пытаться
     угадать то же число в CSS. 0px по умолчанию — если JS ещё не успел
     отработать. */
  --grid-left: 0px;
  --col5-right: 0px;
  --col12-right: 0px;
  /* Панель навигации ниже десктопа: её высота и зазор до контента —
     hero резервирует их снизу, футер тоже, иначе панель накроет ссылки. */
  --nav-h: 48px;
  --nav-gap: 16px;

  --bg: #ebebeb;
  --ink: #111;
  --muted: #6a7282;
  --line: #c5c5c5;

  --purple: #6e5cd2;
  --purple-dark: #5b4ac0;
  --danger: #d6453f;
  /* Диаметр «выросшей» точки-курсора и ореола вокруг неё (К на скетче) —
     общий размер, до которого дорастает и точка при наведении, и стартовый
     кружок подсказки (.tip__label), чтобы переход между ними был незаметен. */
  --cursor-k: 40px;
  /* Размер точки (СП) в покое — общий с .cursor-halo.is-small: на обычных
     кликабельных элементах (ссылки, кнопки) ореол сжимается ровно до него. */
  --cursor-dot: 16px;

  --font: "Geist", system-ui, sans-serif;

  --ease: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* Затемнение фона .dim — единственный источник времени для этой пары:
     подложка ряда (.row-frame) появляется в тот же момент, что и
     затемнение, и пропадает только когда затемнение полностью погасло. */
  --dim-duration: 0.3s;
  --dim-delay: 0.12s;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  /* Ниже этого ширина уже не сжимается — но и не упирается в 320, иначе на
     узких экранах с классическим скроллбаром появляется лишний горизонтальный */
  min-width: 300px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

/* Скроллбар страницы. Прокручивается корневой элемент, а не body, поэтому
   псевдоэлементы — на html. scrollbar-color только там, где нет
   ::-webkit-scrollbar (Firefox): в Chrome он перебил бы кастомную форму. */
html {
  --sb-track-color: var(--bg);
  --sb-thumb-color: var(--purple);
  --sb-size: 10px;
}
html::-webkit-scrollbar { width: var(--sb-size); }
html::-webkit-scrollbar-track {
  background: var(--sb-track-color);
  border-radius: 4px;
}
html::-webkit-scrollbar-thumb {
  background: var(--sb-thumb-color);
  border: 3px solid var(--sb-track-color);
  border-radius: 4px;
}
@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-color: var(--sb-thumb-color) var(--sb-track-color); }
}

/* Системный курсор скрыт везде, где может появиться точка (.cursor-dot) —
   те же условия, что и у OWN_CURSOR в main.js (десктоп + мышь как основной
   указатель), продублированные тут ради простоты (без JS-переключаемого
   класса на body). !important перебивает cursor: pointer у ссылок/кнопок
   и cursor: default у неактивных пунктов меню. */
@media (min-width: 1200px) and (hover: hover) and (pointer: fine) {
  html.has-pointer * { cursor: none !important; }
}

img { display: block; max-width: 100%; }
p, h1, h2, h3 { margin: 0; }
a { color: inherit; text-decoration: none; }
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* ---------- Меню и контакты ---------- */

.menu,
.contacts {
  position: fixed;
  top: var(--pad);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 20px;
  height: 48px;
  padding: 0 24px;
  background: #fff;
  border-radius: 8px;
}

.menu {
  /* Левый край — вровень с началом 1-й колонки hero, а не просто с краем
     окна: на мониторах шире --page-max у hero есть свой боковой отступ
     (margin: 0 auto), и без --grid-left меню осталось бы у истинного
     края экрана, левее самой сетки. */
  left: var(--grid-left);
  /* Размер и трекинг — под arturospatino.com/work: у их навигации 17px и
     letter-spacing: normal, никакого дополнительного сжатия. */
  font-size: 17px;
  line-height: 1.1;
  letter-spacing: normal;
  color: var(--ink);
}
.menu a { transition: opacity 0.2s; }
.menu__short { display: none; }
.menu a:hover { opacity: 0.55; }
/* «Крафт»: пункт из макета, но раздела пока нет — показан неактивным */
.menu__soon { color: var(--muted); cursor: default; }

/* Стартует у правого края 5-й колонки hero и на скролле уезжает в правый
   верхний угол — тот же приём, что раньше был у меню, только теперь у
   контактов и в другую сторону. left:0 + translateX вместо left/right,
   чтобы был один плавный transform, а не скачок между свойствами; 100% в
   translateX — собственная ширина контактов (авто), так что выравнивается
   именно правый край блока, а не левый. */
.contacts {
  left: 0;
  right: auto;
  transform: translateX(calc(var(--col5-right) - 100%));
}
.contacts.is-ready { transition: transform 0.6s var(--ease); }
/* Правым краем вровень с правым краем 12-й (последней) колонки — тот же
   приём и та же переменная-геометрия, что и у стартовой позиции, а не
   100vw: на мониторах шире --page-max контакты раньше уезжали к истинному
   краю окна, а не к краю сетки. */
.contacts.is-docked { transform: translateX(calc(var(--col12-right) - 100%)); }

.contacts__btn { width: 24px; height: 24px; transition: opacity 0.2s; }
.contacts__btn:hover { opacity: 0.55; }
.contacts__btn img { width: 24px; height: 24px; }

/* ---------- NDA: окно пароля и деталка ---------- */

[hidden] { display: none !important; }

.gate {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pad);
  background: rgba(17, 17, 17, 0.45);
}


.gate__panel {
  display: flex;
  gap: 8px;
  padding: 24px;
  background: #fff;
  border-radius: 12px;
}

.gate__input {
  width: 280px;
  max-width: 100%;
  height: 48px;
  padding: 0 16px;
  font: inherit;
  font-size: 17px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  outline: none;
}
.gate__input:focus { border-color: var(--purple); }
.gate__input.is-error { border-color: var(--danger); }

.gate__submit {
  flex-shrink: 0;
  height: 48px;
  padding: 0 24px;
  font-size: 17px;
  color: #fff;
  background: var(--purple);
  border-radius: 8px;
  transition: background-color 0.2s;
}
.gate__submit:hover { background: var(--purple-dark); }
.gate__submit:disabled { opacity: 0.5; }
.gate__panel { flex-wrap: wrap; }
.gate__error {
  flex-basis: 100%;
  font-size: 15px;
  line-height: 1.3;
  color: var(--danger);
}

@media (max-width: 479px) {
  .gate__panel { flex-direction: column; width: 100%; }
  .gate__input { width: 100%; }
}

/* ---------- Тост о копировании ---------- */

.toast {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 1;
  padding: 10px 14px;
  background: var(--ink);
  color: #fff;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.2s, transform 0.3s var(--ease-out);
}
.toast.is-on { opacity: 1; transform: none; }

/* ---------- Hero ---------- */

/* Канвас всей десктопной вёрстки — 1440px по центру (см. --page-max),
   а не во всю ширину окна: на мониторах шире 1440 раньше 12-колоночная
   сетка и всё, что от неё зависит, бесконечно растягивались. */
.hero {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--pad);
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--pad);
}

/* Имя строкой и обёртка меню нужны только ниже десктопа */
.hero__name { display: none; }
.hero__nav { display: contents; }

/* Текст — колонки 1–4, фото — 6–7 (5-я колонка пустует под контакты) */
.hero__intro {
  grid-column: 1 / span 4;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: calc(50 * var(--u));
}

/* Высота — экран минус 80px (на десктопе), кадр режется по ширине колонок */
.hero__photo {
  grid-column: 6 / span 7;
  width: 100%;
  height: calc(100vh - 80px);
  height: calc(100dvh - 80px);
  object-fit: cover;
  border-radius: var(--radius);
}

/* Заголовок подтянут к типографике arturospatino.com/work: там заголовочный
   текст — не жирный (400), крупный, с плотным трекингом (-2.56px при 64px
   ≈ -4%), а не полужирный с почти нулевым сжатием, как было у нас. */
.hero__heading {
  font-size: 64px;
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.04em;
  color: var(--ink);
}
.hero__tag { color: var(--muted); }

.hero__lead {
  /* Фиксированный размер по умолчанию, не завязан на --u */
  font-size: 20px;
  line-height: 1.4;
  letter-spacing: normal;
  color: var(--muted);
}

/* ---------- Логотипы ---------- */

/* Та же ширина канваса, что и у hero (см. --page-max) — раньше лого шли
   во всю ширину окна отдельно от остального, поэтому на широких мониторах
   ряд был непропорционально просторным по сравнению с остальной страницей.
   Отступа сверху нет: зазор до фото — нижний отступ hero плюс воздух ячейки
   над лого (~61px на 1440 при высоте блока 130u ≈ 98px). */
/* Без разделителей: крайние лого прижаты к краям контента (по --pad, как
   hero), промежутки между лого одинаковые. */
.logos {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: var(--page-max);
  height: calc(130 * var(--u));
  margin: 0 auto;
  padding: 0 var(--pad);
}

.logos__cell {
  flex: none;
  display: flex;
  align-items: center;
}

/* Оптическая компенсация: у каждого лого своя высота — 53px × --k (в
   разметке). --k подобран по площади лого с поправкой на плотность
   заливки: плотный Halyk меньше, FAO и Минэк с мелким текстом чуть больше,
   чтобы все четыре читались одного «веса». --w/--h — только пропорции. */
.logos__cell img {
  width: calc(53px * var(--k) * var(--w) / var(--h));
  height: auto;
  aspect-ratio: var(--w) / var(--h);
}

/* Обёртки нужны только для бесконечной прокрутки ниже 1200px (см. адаптив
   внизу файла): на десктопе они прозрачны для раскладки, .logos__cell
   остаются прямыми flex-детьми .logos, как без обёрток. Дублирующий трек
   на десктопе не показываем вовсе. */
.logos__marquee,
.logos__track { display: contents; }
.logos__track[aria-hidden] { display: none; }

@keyframes logos-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- Сетка проектов ---------- */

.cases {
  margin-top: calc(110 * var(--u));
  scroll-margin-top: 108px;
}

.cases__page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--pad);
}

.grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

/* .case — ячейка сетки и контейнер для cqw, .card внутри — сама обложка */
/* z-index снимается с той же задержкой, что и подложка/затемнение (--dim-
   duration + --dim-delay) — тем же приёмом «0s transition + delay», что
   у .row-frame ниже. Раньше это снятие делал JS через setTimeout с
   отдельно прописанным числом (ROW_RELEASE_MS) — тот же интервал, но
   другой, менее точный таймер: JS-таймер мог сработать на кадр раньше
   или позже CSS-transition, и на этот кадр карточки оставались приподняты
   над уже погасшей подложкой — читалось как мигание ряда. Теперь источник
   времени один — сам CSS, а JS просто снимает класс сразу же. */
.case {
  position: relative;
  z-index: 0;
  display: block;
  container-type: inline-size;
  transition: z-index 0s linear calc(var(--dim-duration) + var(--dim-delay));
}
/* Ряд под наведением — над затемнением, поднимается без задержки */
.case.in-row {
  z-index: 52;
  transition: z-index 0s linear 0s;
}

.card {
  position: relative;
  aspect-ratio: 503.33 / 700;
  overflow: hidden;
  border-radius: var(--radius);
  color: #fff;
}

/* Подложка ряда цвета фона страницы: абсолютный элемент сетки, растянутый на весь ряд.
   Появление и исчезновение синхронизированы с затемнением фона (.dim ниже):
   подложка начинает проявляться в тот же момент, что и затемнение (обе — без
   задержки), а прячется только после того, как затемнение полностью погасло —
   transition на снятие is-on выдержан ту же паузу, что и весь цикл гашения
   .dim (--dim-duration + --dim-delay), и лишь затем мгновенно скрывает подложку.
   Резкое переключение между разными рядами (см. dropRow в main.js) обходит
   эту паузу через inline-style. */
.row-frame {
  position: absolute;
  inset: -8px;
  z-index: 51;
  background: var(--bg);
  border-radius: var(--radius);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0s linear calc(var(--dim-duration) + var(--dim-delay));
}
.row-frame.is-on {
  opacity: 1;
  transition: opacity 0.25s ease 0s;
}

.dim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: #111;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dim-duration) ease var(--dim-delay);
}
body.is-dim .dim { opacity: 0.4; transition-delay: 0s; }

/* Подменные обложки соседних карточек */
.swap {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}
.swap img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.swap img.is-on { opacity: 1; }

/* ---------- Карточка ---------- */

.card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card__shade::before,
.card__shade::after {
  content: "";
  position: absolute;
  inset: 0;
  mix-blend-mode: multiply;
}
.card__shade::before { background: linear-gradient(rgba(93, 33, 49, 0) 40%, rgba(93, 33, 49, 0.6)); }
.card__shade::after { background: linear-gradient(rgba(93, 33, 49, 0.6), rgba(93, 33, 49, 0) 43.269%); }

.card__cat {
  position: absolute;
  top: 5.1656cqw;
  right: 5.9603cqw;
  left: 5.9603cqw;
  font-size: 8.9286cqw;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  text-align: right;
}

.card__year {
  position: absolute;
  top: 18.2782cqw;
  right: 5.9603cqw;
  font-size: 4.4643cqw;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

/* Лежит рядом с .card, поэтому на десктопе позиционируется от .case —
   у неё та же геометрия, ведь заголовок выключен из потока */
.card__title {
  position: absolute;
  right: 5.9603cqw;
  bottom: 6.7549cqw;
  left: 5.9603cqw;
  font-size: 8.9286cqw;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: #fff;
}

/* Блок подробностей: 384×504 в карточке 600×875 */
.card__details {
  position: absolute;
  top: 21.2%;
  left: 18%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 64%;
  height: 57.6%;
  padding: 4.7682cqw;
  background: #fff;
  border-radius: 4px;
  color: var(--ink);
  pointer-events: none;
  opacity: 0;
  transform: translateY(2.384cqw);
  transition: opacity 0.25s ease, transform 0.4s var(--ease-out);
}
.case.is-active .card__details,
.case--new:focus-within .card__details {
  pointer-events: auto;
  opacity: 1;
  transform: none;
}

.card__desc {
  font-size: max(14px, 3.9735cqw);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

/* ---------- Курсор: точка (СП) + отстающий ореол (К) вместо системного ---------- */

/* Системный курсор скрыт целиком (см. ниже). Вместо него — два круга:
   К (.cursor-halo) — крупный полупрозрачный, всегда чуть отстаёт от
   курсора (transition на transform, в отличие от точки — её transform
   не анимирован, поэтому она идёт вплотную к курсору без задержки; тот же
   рассинхрон, что на arturospatino.com/work). СП (.cursor-dot) — маленькая
   точка в покое, растущая до размера К при наведении (--cursor-k, общий
   диаметр для обеих фигур). Если у области есть подсказка, точка не ждёт,
   пока дорастёт, а сразу гаснет — на её месте параллельно раздаётся .tip,
   стартующий тем же кружком --cursor-k и растущий дальше в ширину под
   текст (см. showTip() в main.js). Оба круга — в mix-blend-mode:
   exclusion, поэтому белая заливка сама становится тёмной на светлом фоне
   страницы и светлой на тёмных обложках/фиолетовом new.prj, без ручного
   подбора цвета под каждый фон. */
.cursor-layer {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  mix-blend-mode: exclusion;
  opacity: 0;
  transition: opacity 0.15s;
}
.cursor-layer.is-on { opacity: 1; }

/* transition — на базовом классе (см. тот же приём у .cursor-dot ниже):
   opacity без задержки, важно для скрытия точкой саму себя не тут, а её
   ПОЯВЛЕНИЯ при выходе из tip-стадии — ореол должен появиться сразу же,
   без задержки. Задержку на прятанье при входе в tip-стадию добавляет
   .is-tip. width/height/margin — для сжатия до размера точки на обычных
   кликабельных элементах (.is-small). */
.cursor-halo {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--cursor-k);
  height: var(--cursor-k);
  margin: calc(var(--cursor-k) / -2) 0 0 calc(var(--cursor-k) / -2);
  border-radius: 50%;
  background: #fff;
  opacity: 0.35;
  transition: transform 0.35s var(--ease-out), opacity 0.15s, width 0.2s var(--ease-out), height 0.2s var(--ease-out), margin 0.2s var(--ease-out);
}
/* В момент, когда точка становится подсказкой, прячем и ореол — иначе он
   какое-то время виден рядом (сам ореол не привязан к точке, у него свой
   отстающий transform) и получается лишняя фигура сбоку от тултипа. Без
   задержки — t3 стартует сразу по входу в область, не дожидаясь, пока
   точка успеет дорасти (см. комментарий у .cursor-dot ниже). */
.cursor-halo.is-tip {
  opacity: 0;
  transition: transform 0.35s var(--ease-out), opacity 0.15s;
}
/* Обычные кликабельные элементы без подсказки (меню, ссылки, кнопки
   копирования) — ореол не прячется, а сжимается ровно до размера точки
   (--cursor-dot), сигналя «здесь можно кликнуть» без полноценного tip. */
.cursor-halo.is-small {
  width: var(--cursor-dot);
  height: var(--cursor-dot);
  margin: calc(var(--cursor-dot) / -2) 0 0 calc(var(--cursor-dot) / -2);
}

/* transition — на базовом классе, один и тот же список для любого
   направления: рост/сжатие всегда 0.2s, а опасити без задержки — это
   важно именно для СКРЫТИЯ (is-tip снят → точка тут же проступает обратно,
   без задержки). Попадая в область с подсказкой, .is-hover и .is-tip
   ставятся одновременно (см. showTip() в main.js) — точка не ждёт, пока
   сама дорастёт до --cursor-k (это и была стадия t2), а сразу начинает
   гаснуть, пока подсказка уже параллельно раздаётся у неё поверх (t3
   стартует сразу, t2 просто пропускается). */
.cursor-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--cursor-dot);
  height: var(--cursor-dot);
  margin: calc(var(--cursor-dot) / -2) 0 0 calc(var(--cursor-dot) / -2);
  border-radius: 50%;
  background: #fff;
  transition: width 0.2s var(--ease-out), height 0.2s var(--ease-out), margin 0.2s var(--ease-out), opacity 0.15s;
}
.cursor-dot.is-hover {
  width: var(--cursor-k);
  height: var(--cursor-k);
  margin: calc(var(--cursor-k) / -2) 0 0 calc(var(--cursor-k) / -2);
}
.cursor-dot.is-tip { opacity: 0; }

/* Подсказка появляется на месте точки — не рядом с курсором, а вместо
   него: стартует тем же кружком --cursor-k, что и точка в покое (тот же
   центр, тот же размер), и сразу же раздаётся в ширину под текст, не
   дожидаясь точки. Ширину меряет и анимирует showTip()/hideTip() в main.js. */
.tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 90;
  pointer-events: none;
}
.tip__label {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  width: var(--cursor-k);
  height: var(--cursor-k);
  padding: 0 24px;
  background: var(--ink);
  color: #fff;
  border-radius: calc(var(--cursor-k) / 2);
  font-size: 18px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  opacity: 0;
  transition: width 0.15s var(--ease-out), opacity 0.15s;
}
/* Стартует сразу по входу в область, параллельно с точкой (см. .cursor-dot
   выше) — без ожидания, пока точка сама дорастёт до --cursor-k. */
.tip.is-on .tip__label {
  opacity: 1;
  transition: width 0.22s var(--ease-out), opacity 0.15s;
}
/* NDA у проектов под соглашением о неразглашении — красная карточка
   вместо обычной тёмной с «Открыть проект» */
.tip--nda .tip__label { background: var(--danger); }

/* ---------- Карточка «new.prj» ---------- */

.case--new .card { background: var(--purple); }
.case--new .card__details { justify-content: space-between; }

/* Уголки: в покое у краёв карточки, при наведении обрамляют блок подробностей */
.corner {
  position: absolute;
  width: 3.3775cqw;
  height: 3.3775cqw;
  transition: transform 0.5s var(--ease);
}
.corner img { width: 100%; height: 100%; }
.corner--tl { top: 5.1656cqw; left: 5.9603cqw; }
.corner--tl img { transform: scaleY(-1); }
.corner--bl { bottom: 5.9603cqw; left: 5.9603cqw; }
.corner--br { right: 5.9603cqw; bottom: 5.9603cqw; }
.corner--br img { transform: scaleX(-1); }

/* Уголок сдвигается к подробностям в 2 шага: сперва ровно до касания угла
   подложки (расстояние минус размер самого уголка), а затем ещё на 16px
   (3.5714cqw при базе 448 — карточка при текущей ширине блока кейсов, см.
   верх файла) назад, чтобы между уголком и подложкой остался зазор. */
.case.is-active .corner--tl { transform: translate(5.0911cqw, 17.3711cqw); }
.case.is-active .corner--bl { transform: translate(5.0911cqw, -16.5711cqw); }
.case.is-active .corner--br { transform: translate(-5.0911cqw, -16.5711cqw); }

.plus {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6.7549cqw;
  height: 6.7549cqw;
  transform: translate(-50%, -50%);
  transition: opacity 0.25s, transform 0.4s var(--ease);
}
.case.is-active .plus { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }

.new-actions {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1.9868cqw;
}

.copy-btn {
  display: inline-flex;
  align-items: center;
  gap: 1.5894cqw;
  height: 8.7418cqw;
  padding: 0 3.9735cqw;
  border: 1px solid var(--purple);
  border-radius: 1.5894cqw;
  font-size: 3.1788cqw;
  line-height: 1.1;
  letter-spacing: -0.02em;
  white-space: nowrap;
  transition: background-color 0.2s, border-color 0.2s;
}
.copy-btn img { width: 3.1788cqw; height: 3.1788cqw; }

.copy-btn--fill { background: var(--purple); color: #fff; }
.copy-btn--fill:hover { background: var(--purple-dark); border-color: var(--purple-dark); }
.copy-btn--line { color: var(--purple); }
.copy-btn--line:hover { background: rgba(110, 92, 210, 0.08); }

/* Кнопка «Показать ещё» — только на телефоне, включает её main.js */
.cases__more {
  display: none;
  margin: 32px auto 0;
  height: 48px;
  padding: 0 24px;
  background: #fff;
  border-radius: 8px;
  font-size: 16px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.cases__more.is-on { display: block; }

/* ---------- Футер ---------- */

/* Фон — та же живописная картинка, что и в макете, с фиолетовым градиентом
   поверх (soft-light, как в Figma) вместо сплошной заливки. */
.footer {
  margin-top: calc(110 * var(--u));
  background-image: linear-gradient(to bottom, var(--purple), #21165e), url("assets/footer-bg.png");
  background-blend-mode: soft-light;
  background-size: cover;
  background-position: center 60%;
  color: #fff;
}

.footer__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: calc(70 * var(--u)) var(--pad);
}

/* Размер и трекинг — под их же служебный текст (17px, letter-spacing:
   normal), а не отдельный увеличенный масштаб с -0.01em, как было раньше */
.footer__about {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: normal;
  text-align: right;
  white-space: nowrap;
}
.footer__about a { text-decoration: underline; text-underline-offset: 2px; }

.footer__mark {
  width: calc(300 * var(--u));
  height: auto;
  flex-shrink: 0;
}

.footer__links {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: normal;
}

.footer__about a,
.footer__links a { transition: opacity 0.2s; }
.footer__about a:hover,
.footer__links a:hover { opacity: 0.7; }

/* ==========================================================================
   Страница кейса (case.html)

   Ширины тут другие, чем на главной: обложка и лента карточек занимают весь
   канвас минус --pad (1360px), а текстовые блоки — колонку 1126px по центру
   (в макете это x=157..1283). Внутри этой колонки два столбца, 426 и 660
   с зазором 40 — те же, что у шагов, поэтому заголовки блоков и подписи
   шагов стоят на одной вертикали.
   ========================================================================== */

.cs-block {
  display: grid;
  grid-template-columns: 426fr 660fr;
  gap: 40px;
  width: min(1126px, 100% - var(--pad) * 2);
  margin: 120px auto 0;
}

.cs-block__head {
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.36px;
  color: #111;
}

/* Зазор между абзацами — 1.6em, то есть ровно одна пустая строка того же
   кегля: в макете абзацы разделены именно пустой строкой, а не отступом. */
.cs-block__body {
  display: flex;
  flex-direction: column;
  gap: 1.6em;
  font-size: 20px;
  line-height: 1.6;
  letter-spacing: -0.4px;
  color: var(--muted);
}

/* ---------- Первый экран кейса ---------- */

/* В макете кадр нарисован на 764px, но это просто «сколько было на экране
   у дизайнера» — здесь высота настоящая (100dvh), фиксированы только
   отступы, а обложка добирает весь остаток между меню и подписью.
   119px сверху — 40 (отступ меню) + 48 (его высота) + 31 (зазор до обложки). */
.cs-hero {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 119px var(--pad) var(--pad);
}

/* Базис 0, а не auto: иначе flex взял бы за основу натуральную высоту
   картинки (она заметно выше экрана) и hero растянулся бы под неё вместо
   того, чтобы остаться ровно в экран, — кадр режется по центру. */
.cs-hero__cover {
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Заголовок и описание под обложкой выровнены по нижней линии */
.cs-hero__foot {
  display: grid;
  grid-template-columns: 543fr 777fr;
  align-items: end;
  gap: 40px;
  margin-top: 29px;
}

.cs-hero__title {
  font-size: 48px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.72px;
}

.cs-hero__lead {
  font-size: 20px;
  line-height: 1.6;
  letter-spacing: -0.4px;
  color: var(--muted);
}

/* ---------- Пошаговая анимация ---------- */

/* Секция высокая — экран плюс по --step-scroll прокрутки на каждый шаг, —
   а сцена внутри неё залипает на весь экран. За счёт этого прокрутка внутри
   секции не двигает сцену, а перелистывает шаги: в кадре всегда ровно один
   .step, как в макетах «Работа шагов, 1» и «Работа шагов, 2». Индекс
   активного шага и --steps (число шагов) проставляет main.js по разметке —
   в CSS ничего вручную синхронизировать не нужно. */
.steps {
  --steps: 1;
  --step-scroll: 70vh;
  height: calc(100vh + var(--steps) * var(--step-scroll));
  margin-top: 120px;
}

.steps__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--pad);
}

.steps__grid {
  position: relative;
  width: min(1126px, 100%);
  height: 100%;
  margin: 0 auto;
}

/* Каждый шаг — самостоятельный слайд на всю сцену: текст прижат к низу левой
   колонки (align-items: end), картинка растянута на всю правую. Все слайды
   лежат друг на друге, видимый — только с .is-on. */
.step {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 426fr 660fr;
  gap: 40px;
  align-items: end;
  opacity: 0;
  transition: opacity 0.45s var(--ease-out);
}
.step.is-on { opacity: 1; }

/* Картинка только проявляется, оставаясь на месте, а текст ещё и чуть
   подъезжает снизу — иначе смена шага читается как подмена кадра целиком */
.step__text {
  display: flex;
  flex-direction: column;
  gap: 20px;
  transform: translateY(14px);
  transition: transform 0.45s var(--ease-out);
}
.step.is-on .step__text { transform: none; }
/* У первого шага подпись заодно и заголовок секции — отсюда крупный кегль */
.step--lead .step__text { gap: 32px; }

.step__head {
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.3px;
}
.step--lead .step__head {
  font-size: 32px;
  letter-spacing: -0.48px;
}

.step__body {
  font-size: 20px;
  line-height: 1.6;
  letter-spacing: -0.4px;
  color: var(--muted);
}

/* min-height: 0 обязателен: у элемента сетки автоминимум по высоте — это его
   собственная пропорция от заданной ширины, и вертикальный кадр (например,
   800×1315 при колонке 660) требовал бы 1085px. Ряд разъезжался под картинку,
   и она вылезала за экран вместо того, чтобы обрезаться по сцене. */
.step__img {
  align-self: stretch;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Индикатор — в правом нижнем углу канваса, вне контентной колонки 1126
   (в макете он вровень с --pad, а не с текстом). Активная пилюля
   вытягивается, остальные остаются контурными точками. */
.steps__dots {
  position: absolute;
  right: var(--pad);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.steps__dot {
  width: 24px;
  height: 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  transition: height 0.35s var(--ease-out), background-color 0.35s var(--ease-out);
}
.steps__dot.is-on {
  height: 44px;
  background: var(--line);
}

/* ---------- Сравнение «до / после» ---------- */

.compare {
  width: min(1126px, 100% - var(--pad) * 2);
  margin: 60px auto 0;
}

.compare__switch {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  font-size: 24px;
  line-height: 1;
  letter-spacing: -0.36px;
}

.switch {
  position: relative;
  flex-shrink: 0;
  width: 54px;
  height: 24px;
  background: rgba(17, 17, 17, 0.1);
  border-radius: 100px;
  transition: background-color 0.25s var(--ease-out);
}
.switch[aria-checked="true"] { background: var(--purple); }

/* Ползунок — белая таблетка 32×20, как в компоненте Toggles - Switches из макета */
.switch__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 32px;
  height: 20px;
  background: #fff;
  border-radius: 100px;
  box-shadow: 0 3px 36px rgba(17, 17, 17, 0.05);
  transition: transform 0.25s var(--ease-out);
}
.switch[aria-checked="true"] .switch__knob { transform: translateX(18px); }

.compare__frame {
  position: relative;
  margin-top: 32px;
  aspect-ratio: 1126 / 600;
  overflow: hidden;
  border-radius: var(--radius);
}

.compare__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.35s var(--ease-out);
}
.compare__img.is-on { opacity: 1; }

/* Пустое место под картинку — те же серые заглушки, что нарисованы в макете.
   Ставится вместо <img> с тем же классом слота (.cs-hero__cover, .step__img,
   .compare__img), пока кадра ещё нет, и подписывается тем, что в него нужно
   положить. На опубликованной странице таких быть не должно. */
.ph {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  background: #d9d9d9;
  border-radius: var(--radius);
  font-size: 20px;
  line-height: 1.6;
  letter-spacing: -0.4px;
  color: var(--muted);
  text-align: center;
}

/* На главной лента карточек и футер отбиты от предыдущего блока по --u,
   в кейсе между всеми блоками ровно 120px — отсюда переопределение */
.page-case .cases,
.page-case .footer { margin-top: 120px; }

/* ---------- Деталка NDA-кейса: новые блоки ---------- */

.cs-hero__cover-wrap {
  display: flex;
  flex: 1 1 0;
  min-height: 240px;
}
.cs-hero__cover-wrap .cs-hero__cover { flex: 1 1 0; height: 100%; min-height: 0; }

/* Блоки кейса: сплошной текст без приглушения — у «Результата», «Ограничений» и отзывов в макете цвет #111 */
.cs-block--solid .cs-block__body { opacity: 1; }

.hypo {
  width: min(1126px, 100% - var(--pad) * 2);
  margin: 120px auto 0;
  padding: 24px 32px 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: #fff;
  border-radius: var(--radius);
}
.hypo__label { font-size: 20px; line-height: 1.6; letter-spacing: -0.4px; color: var(--muted); }
.hypo__text { font-size: 20px; line-height: 1.6; letter-spacing: -0.4px; color: #111; }

/* Шаги исследования: слева текст, справа визуал (схема или таблица уровней) */
.steps--split .step { grid-template-columns: 426fr 660fr; }

/* Конкурентный анализ: фиксированная карточка 600px, сверху текст, снизу вендоры — высота не меняется от строк состояния */
.steps--wide .step { display: flex; align-items: center; justify-content: center; }
.steps--wide .steps__grid { width: min(1126px, 100%); }
.steps--wide .step__card {
  width: 100%;
  height: 600px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 24px 32px 32px;
  background: #fff;
  border-radius: var(--radius);
}
.steps--wide .step__top { display: flex; flex-direction: column; gap: 24px; }
.steps--wide .step__body b { font-weight: 500; color: var(--ink); }

.vendors {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 40px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.4px;
  color: #111;
}
.vendors li { transition: opacity 0.3s var(--ease-out); }
.s2 .vendors li[data-till="1"],
.s3 .vendors li[data-till="1"], .s3 .vendors li[data-till="2"],
.s4 .vendors li[data-till="1"], .s4 .vendors li[data-till="2"], .s4 .vendors li[data-till="3"] {
  opacity: 0.2;
}

/* Частоты уровней — внутри визуальной колонки второго шага */
.levels {
  padding: 32px;
  background: #fff;
  border-radius: var(--radius);
}
.levels__caption { font-size: 20px; line-height: 1.2; letter-spacing: -0.3px; color: #111; }
.levels__examples + .levels__chart { margin-top: 32px; }
.levels__chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; padding: 0; list-style: none; }
.levels__chips li {
  padding: 8px 16px;
  font-size: 17px;
  color: #111;
  border: 1px solid var(--line);
  border-radius: 999px;
}
.bar {
  display: grid;
  grid-template-columns: 120px 1fr 56px;
  align-items: center;
  gap: 16px;
  margin-top: 16px;
  font-size: 17px;
  color: #111;
}
.bar i { position: relative; height: 8px; background: #d9d9d9; border-radius: 4px; }
.bar i::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--v);
  background: var(--ink);
  border-radius: 4px;
}
.bar b { font-weight: 500; text-align: right; }

/* Сектор › Ряд › Стеллаж › Ячейка — текстовые слова; клик затемняет только нажатое */
.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 24px;
  font-size: 20px;
  letter-spacing: -0.4px;
  color: #111;
}
.chip { transition: opacity 0.2s; }
.chip.is-dim { opacity: 0.2; }
.chips__sep { color: var(--muted); }

/* Скриншоты конкурентов: подпись проявляется при наведении на десктопе */
.gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  width: min(1126px, 100% - var(--pad) * 2);
  margin: 120px auto 0;
}
.gallery__item { position: relative; margin: 0; overflow: hidden; background: #d9d9d9; border-radius: var(--radius); }
.gallery__item--wide { grid-column: 1 / -1; }
.gallery__item img { display: block; width: 100%; height: auto; }
.gallery__item .ph { aspect-ratio: 16 / 10; border-radius: 0; }
.gallery__item--wide .ph { aspect-ratio: 1126 / 600; }
.gallery figcaption {
  position: absolute;
  top: 16px;
  left: 16px;
  padding: 8px 12px;
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  border-radius: 8px;
  opacity: 0;
  transition: opacity 0.2s;
}
@media (min-width: 1200px) and (any-hover: hover) and (any-pointer: fine) {
  .gallery__item:hover figcaption { opacity: 1; }
}

/* Практики: слева лид, справа нумерованный список с линиями между строками */
.cs-block__lead {
  font-size: 20px;
  line-height: 1.6;
  letter-spacing: -0.4px;
  color: var(--muted);
}
.practices { margin: 0; padding: 0; list-style: none; }
.practices li {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.practices__num { flex: none; width: 28px; font-size: 16px; line-height: 1.5; color: var(--muted); }
.practices__text { font-size: 20px; line-height: 1.2; letter-spacing: -0.4px; color: #111; }

/* Фигуры во всю колонку канваса: скриншоты и схема */
.cs-figure {
  display: block;
  width: min(1126px, 100% - var(--pad) * 2);
  height: auto;
  margin: 120px auto 0;
  border-radius: var(--radius);
}
.cs-figure.ph { aspect-ratio: 1126 / 600; }
/* Скругление у figure — картинка внутри обрезается по нему, иначе углы острые */
.cs-figure { overflow: hidden; }
.cs-figure img { display: block; width: 100%; height: auto; }

/* Отзывы: слева заголовок и респонденты, справа два столбца */
.feedback__head { font-size: 20px; line-height: 1; letter-spacing: -0.3px; color: #111; }
.feedback__who { margin-top: 12px; font-size: 16px; line-height: 1.2; color: var(--muted); }
.feedback__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
.feedback__title { font-size: 16px; line-height: 1.2; color: var(--muted); }
.feedback ul { margin: 0; padding: 0; list-style: none; }
.feedback li {
  padding: 12px 0 12px 40px;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -0.36px;
  color: #111;
  border-top: 1px solid var(--line);
}

/* Результат: переключатель над картинкой, сдвинут к центру колонки */
.compare {
  width: min(1126px, 100% - var(--pad) * 2);
  margin: 120px auto 0;
}
.compare__switch { padding-left: 433px; justify-content: flex-start; }

/* ==========================================================================
   Планшет и телефон (< 1200px)

   Ниже десктопа ховеров нет вообще (main.js не включает наведение), поэтому
   ряд, затемнение, подсказка у курсора и подменные обложки тут не участвуют.
   Карточка упрощается до «обложка + заголовок под ней», как в мобильном
   макете, а меню с контактами встают в поток под фото.
   ========================================================================== */

@media (max-width: 1199px) {
  :root { --pad: 32px; }

  .dim,
  .tip,
  .cursor-layer,
  .row-frame,
  .case--ghost { display: none !important; }

  /* ---- Hero: одна колонка на весь экран ---- */

  /* Hero занимает ровно высоту вьюпорта, фото добирает весь остаток: сколько
     бы ни было текста сверху, нижний край фото всегда над панелью навигации.
     dvh — чтобы на телефоне не считалась высота под убирающейся адресной
     строкой; vh оставлен запасным для браузеров без dvh. */
  .hero {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 28px var(--pad) calc(var(--nav-h) + var(--nav-gap) + var(--pad));
  }

  /* Тот же бренд-лейбл, что и у них в шапке: 17px/500 и line-height 1 —
     без нашего прежнего 1.1 и лишнего сжатия трекинга. */
  /* Имени над заголовком на мобиле нет — оно в панели как «ЕЛ» */
  .hero__intro { gap: 24px; }

  /* Заголовок — их md-размер (64px), раз планшет по ширине уже попадает в
     их «десктопную» зону; трекинг и межстрочный — оттуда же (см. комментарий
     у десктопного .hero__heading выше). */
  .hero__heading {
    font-size: 64px;
    font-weight: 400;
    line-height: 1.05;
    letter-spacing: -0.04em;
  }

  .hero__lead {
    font-size: 17px;
    line-height: 1.4;
    letter-spacing: normal;
    max-width: 640px;
  }

  /* Пропорции не задаём — высоту даёт остаток hero, кадр режется по центру.
     min-height страхует короткие экраны (ландшафт): фото не схлопнется,
     страница просто станет чуть выше вьюпорта. */
  .hero__photo {
    flex: 1 1 0;
    min-height: 240px;
    margin-top: 32px;
    aspect-ratio: auto;
  }

  /* Меню и контакты остаются внизу экрана при скролле всей страницы */
  .hero__nav {
    position: fixed;
    z-index: 60;
    right: var(--pad);
    bottom: var(--pad);
    left: var(--pad);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  .menu,
  .contacts {
    position: static;
    transform: none;
    font-size: 17px;
    letter-spacing: normal;
    gap: 24px;
  }
  .contacts { gap: 20px; }
  .contacts.is-ready { transition: none; }
  /* Имя вынесено отдельной строкой наверх, в меню его дублировать не нужно.
     На главной вместо него — «ЕЛ»: та же ссылка наверх страницы. */
  .menu a:first-child:not(.menu__home) { display: none; }
  .menu__full { display: none; }
  .menu__short { display: inline; font-weight: 500; }
  /* Раздела «Крафт» пока нет — в мобильной панели его не показываем */
  .menu__soon { display: none; }

  /* ---- Логотипы: бесконечная горизонтальная прокрутка ---- */

  /* Фото занимает весь экран, поэтому лого идут сразу под ним: margin-top
     гасит зарезервированный под неподвижную навигацию отступ hero (см.
     --nav-h/--nav-gap/--pad там) и оставляет только явный зазор в 24px —
     без этого между фото и лого была бы пустая полоса высотой с саму панель.
     Видимость при этом не завязана на пересечение с вьюпортом (секция и так
     почти в нём с самого начала) — .is-in вешает main.js по проценту
     скролла, тем же приёмом, что и докинг контактов. */
  .logos {
    height: auto;
    margin-top: calc(-1 * (var(--nav-h) + var(--nav-gap) + var(--pad)) + 24px);
    padding: 0;
    overflow: hidden;
  }

  .logos.is-fade {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.45s ease, transform 0.45s var(--ease-out);
  }
  .logos.is-fade.is-in {
    opacity: 1;
    transform: none;
  }

  /* Два одинаковых трека подряд + анимация ровно на половину общей ширины —
     то есть на ширину одного трека — дают бесшовный цикл без JS-перерасчётов. */
  .logos__marquee {
    display: flex;
    flex: 0 0 auto;
    width: max-content;
    animation: logos-marquee 24s linear infinite;
  }
  @media (prefers-reduced-motion: reduce) {
    .logos__marquee { animation: none; }
  }

  .logos__track {
    display: flex;
    flex: 0 0 auto;
  }
  .logos__track[aria-hidden] { display: flex; }

  .logos__cell {
    flex: 0 0 auto;
    padding: 12px 20px;
    border-left: 0;
  }

  .logos__cell img {
    width: auto;
    height: calc(clamp(30px, 6.3vw, 46px) * var(--k));
  }

  /* ---- Кейсы: 2 колонки, заголовок под обложкой ---- */

  .cases {
    margin-top: 48px;
    scroll-margin-top: 16px;
  }

  .cases__page {
    max-width: none;
    padding: 0 var(--pad);
  }

  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 40px 24px;
  }

  .case {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  /* Обложки проектов вытянуты вертикально, а не альбомно, как раньше */
  .card { aspect-ratio: 3 / 4; }

  /* На обложке проекта ничего не пишем — только заголовок под ней */
  .case--project .card__cat,
  .case--project .card__year,
  .case--project .card__details { display: none; }

  /* Подпись под обложкой — та же типографика, что у карточек их работ:
     17px/500, свободнее строка, без сжатия трекинга */
  .card__title {
    position: static;
    font-size: 17px;
    font-weight: 500;
    line-height: 1.6;
    letter-spacing: normal;
    color: var(--ink);
  }

  /* ---- new.prj: ховера нет, поэтому содержимое показано сразу ---- */

  /* Фиолетовая карточка отступает от края ячейки — видна светлая рамка
     фона страницы вокруг неё, а не заливка в край. */
  .case--new { padding: 12px; }

  /* Уголки стоят по краям блока, а текст отбит от них паддингом:
     12 (отступ уголка) + 17 (его размер) + 7 = 36 сверху и снизу */
  .case--new .card {
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 36px 24px;
    min-height: 100%;
  }

  .case--new .plus { display: none; }

  /* Только верхний левый уголок — нижние убраны, чтобы не спорить с
     кнопками копирования внизу карточки */
  .case--new .corner--bl,
  .case--new .corner--br { display: none; }

  .case--new .corner {
    width: 17px;
    height: 17px;
    transition: none;
  }
  .case--new .corner--tl { top: 12px; left: 12px; }

  /* «new.prj 2026» — в правый верхний угол блока, а не к левому краю:
     оба текстовых элемента full-width внутри flex-колонки .card, так что
     text-align: right ставит их вплотную к правому краю */
  .case--new .card__cat {
    position: static;
    font-size: 32px;
    line-height: 1.1;
    letter-spacing: -0.02em;
    text-align: right;
  }
  /* Год — служебная мелочь, снизил до их размера подписи (14px) */
  .case--new .card__year {
    position: static;
    margin-top: -16px;
    font-size: 14px;
    text-align: right;
    opacity: 0.7;
  }

  .case--new .card__details {
    position: static;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 20px;
    width: auto;
    height: auto;
    margin-top: auto;
    padding: 0;
    background: none;
    color: #fff;
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }

  .case--new .card__desc {
    font-size: 16px;
    font-weight: 400;
    line-height: 1.6;
  }

  .new-actions {
    align-items: stretch;
    gap: 12px;
  }

  /* На фиолетовом фоне кнопки инвертируются: белая заливка и белый контур.
     Иконку берём фоном, чтобы поменять её цвет местами с десктопной. */
  .copy-btn {
    justify-content: center;
    height: 48px;
    padding: 0 20px;
    gap: 8px;
    border-radius: 8px;
    font-size: 16px;
  }
  .copy-btn img { display: none; }
  .copy-btn::after {
    content: "";
    width: 16px;
    height: 16px;
    background: no-repeat center / contain;
  }
  .copy-btn--fill {
    background: #fff;
    border-color: #fff;
    color: var(--purple);
  }
  .copy-btn--fill::after { background-image: url("assets/ic-copy-purple.svg"); }
  .copy-btn--line {
    color: #fff;
    border-color: rgba(255, 255, 255, 0.5);
  }
  .copy-btn--line::after { background-image: url("assets/ic-copy-white.svg"); }

  .toast { font-size: 14px; }

  /* ---- Футер: одна колонка по центру ---- */

  .footer { margin-top: 48px; }

  /* Снизу оставляем место под закреплённую панель навигации */
  .footer__inner {
    flex-direction: column;
    gap: 24px;
    padding: 40px var(--pad) calc(40px + var(--nav-h) + var(--nav-gap));
  }

  .footer__mark {
    order: -1;
    width: min(300px, 72%);
  }

  /* Тот же размер служебного текста, что и в остальных местах (17px) —
     раньше здесь был отдельный уменьшенный масштаб под мобильный макет */
  .footer__about {
    align-items: center;
    gap: 6px;
    font-size: 17px;
    text-align: center;
  }

  .footer__links {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px 20px;
    font-size: 17px;
  }

  /* ---- Страница кейса: одна колонка, без пошаговой анимации ---- */

  /* Двухколоночные блоки схлопываются: заголовок встаёт над текстом */
  .cs-block,
  .cs-hero__foot {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .cs-block {
    width: auto;
    margin: 80px var(--pad) 0;
  }

  .cs-hero {
    padding: 28px var(--pad) calc(var(--nav-h) + var(--nav-gap) + var(--pad));
  }
  .cs-hero__cover { min-height: 240px; }
  .cs-hero__title {
    font-size: 36px;
    font-weight: 400;
    line-height: 1.05;
    letter-spacing: -0.04em;
  }
  .cs-hero__lead {
    padding-top: 0;
    font-size: 17px;
    line-height: 1.6;
    letter-spacing: normal;
  }

  /* Шаги остаются залипающими и на телефоне: смена текста при прокрутке — это
     содержание, а не ховер. Сцена встаёт на весь экран, текст сверху,
     картинка под ним, индикатор остаётся справа внизу. */
  .steps { margin-top: 80px; }
  .steps__stage {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    padding: 0 var(--pad);
  }
  .steps__grid { width: auto; height: 100%; }
  .step {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 24px;
  }
  .step__text { transform: none; }
  .step--lead .step__head { font-size: 28px; }
  .step__img {
    flex: none;
    height: 36dvh;
    min-height: 0;
    margin-top: 0;
  }
  .steps--wide .step__card { padding: 24px; }
  .steps--wide .vendors { font-size: 15px; gap: 6px 16px; }
  .steps__dots { top: var(--pad); right: var(--pad); bottom: auto; transform: none; flex-direction: row; }

  /* Клика по словам на телефоне нет (см. initCaseWidgets) */
  .chip { pointer-events: none; }

  .hypo { margin-top: 80px; padding: 24px; }
  .gallery { grid-template-columns: 1fr; margin-top: 80px; }
  .gallery figcaption { opacity: 1; }
  .cs-figure { margin-top: 48px; }
  .feedback__cols { grid-template-columns: 1fr; gap: 32px; }
  .steps--wide .step__card { height: 80dvh; padding: 20px; }
  .steps--wide .step__body { font-size: 17px; line-height: 1.6; }
  .steps--wide .step__top { gap: 16px; }
  .steps--wide .vendors { font-size: 16px; gap: 8px 16px; }
  .compare__switch { padding-left: 0; justify-content: center; }

  .compare {
    width: auto;
    margin: 40px var(--pad) 0;
  }
  .compare__switch { font-size: 17px; gap: 12px; }

  .page-case .cases { margin-top: 80px; }
  .page-case .footer { margin-top: 48px; }
}

/* ==========================================================================
   Телефон (< 768px) — размеры по мобильному макету
   ========================================================================== */

@media (max-width: 767px) {
  :root { --pad: 16px; }

  /* Их единственная «мобильная» точка типографики — 36px (у нас раньше
     было 32); line-height/трекинг наследуются от планшетного блока выше */
  .hero__heading {
    font-size: 36px;
    max-width: min(260px, 100%);
  }

  /* .hero__lead и .card__title дальше в этом блоке не переопределяем —
     у них тот же размер (17px), что и на планшете: в отличие от нашего
     прежнего масштаба, у arturospatino.com/work служебный текст не мельчает
     на телефоне */

  .hero__nav { gap: 12px; }
  .menu { gap: 20px; min-width: 0; }
  .menu,
  .contacts { padding: 0 20px; }

  .cases { margin-top: 40px; }

  /* Одна колонка, первыми показываем три карточки (см. .cases__more) */
  .grid { grid-template-columns: 1fr; gap: 40px; }
  .grid.is-collapsed > .case:nth-child(n + 4) { display: none; }

  .case--new .card { gap: 16px; padding: 36px 20px; }
  .case--new .card__cat { font-size: 28px; }

  /* Снизу — место под закреплённую панель навигации, как и на планшете */
  .footer__inner { padding: 32px var(--pad) calc(32px + var(--nav-h) + var(--nav-gap)); }

  .cs-block { margin-top: 48px; }
  .steps { margin-top: 48px; }
  .page-case .cases { margin-top: 48px; }
}

/* ---------- NDA-деталка: доводка ---------- */

/* Прямая ссылка на кейс без пароля: только окно, без фона страницы */
body.gate-only main,
body.gate-only footer { display: none; }
body.gate-only .gate { background: transparent; }

/* Визуал шага — фиксированные 740px, и у схемы, и у таблицы уровней */
/* Визуал 740px по центру сцены; низ текста — вровень с низом визуала */
.steps--split .step { align-content: center; }
.steps--split .step__img,
.steps--split .levels { height: min(740px, 100vh - 80px); align-self: stretch; }
.steps--split .levels { box-sizing: border-box; }

/* Конкурентный анализ: новый текст сразу поверх старого, без фейда */
.steps--wide .step { transition: none; }
.vendors li { transition: none; }
.steps--wide .step__head { font-size: 32px; line-height: 1; letter-spacing: -0.48px; }


.gallery figcaption { background: #111; color: #fff; }

@media (max-width: 1199px) {
  .cs-block__body,
  .step__body,
  .hypo__text,
  .cs-block__lead,
  .feedback li,
  .practices__text { font-size: 17px; line-height: 1.6; }

  .steps--split .step__img { height: 36dvh; }
  .steps--split .levels { height: auto; padding: 16px; }
  .levels__chips li { font-size: 15px; }
  .bar { grid-template-columns: 88px 1fr 40px; gap: 12px; margin-top: 12px; font-size: 15px; }

  .steps--wide .step__card { height: 80dvh; }

  .practices { display: grid; grid-template-columns: 1fr 1fr; column-gap: 12px; }
  .practices li { display: block; }
  .practices__num { display: none; }
}

@media (max-width: 1199px) {
  .steps--split .step { align-content: normal; }
  .steps__dots { gap: 6px; }
  .steps__dot { width: 16px; height: 12px; border-radius: 6px; }
  .steps__dot.is-on { width: 32px; height: 12px; }
}

/* Конкурентный анализ: сцена облегает карточку и залипает по центру экрана —
   так после последнего шага картинки идут сразу за карточкой, без пустого
   места от центровки внутри сцены высотой в экран. */
.steps--wide {
  --card-h: 600px;
  height: calc(var(--card-h) + var(--steps) * var(--step-scroll));
}
.steps--wide .steps__stage {
  top: calc(50vh - var(--card-h) / 2);
  height: var(--card-h);
  padding-block: 0;
}
.steps--wide .steps__grid { height: 100%; }
.steps--wide .step__card { height: 100%; }
.gallery { margin-top: 16px; }

@media (max-width: 1199px) {
  .steps--wide { --card-h: 80dvh; }
  .steps--wide .steps__stage { top: 10dvh; }
  .steps--wide .steps__dots { top: -24px; }
  .gallery { margin-top: 16px; }
}

/* ==========================================================================
   Страницы кейсов — правила по макету кейса Autoretail (Figma 1149:1904), общие для всех кейсов
   ========================================================================== */

/* Заголовок первого шага исследования оформлен как заголовок раздела
   (.cs-block__head) — Regular 24, #111; текст — сплошной #111 */
.page-case .steps--split .step--lead .step__head {
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.36px;
  color: #111;
}
.page-case .cs-block__body { gap: 20px; }
.page-case .cs-hero__lead { color: var(--muted); opacity: 1; }
.page-case .cs-hero + .cs-block { margin-top: 120px; }
.page-case .cs-hero__cover { object-fit: cover; }

/* Шаги исследования: текст #111, у первого шага два абзаца */
.page-case .steps--split .step__body { color: #111; opacity: 1; }
.page-case .steps--split .step--lead .step__text { gap: 32px; }
.page-case .steps--split .step--lead .step__body + .step__body { margin-top: -4px; }

/* Сектор › Ряд › Стеллаж › Ячейка — Medium 20, шеврон из макета */
.page-case .chips {
  gap: 6px;
  align-items: center;
  margin-bottom: 0;
  font-weight: 500;
  letter-spacing: -0.3px;
  line-height: 1;
}
.page-case .chips__sep {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: var(--line);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.page-case .steps--split .step:not(.step--lead) .step__text { gap: 20px; }

/* Визуал первого шага: примеры названий и частота уровней на белой карточке */
.page-case .levels {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 40px;
}
.page-case .levels__caption {
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.3px;
  color: #111;
}
.page-case .levels__examples + .levels__chart { margin-top: 0; }
.page-case .levels__names {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.4px;
  color: var(--muted);
  white-space: pre;
}
.page-case .levels__rows { margin-top: 24px; }
.page-case .bar {
  grid-template-columns: 120px 1fr 48px;
  gap: 16px;
  margin-top: 0;
  padding: 12px 0;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.4px;
  border-top: 1px solid var(--line);
}
.page-case .bar:first-child { border-top: 0; }
.page-case .bar span { color: var(--muted); }
.page-case .bar i { background: var(--line); }
.page-case .bar i::before { background: #111; }
.page-case .bar b {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-weight: 400;
  color: #111;
}
.page-case .bar--minor i::before { background: var(--muted); }
.page-case .bar--minor b { color: var(--muted); }

/* Визуал второго шага — готовая карточка стеллажа из макета */
.page-case .step__img--card {
  height: min(740px, 100vh - 80px);
  object-fit: cover;
  object-position: top;
  background: #fff;
}

/* Конкурентный анализ: карточка с отступами 40, заголовок 40, вендоры в три колонки */
.page-case .steps--wide .step__card { padding: 40px; }
.page-case .steps--wide .step__head {
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.6px;
  color: #111;
}
.page-case .steps--wide .step__body { color: var(--muted); opacity: 1; }
.page-case .steps--wide .step__body b { color: #111; }
.page-case .vendors { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Практики: серый лид слева, справа две колонки с линиями, без номеров */
.page-case .cs-block__lead { color: var(--muted); }
.page-case .practices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 16px;
}
.page-case .practices li {
  display: block;
  padding: 12px 0;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.4px;
  color: #111;
  border-top: 1px solid var(--line);
}
.page-case .practices li:nth-child(-n + 2) { border-top: 0; }
.page-case .practices__num { display: none; }

/* Схема процесса шире колонки: стоит по сетке, тянется мышью влево-вправо */
.page-case .drag-scroll {
  width: min(1126px, 100% - var(--pad) * 2);
  height: 800px;
  margin: 120px auto 0;
  overflow-x: auto;
  overflow-y: hidden;
  background: #3c3c3c;
  border-radius: var(--radius);
  scrollbar-width: none;
  user-select: none;
  -webkit-user-select: none;
}
.page-case .drag-scroll::-webkit-scrollbar { display: none; }
.page-case .drag-scroll img {
  display: block;
  width: auto;
  max-width: none;
  height: 100%;
  pointer-events: none;
}
/* Подсказка «тяни» (класс ставит main.js только на десктопе): картинка
   один раз уезжает влево на 20px и возвращается */
.page-case .drag-scroll.is-nudge img {
  animation: drag-nudge 1.2s cubic-bezier(0.65, 0, 0.35, 1);
}
@keyframes drag-nudge {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(-20px); }
}
@media (prefers-reduced-motion: reduce) {
  .page-case .drag-scroll.is-nudge img { animation: none; }
}

/* Ограничения: список с фиолетовыми метками, затем абзац через 45px */
.page-case .limits {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.page-case .limits li { display: flex; gap: 13px; }
.page-case .limits li::before {
  content: "";
  flex: none;
  width: 22px;
  height: 12px;
  margin-top: 8px;
  background: var(--purple);
  border-radius: 19px;
}
.page-case .limits__after { margin-top: 25px; }

/* Отзывы: метка респондента — 22×12, половинки, если сказали оба */
.page-case .who {
  display: inline-block;
  flex: none;
  width: 22px;
  height: 12px;
  border-radius: 19px;
}
.page-case .who--1 { background: #3060ff; }
.page-case .who--2 { background: #ff5117; }
.page-case .who--both { background: linear-gradient(90deg, #3060ff 50%, #ff5117 50%); }
.page-case .feedback__legend { display: flex; flex-direction: column; gap: 24px; }
.page-case .feedback__who {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -0.36px;
  color: #111;
}
.page-case .feedback__who li { display: flex; align-items: center; gap: 8px; padding: 0; border: 0; }
.page-case .feedback__title { margin-bottom: 12px; }
.page-case .feedback__cols li {
  display: flex;
  gap: 12px;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}
.page-case .feedback__cols li .who { margin-top: 5.5px; }

@media (max-width: 1199px) {
  .page-case .cs-hero + .cs-block { margin-top: 80px; }
  .page-case .steps--split .step--lead .step__text { gap: 16px; }

  .page-case .levels { padding: 16px; justify-content: flex-start; gap: 16px; }
  .page-case .levels__names { flex-direction: row; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; font-size: 15px; }
  .page-case .levels__rows { margin-top: 8px; }
  .page-case .bar { grid-template-columns: 76px 1fr 40px; gap: 10px; padding: 6px 0; font-size: 14px; }
  .page-case .step__img--card { height: 36dvh; }

  .page-case .steps--wide .step__card { padding: 20px; }
  .page-case .steps--wide .step__head { font-size: 28px; }
  .page-case .vendors { grid-template-columns: repeat(2, minmax(0, 1fr)); }


  .page-case .practices { column-gap: 12px; }
  .page-case .practices li { font-size: 17px; line-height: 1.6; }

  .page-case .drag-scroll { width: auto; height: 320px; margin: 48px var(--pad) 0; }

  .page-case .limits li { font-size: 17px; }
  .page-case .limits li::before { margin-top: 6px; }
  .page-case .feedback__who { font-size: 17px; }
  .page-case .feedback__cols li { font-size: 17px; }
  .page-case .feedback__cols li .who { margin-top: 6px; }
}
