﻿/* =============================================================
   НЕ КАК ВСЕ — public site
   Graffiti energy, but the loud bits are rationed: one accent
   gesture per screenful, everything else stays near-black.
   ============================================================= */

/* ---- Page backdrop -----------------------------------------
   В макете фон — квадрат во всю ширину страницы, размноженный по
   вертикали: в содержимом PDF он нарисован дважды с шагом ровно в
   ширину страницы. Повторяем так же, одним слоем на весь документ,
   поэтому фон не привязан к границам блоков и стыков между ними нет.

   Плитка — картинка плюс её зеркало: у исходного квадрата верхний и
   нижний края не совпадают (расхождение до 241 из 255), и при обычном
   повторе на каждом стыке была бы видна горизонтальная линия.
   У зеркальной пары верх совпадает с низом, шва нет нигде.

   Краска в плитке лежит двумя сгустками с пустотой между ними:
   период рисунка — половина плитки, и каждый второй экран попадал
   ровно в пустую полосу. Поэтому слоёв два, второй сдвинут на
   четверть плитки — его сгустки приходятся на пустоты первого.
   Сгустки нигде не накладываются друг на друга, так что плотность
   на любом экране такая же, как на первом.

   Второй слой отзеркален по горизонтали: иначе одни и те же кляксы
   читались бы как явный повтор.

   Прозрачность 37% снята с макета. Под кляксами чистый чёрный —
   никаких подцветок поверх. */
body { position: relative; }

body::before,
body::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url('../img/bg/splatter-tile.webp') top center / 100% auto repeat-y;
  opacity: .37;
  pointer-events: none;
}

/* Сдвиг подобран перебором: при нём ни один экран не остаётся
   пустым и ни на одном краска не удваивается. */
body::after {
  background-position: center -65vw;
  transform: scaleX(-1);
}

main { position: relative; z-index: var(--z-content); }

/* =============================================================
   Header
   ============================================================= */

/*
 * Шапка прилипает целиком — вместе с полосой над ней: обе строки
 * лежат внутри .site-header, поэтому отдельного прилипания полосе
 * не нужно.
 *
 * Прячется полоса сдвигом точки прилипания, а не высотой. Высота
 * поменяла бы поток: страница стала бы на 145 px короче прямо во
 * время прокрутки и дёрнулась бы под курсором, а сторожок уехал бы
 * обратно в окно — полоса замигала бы. Сдвиг top поток не трогает:
 * блок просто прилипает выше, и полоса уходит за край экрана.
 */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--header-bg);
  transition: top var(--t-med) var(--ease);
}

.is-topbar-off .site-header { top: calc(-1 * var(--topbar-h)); }

/* Сторожок: пустая метка в самом верху страницы, до шапки
   (см. watchTopbar в site.js). Ушла выше окна — значит страницу
   тронули с места, и полоса прячется. Отрицательное нижнее поле
   гасит её собственную высоту, чтобы вёрстка не сдвинулась. */
.chrome-sentinel {
  display: block;
  width: 100%;
  height: 1px;
  margin-bottom: -1px;
  pointer-events: none;
}

/* =============================================================
   Полоса над шапкой

   Макет «Шапка_шапка» (1920 × 145): логотип на жёлтой краске слева,
   телефон с подписью и почта — справа. Фон #121212, как в макете.
   ============================================================= */

.site-topbar {
  display: none;
  height: var(--topbar-h);
  background: #121212;
  overflow: hidden;
}

/* Полоса выровнена по той же сетке, что и контент страницы: её
   контейнер шире остального на 3,75 % ширины экрана с каждой
   стороны (83,5 % против 76 %), это поле и возвращаем. */
.site-topbar__row {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  height: 100%;
  padding-inline: min(3.75%, 71px);
}

/*
 * Логотип в полосе.
 *
 * Раньше это была жёлтая краска-спрей с чёрным знаком поверх, и
 * их приходилось подгонять друг к другу вручную: файлы разные, и
 * подпись «ивент-компания» сползала с пятна. Теперь в полосе
 * стоит цветной знак целиком, одним файлом, — подгонять нечего.
 *
 * Высота 90 % полосы: знак заполняет её почти целиком, оставляя
 * воздух сверху и снизу. Левый край выровнен по контенту
 * страницы — это поле строки, см. .site-topbar__row.
 */
.topbar-logo {
  flex: none;
  align-self: center;
  display: block;
  height: 90%;
}

.topbar-logo__mark {
  display: block;
  height: 100%;
  width: auto;
}

.site-topbar__contacts {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.6vw, 50px);
}

.topbar-contact {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.354vw, 26px);               /* 26 по макету */
  color: var(--text);
  transition: color var(--t-fast) var(--ease);
}

/* Кружок с обводкой — 64 на 1920 по макету. */
.topbar-contact__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: clamp(38px, 3.33vw, 64px);
  aspect-ratio: 1;
  border: 2px solid var(--yellow);
  border-radius: 50%;
  color: var(--yellow);
  transition: background var(--t-fast) var(--ease);
}
.topbar-contact__icon svg { display: block; width: 48%; height: auto; }

.topbar-contact__body { display: grid; gap: .25em; }

.topbar-contact__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(15px, 1.5625vw, 30px);        /* 30 на 1920 */
  line-height: 1.15;
  white-space: nowrap;
}

.topbar-contact__note {
  font-size: clamp(10px, .781vw, 15px);          /* 15 на 1920 */
  line-height: 1.2;
  color: var(--text-3);
  white-space: nowrap;
}

.topbar-contact:hover { color: var(--yellow); }
.topbar-contact:hover .topbar-contact__icon { background: rgba(254, 251, 5, .12); }
.topbar-contact:hover .topbar-contact__note { color: var(--text-3); }

.site-topbar__sep {
  flex: none;
  width: 1px;
  height: clamp(32px, 3.9vw, 75px);
  background: var(--line-2);
}

/* Полоса появляется там же, где раскрывается меню: ниже этого порога
   шапка живёт логотипом и бургером, и вторая строка ей только мешает. */
@media (min-width: 1040px) {
  /* Полоса подросла со 113 до 150 ради логотипа: знак должен
     заполнять пустоту слева, а его ширина жёстко связана с
     высотой пропорцией файла. Кегли телефона и почты от этого
     не зависят — они заданы отдельно и остались прежними. */
  :root { --topbar-h: clamp(88px, 7.813vw, 150px); }   /* 150 на 1920 */
  .site-topbar { display: block; }
}

.site-header__row {
  position: relative;                            /* для логотипа, см. ниже */
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--header-h);
  padding-block: 0;
}

.site-logo { flex: none; display: flex; align-items: center; }
.site-logo img { height: 48px; width: auto; }

/* Меню стоит по центру промежутка между логотипом и кнопкой. */
.site-nav {
  display: none;
  align-items: center;
  gap: 45px;              /* по макету */
  margin-inline: auto;
}

.site-nav a {
  position: relative;
  font-family: var(--font-display);   /* Unbounded Bold 14 по макету */
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--text);
  padding-block: 6px;
  transition: color var(--t-fast) var(--ease);
}

.site-nav a::after {
  content: '';
  position: absolute;
  left: 0; right: 100%;
  bottom: 0;
  height: 3px;
  background: var(--yellow);
  transform: skewX(-20deg);
  transition: right var(--t-med) var(--ease);
}

.site-nav a:hover,
.site-nav a[aria-current='page'] { color: var(--yellow); }
.site-nav a:hover::after,
.site-nav a[aria-current='page']::after { right: 0; }

.header-cta {
  flex: none;
  display: none;
  min-height: 46px;
  min-width: 230px;        /* 230×46 по макету */
  padding-inline: 22px;
  font-size: 13px;
  gap: 6px;
}

.menu-toggle {
  margin-left: auto;
  display: inline-grid;
  place-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--ink-1);
}
.menu-toggle span {
  display: block;
  width: 18px; height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.menu-toggle[aria-expanded='true'] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded='true'] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav {
  display: grid;
  gap: var(--sp-2);
  padding-bottom: var(--sp-4);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav a {
  padding: .85rem 1rem;
  border-radius: var(--r-md);
  background: var(--ink-1);
  border: 1px solid var(--line);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-2);
}
.mobile-nav a:hover { color: var(--text); border-color: var(--line-accent); }

@media (min-width: 1040px) {
  .site-nav    { display: flex; }
  .header-cta  { display: inline-flex; }
  .menu-toggle { display: none; }
  .mobile-nav-wrap { display: none; }

  /*
   * Логотип в строке с меню показывается только после того, как
   * полоса свернулась: пока она висит сверху, знак уже там, и
   * дублировать его незачем.
   *
   * Из потока он вынут нарочно. Появись он строкой, пункты меню
   * сдвинулись бы вправо — а они должны стоять на месте. Абсолютный
   * знак на сетку строки не влияет вовсе.
   *
   * Проявляется, а не выезжает: меняются только прозрачность и
   * едва заметный масштаб, никакого сдвига по месту. visibility с
   * задержкой нужна, чтобы спрятанный знак не ловил курсор.
   */
  .site-logo {
    position: absolute;
    /* Вровень с контентом страницы. Доля здесь больше, чем у полосы
       (4,49 против 3,75): процент у left считается от ширины самой
       строки, а она уже всего экрана — 83,5 % от него. */
    left: min(4.49%, 71px);
    top: 50%;
    display: flex;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-50%) scale(.9);
    transform-origin: left center;
    transition: opacity var(--t-med) var(--ease),
                transform var(--t-med) var(--ease),
                visibility 0s linear var(--t-med);
  }

  .is-topbar-off .site-logo {
    opacity: 1;
    visibility: visible;
    transform: translateY(-50%) scale(1);
    transition-delay: 0s;
  }

  .site-logo img { height: 40px; }

  /*
   * Логотип и телефон из строки ушли, и меню, которое держится на
   * авто-полях, само собой уехало бы вправо на 20,5 px. Пустая
   * отбивка справа возвращает пункты на прежние места.
   *
   * 25 — не подбор: это ширина телефона (159) минус ширина
   * логотипа (118) минус зазор строки (16). Обе ширины были
   * постоянными, поэтому и поправка постоянная — она верна на
   * любой ширине экрана.
   */
  .site-header__row::after {
    content: '';
    flex: none;
    width: 25px;
  }

  /*
   * Правый край кнопки «Обсудить проект» встаёт на одну линию с
   * контентом страницы — с плашками первого экрана.
   *
   * Строка шапки живёт в контейнере пошире остального (83,5 %
   * против 76 %), и её правый край проходит правее плашек. Разница
   * половин — ровно 3,75 % ширины экрана, но не больше 71 px: выше
   * 1920 оба контейнера упираются в свои потолки, 1602 и 1460.
   *
   * Отступ симметричный, и это важно: меню держится на авто-полях,
   * а равные поля слева и справа его не двигают — края сходятся к
   * центру одинаково. Слева у строки теперь ничего не стоит
   * (логотип убран), поэтому левый отступ ничего и не задевает.
   *
   * Вычитаем 41: между кнопкой и краем строки уже есть зазор 16 и
   * отбивка 25, которая держит меню на месте.
   */
  .site-header__row { padding-inline: max(0px, min(3.75%, 71px) - 41px); }
}

@media (max-width: 1039px) {
  .site-logo img { height: 44px; }
}

/* =============================================================
   Section heading block
   ============================================================= */

/* Каждый блок занимает ровно один экран: высота задаётся вьюпортом,
   содержимое центрируется, а не растягивает блок отступами. */
.section--screen {
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  display: grid;
  align-content: center;
}

.section-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: end;
  margin-bottom: clamp(1.1rem, 3vh, 2rem);
}

.section-head__main { display: grid; gap: var(--sp-3); max-width: 46rem; min-width: 0; }
.section-head__aside { display: grid; gap: var(--sp-4); justify-items: start; min-width: 0; }
.section-head__mascot { width: clamp(110px, 16vw, 170px); justify-self: start; }

@media (min-width: 900px) {
  .section-head { grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--sp-7); }
  .section-head__aside { justify-items: end; text-align: right; }
  .section-head__mascot { justify-self: end; }
}

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

   Собран по макету «Широкие компы» (1920×1080). Все доли считаются
   от контейнера 1460 и от высоты экрана, поэтому пропорции держатся
   на любом мониторе, а не только на 1920.
   ============================================================= */

.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  /* Строка по высоте контента, а не по высоте экрана: иначе колонка
     плиток растягивалась бы на весь первый экран, а не по тексту. */
  align-content: center;
  /*
   * Контент макета стоит на 40px выше центра экрана — отсюда 7.5vh.
   *
   * Плюс высота полосы над шапкой. Блок ростом во весь экран, но
   * на старте полоса закрывает его верх, и видно не всё: без этой
   * добавки содержимое центрировалось бы по полной высоте и нижним
   * краем уходило под сгиб. Отступ сдвигает его в центр именно
   * видимой части. Ниже 1040 полосы нет и слагаемое равно нулю.
   */
  padding-block: 0 calc(7.5vh + var(--topbar-h));
  /* Высота та же, что у остальных блоков: экран минус шапка. Полосу
     над шапкой вычитать нельзя — первый экран стал бы на её высоту
     ниже всех прочих, а они должны быть одного роста.
     Содержимое при этом остаётся над сгибом и на старте: оно
     заметно ниже полной высоты блока, запас проверен. */
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  isolation: isolate;
}

/* Собственного фона у первого экрана больше нет — кляксы лежат
   на всей странице, см. body::before. */

.hero__copy {
  position: relative;
  z-index: 2;
  display: grid;
  justify-items: start;
  min-width: 0;
}

/* ---- Заголовок с граффити-словом --------------------------- */

/* Заголовок набран капсом, Unbounded Bold без разрядки: именно при
   этих параметрах строки дают макетные 512 и 555 px на 1920. */
.hero__title {
  margin: 0;
  display: grid;
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0;
}
.hero__title > span { display: block; }

/* Слот, который слово занимает в потоке. По макету строки стоят на
   Y=219 и Y=469 при интерлиньяже 70, значит на слово остаётся
   469 − (219 + 70 + 70) = 110 px. Картинка крупнее слота и наезжает
   на соседние строки сверху и снизу. */
.hero__graffiti {
  position: relative;
  height: 1.4667em;        /* 110 / 75 */
  pointer-events: none;
}
/* Доли посчитаны от бокса картинки: внутри SVG краска занимает
   не весь viewBox, поэтому значения не «круглые». */
.hero__graffiti img {
  position: absolute;
  left: .7467em;           /*  56 / 75 */
  top: -.6667em;           /* -50 / 75 */
  width: 8.548em;          /* 641 / 75 */
  max-width: none;
}

.hero__lead {
  /* 514 из 559: ровно та ширина, при которой Roboto ложится в те же
     три строки с теми же переносами, что и в макете. */
  max-width: 92%;
  margin: 4.94vh 0 0;                          /* 53 px на 1080 */
  font-size: clamp(1rem, 1.15vw, 1.375rem);   /* 22 на 1920 */
  line-height: 1.364;                          /* 30 / 22 */
  color: var(--text);                          /* в макете лид белый, не серый */
}

/* Ряд кнопок обязан поместиться в колонку текста: иначе он вылезает
   под маскота. Кнопки фиксированного размера перестают влезать уже
   на 1500, поэтому на первом экране они тянутся вместе с макетом —
   на 1920 значения ровно макетные (15 / 28 / 67 / 7). */
.hero__actions {
  display: flex;
  flex-wrap: nowrap;
  gap: clamp(5px, .36vw, 7px);
  margin-top: 8.4vh;                           /* 91 px на 1080 */
}

.hero__actions .btn {
  font-size:      clamp(11px,  .78vw, 15px);
  padding-inline: clamp(14px, 1.46vw, 28px);
  min-height:     clamp(44px, 3.49vw, 67px);
}

/* ---- Маскот ------------------------------------------------- */

.hero__mascot {
  position: absolute;
  z-index: 1;
  left: 54.8%;             /* центр маскота по макету */
  transform: translateX(-50%);
  /* 10 % по макету плюс половина полосы над шапкой. Маскот считается
     от низа блока и полями не двигается, а текст с плитками сдвинут
     вверх нижним отступом ровно на половину полосы (см. .hero).
     Без этой добавки утка оставалась бы на месте и упиралась бы
     ногами в сгиб. Ниже 1040 полосы нет и слагаемое равно нулю. */
  bottom: calc(10% + var(--topbar-h) / 2);
  height: 68.3%;           /* 694 / 1016 */
  width: auto;
  max-width: 46%;
  filter: drop-shadow(0 26px 40px rgba(0, 0, 0, .55));
}

/* ---- Бенто-сетка форматов ----------------------------------- */

.bento {
  position: relative;
  z-index: 2;
  /* Колонка стоит в одной строке с текстом и тянется по ней, поэтому её
     низ совпадает с низом кнопок. Верх сдвинут на полуинтерлиньяж
     заголовка: иначе он встал бы по строке, а не по буквам.

     Не grid: у трека 1fr минимум равен max-content фотографии, и колонка
     распирала бы строку вместо того, чтобы тянуться по ней. У flex-базиса
     0 такой проблемы нет — собственная высота колонки равна только
     зазорам, а высоту ей задаёт строка. */
  grid-column: 3;
  grid-row: 1;
  align-self: stretch;
  margin-top: calc(var(--fs-display) * .0747);   /* (70−92.8)/2 + (75−58) = 5.6 при 75 */
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
  min-height: 0;
}

.bento__item {
  position: relative;
  display: block;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  border-radius: 24px;
  background: var(--ink-2);
  isolation: isolate;
}
.bento__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.bento__item:hover img { transform: scale(1.05); }

/* Подпись белая, фото бывают светлые — нужен градиент снизу. */
.bento__item::after {
  content: '';
  position: absolute;
  inset: 35% 0 0;
  background: linear-gradient(transparent, rgba(0, 0, 0, .78));
  pointer-events: none;
}

/* Карточка сама тянется долей контейнера, поэтому и подпись считаем
   от ширины экрана: 24 / 27 / 20 / 22 — значения на 1920. */
.bento__label {
  position: absolute;
  left:   clamp(12px, 1.25vw, 24px);
  right:  clamp(8px,   .60vw, 12px);
  bottom: clamp(12px, 1.15vw, 22px);
  z-index: 2;
  font-family: var(--font-display);
  font-size: clamp(13px, 1.25vw, 24px);
  font-weight: 700;
  line-height: 1.042;      /* 25 / 24 */
  letter-spacing: 0;
  color: #fff;
  /* «Тимбилдинги» длиннее узкой карточки. В макете слово просто
     переносится посередине — без этого оно уезжает под обрезку. */
  overflow-wrap: anywhere;
}

@media (min-width: 900px) {
  /* Доли считаются от контейнера: 562 / 1460 и 370 / 1460 */
  .hero { grid-template-columns: 38.5% 1fr 25.34%; }
}

/* Средняя колонка пустая — маскот спозиционирован абсолютно, — поэтому
   на узких экранах текстовой колонке можно отдать больше места, и ряд
   кнопок перестаёт вылезать под маскота. */
@media (min-width: 900px) and (max-width: 1400px) {
  .hero { grid-template-columns: 44% 1fr 25.34%; }
}

/* Ниже ~1200 две кнопки в строку уже не помещаются даже в минимальном
   кегле — честнее перенести вторую, чем выпускать ряд за колонку. */
@media (max-width: 1200px) {
  .hero__actions { flex-wrap: wrap; }
}

@media (max-width: 899px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    padding-block: 5vh 6vh;
    gap: 4vh;
    min-height: 0;
  }
  .hero__copy { max-width: none; }
  .hero__lead { max-width: 34ch; }
  .hero__mascot {
    position: static;
    transform: none;
    height: auto;
    width: min(62%, 300px);
    max-width: none;
    justify-self: center;
  }
  /* Пропорция 370×652 держит бенто только в три колонки первого экрана;
     в мобильной раскладке высоту задают ряды. */
  .bento {
    grid-column: auto;
    grid-row: auto;
    align-self: auto;
    margin-top: 0;
  }
  .bento__item { flex: 0 0 150px; }
  .bento__label { font-size: clamp(15px, 3.6vw, 22px); left: 18px; right: 14px; bottom: 16px; }
}

@media (max-width: 560px) {
  .bento { gap: 8px; }
  .bento__item { flex: 0 0 118px; }
  .hero__actions .btn { flex: 1 1 100%; }
}

/* =============================================================
   Decor stickers — sparse, low-key, never more than one per band
   ============================================================= */

.decor {
  position: absolute;
  pointer-events: none;
  z-index: var(--z-decor);
  opacity: .5;
  user-select: none;
}
.decor--crown  { width: clamp(70px, 8vw, 118px); }
.decor--arrow  { width: clamp(80px, 9vw, 140px); }
.decor--arc    { width: clamp(140px, 16vw, 240px); }

@media (max-width: 760px) { .decor { display: none; } }

/* =============================================================
   Блок «О нас»

   Собран по макету «Широкие компы 2» (1920×1080). Доли считаются от
   контейнера 1460 и от кегля, поэтому пропорции держатся на любой
   ширине. Опорные числа макета: карточка 432×302 (радиус 36, обводка
   1 px #9700FF), шаг между карточками 505, поле внутри карточки 54.
   ============================================================= */

/* ---- Шапка блока: надзаголовок-граффити, заголовок, лид -----
   Одна на все экраны. Разрядку заголовка каждый блок задаёт сам —
   в макетах она разная: у «О нас» −2%, у «Кейсов» +1 px. */
.sec-head { display: grid; justify-items: start; }

/* viewBox у SVG подрезан по краске, поэтому бокс картинки и есть
   её видимые границы — никаких поправок на пустые поля. */
.sec-head__kicker {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;                                   /* ширину задаёт .kicker-wrap */
  /* Надпись приходит жёлтой, а в макете она белая. Фильтр гасит цвет
     в чёрный и выворачивает в белый — так ассет остаётся исходным. */
  filter: brightness(0) invert(1);
}

/* Отступ до заголовка висит на обёртке: у картинки внутри своя
   ширина 100 %, а поля блока задаёт она. */
.sec-head .kicker-wrap { margin-bottom: var(--kicker-gap); }

/*
 * Подчёркивание-напыление за надписью.
 *
 * Рисуем фоном псевдоэлемента, а не отдельной картинкой в разметке:
 * оно шире слова и уходит левее его, а внутрь <img> такой фон не
 * помещается. Ширина у каждого блока своя (она в --spray-w и взята
 * из макета), высота везде 73, растяжение неравномерное — у самого
 * SVG стоит preserveAspectRatio="none".
 *
 * Обёртка нужна, чтобы считать положение от самой надписи, а не от
 * блока: у «Контактов» секция — сетка с центровкой по вертикали, и
 * спрей, привязанный к ней, улетал к верху экрана.
 *
 * По макетам спрей всегда на 60 левее краски слова, а по вертикали
 * его центр на 10 ниже центра слова — при разной высоте надписей
 * это сходится само.
 */
.kicker-wrap {
  position: relative;
  display: block;
  width: var(--kicker-w);
}

.kicker-wrap::before {
  content: '';
  position: absolute;
  z-index: 0;
  left: max(-3.125vw, -60px);                    /* −60 на 1920 */
  top: calc(50% - min(1.901vw, 36.5px) + min(.521vw, 10px));
  width: var(--spray-w, 0);
  height: min(3.802vw, 73px);                    /* 73 на 1920 */
  background: url('../img/graffiti/spray-line.svg') no-repeat 0 0 / 100% 100%;
  pointer-events: none;
}

.sec-head__title {
  position: relative;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 3.385vw, 4.0625rem);   /* 65 на 1920 */
  line-height: .923;                             /* 60 / 65 */
  letter-spacing: var(--head-track);
  color: var(--text);
}
/* fit-content, а не max-content: строка обнимает текст, чтобы значок
   держался за её конец, но на узком экране не вылезает за колонку. */
.sec-head__title > span { display: block; position: relative; width: fit-content; }

.sec-head__lead {
  margin: var(--lead-gap) 0 0;
  max-width: var(--lead-w);
  font-size: clamp(.95rem, 1.042vw, 1.25rem);    /* 20 на 1920 */
  line-height: 1.185;                            /* 23.7 / 20 */
  color: var(--text);
}

/* Цветной логотип справа на экране «О нас».
   В одном ряду с шапкой блока, чтобы верх совпал с надписью, а низ
   с последней строкой лида: высоту задаёт сам ряд, ширина идёт за
   пропорцией. У узких экранов места под него нет — прячется. */
.about { position: relative; }

/* Текстовая колонка не должна заезжать под логотип: в макете он
   начинается на 1227 из 1920, то есть на 68 % контейнера. Колонка
   чуть уже — 65 %, чтобы между текстом и логотипом остался воздух. */
.about__body { position: relative; }

@media (min-width: 1280px) {
  .about__body { width: 65%; }                   /* 949 / 1460 */
}

/* Логотип считается от всей секции, а не от её шапки: в макете он
   идёт во всю высоту экрана — 209..925 из 1080 — и правым краем
   чуть выходит за контейнер. */
/*
 * Размер берётся от ширины контейнера, а не от высоты секции:
 * высота секции зависит от окна, и на невысоком экране логотип
 * съёживался бы, хотя сетка макета не менялась.
 *
 * Центрируется по вертикали полем, а не transform: transform
 * занят анимацией появления (.reveal), и они бы спорили. Процент
 * у margin считается от ширины родителя, поэтому −24,17 % — это
 * ровно половина высоты логотипа при его пропорции 0,693.
 */
.about__logo {
  position: absolute;
  top: 50%;
  right: -1.75%;                                 /* 1715,6 за краем 1690 */
  width: 33.5%;                                  /* 489 / 1460 */
  height: auto;
  margin-top: -24.17%;
  pointer-events: none;
}
@media (max-width: 1279px) {
  .about__logo { display: none; }
}

.about {
  --about-gap: 4.45%;
  /* Процент считается от .sec-head, а она лежит в .about__body
     шириной 65 % контейнера — поэтому доля здесь больше, чем у
     других блоков, хотя надпись выходит той же: 160 из 1460.
     Раньше тут стояли те же 10,98 %, что и у блоков во всю
     ширину, и надпись ужималась до 104 — вдвое мельче соседних. */
  --kicker-w: 16.98%;      /* 160.3 / (1460 × 0.65) */
  /* Длина краски здесь не из макета (там 274), а подогнана под
     соседние блоки: все краски начинаются с одной точки, и правый
     край «О НАС» должен вставать вровень с «Кейсами». */
  --spray-w:  min(15.573vw, 299px);  /* как у .cases */
  --kicker-gap: 2.82vh;    /* 30.4 на 1080 */
  --head-track: -.02em;    /* −2 % по макету */
  --lead-gap: 2.95vh;      /* 31.9 на 1080 */
  --lead-w: 83%;           /* 791 из 949: две строки с теми же переносами */
}

/* В «О нас» лид крупнее общего: по макету 24, а не 20. */
.about .sec-head__lead {
  font-size: clamp(1rem, 1.25vw, 1.5rem);        /* 24 на 1920 */
  line-height: 1;                                /* межстрочный 24 при кегле 24 */
}

/* Корона висит у конца последней строки и заходит на неё.
   В макете она повёрнута — без наклона габарит не сходится. */
.about__crown {
  position: absolute;
  left: 100%;
  width: 1.95em;          /* 126.6 / 65 */
  margin-left: -.457em;
  top: -1.146em;
  transform: rotate(19deg);
  pointer-events: none;
}

/* ---- Строки принципов ---------------------------------------
 *
 * Макет «Широкие компы 2 о нас» (1920×1080). Раньше это были три
 * карточки в ряд, теперь три строки одна под другой: слева
 * квадрат со значком, справа заголовок и текст.
 *
 * Опорные числа макета: квадрат 101 × 101 с обводкой 10 — то есть
 * 111 по внешнему габариту, потому что обводка в макете идёт по
 * центру контура. Шаг строк 140, значит между квадратами 30.
 * Столбец текста начинается на 140 от левого края — ровно за
 * квадратом с тем же зазором 30.
 */
.about__list {
  display: grid;
  gap: min(1.563vw, 30px);                       /* 30 на 1920 */
  margin: min(1.563vw, 30px) 0 0;                /* 30 от краски лида */
  padding: 0;
  list-style: none;
}

.about-row {
  display: grid;
  grid-template-columns: min(5.781vw, 111px) minmax(0, 1fr);
  gap: min(1.563vw, 30px);
  /* По центру квадрата: в макете текстовый блок стоит ровно
     посередине его высоты, и при другом числе строк так же. */
  align-items: center;
}

/*
 * Рамка — картинка из макета, а не CSS-обводка: контур там
 * нарисован от руки, ровной рамкой его не повторить.
 *
 * Размер задан жёстко и не зависит от того, сколько текста в
 * строке: ширину даёт колонка сетки, высоту — пропорция, а
 * align-self не даёт строке растянуть рамку по своей высоте.
 * Раньше рамки получались разной высоты именно из-за растяжения.
 */
.about-row__icon {
  display: grid;
  place-items: center;
  align-self: center;
  /* Обе стороны заданы одним и тем же выражением, без aspect-ratio:
     так высота не может прийти из строки ни при каких условиях. */
  width: min(5.781vw, 111px);
  height: min(5.781vw, 111px);
  background: url('../img/decor/square-brush.svg') center / contain no-repeat;
}
/* Значок вписан в 58 % рамки по большей стороне: у нарисованного
   контура поля внутри шире, чем у ровной обводки. contain
   сохраняет пропорцию каждого значка — они разные. */
.about-row__icon img {
  width: 58%;
  height: 58%;
  object-fit: contain;
}

.about-row__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.25vw, 1.5rem);        /* 24 по макету */
  line-height: .833;                             /* межстрочный 20 при кегле 24 */
  color: #fff;
}

.about-row__text {
  margin: min(.625vw, 12px) 0 0;
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 по макету */
  line-height: 1.185;                            /* 23.7 / 20 */
  color: #fcfcfc;
}

/* ---- Общая оболочка фиолетовой карточки ---------------------
   Осталась только у «Услуг»: 432×302, радиус 36, кант 1 px
   #9700FF и свечение в левом верхнем углу. В «О нас» карточек
   больше нет — там строки, см. выше. */
.svc-card {
  position: relative;
  display: grid;
  min-height: min(15.729vw, 302px);              /* 302 по макету «Услуг» */
  /* Цвет рамки рисует фон (см. ниже), поэтому сама рамка прозрачная. */
  border: 1px solid transparent;
  border-radius: var(--r-plate);                 /* 36 по макету */
  /*
   * Свечение в левом верхнем углу: от #9700FF в самом углу и в фон
   * примерно к трети карточки. Средняя точка нужна, чтобы спад шёл
   * круто, — без неё верх карточки получается вдвое ярче.
   *
   * Тем же градиентом залита и рамка: слои с padding-box закрывают
   * внутреннюю часть, а слой с border-box остаётся виден только в
   * однопиксельном канте. Поэтому кант светится вместе с углом и
   * гаснет вместе с ним, а не висит ровной яркой линией.
   *
   * Хотите слабее — уменьшайте .45 и 35%; ярче — увеличивайте.
   */
  background:
    linear-gradient(162deg,
      var(--violet-line) 0%,
      rgba(151, 0, 255, .45) 8%,
      rgba(19, 19, 19, 0) 35%) padding-box,
    /* сплошная заливка: в шорткоде цвет допустим только последним
       слоем, поэтому подложку задаём градиентом из одного цвета */
    linear-gradient(var(--header-bg), var(--header-bg)) padding-box,
    linear-gradient(162deg,
      var(--violet-line) 0%,
      rgba(151, 0, 255, .45) 8%,
      rgba(151, 0, 255, .16) 35%) border-box,
    var(--header-bg);
}

@media (max-width: 899px) {
  .about-row { grid-template-columns: 72px minmax(0, 1fr); gap: 18px; }
  .sec-head__kicker { width: var(--kicker-w-mob, 150px); }
  .sec-head__lead { max-width: none; }
  /* На узком экране заголовок занимает всю ширину, и короне некуда
     свешиваться — уменьшаем её и сильнее заводим на текст. */
  .about__crown { width: 1.35em; margin-left: -.95em; top: -.8em; }
}

/* =============================================================
   Блок «Услуги»

   Макет «Широкие компы 4» (1920×1080). Карточка — та же оболочка,
   что в «О нас»: 432×302, шаг 505, зазор 73. Отличия: вместо цифры
   иконка, заголовок 24, описание 17, внизу жёлтая ссылка.
   ============================================================= */

.services {
  --svc-gap: 5%;           /* 73 / 1460 */
  --kicker-w: 15.66%;      /* 228.6 / 1460 */
  --spray-w:  min(18.177vw, 349px);  /* 349 на 1920 */
  --kicker-gap: 1.87vh;    /* 20.2 на 1080 */
  --head-track: .0154em;   /* 1 px при кегле 65 */
  --lead-gap: 3.03vh;      /* 32.7 на 1080 */
  --lead-w: 50%;           /* 730 / 1460: две строки, как в макете */
  --link-track: .07em;     /* 0.91 px при кегле 13 */
}

.services__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--svc-gap);
  margin-top: 6.17vh;                            /* 66.6 на 1080 */
}

.svc-card {
  /* Карточка-анонс: размер держит макет, а не длина текста.
     Описание обрезается, целиком его видно на странице услуги.
     Нижняя граница, а не жёсткая высота: иначе подпись «как это
     работает» наезжает на описание, когда текста чуть больше. */
  min-height: min(15.729vw, 302px);
  /* Последняя строка тянется, поэтому ссылка всегда прижата к низу
     независимо от того, три в описании строки или четыре. */
  grid-template-rows: auto auto 1fr;
  /* Доли от ширины карточки (432): 45 / 38 / 36 / 54 по макету. */
  padding: 10.51% 8.8% 8.31% 12.5%;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

/* Иконка выходит за верхний левый угол — как цифра в «О нас». */
.svc-card__icon {
  position: absolute;
  bottom: 81.79%;                                /* низ иконки на 55 ниже верха карточки */
  left: -2.8%;                                   /* 12 / 432 */
  height: 31.5%;                                 /* 95 / 302 */
  width: auto;
  max-width: none;
  pointer-events: none;
}

.svc-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.25vw, 1.5rem);        /* 24 на 1920 */
  line-height: 1.208;                            /* 29 / 24 */
  letter-spacing: .0417em;                       /* 1 px при кегле 24 */
  color: #fff;
  white-space: pre-line;
}

.svc-card__text {
  /* em, а не проценты: процентный отступ считался бы от ширины
     содержимого карточки, которая сама зависит от полей. */
  margin: 1.15em 0 0;                            /* 23 при кегле 20 */
  font-size: clamp(.95rem, 1.042vw, 1.25rem);    /* 20 на 1920 */
  line-height: 1.25;                             /* 25 / 20 */
  color: #fff;
  /* Четыре строки, как в макете: остальное — в окне направления. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
  align-self: start;
}

.svc-card__link { align-self: end; justify-self: start; margin: 0; }

.services__more { margin: 2.5vh 0 0; }           /* 27 на 1080 */

/* На низких экранах блок перестаёт помещаться целиком. Пропорция
   макета здесь уступает требованию «блок в один экран»: карточка
   становится ниже, а описание — на строку короче. */
@media (max-height: 700px) {
  .svc-card { height: min(13.802vw, 265px); }
}

@media (max-width: 899px) {
  .services__grid { grid-template-columns: minmax(0, 1fr); gap: 46px; }
  .svc-card { height: auto; grid-template-rows: none; padding: 34px 24px 28px 30px; }
  .svc-card__text { -webkit-line-clamp: 6; line-clamp: 6; }
  .svc-card__icon { bottom: auto; top: -46px; left: -4px; height: 76px; }
  .svc-card__link { margin-top: 20px; }
}

/* =============================================================
   Блок «Кейсы»

   Макет «Широкие компы 3» (1920×1080). Опорные числа: карточка
   470×300 (радиус 36, фон #131313, без обводки), обложка 470×150,
   шаг карточек 487 — то есть зазор 17. Поле слева 26, колонка
   текста 308, поэтому справа остаётся много воздуха — так в макете.
   ============================================================= */

.cases {
  --cases-gap: 1.16%;      /* 17 / 1460 */
  --kicker-w: 13.51%;      /* 197.2 / 1460 */
  --spray-w:  min(15.573vw, 299px);  /* 299 на 1920 */
  --kicker-gap: 3.11vh;    /* выставлен по макетным 24.9 между краской */
  --head-track: .0154em;   /* 1 px при кегле 65 */
  --lead-gap: 3.03vh;      /* 32.7 на 1080 */
  --lead-w: 46%;           /* 668 / 1460: две строки с теми же переносами */
  --link-track: .12em;     /* 1.56 px при кегле 13 */
}

/* Экспорт надписи выше своей краски на 9 %: пропорция взята из макета. */
.cases .sec-head__kicker { aspect-ratio: 197.2 / 73.2; }

.cases__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--cases-gap);
  margin-top: 3.68vh;                            /* 39.7 на 1080 */
}

/* ---- Общая оболочка карточки с фотографией -------------------
   Одна и та же в «Кейсах» и «Идеях»: ширина 470, радиус 36, фон
   #131313, обложка 470×150 сверху. Различаются высотой и полями. */
.case-card,
.idea-card {
  display: grid;
  align-content: start;
  /* Боковых полей у самой карточки нет: обложка идёт во всю ширину,
     а текст отступает сам. Так все проценты внутри считаются от
     полной ширины карточки, а не от остатка после полей. */
  border-radius: var(--r-plate);                 /* 36 по макету */
  background: var(--header-bg);
  overflow: hidden;
  color: inherit;
}

/* Карточки-анонсы: размер держит макет, а не длина текста. Описание
   обрезается, целиком его видно на странице кейса или идеи.
   Пустая строка 1fr забирает весь остаток, поэтому ссылка и цена
   прижаты к низу плашки одинаково во всех карточках ряда. */
/* Высота из макета — но как нижняя граница, а не как жёсткий размер:
   если строка со стоимостью на узком экране перенесётся, карточка
   должна стать выше, а не положить подвал поверх описания. */
.case-card {
  min-height: min(15.625vw, 300px);
  grid-template-rows: auto auto auto 1fr auto;
  align-content: stretch;
  padding: 0 0 4.68%;                            /* 22 / 470 */
}
.idea-card {
  min-height: min(17.24vw, 331px);               /* 470 × 331 по макету */
  grid-template-rows: auto auto auto 1fr auto;
  align-content: stretch;
  padding: 0 0 3.83%;                            /* 18 / 470 */
}

/* Поля текста в долях от ширины карточки 470. Справа много воздуха —
   так в макете: колонка текста 308 в «Кейсах» и 360 в «Идеях». */
.case-card__type,
.case-card__title,
.case-card__text,
.case-card__link { margin-inline: 5.53% 28.94%; }

.idea-card__type,
.idea-card__title,
.idea-card__text { margin-inline: 5.53% 17.87%; }

/* Нижняя строка карточки: ссылка слева, стоимость справа. Она шире
   колонки текста — поля 26 слева и 29.5 справа от ширины 470. */
.idea-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Когда карточка узкая, строка переносится целиком, а не ломает
     подпись ссылки посередине. */
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-inline: 5.53% 6.28%;
  margin-top: 3.26%;                             /* 15.3 / 470 */
}
.idea-card__link { white-space: nowrap; }

/* Стоимость — плашка 165 × 48 с фиолетовой заливкой на 20 % и
   обводкой в пиксель. Высота задана, поэтому поля только по бокам:
   общее правило меток (см. «Метки и стоимость») их обнуляет ниже. */
.idea-card__price {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  min-width: min(8.594vw, 165px);                /* 165 на 1920 */
  min-height: min(2.5vw, 48px);                  /* 48 на 1920 */
  padding-block: 0;
  padding-inline: min(.573vw, 11px);             /* 11 слева по макету */
  background: rgba(151, 0, 255, .2);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(10px, .781vw, 15px);          /* 15 на 1920 */
  line-height: 1.2;                              /* 18 / 15 */
  letter-spacing: .104em;                        /* 1,56 px при кегле 15 */
  text-transform: uppercase;
  white-space: nowrap;
}

/* Обложка обрезается по скруглению карточки — своего радиуса не нужно. */
.case-card__media,
.idea-card__media {
  aspect-ratio: 470 / 150;
  overflow: hidden;
  background: var(--ink-2);
}
.case-card__media img,
.idea-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.case-card:hover .case-card__media img,
.idea-card:hover .idea-card__media img { transform: scale(1.04); }

.case-card__type,
.idea-card__type {
  font-size: clamp(9px, .521vw, 10px);           /* 10 на 1920 */
  line-height: 1.2;
  text-transform: uppercase;
}
.case-card__type { margin-top: 2.43%; }          /* 11.4 / 470 */


/* В «Идеях» надзаголовок мельче, а плашка под него — 103 × 15. */
.idea-card__type {
  margin-top: 2.87%;                             /* верх плашки на 13.5 от обложки */
  font-size: clamp(8px, .469vw, 9px);            /* 9 на 1920 */
  line-height: 1.33;
}

.case-card__title,
.idea-card__title {
  /* h3 без класса .h3 сохраняет браузерный margin-bottom в 1em —
     это лишние 21 px, из-за которых карточка не влезала в высоту. */
  margin-bottom: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.083vw, 1.3rem);       /* 20.8 на 1920 */
  line-height: 1.25;                             /* 26 / 20.8 */
  letter-spacing: .048em;                        /* 1 px при кегле 20.8 */
  color: var(--text);
}
.case-card__title { margin-top: 1%; }            /* 4.7 / 470 */
.idea-card__title { margin-top: 2.21%; }         /* 10.4 / 470 */

.case-card__text,
.idea-card__text {
  font-size: clamp(.8125rem, .781vw, .9375rem);  /* 15 на 1920 */
  line-height: 1.133;                            /* 17 / 15 */
  color: #fff;
  /* Две строки, как в макете: остальное читается на странице. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  align-self: start;
}
.case-card__text { margin-top: 2.02%; }          /* 9.5 / 470 */
.idea-card__text { margin-top: 2.13%; }          /* 10 / 470 */

/* Жёлтая ссылка со стрелкой — общая для всех трёх блоков.
   Разрядку блоки задают сами: в макетах она разная. */
.case-card__link,
.idea-card__link,
.svc-card__link {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: .8em;
  font-weight: 700;
  font-size: clamp(11px, .677vw, 13px);          /* 13 на 1920 */
  line-height: 1.23;
  letter-spacing: var(--link-track, .1em);
  text-transform: uppercase;
  color: #f8ef01;
}

.case-card__link { margin-top: 3.06%; }          /* 14.4 / 470 */
/* В «Идеях» отступ держит строка .idea-card__foot, а не сама ссылка. */

/* Стрелка из макета. Маска, а не картинка: так она красится
   currentColor и годится и для жёлтой ссылки, и для белой кнопки. */
.arrow-i {
  flex: none;
  /* Целые пиксели, а не доли кегля: штрих стрелки толщиной ~1.5 px, и
     при дробной высоте он попадает на границу пикселя и округляется
     вниз — стрелка визуально съезжает под строку. Поэтому размер задаётся
     переменными, а не em: подписи кеглем 13 берут базовый 18×12,
     кнопки кеглем 15 — увеличенный, и обе пары целые. */
  width: var(--arrow-w, 18px);
  height: var(--arrow-h, 12px);                  /* 509 : 336 */
  /* Оптический центр прописных выше середины строки — поднимаем. */
  position: relative;
  top: -1px;
  background: currentColor;
  -webkit-mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
  mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
  transition: transform var(--t-fast) var(--ease);
}
/* Подписи кнопок набраны кеглем 15 — стрелка тянется за ними. */
.btn { --arrow-w: 21px; --arrow-h: 14px; }
.btn--sm { --arrow-w: 18px; --arrow-h: 12px; }

.case-card:hover .arrow-i,
.idea-card:hover .arrow-i,
.btn:hover .arrow-i { transform: translateX(3px); }

/* =============================================================
   Блок «Идеи»

   Макет «Широкие компы 5» (1920×1117). Карточка — та же оболочка,
   что в «Кейсах», но 470×312 и колонка текста шире. Над карточками
   ряд вкладок-пилюль: активная залита #9700FF, остальные в обводке.
   ============================================================= */

.ideas {
  --ideas-gap: 1.16%;      /* 17 / 1460 */
  --kicker-w: 12.32%;      /* 179.9 / 1460 */
  --spray-w:  min(14.74vw, 283px);   /* 283 на 1920 */
  --kicker-gap: 2.69vh;    /* 29 на 1080 */
  --head-track: .0154em;   /* 1 px при кегле 65 */
  --lead-gap: 2.25vh;      /* 24.3 на 1080 */
  --lead-w: 52%;           /* 760 / 1460: две строки, как в макете */
  --link-track: .12em;     /* 1.56 px при кегле 13 */
}

.ideas__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 2.21vh;                            /* 23.9 на 1080 */
}

/* Пилюля: 245×38, поля 27 слева и 26 справа до счётчика. */
.ideas__tabs .tab {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 38px;
  padding: 0 26px 0 27px;
  border: 1px solid #5e5e5e;
  border-radius: var(--r-pill);
  background: transparent;
  /* Шрифт и кегль как у кнопки «Все идеи» — она фиксированные 13 px. */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.2;
  /* Общий .tab ниже по файлу задаёт разрядку .1em — в макете её нет. */
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text);
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
.ideas__tabs .tab:hover { border-color: var(--text-2); }

.ideas__tabs .tab b {
  display: inline-grid;
  place-content: center;
  min-width: 22px;
  height: 22px;
  padding-inline: 5px;
  border-radius: var(--r-pill);
  background: #1d1d1d;
  font-weight: 700;
  font-size: inherit;
}

/* Текст остаётся белым и у выбранной вкладки: общий .tab ниже по
   файлу перекрашивал её в тёмный под жёлтую заливку. */
.ideas__tabs .tab[aria-selected='true'],
.ideas__tabs .tab[aria-selected='true'] b {
  color: var(--text);
}
.ideas__tabs .tab[aria-selected='true'] {
  background: var(--violet-line);
  border-color: var(--violet-line);
}
.ideas__tabs .tab[aria-selected='true'] b { background: #6f00bc; }

.ideas__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--ideas-gap);
  margin-top: 2.22vh;                            /* 24 на 1080 */
}

.ideas__more { margin: 1.48vh 0 0; }             /* 16 на 1080 */

/* Блок самый высокий из переделанных: к карточкам добавляется ряд
   вкладок. На низких экранах пропорция макета уступает требованию
   «блок в один экран» — карточка и обложка становятся ниже,
   описание сокращается до строки. */
@media (max-height: 700px) {
  .ideas { --kicker-gap: 1.7vh; --lead-gap: 1.6vh; }
  .ideas__tabs { margin-top: 1.5vh; }
  .ideas__tabs .tab { min-height: 32px; padding-inline: 18px; }
  .ideas__grid { margin-top: 1.5vh; }
  .idea-card { height: min(13.438vw, 258px); }
  .idea-card__media { aspect-ratio: 470 / 112; }
}

@media (max-width: 899px) {
  .ideas__grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .idea-card { height: auto; grid-template-rows: none; padding: 0 0 24px; }
  .idea-card__text { -webkit-line-clamp: 3; line-clamp: 3; }
  .idea-card__type,
  .idea-card__title,
  .idea-card__text { margin-inline: 24px; }
  .idea-card__foot { margin-inline: 24px; flex-wrap: wrap; gap: 8px 16px; }
  .idea-card__type { margin-top: 16px; }
  .ideas__tabs .tab { padding-inline: 16px; gap: 10px; }
}

.cases__more { margin: 2.59vh 0 0; }             /* 28 на 1080 */

/* Кнопка из макета: 163×42, обводка 1 px, подпись Unbounded 13. */
.btn--outline {
  min-height: 42px;
  /* padding-block обнулён: высоту держит min-height, иначе .btn
     добавляет свои .9rem сверху и снизу и кнопка выше макетных 42. */
  padding: 0 20px;
  gap: 8px;
  font-size: 13px;
  letter-spacing: 0;
  background: transparent;
  border: 1px solid #fcfcfc;
  color: var(--text);
}
.btn--outline:hover { background: rgba(255, 255, 255, .08); }

/* =============================================================
   Блок «Как работаем»
   ============================================================= */

.process {
  --step-gap: 1.37%;       /* 20 / 1460 — зазор между обводками */
  --kicker-w: 27.05%;      /* 390.6 / 1444 */
  --spray-w:  min(26.51vw, 509px);   /* 509 на 1920 */
  --kicker-gap: 2.86vh;    /* выставлен по макетным 21.3 между краской */
  --head-track: .0154em;   /* 1 px при кегле 65 */
  --lead-gap: 1.28vh;      /* выставлен по макетным 21.1 между краской */
  --lead-w: 48%;           /* 700 / 1460: две строки, как в макете */
}

/* Надпись в макете растянута по горизонтали: 390.6 × 69.2 против
   1212 × 290 у самой краски. Пропорция задана явно, картинка тянется. */
.process .sec-head__kicker { aspect-ratio: 390.6 / 69.2; }

.process__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Процент у row-gap считается от высоты сетки, а не от ширины, и
     вертикальный зазор выходил вчетверо меньше горизонтального.
     Поэтому вертикальный задан от ширины окна — с тем же потолком
     в 20 px, до которого доходит горизонтальный на широком экране. */
  column-gap: var(--step-gap);
  row-gap: min(1.042vw, 20px);
  margin-top: 2.62vh;                            /* 29.9 на 1080 между краской лида и обводкой */
}

/* Плашка шага: 465 × 183 внутри обводки 2 px — в макете это обводка
   снаружи, в CSS она часть бокса, поэтому пропорция от 469 × 187. */
.step-card {
  position: relative;
  display: grid;
  align-content: start;
  min-height: min(9.74vw, 187px);
  /* Доли ширины грид-ячейки (469): 44.5 сверху, 57 слева, 72 справа.
     Нижнее поле держит текст, когда плашка растёт. */
  padding: 9.49% 15.35% 9.49% 12.15%;
  border: 2px solid var(--violet-line);
  /* Два радиуса: процент по горизонтали считается от ширины, по
     вертикали — от высоты, одним числом угол вышел бы эллипсом. */
  border-radius: 9.38% / 23.53%;
  background-color: var(--header-bg);
  /* Свечение то же, что на карточках «Услуг»: по просьбе заказчика
     все плашки сайта светятся одинаково. Направление своё — по
     диагонали плашки, как в макете этого экрана. */
  background-image: linear-gradient(166.48deg,
    var(--violet-line) 0%,
    rgba(151, 0, 255, .45) 8%,
    rgba(19, 19, 19, 0) 35%);
}

.step-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.25vw, 1.5rem);        /* 24 на 1920 */
  line-height: 1.1875;                           /* 28.5 / 24 */
  letter-spacing: .0417em;                       /* 1 px при кегле 24 */
  color: var(--text);
}

.step-card__text {
  margin: 4.1% 0 0;                              /* 19 / 465 */
  font-size: clamp(.95rem, 1.042vw, 1.25rem);    /* 20 на 1920 */
  line-height: 1.25;                             /* 25 / 20 */
  color: var(--text);
}

/* Цифра висит на правом верхнем углу и заходит на поле над плашкой.
   Размер и вынос у каждой свои — в макете они подогнаны вручную,
   поэтому значения лежат в переменных, а не выводятся из кегля.
   Проценты: по горизонтали от 465, по вертикали от 183. */
.step-card__num {
  position: absolute;
  left: var(--num-left, 85%);
  top: var(--num-top, -14%);
  width: var(--num-w, 16%);
  height: var(--num-h, 55%);
  pointer-events: none;
}
.step-card[data-step="1"] { --num-left: 85.31%; --num-top: -13.68%; --num-w: 14.95%; --num-h: 57.84%; }
.step-card[data-step="2"] { --num-left: 83.39%; --num-top: -13.06%; --num-w: 18.07%; --num-h: 53.08%; }
.step-card[data-step="3"] { --num-left: 84.53%; --num-top: -14.31%; --num-w: 17.80%; --num-h: 53.68%; }
.step-card[data-step="4"] { --num-left: 83.38%; --num-top: -27.22%; --num-w: 19.68%; --num-h: 54.58%; }
.step-card[data-step="5"] { --num-left: 85.04%; --num-top: -28.07%; --num-w: 18.45%; --num-h: 55.43%; }
.step-card[data-step="6"] { --num-left: 86.45%; --num-top: -28.96%; --num-w: 13.47%; --num-h: 50.36%; }

/* Нижний ряд цифр заходит в зазор между рядами — он ему и принадлежит,
   поэтому плашки нижнего ряда рисуются поверх верхних. */
.process__grid > .step-card:nth-child(n + 4) { z-index: 1; }

@media (max-height: 700px) {
  .process { --kicker-gap: 1.3vh; --lead-gap: 1.3vh; }
  .process__grid { margin-top: 1.8vh; }
  .step-card { min-height: min(8.333vw, 160px); padding-block: 7.2%; }
}

@media (max-width: 1199px) {
  .process__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .step-card { padding: 26px 70px 26px 26px; }
  .step-card__num { left: auto; right: 10px; top: -22px; width: 70px; height: 86px; }
}

@media (max-width: 719px) {
  .process__grid { grid-template-columns: minmax(0, 1fr); }
  .step-card { border-radius: 20px; }
}

/* =============================================================
   Блок «Контакты»
   ============================================================= */

.contacts {
  --kicker-w: 19.01%;      /* 274.4 / 1444 */
  --spray-w:  min(20.938vw, 402px);  /* 402 на 1920 */
  --kicker-gap: 2.72vh;    /* 29.4 на 1080 между краской и обводкой */
}

/* Надпись, как и остальные граффити, в макете сжата по вертикали. */
.contacts .sec-head__kicker { aspect-ratio: 274.4 / 56.8; }

.contacts__body { position: relative; }

/*
 * Надзаголовок встаёт вровень с короной маскота.
 *
 * Утка отсчитывается от высоты экрана: верх картинки на 4.9 %, рост
 * 84.3 %, и внутри самого файла над короной ещё 2 % пустого поля —
 * значит корона начинается на 6.59 % высоты. Чтобы надпись легла
 * туда же, содержимое секции прижимается к верху и опускается на
 * те же 6.59 %. Поле считается от высоты окна, а не процентом: у
 * padding процент берётся от ширины родителя, и отступ уехал бы в
 * 95 px вместо 65.
 *
 * Надпись при этом остаётся строкой сетки — так она не может
 * наехать на плашку ни на какой высоте экрана. Из потока её
 * выдёргивать нельзя: на невысоких ноутбуках плашка поднимается
 * к самому верху, и надпись легла бы прямо на неё.
 *
 * Ниже 1280 утки нет, и секция снова центрируется по вертикали.
 */
@media (min-width: 1280px) {
  .contacts {
    align-content: start;
    padding-top: calc((100vh - var(--header-h)) * .0659);
    padding-top: calc((100svh - var(--header-h)) * .0659);
  }
}

/* Зазор между краской надписи и обводкой плашки — 29.4 на 1080,
   как в макете. У «Контактов» надпись не внутри .sec-head, поэтому
   общее правило отступа её не достаёт, и он задан здесь. */
.contacts .kicker-wrap { margin-bottom: var(--kicker-gap); }

/* Плашка 940 × 622 вместе с обводкой 2 px. Внутренние поля заданы
   в долях контейнера, а не своей ширины: процент у padding считается
   от родителя, и так он остаётся верным на любой ширине экрана. */
.contacts__plate {
  position: relative;
  width: 65.1%;            /* 940 / 1444 */
  padding: 3.46% 2.701% 3.016% 2.632%;
  border: 2px solid var(--violet-line);
  border-radius: 4.68% / 7.07%;             /* 44 px по обеим осям */
  background-color: var(--header-bg);
  /* Свечение то же, что на карточках «Услуг» — см. .svc-card.
     Направление своё, по диагонали плашки из макета. */
  background-image: linear-gradient(146.98deg,
    var(--violet-line) 0%,
    rgba(151, 0, 255, .45) 8%,
    rgba(19, 19, 19, 0) 35%);
}

.contacts__title {
  line-height: 1;
  letter-spacing: .0154em;                  /* 1 px при кегле 65 */
}

.contacts__lead {
  margin: 4.45% 0 0;                        /* 42.6 между краской заголовка и лида */
  max-width: 86.1%;                         /* 740 / 859 */
  font-size: clamp(1rem, 1.25vw, 1.5rem);   /* 24 на 1920 */
  line-height: 1.125;                       /* 27 / 24 */
  color: var(--text);
}

.contacts__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(8px, .677vw, 13px) 1.979%;     /* 13 по вертикали, 17 по горизонтали */
  margin-top: 6.78%;                        /* 60.5 между краской лида и обводкой */
}

/* Плашка контакта 419 × 112 внутри обводки 1 px. */
.ch-card {
  position: relative;
  display: grid;
  align-content: start;
  min-height: min(5.938vw, 114px);
  padding: 5.05% 5.94% 4.228%;              /* доли ширины ячейки 421 */
  border: 1px solid var(--violet-line);
  border-radius: 7.13% / 26.32%;            /* 30 px по обеим осям */
  background: var(--header-bg);
  transition: border-color var(--t-fast) var(--ease),
              background var(--t-fast) var(--ease);
}
.ch-card:hover { border-color: var(--yellow); background: var(--ink-3); }

.ch-card__name,
.ch-card__value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(.875rem, 1.042vw, 1.25rem);  /* 20 на 1920 */
  line-height: 1.185;                           /* 23.7 / 20 */
}
.ch-card__name  { color: var(--text); }
.ch-card__value { margin-top: 6.9%; color: #f8ef01; }   /* шаг строк 49 */

/* Стрелка та же, что у кнопок, но жёлтая и по центру верхней строки. */
.ch-card__arrow {
  position: absolute;
  right: 5.49%;                             /* 23 / 419 */
  top: 28.29%;                              /* центр верхней строки */
  width: 21px;
  height: 14px;
  background: #f8ef01;
  -webkit-mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
  mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
  /* top задаёт центр строки, а не верх: высота стрелки в пикселях,
     и без сдвига она уезжала бы вниз на узких экранах. */
  transform: translate(0, -50%);
  transition: transform var(--t-fast) var(--ease);
}
.ch-card:hover .ch-card__arrow { transform: translate(3px, -50%); }

.contacts__helper {
  margin: 3.84% 0 0;                        /* 36.1 между обводкой и краской */
  font-size: clamp(.8125rem, .885vw, 1.0625rem);  /* 17 на 1920 */
  line-height: 1.2;
  color: #9d9d9d;
}

/*
 * Маскот — украшение всего экрана, а не плашки.
 *
 * Раньше его размер считался от ширины окна, а положение от верха
 * плашки. Но высота плашки зависит от высоты окна: на невысоких
 * ноутбуках поля внутри сжимаются (см. @media max-height ниже), и
 * утка прежнего размера наезжала пальцем на стрелку. Привязка к
 * плашке это чинила, но на широком и низком окне крона вылезала в
 * блок выше.
 *
 * Поэтому и размер, и положение считаются от высоты секции — она
 * равна экрану. Доли из макета «Широкие компы 7» (экран 1920×1080,
 * утка 728,5 × 910,3 в точке 1018; 52,9): по вертикали утка
 * занимает 4,9…89,2 % экрана и за его пределы не выходит нигде.
 *
 * По горизонтали так считать нельзя, и вот почему.
 *
 * Ширина утки идёт от высоты экрана, а плашка с контактами — от
 * ширины контейнера. Базы разные, поэтому при смене пропорций окна
 * утка едет относительно плашки: на одних размерах палец попадал в
 * пустое место, на других накрывал стрелку карточки. Фиксированный
 * left лечить это не может в принципе — он задаёт левый край
 * картинки, а не кончик пальца, который гуляет вместе с шириной.
 *
 * Поэтому left вычисляется от кончика пальца. В файле маскота он
 * лежит на 4,9 % ширины от левого края (55 из 1122) и это самая
 * левая непрозрачная точка всей картинки. Ширина утки — 0,843
 * высоты секции × 1122/1402 = 0,674881 высоты, значит отступ от
 * левого края картинки до пальца равен 0,033069 высоты секции.
 *
 * Палец прибит к 62,5 % ширины контейнера. Правый край самой правой
 * стрелки — 60,6 %, правый край плашки — 65,1 %: палец встаёт в
 * зазор между ними. Левее пальца у картинки пикселей нет, поэтому
 * накрыть стрелку утка не может ни на каком размере окна, а жест
 * «показывает на контакты» остаётся — рука по-прежнему над плашкой.
 */
.contacts__mascot {
  position: absolute;
  z-index: 1;
  top: 4.9%;                                /* 52.9 / 1080 */
  height: 84.3%;                            /* 910.3 / 1080 */
  left: calc(62.5% - (100vh - var(--header-h)) * .033069);
  left: calc(62.5% - (100svh - var(--header-h)) * .033069);
  width: auto;
  max-width: none;
  pointer-events: none;
}

@media (max-height: 820px) {
  .contacts { --kicker-gap: 1.8vh; }
  .contacts__plate { padding-top: 1.9%; padding-bottom: 2.2%; }
  .contacts__lead { margin-top: 2.2%; }
  .contacts__grid { margin-top: 3%; }
  .contacts__helper { margin-top: 1.8%; }
}

/* Маскот перестаёт помещаться рядом раньше, чем ломается сетка, —
   сначала убираем его, потом отпускаем плашку на всю ширину. */
@media (max-width: 1279px) {
  .contacts__plate { width: 100%; }
  .contacts__mascot { display: none; }
}

@media (max-width: 719px) {
  .contacts__plate { padding: 24px 20px 28px; border-radius: 24px; }
  .contacts__grid { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 24px; }
  .ch-card { padding: 18px 54px 20px 20px; border-radius: 18px; }
  .ch-card__value { margin-top: 10px; }
  .ch-card__arrow { right: 20px; top: 22px; }
  .contacts__lead { max-width: 100%; margin-top: 14px; }
  .contacts__helper { margin-top: 20px; }
}

/* Ширина лида подобрана под макетные переносы на 1920. На узких
   экранах кегль упирается в минимум, а колонка продолжает сжиматься —
   текст уходит в лишнюю строку и блок перестаёт помещаться в экран.
   Поэтому ниже 1500 колонку отпускаем. Правило стоит после объявлений
   блоков: иначе их собственные --lead-w перебивают его. */
@media (max-width: 1500px) {
  .about, .cases, .services, .process { --lead-w: 70%; }
}

@media (max-width: 899px) {
  .cases__grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .case-card { height: auto; grid-template-rows: none; padding: 0 0 24px; }
  .case-card__text { -webkit-line-clamp: 3; line-clamp: 3; }
  /* Боковые поля в пикселях: доли от ширины карточки здесь дали бы
     слишком узкую колонку текста. */
  .case-card__type,
  .case-card__title,
  .case-card__text,
  .case-card__link { margin-inline: 24px; }
  .case-card__type  { margin-top: 16px; }
}

/* =============================================================
   Manifest cards
   ============================================================= */

.grid-3 { display: grid; gap: var(--sp-4); }
.grid-2 { display: grid; gap: var(--sp-4); }

@media (min-width: 760px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

.manifest-card { display: grid; gap: var(--sp-3); align-content: start; min-height: 190px; }
.manifest-card__num {
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--magenta-soft);
  letter-spacing: .08em;
}
.manifest-card:nth-child(2) { border-color: var(--line-accent); background: linear-gradient(170deg, rgba(236,40,252,.09), var(--ink-2) 58%); }

/* =============================================================
   Service cards
   ============================================================= */

.service-card {
  position: relative;
  display: grid;
  gap: var(--sp-3);
  align-content: start;
  min-height: 240px;
  overflow: hidden;
}
.service-card__num {
  font-family: var(--font-display);
  font-size: 2.5rem;
  line-height: 1;
  color: var(--yellow);
}
.service-card::after {
  content: '';
  position: absolute;
  top: 18px; right: -30px;
  width: 120px; height: 10px;
  background: var(--magenta);
  transform: rotate(-16deg);
  opacity: .8;
}
.service-card:nth-child(even)::after { background: var(--yellow); }
.service-card .link-cta { margin-top: auto; }

/* =============================================================
   Media cards — cases & concepts
   ============================================================= */

.media-card {
  /* Колонка, а не сетка: описание забирает остаток высоты, поэтому
     список и нижняя строка стоят у низа одинаково во всех карточках
     ряда — и когда текста много, и когда мало. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.media-card__media {
  position: relative;
  flex: none;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--ink-1);
}
.media-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.media-card:hover .media-card__media img { transform: scale(1.05); }
.media-card__media .badge { position: absolute; top: 12px; left: 12px; }
.media-card__index {
  position: absolute;
  top: 12px; right: 12px;
  display: grid; place-content: center;
  min-width: 30px; height: 30px;
  padding-inline: 8px;
  border-radius: var(--r-sm);
  background: var(--yellow);
  color: var(--text-on-accent);
  font-size: .6875rem;
  font-weight: 800;
}
.media-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  gap: var(--sp-3);
  padding: clamp(1.1rem, 2vw, 1.5rem);
}
/* Описание тянется на весь остаток и обрезается — остальное
   читается на странице самой идеи или услуги. */
.media-card__body > .body-text {
  flex: 1 1 auto;
  min-height: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}
.media-card__body > .concept-card__mini,
.media-card__body > ul,
.media-card__body > .media-card__foot,
.media-card__body > .link-cta { flex: none; }
.media-card__type {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--magenta-soft);
}
.media-card .link-cta { margin-top: 0; }

/* Нижняя строка карточки каталога: ссылка слева, стоимость справа.
   Прижата к низу вместо самой ссылки — та теперь внутри строки. */
.media-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
}
.media-card__foot .link-cta { margin-top: 0; }

/* Стоимость — информация, а не ссылка: тот же набор, что у ссылки
   рядом, но без стрелки и без перехода. */
.concept-price {
  font-weight: 700;
  font-size: var(--fs-xs);
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* =============================================================
   Метки и стоимость

   Категория, формат, тип события и строка стоимости — это один и
   тот же элемент интерфейса: белая надпись в фиолетовой обводке,
   скруглённой по высоте, без углов. Встречается в семи местах, и
   собран здесь, чтобы вид правился один раз, а не семь.

   Кегль, разрядка и положение у каждого места свои — они заданы
   рядом со своим блоком и отсюда не переопределяются. Поля в em,
   поэтому обводка одинаково сидит и на 8 px в карточке, и на 20 px
   на странице.
   ============================================================= */

.idea-card__type,
.idea-card__price,
.case-card__type,
.cs-card__type,
.media-card__type,
.concept-price,
.dm__chip,
.detail-page__type,
.detail-page__price,
.detail-page__tag {
  display: inline-flex;
  align-items: center;
  /* В колонке-флексе и в сетке метка иначе растянулась бы во всю
     ширину: обводка должна обнимать текст. */
  align-self: flex-start;
  justify-self: start;
  width: fit-content;
  padding: .3em .85em;
  border: 1px solid var(--violet-line);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
}

/* Метка категории в карточках — плашка 103 × 15 с заливкой тем же
   фиолетовым на 21 %. Высота задана макетом, поэтому поля сверху и
   снизу не нужны. Правило идёт после общего: иначе сокращённая
   запись padding выше его перебивает. */
.idea-card__type,
.case-card__type,
.cs-card__type,
.media-card__type {
  min-height: min(.781vw, 15px);                 /* 15 на 1920 */
  padding-block: 0;
  background: rgba(151, 0, 255, .21);
}

/* Плашка стоимости: подложка тем же фиолетовым на 20 % и скругление
   11 — не «таблетка». Здесь же, после общего правила, иначе оно
   гасит заливку своим background: transparent. */
.idea-card__price {
  border-radius: 11px;
  background: rgba(151, 0, 255, .2);
}
/* Подпись жёлтая, сумма белая — как в макете. */
.idea-card__price-label { color: #f8ef01; }

/*
 * Высоту обводка занимает честно, не влезая в соседей.
 *
 * Был соблазн вернуть её отрицательными полями, чтобы блок остался
 * прежней высоты, — но тогда рамка метки наезжает на фотографию
 * сверху. Поэтому плашка просто выше текста, а карточки, которые
 * раньше держали жёсткую высоту из макета, теперь задают её как
 * минимальную и подрастают на эту разницу.
 */


/* =============================================================
   Concept tabs
   ============================================================= */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}

.tab {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: .8rem 1.1rem;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--ink-1);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-2);
  transition: all var(--t-fast) var(--ease);
}
.tab:hover { color: var(--text); border-color: var(--line-2); }
.tab b {
  display: inline-grid;
  place-content: center;
  min-width: 24px; height: 22px;
  padding-inline: 6px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .07);
  font-size: .6875rem;
}
.tab[aria-selected='true'] {
  background: var(--yellow);
  border-color: var(--yellow);
  color: var(--text-on-accent);
}
.tab[aria-selected='true'] b { background: rgba(0, 0, 0, .18); color: var(--text-on-accent); }

.concept-grid { display: grid; gap: var(--sp-4); }
@media (min-width: 680px) { .concept-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) { .concept-grid { grid-template-columns: repeat(3, 1fr); } }

.concept-card__mini {
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .025);
  border: 1px solid var(--line);
}
.concept-card__mini h4 {
  margin: 0;
  font-size: .625rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--yellow);
}
.concept-card__mini ul { padding-left: 1.1rem; display: grid; gap: 5px; }
.concept-card__mini li { font-size: var(--fs-sm); color: var(--text-2); line-height: 1.45; }

/* =============================================================
   Footer
   ============================================================= */

.site-footer {
  position: relative;
  z-index: var(--z-content);
  border-top: 1px solid var(--line);
  background: rgba(8, 8, 10, .9);
  margin-top: var(--sp-7);
}

.site-footer__top {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-7);
}
/* Колонок в подвале столько, сколько их завёл редактор, плюс контакты
   и документы. С фиксированной сеткой лишняя колонка уезжала во второй
   ряд и подвал становился вдвое выше — поэтому ряд гибкий. */
@media (min-width: 860px) {
  .site-footer__top { display: flex; flex-wrap: wrap; }
  .site-footer__brand { flex: 1.6 1 240px; }
  .footer-col { flex: 1 1 150px; }
}

.site-footer__brand { display: grid; gap: var(--sp-4); align-content: start; }
.site-footer__brand img { width: 150px; }

.footer-col h4 {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--text-3);
}
.footer-col ul { list-style: none; display: grid; gap: var(--sp-2); }
.footer-col a { font-size: var(--fs-sm); color: var(--text-2); transition: color var(--t-fast) var(--ease); }
.footer-col a:hover { color: var(--yellow); }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  justify-content: space-between;
  align-items: center;
  padding-block: var(--sp-4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-xs);
  color: var(--text-3);
}

/* =============================================================
   Detail pages
   ============================================================= */

.page-hero {
  display: grid;
  gap: var(--sp-6);
  padding-block: clamp(2rem, 5vw, 3.5rem) var(--sp-7);
  align-items: center;
}
@media (min-width: 940px) { .page-hero { grid-template-columns: minmax(0, 1fr) minmax(0, .95fr); } }

.page-hero__media img {
  width: 100%;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
}

.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  padding-top: var(--sp-5);
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.breadcrumbs a:hover { color: var(--yellow); }
.breadcrumbs span[aria-hidden] { opacity: .5; }

.detail-grid { display: grid; gap: var(--sp-4); }
@media (min-width: 860px) { .detail-grid { grid-template-columns: repeat(3, 1fr); } }

.detail-card { display: grid; gap: var(--sp-3); align-content: start; }
.detail-card ul { padding-left: 1.15rem; display: grid; gap: var(--sp-2); color: var(--text-2); }
.detail-card--accent { border-color: var(--line-accent); background: linear-gradient(170deg, rgba(236,40,252,.1), var(--ink-2) 60%); }

.stat-grid { display: grid; gap: var(--sp-4); }
@media (min-width: 620px) { .stat-grid { grid-template-columns: repeat(3, 1fr); } }
.stat {
  display: grid;
  gap: var(--sp-1);
  padding: var(--sp-5);
  border-radius: var(--r-lg);
  background: var(--ink-2);
  border: 1px solid var(--line);
  text-align: center;
}
.stat b { font-family: var(--font-display); font-size: clamp(2rem, 4vw, 2.75rem); color: var(--yellow); line-height: 1; }
.stat span { font-size: var(--fs-sm); color: var(--text-3); }

.cta-band {
  display: grid;
  gap: var(--sp-4);
  align-items: center;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border-radius: var(--r-xl);
  border: 1px solid var(--line-accent);
  background: linear-gradient(130deg, rgba(236, 40, 252, .14), var(--ink-1) 55%);
}
@media (min-width: 760px) { .cta-band { grid-template-columns: 1fr auto; } }

.notice {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-md);
  border: 1px solid var(--line-warm);
  background: rgba(254, 251, 5, .05);
  color: var(--text-2);
  font-size: var(--fs-sm);
  line-height: 1.5;
}

/* Gallery ----------------------------------------------------- */
.gallery { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  cursor: zoom-in;
  transition: transform var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.gallery img:hover { transform: scale(1.02); border-color: var(--line-accent); }

/* Полноэкранный просмотр фотографий --------------------------- */
.lbx {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 12px;
  padding: 16px;
  background: rgba(4, 4, 6, .94);
  backdrop-filter: blur(10px);
}
.lbx__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: 44px;
}
.lbx__count {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--text-3);
}
.lbx__close {
  width: 44px; height: 44px;
  display: grid; place-content: center;
  border-radius: var(--r-md);
  background: var(--yellow);
  color: var(--text-on-accent);
  font-size: 1.4rem;
  font-weight: 800;
}

.lbx__stage { position: relative; display: grid; place-items: center; min-height: 0; }
.lbx__img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--r-lg);
  /* иначе свайп по фото превращается в перетаскивание картинки */
  user-select: none;
  -webkit-user-drag: none;
}

.lbx__nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  border: 1px solid var(--line);
  transition: background var(--t-fast) var(--ease);
}
.lbx__nav:hover { background: rgba(255, 255, 255, .2); }
.lbx__nav--prev { left: 8px; }
.lbx__nav--next { right: 8px; }
/* Стрелка — та же маска, что у кнопок сайта. */
.lbx__nav::before {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 22px; height: 15px;
  background: var(--text);
  -webkit-mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
  mask: url('../img/decor/arrow-right.svg') center / contain no-repeat;
}
.lbx__nav--prev::before { rotate: 180deg; }

.lbx__thumbs {
  display: flex;
  gap: 8px;
  justify-content: center;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.lbx__thumb {
  flex: none;
  width: 92px;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-sm);
  border: 2px solid transparent;
  overflow: hidden;
  opacity: .55;
  transition: opacity var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.lbx__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lbx__thumb:hover { opacity: .85; }
.lbx__thumb.is-on { opacity: 1; border-color: var(--yellow); }

@media (max-width: 719px) {
  .lbx { padding: 10px; }
  .lbx__nav { width: 42px; height: 42px; }
  .lbx__thumb { width: 64px; }
}

/* List pages -------------------------------------------------- */
.list-head { display: grid; gap: var(--sp-4); padding-block: var(--sp-6) var(--sp-7); max-width: 48rem; }

/* Toast ------------------------------------------------------- */
.toast-host {
  position: fixed;
  z-index: var(--z-toast);
  bottom: var(--sp-5);
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  gap: var(--sp-2);
  width: min(420px, calc(100% - 2rem));
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: .9rem 1.1rem;
  border-radius: var(--r-md);
  background: var(--ink-3);
  border: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-sm);
  animation: toastIn .25s var(--ease-out);
}
.toast--ok     { border-color: rgba(55, 214, 122, .4); }
.toast--error  { border-color: rgba(255, 92, 122, .45); }
@keyframes toastIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* =============================================================
   Плашка о cookie
   ============================================================= */

.cookie-bar {
  position: fixed;
  z-index: var(--z-toast);
  left: 50%;
  bottom: var(--sp-4);
  transform: translateX(-50%);
  width: min(var(--container), 100% - var(--gutter) * 2);
  display: grid;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-lg);
  background: rgba(13, 13, 16, .96);
  backdrop-filter: blur(16px);
  border: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg);
  animation: cookieIn .35s var(--ease-out);
}
.cookie-bar[hidden] { display: none; }

@media (min-width: 720px) {
  .cookie-bar { grid-template-columns: minmax(0, 1fr) auto; }
}

@keyframes cookieIn {
  from { opacity: 0; transform: translate(-50%, 16px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .cookie-bar { animation: none; }
}

.cookie-bar__text {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--text-2);
}
.cookie-bar__text a { color: var(--yellow); text-decoration: underline; text-underline-offset: .15em; }
.cookie-bar__text a:hover { color: var(--yellow-soft); }

.cookie-bar .btn { white-space: nowrap; }

/* =============================================================
   Правовые страницы
   ============================================================= */

.legal {
  display: grid;
  gap: var(--sp-5);
  align-content: start;
  max-width: 48rem;
  /* Документ бывает в три строки: держим высоту экрана, чтобы подвал
     не подъезжал под заголовок. */
  min-height: calc(100svh - var(--header-h) - var(--sp-7));
  padding-block: var(--sp-6) var(--section-y);
}
.legal__updated { font-size: var(--fs-xs); color: var(--text-3); }

.legal__body { color: var(--text-2); line-height: 1.7; }
.legal__body > * + * { margin-top: var(--sp-4); }
.legal__body h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 700;
  color: var(--text);
  margin-top: var(--sp-6);
}
.legal__body h3 { font-size: 1.0625rem; font-weight: 700; color: var(--text); margin-top: var(--sp-5); }
.legal__body ul, .legal__body ol { padding-left: 1.3rem; display: grid; gap: var(--sp-2); }
.legal__body a { color: var(--magenta-soft); text-decoration: underline; }

/* =============================================================
   Плотность блоков главной

   Собрано в одном месте, чтобы было понятно, чем оплачено условие
   «каждый блок помещается в экран целиком».
   ============================================================= */

/* Карточки не держат лишнюю высоту «про запас» */
.manifest-card,
.service-card,

.manifest-card { gap: var(--sp-2); }
.service-card  { gap: var(--sp-2); }
.service-card__num { font-size: 2.1rem; }

.media-card__media { aspect-ratio: 16 / 9; }
.media-card__body  { gap: var(--sp-2); padding: clamp(.9rem, 1.8vh, 1.3rem); }
.media-card__body h3 { font-size: clamp(1.05rem, 1.5vw, 1.3rem); }

/* На главной высота обложки считается от экрана, иначе карточка
   растёт вместе с шириной и блок перестаёт помещаться. */
#concepts .tabs { margin-bottom: clamp(.7rem, 1.8vh, 1.3rem); }

/* Описание в карточке — короткий анонс, подробности по ссылке */
.media-card__body .body-text,
.service-card .body-text {
  font-size: var(--fs-sm);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Шапка блока: лид короткий, маскот не задаёт высоту */
.section-head__main .lead {
  font-size: var(--fs-sm);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.section-head__mascot {
  width: auto;
  max-height: clamp(84px, 15vh, 150px);
  max-width: 170px;
  object-fit: contain;
}
.section-head__aside .mark { font-size: clamp(1rem, 1.5vw, 1.35rem); }

.section-actions-row .btn { min-height: 46px; padding: .55rem 1.3rem; font-size: var(--fs-sm); }

/* На низких экранах блок сокращается до заголовка и сути: подводка
   и маскот уходят, чтобы содержимое всё равно помещалось целиком. */
@media (max-height: 780px) {
  .section--screen .section-head__main .lead,
  .section--screen .section-head__mascot,
  .section--screen .section-head__aside { display: none; }
  .section--screen .section-head h2 { font-size: var(--fs-h3); }
}

/* На главной карточки показывают только суть — подробности на своих
   страницах и в окне услуги. */
#concepts .concept-card__mini { display: none; }

.grid-3, .concept-grid { gap: clamp(.75rem, 1.6vh, 1.1rem); }

.section-actions-row { margin-top: clamp(.9rem, 2vh, 1.4rem); }


/* =============================================================
   Страница «Кейсы»

   Макет «Широкие компы 8» (1920×1205). Колонка 1444 (238…1682),
   карточка 470×408 с шагом 487 — зазор 17, нижняя плашка 1444×173
   в обводке 2 px. Размеры внутри карточки — доли её ширины (470),
   размеры по странице — доли колонки.
   ============================================================= */

.cases-page {
  --kicker-w: 12.55%;      /* 181.2 / 1444 */
  --spray-w:  min(15.573vw, 299px);  /* 299 на 1920 */
}

.cases-page__head {
  display: grid;
  justify-items: start;
  /* Немного воздуха после хлебных крошек — по просьбе заказчика
     шапка страницы стоит чуть ниже, чем в макете. */
  margin-top: 1.117%;
}

.cases-page__kicker {
  position: relative;
  z-index: 1;
  display: block;
  filter: brightness(0) invert(1);               /* см. .sec-head__kicker */
  width: 100%;                                   /* ширину задаёт .kicker-wrap */
  /* У SVG стоит preserveAspectRatio="none", своей пропорции у него
     больше нет — задаём её здесь, иначе высота уедет в 150 px. */
  aspect-ratio: 181.2 / 73.2;
}
.cases-page__head .kicker-wrap {
  margin-bottom: 1.56%;                          /* надпись придвинута к заголовку: 14 между краской */
}

.cases-page__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 3.385vw, 4.0625rem);    /* 65 на 1920 */
  line-height: .923;                             /* 60 / 65 */
  letter-spacing: .0154em;                       /* 1 px при кегле 65 */
  color: var(--text);
}

.cases-page__lead {
  margin: 1.639% 0 0;                            /* выставлен по макетным 31.3 между краской */
  max-width: 65.1%;                              /* 940 / 1444: два ряда с теми же переносами */
  font-size: clamp(1rem, 1.146vw, 1.375rem);     /* 22 на 1920 */
  line-height: 1.0773;                           /* 23.7 / 22 */
  color: var(--text);
}

.cases-page__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.177%;                                   /* 17 / 1444 */
  margin-top: 3.76%;                             /* выставлен по макетным 38.3 до обводки */
}

/* ---- Карточка кейса ---------------------------------------- */

.cs-card {
  /* Колонка, а не сетка: описание забирает весь остаток высоты,
     поэтому плашка «момента» и ссылка стоят у низа одинаково во
     всех карточках — и когда текста много, и когда мало. */
  display: flex;
  flex-direction: column;
  /* Нижняя граница, а не жёсткая высота: описание не должно
     обрезаться посреди строки, когда содержимого чуть больше. */
  min-height: min(21.25vw, 408px);
  padding: 0 0 5.183%;                           /* низ по макету, с поправкой на выносные */
  border-radius: var(--r-plate);                 /* 36 по макету */
  background: var(--header-bg);
  overflow: hidden;
  transition: transform var(--t-fast) var(--ease);
}
.cs-card:hover { transform: translateY(-3px); }

.cs-card__media {
  flex: none;
  aspect-ratio: 470 / 150;
  overflow: hidden;
  background: var(--ink-2);
}
.cs-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.cs-card:hover .cs-card__media img { transform: scale(1.04); }

.cs-card__type {
  margin: 3.053% 5.53% 0;                        /* краска на 165.1 от верха карточки */
  font-size: clamp(9px, .521vw, 10px);           /* 10 на 1920 */
  line-height: 1.2;
  text-transform: uppercase;
}

.cs-card__title {
  margin: 2.119% 5.53% 0;                        /* краска на 190.4 */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.083vw, 1.3rem);       /* 20.8 на 1920 */
  line-height: 1.25;
  letter-spacing: .048em;                        /* 1 px при кегле 20.8 */
  color: #f5f5f5;
}

.cs-card__text {
  margin: 2.489% 24.26% 0 5.53%;                 /* краска на 223.6, колонка 330 */
  font-size: clamp(.8125rem, .833vw, 1rem);      /* 16 на 1920 */
  line-height: 1.0625;                           /* 17 / 16 */
  color: var(--text);
  /* Остаток высоты уходит сюда, сам текст обрезан двумя строками —
     целиком он виден на странице кейса. Нижняя граница ровно в две
     строки: без неё остаток мог оказаться меньше, и вторая строка
     обрезалась посередине. */
  flex: 1 1 auto;
  min-height: 2.125em;                           /* 2 × 1.0625 */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Плашка «тот самый момент»: заливка плоская, не градиент. */
.cs-moment {
  flex: none;
  display: grid;
  margin: 2.985% 6.6% 0 5.53%;                   /* верх плашки на 272 */
  padding: 2.43% 2.553% 2.436%;                  /* высота плашки ровно 74 */
  border: 1px solid var(--violet-line);
  border-radius: 11px;
  background: rgba(151, 0, 255, .19);
}
.cs-moment__label {
  font-size: clamp(10px, .625vw, 12px);          /* 12 на 1920 */
  line-height: 1.2;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--violet-line);
}
.cs-moment__text {
  margin-top: 1.9%;
  font-size: clamp(10px, .625vw, 12px);          /* 12 на 1920 */
  line-height: 1.167;                            /* 14 / 12 */
  color: var(--text);
}

.cs-card__link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: .8em;
  margin: 4.606% 5.53% 0;                        /* краска на 368.3 */
  font-weight: 700;
  font-size: clamp(11px, .677vw, 13px);          /* 13 на 1920 */
  line-height: 1.23;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #f8ef01;
}
.cs-card:hover .cs-card__link .arrow-i { transform: translateX(3px); }

/* ---- Нижняя плашка ------------------------------------------ */

.cta-plate {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4%;
  margin-top: 2.98%;                             /* выставлен по макетным 43 до обводки */
  /* Высота плашки в макетах всегда 177, а текста внутри бывает и
     одна строка, и две — поэтому фиксированная высота и центровка
     по вертикали, а поля сверху и снизу только как запас. */
  min-height: min(9.219vw, 177px);
  padding: min(1.25vw, 24px) 3.95% min(1.25vw, 24px) 3.6%;   /* 57 справа и 52 слева от 1444 */
  border: 2px solid var(--violet-line);
  border-radius: 38px;                           /* 36 внутри обводки */
  background-color: var(--header-bg);
  /* Градиент из макета: #9700FF уходит в серый, вся заливка
     на 42 % прозрачности. Промежуточные точки повторяют
     смешивание Figma — цвет и прозрачность там считаются
     раздельно, и середина получается темнее. */
  background-image: linear-gradient(175.87deg,
    rgba(151, 0, 255, .42)   8.23%,
    rgba(144, 30, 222, .315) 22.66%,
    rgba(136, 61, 188, .21)  37.08%,
    rgba(129, 91, 155, .105) 51.51%,
    rgba(121, 121, 121, 0)   65.93%);
}

.cta-plate__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.083vw, 2.5rem);     /* 40 на 1920 */
  line-height: 1;
  letter-spacing: .025em;                        /* 1 px при кегле 40 */
  color: var(--text);
}
.cta-plate__text {
  margin: .963% 0 0;                             /* краска на 96.3 от верха плашки */
  font-size: clamp(1rem, 1.25vw, 1.5rem);        /* 24 на 1920 */
  line-height: 1.0417;                           /* 25 / 24 */
  color: var(--text);
}

.cta-plate__btn {
  flex: none;
  min-height: 69px;
  padding: 0 26px 0 27px;
  gap: 10px;
  border-radius: 29px;
  font-size: clamp(14px, .938vw, 18px);          /* 18 на 1920 */
  letter-spacing: 0;
  --arrow-w: 26px;
  --arrow-h: 17px;
}

@media (max-width: 1099px) {
  .cases-page__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .cases-page__lead { max-width: 100%; }
}

@media (max-width: 719px) {
  .cases-page__grid { grid-template-columns: minmax(0, 1fr); }
  .cs-card { height: auto; padding: 0 0 24px; border-radius: 24px; }
  .cs-card__text { flex: none; -webkit-line-clamp: 3; line-clamp: 3; }
  .cs-card__type,
  .cs-card__title,
  .cs-card__link { margin-inline: 24px; }
  .cs-card__text { margin-inline: 24px; }
  .cs-card__type { margin-top: 16px; }
  .cs-moment { margin: 16px 24px 0; padding: 12px 14px 14px; }
  .cs-card__link { margin-top: 18px; }

  .cta-plate {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
    min-height: 0;
    padding: 24px 20px 26px;
    border-radius: 24px;
  }
  .cta-plate__btn { align-self: stretch; justify-content: center; min-height: 56px; }
}

/* =============================================================
   Страницы кейса, направления и идеи

   Один компонент на три макета: «Широкие компы 9» (кейс),
   «10» (направление) и «11» (идея). Общая сетка 1444 (238…1682),
   плашки со скруглением 36 и обводкой 1 px; различаются цвет
   обводки, кегли внутри плашек и вертикальный шаг — это вынесено
   в модификаторы .detail-page--case / --service / --concept.
   Направление и идея нарисованы в одном ключе, поэтому общие для
   них правила перечислены парой селекторов.

   Проценты считаются от разных баз, и это важно при правке:
     · у секционных отступов  — ширина контейнера (1444);
     · у шапки изнутри        — левая колонка сетки (870,6);
     · у снимка               — его колонка сетки (573,4);
     · у полей плашек         — ширина самой плашки (472).
   ============================================================= */

.detail-page--case { --plate-line: var(--violet-line); }
.detail-page--service,
.detail-page--concept { --plate-line: #f8ef01; }

/* ---- Шапка --------------------------------------------------- */

.detail-page__head {
  display: grid;
  /* Снимок занимает правые 573 из 1444, текст — остальное. */
  grid-template-columns: minmax(0, 1fr) 39.71%;
  align-items: start;
}
.detail-page--case .detail-page__head { margin-top: .776%; }      /* краска подписи на 146 */
.detail-page--service .detail-page__head,
.detail-page--concept .detail-page__head { margin-top: 1.482%; }  /* краска подписи на 134,7 */

.detail-page__type {
  margin: 0;
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 на 1920 */
  line-height: 1.2;
  letter-spacing: .105em;
}
/* В макетах направления и идеи разрядки нет: с ней строка уезжает
   на 25 px. */
.detail-page--service .detail-page__type,
.detail-page--concept .detail-page__type { letter-spacing: 0; text-transform: uppercase; }

.detail-page__title {
  margin: 2.084% 0 0;                            /* краска на 194,2 */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 3.385vw, 4.0625rem);    /* 65 на 1920 */
  line-height: .923;                             /* 60 / 65 */
  letter-spacing: .0154em;                       /* 1 px при кегле 65 */
  color: var(--text);
}
.detail-page--service .detail-page__title,
.detail-page--concept .detail-page__title { margin-top: .865%; }   /* краска на 179,2 */

.detail-page__lead {
  margin: 2.434% 0 0;
  max-width: 52.6%;
  font-size: clamp(1rem, 1.146vw, 1.375rem);     /* 22 на 1920 */
  line-height: 1.227;                            /* 27 / 22 */
  color: var(--text);
}
.detail-page--service .detail-page__lead,
.detail-page--concept .detail-page__lead {
  max-width: 83.9%;                              /* 730 из 870,6: как в макете */
}
.detail-page--service .detail-page__lead { margin-top: 2.444%; }  /* краска на 319,3 */
.detail-page--concept .detail-page__lead { margin-top: 4.064%; }  /* краска на 333,4 */

/* ---- Шапка идеи: цена, оговорка, две кнопки ------------------ */

.detail-page__price {
  margin: 2.366% 0 0;                            /* краска на 408,6 */
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 на 1920 */
  line-height: 1.2;
  letter-spacing: 0;
  text-transform: uppercase;
}

/* Оговорка про «не фиксированный пакет» — та же подложка и то же
   скругление, что у меток формата на странице направления. */
.detail-page__notice {
  margin: 1.746% 0 0;                            /* обводка на 456,5 */
  max-width: 91.2%;                              /* 794 из 870,6 */
  padding: 7px 19.5px 8px;
  border: 1px solid var(--plate-line);
  border-radius: 8.5px;
  background: rgba(248, 239, 1, .12);
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 на 1920 */
  /* В макете 17/20, но на экране строки слипаются — держим тот же
     ритм, что и у основного текста плашек. Поля сверху и снизу
     уменьшены на полуинтерлиньяж, чтобы врезка не раздулась. */
  line-height: 1.15;                             /* 23 / 20 */
  color: var(--plate-line);
}

.detail-page--concept .detail-page__actions { margin-top: 3.733%; }  /* верх кнопки на 543 */
/* Вторая кнопка в макете идеи обведена белым в один пиксель. */
.detail-page__btn--ghost { border-width: 1px; border-color: #fff; }

.detail-page__tags { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 3.038%; }
.detail-page__tag {
  /* Высота метки задана макетом, поля сверху и снизу не нужны. */
  padding-block: 0;
  min-height: 35px;
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 на 1920 */
  line-height: 1.2;
  letter-spacing: .017em;
  text-transform: uppercase;
}
.detail-page--service .detail-page__tags { margin-top: 2.573%; }   /* обводка на 418,5 */

/* Кнопка в шапке ниже обычной (53 вместо 67) и со своей стрелкой. */
.detail-page__actions { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 5%; }
.detail-page__btn {
  min-height: 53px;
  padding: 0 28px 0 27px;
  gap: 12px;
  font-size: clamp(14px, .938vw, 18px);          /* 18 на 1920 */
  letter-spacing: 0;
  --arrow-w: 23px;
  --arrow-h: 15px;
}

/* Снимок прижат к правому краю колонки. */
.detail-page__hero {
  grid-column: 2;
  grid-row: 1;
  width: 100%;
  aspect-ratio: 573.4 / 244;
  object-fit: cover;
  border-radius: var(--r-plate);                 /* 36 по макету */
  margin-top: 6.11%;                             /* верх снимка на 180 */
}
.detail-page--service .detail-page__hero,
.detail-page--concept .detail-page__hero {
  aspect-ratio: 573.4 / 274;
  margin-top: 8.563%;                            /* верх снимка на 179 */
}

/* ---- Плашки с цифрами --------------------------------------- */

.detail-page__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.108%;                                   /* 16 между обводками */
  margin-top: 3.498%;                            /* верх плашек на 475 */
}
.detail-page--service .detail-page__stats { margin-top: 2.978%; }  /* верх плашек на 593 */

.cd-stat {
  display: grid;
  align-content: center;
  justify-items: center;
  /* Процент у row-gap считался бы от высоты плашки — берём от ширины окна. */
  row-gap: min(.47vw, 9px);                      /* цифра на 28, подпись на 91,6 */
  min-height: min(7.396vw, 142px);
  padding: 4% 4%;
  border: 1px solid var(--plate-line);
  border-radius: var(--r-plate);                 /* 36 по макету */
  background: var(--header-bg);
  text-align: center;
}
.cd-stat__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 3.333vw, 4rem);         /* 64 на 1920 */
  /* Рамка цифры обнимает саму краску: в макете она 50 при кегле 64,
     с обычным интерлиньяжем подпись уезжала бы вниз. */
  line-height: .78;
  letter-spacing: .0156em;                       /* 1 px при кегле 64 */
  color: var(--plate-line);
}
.cd-stat__label {
  font-size: clamp(.875rem, 1.042vw, 1.25rem);   /* 20 на 1920 */
  line-height: 1.2;
  color: #9c9c9c;
}

/*
 * В макете направления значение набрано мельче и стоит не по
 * центру плашки, а по центру отведённой ему строки: подпись
 * держится на одной высоте и у коротких, и у двухстрочных
 * значений. Поэтому не align-content: center, а сетка с первой
 * строкой фиксированной высоты, внутри которой значение
 * центрируется. Третья строка текста просто растит плашку вниз.
 */
.detail-page--service .cd-stat {
  align-content: start;
  grid-template-rows: minmax(min(3.125vw, 60px), auto) auto;
  row-gap: min(.396vw, 7.6px);
  padding: 5.18% 4%;                             /* 24,45 сверху от ширины 472 */
}
.detail-page--service .cd-stat__value {
  align-self: center;
  font-size: clamp(1.25rem, 1.667vw, 2rem);      /* 32 на 1920 */
  line-height: .9375;                            /* 30 / 32 */
  letter-spacing: .03125em;                      /* 1 px при кегле 32 */
}
.detail-page--service .cd-stat__label { line-height: .85; }  /* 17 / 20 */

/* ---- Плашки с текстом --------------------------------------- */

.detail-page__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 1.108%;                            /* 16 между обводками */
  /* Процент у row-gap считался бы от высоты сетки — берём от ширины окна. */
  row-gap: min(.99vw, 19px);
  margin-top: 2.56%;                             /* верх плашек на 654 */
}

.cd-card {
  display: grid;
  align-content: start;
  min-height: min(12.76vw, 245px);
  padding: 8.505% 8.9% 8.5% 9.11%;               /* доли ширины плашки 472 */
  border: 1px solid var(--plate-line);
  border-radius: var(--r-plate);                 /* 36 по макету */
  background: var(--header-bg);
}
.cd-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.25rem, 1.771vw, 2.125rem);  /* 34 на 1920 */
  line-height: 1;
  letter-spacing: .0294em;                       /* 1 px при кегле 34 */
  color: var(--text);
}
.cd-card__text {
  margin-top: 4.109%;                            /* краска на 746,8 */
  font-size: clamp(1rem, 1.146vw, 1.375rem);     /* 22 на 1920 */
  line-height: 1;                                /* 22 / 22 */
  color: #9c9c9c;
}
.cd-card__text p { margin: 0 0 .6em; }
.cd-card__text p:last-child { margin-bottom: 0; }

/* «Тот самый момент» — ниже остальных и залита фиолетовым. */
.cd-card--moment {
  min-height: min(10.99vw, 211px);               /* 470 × 209 плюс обводка */
  padding-top: 8.058%;
  background: rgba(151, 0, 255, .15);
}
.cd-card--moment .cd-card__title { line-height: .882; }  /* 30 / 34 */
.cd-card--moment .cd-card__text { margin-top: 3.162%; color: var(--text); }

.detail-page--service .detail-page__grid { margin-top: 2.562%; }   /* верх плашек на 772 */
.detail-page--concept .detail-page__grid { margin-top: 3.186%; }   /* верх плашек на 644 */

.detail-page--service .cd-card,
.detail-page--concept .cd-card {
  /* Снизу поле меньше, чем сверху: в макете плашка, которой не
     хватило высоты, дорастает до 299 — ровно на 41 ниже текста. */
  padding: 10.445% 9% 8.729% 9.322%;             /* 49,3 / 42,5 / 41,2 / 44 от ширины 472 */
}
.detail-page--service .cd-card { min-height: min(16.823vw, 323px); }  /* 470 × 321 */
/* Плашка идеи ниже и текст в ней поднят к заголовку. */
.detail-page--concept .cd-card {
  min-height: min(12.24vw, 235px);
  padding-top: 7.69%;                            /* 36,3 от ширины 472 */
}

.detail-page--service .cd-card__title,
.detail-page--concept .cd-card__title {
  font-size: clamp(1.25rem, 1.667vw, 2rem);      /* 32 на 1920 */
  line-height: .90625;                           /* 29 / 32 */
  letter-spacing: .03125em;                      /* 1 px при кегле 32 */
}
.detail-page--service .cd-card__text,
.detail-page--concept .cd-card__text {
  /* Процент считался бы от ширины текстового поля плашки, а она
     зависит от самих полей — берём отступ от ширины окна. */
  margin-top: min(1.224vw, 23.5px);              /* краска на 105,8 */
}

/* Маркированный список внутри плашки: маркер висит левее текста. */
.cd-list { margin: 0 0 0 -4.5px; padding: 0; list-style: none; }
.cd-list li { position: relative; padding-left: 18.5px; }
.cd-list li + li { margin-top: 0; }
.cd-list li::before { content: '•'; position: absolute; left: 0; top: 0; }

/* ---- Галерея ------------------------------------------------ */

.detail-page__gallery-title {
  margin: 7.286% 0 0;                            /* краска на 1214,2 */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 3.385vw, 4.0625rem);    /* 65 на 1920 */
  line-height: .923;
  letter-spacing: .0154em;
  color: var(--text);
}

.detail-page__gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 5.367%;                                   /* 77,5 / 1444 */
  margin-top: 2.293%;                            /* верх плашек на 1312 */
}
.detail-page--service .detail-page__gallery-title,
.detail-page--concept .detail-page__gallery-title { margin-top: 7.952%; }  /* краска на 1187,2 */
.detail-page--service .detail-page__gallery,
.detail-page--concept .detail-page__gallery { margin-top: 2.99%; }         /* верх плашек на 1285 */

.cd-shot {
  display: block;
  width: 100%;
  aspect-ratio: 430 / 254;
  border-radius: var(--r-plate);                 /* 36 по макету */
  overflow: hidden;
  background: var(--ink-2);
  cursor: zoom-in;
}
.cd-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.cd-shot:hover img { transform: scale(1.04); }

.detail-page .cta-plate { margin-top: 4.16%; }   /* верх обводки на 1626 */
/* У идеи галереи в макете нет, и нижняя плашка стоит ближе. */
.detail-page--concept .cta-plate { margin-top: 3.116%; }            /* верх обводки на 924 */
.detail-page--concept .detail-page__gallery + .cta-plate { margin-top: 4.16%; }

/* ---- Узкие экраны ------------------------------------------- */

@media (max-width: 1099px) {
  .detail-page__head { grid-template-columns: minmax(0, 1fr); row-gap: 24px; }
  .detail-page__hero { grid-column: 1; grid-row: 2; margin-top: 0; }
  .detail-page--service .detail-page__hero,
  .detail-page--concept .detail-page__hero { margin-top: 0; }
  .detail-page__lead,
  .detail-page--service .detail-page__lead,
  .detail-page--concept .detail-page__lead { max-width: 100%; }
  /* Макетные 17/20 на узком экране слипаются: кегль падает, а
     интерлиньяж вместе с ним. */
  .detail-page__notice { max-width: 100%; line-height: 1.4; padding: 12px 16px 13px; }
  .detail-page__stats,
  .detail-page__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  .detail-page__gallery { gap: 24px; }
  .cd-card { padding: 26px 24px 28px; }
  .cd-card--moment { padding-top: 26px; }
  .detail-page--service .cd-card,
  .detail-page--concept .cd-card { padding: 28px 24px 28px; }
  .detail-page--service .cd-stat { padding: 20px 16px; }
}

@media (max-width: 719px) {
  .detail-page__stats,
  .detail-page__grid,
  .detail-page__gallery { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .cd-stat { padding: 18px; border-radius: 24px; }
  .detail-page--service .cd-stat { padding: 18px; }
  .cd-card { border-radius: 24px; }
  .cd-shot { border-radius: 24px; }
}

/* =============================================================
   Окно направления («Как это работает»)

   Макет нарисован в натуральную величину: плашка 1200 × 866.
   Поэтому размеры здесь в пикселях, а не в долях контейнера —
   на узких экранах окно переключается в одну колонку.
   ============================================================= */

.dm {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: clamp(.75rem, 3vh, 2rem);
  background: rgba(4, 4, 6, .82);
  backdrop-filter: blur(10px);
  animation: dmFade .2s var(--ease-out);
}
.dm[hidden] { display: none; }

@keyframes dmFade { from { opacity: 0; } to { opacity: 1; } }

.dm__card {
  position: relative;
  display: grid;
  /* 556 + 63 + 470 = 1089 — ровно ширина плашки за вычетом полей. */
  grid-template-columns: 556fr 470fr;
  column-gap: 63px;
  /* 1200 × 866 в макете — это поле внутри обводки, она снаружи. */
  width: min(1202px, 100%);
  height: min(868px, 92svh);
  padding: 37px 66px 40px 45px;
  border: 1px solid var(--violet-line);
  border-radius: 48px;
  background: var(--header-bg);
  animation: dmIn .26s var(--ease-out);
}

@keyframes dmIn { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .dm, .dm__card { animation: none; }
}

/* Крестик — всегда поверх, вне прокрутки. */
.dm__close {
  position: absolute;
  z-index: 3;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  display: grid;
  place-content: center;
  border-radius: 50%;
  background: var(--yellow);
  color: var(--text-on-accent);
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1;
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.dm__close:hover { background: var(--yellow-soft); transform: scale(1.06); }

/* ---- Левая колонка ----------------------------------------- */

.dm__col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}

.dm__kicker {
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  color: #f8ef01;
}

.dm__title {
  margin: 21.5px 0 0;
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--text);
  overflow-wrap: break-word;
}

.dm__block { margin-top: 24px; width: 100%; }
/* Отбивки сняты с макета: перед каждым подзаголовком своя. */
.dm__block--short    { margin-top: 20.4px; }
.dm__block--formats  { margin-top: 21.5px; }
.dm__block--includes { margin-top: 24.7px; }
.dm__block--why      { margin-top: 34.6px; }
.dm__block--facts    { margin-top: 28.7px; }
.dm__block--short    .dm__sub { margin-bottom: 9px; }
.dm__block--formats  .dm__sub { margin-bottom: 5.3px; }
.dm__block--includes .dm__sub { margin-bottom: 8.9px; }
.dm__block--why      .dm__sub { margin-bottom: 10.5px; }
.dm__block--facts    .dm__sub { margin-bottom: 15.7px; }

.dm__sub {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  color: #f8ef01;
}

.dm__text {
  font-size: 14px;
  line-height: 1.143;                 /* 16 / 14 */
  color: #9c9c9c;
}
.dm__text p { margin: 0 0 8px; }
.dm__text p:last-child { margin-bottom: 0; }
.dm__text ul, .dm__text ol { margin: 0; padding-left: 1.1rem; }

/* Форматы — овальные чипы, вид общий (см. «Метки и стоимость»). */
.dm__chips { display: flex; flex-wrap: wrap; gap: 4px; }
.dm__chip {
  min-height: 18.5px;
  font-size: 8px;
  font-weight: 500;
  line-height: 1.2;
  text-transform: uppercase;
}

/* «Что можно взять» — отмеченные и неотмеченные пункты. */
.dm__check { display: grid; gap: 5px; list-style: none; margin: 0; padding: 0; }
.dm__check li {
  display: flex;
  align-items: center;
  gap: 8.5px;
  min-height: 17px;
  font-size: 14px;
  line-height: 1.143;
  color: #9c9c9c;
}
.dm__tick {
  position: relative;
  flex: none;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 1px solid #fff;
}
.dm__check li.is-on .dm__tick { background: #f8ef01; border-color: #f8ef01; }
/* Галочка из двух сторон рамки — отдельная картинка тут лишняя. */
.dm__check li.is-on .dm__tick::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 3px;
  width: 4px;
  height: 7px;
  border: 2px solid var(--header-bg);
  border-top: 0;
  border-left: 0;
  rotate: 45deg;
}

/* «Коротко в цифрах» — три плашки в жёлтой обводке. */
.dm__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5px; }
.dm__fact {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 5px;
  min-height: 87px;
  padding: 10px 12px;
  border: 1px solid #f8ef01;
  border-radius: 28px;
  background: var(--header-bg);
  text-align: center;
}
.dm__fact-label {
  font-size: 8px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #f8ef01;
}
.dm__fact-value {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.231;                 /* 16 / 13 */
  color: var(--text);
}

.dm__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 15px; margin-top: 40px; }
.dm__cta {
  min-height: 40px;
  padding: 0 22px;
  gap: 10px;
  font-size: 13px;
  letter-spacing: 0;
  --arrow-w: 17px;
  --arrow-h: 11px;
}
.dm__cta.btn--ghost { min-height: 42px; padding: 0 18px; border-width: 1px; border-color: #fff; }

/* ---- Правая колонка: фотографии ----------------------------- */

.dm__photos {
  display: grid;
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 30px;
  min-height: 0;
}
.dm__photo {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 16px;
  overflow: hidden;
  background: var(--ink-2);
  cursor: zoom-in;
}
.dm__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.dm__photo:hover img { transform: scale(1.03); }
/* «+N» на последней плитке, если снимков больше трёх. */
.dm__more {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  background: rgba(4, 4, 6, .55);
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
}

/* Если фотографий меньше трёх, колонка не растягивает их на всю
   высоту — иначе кадр выглядит неестественно вытянутым. */
.dm__photos:has(> :nth-child(1):last-child) { grid-template-rows: minmax(0, 243fr) minmax(0, 546fr); }
.dm__photos:has(> :nth-child(2):last-child) { grid-template-rows: repeat(2, minmax(0, 243fr)) minmax(0, 273fr); }

@media (max-width: 1099px) {
  /* Узкий экран: одна колонка, фотографии лентой над текстом. */
  .dm__card {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: 0;
    row-gap: 16px;
    padding: 24px 20px 28px;
    border-radius: 28px;
  }
  .dm__photos {
    order: -1;
    display: flex;
    gap: 10px;
  }
  /* Крестик приходится на ленту фотографий, тексту место под него
     освобождать не нужно. */
  .dm__photo { flex: 1 1 0; height: clamp(84px, 15vh, 150px); }
  .dm__facts { gap: 8px; }
  .dm__fact { min-height: 72px; border-radius: 20px; }
}

@media (max-width: 599px) {
  .dm__card { padding: 20px 16px 24px; border-radius: 22px; }
  .dm__title { font-size: 26px; }
  .dm__facts { grid-template-columns: minmax(0, 1fr); }
  .dm__actions { align-self: stretch; align-items: stretch; }
  /* Подпись длинной кнопки в 390 px влезает только с узкими полями. */
  .dm__cta { justify-content: center; padding-inline: 12px; }
}
/* Preview ribbon ---------------------------------------------- */
.preview-ribbon {
  position: fixed;
  left: var(--sp-4);
  bottom: var(--sp-4);
  z-index: var(--z-toast);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  padding: .65rem .9rem;
  border-radius: var(--r-md);
  background: var(--yellow);
  color: var(--text-on-accent);
  font-size: .6875rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  box-shadow: 4px 4px 0 var(--magenta);
}
.preview-ribbon a { text-decoration: underline; }

/* =============================================================
   Карточка с виньеткой

   Общий вид для карточек с фотографией: «Кейсы» и «Идеи» на
   главной и их каталоги. Раньше фотография была полоской сверху,
   а текст лежал на плашке под ней. Теперь наоборот: снимок
   занимает карточку целиком, а текст читается за счёт затемнения,
   которое поднимается от нижнего края.

   Опорные числа — макеты «Широкие компы 3_2» (карточка 470 × 379)
   и экран с идеями: рубрика кеглем 13 в плашке высотой 29,
   описание Roboto Regular 24/24, подпись ссылки 13. Все кегли
   взяты из текстового слоя макета, а не на глаз.

   Блок идёт последним в файле: он намеренно перекрывает прежние
   правила .case-card / .idea-card / .cs-card / .media-card, а не
   переписывает их — так видно, что в карточке изменилось.
   ============================================================= */

.photo-card {
  position: relative;
  display: flex;
  flex-direction: column;
  /* Текст прижат к низу: над ним остаётся чистая часть снимка. */
  justify-content: flex-end;
  padding: 0;
  border-radius: var(--r-plate);
  background: var(--header-bg);
  overflow: hidden;
  color: inherit;
}

/*
 * Снимок — подложка сверху карточки, а не строка сетки.
 *
 * Высота задана пропорцией, а не растяжкой на всю карточку, и вот
 * почему. object-fit: cover вписывает снимок в коробку по
 * короткой стороне и срезает лишнее. Коробка во всю карточку —
 * это 470 × 379, почти квадрат, а снимки широкие: кадр резался по
 * бокам и выезжал на зрителя. В макете снимок — широкая полоса
 * 470 × 185, и кадр виден целиком, без приближения.
 *
 * Нижний край снимка растворяется маской, чтобы под виньеткой не
 * было видно стыка с фоном карточки.
 */
.photo-card > .case-card__media,
.photo-card > .idea-card__media,
.photo-card > .cs-card__media,
.photo-card > .media-card__media {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: auto;
  z-index: 0;
  margin: 0;
  height: auto;
  /* Снимок доходит до описания: рубрика и заголовок лежат на нём,
     а затемнение начинается ниже — там, где идёт основной текст. */
  aspect-ratio: 470 / 263;
  flex: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}

/* В каталогах карточка заметно выше — полоса снимка тоже, иначе
   под ней остаётся пустая темнота в половину карточки. */
.cs-card.photo-card > .cs-card__media,
.media-card.photo-card > .media-card__media { aspect-ratio: 470 / 265; }

.photo-card > .case-card__media img,
.photo-card > .idea-card__media img,
.photo-card > .cs-card__media img,
.photo-card > .media-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Виньетка.
 *
 * Градиент висит на самой обёртке текста, а не отдельным слоем с
 * фиксированной высотой. Поэтому затемнение всегда ровно такой
 * высоты, какой получился текст: у карточки идеи на главной оно
 * закрывает примерно половину снимка, у каталожной карточки с
 * перечнем — больше. Разбираться с этим вручную для четырёх
 * разных карточек не нужно.
 *
 * Верхние поля и есть зона растушёвки: текст начинается там, где
 * заливка уже почти непрозрачна.
 */
.photo-card__body {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  /* Растягиваться нельзя: обёртка должна быть ровно по тексту,
     иначе затемнение накроет весь снимок. */
  flex: none;
  padding: min(3.65vw, 70px) 6.28% min(.94vw, 18px) 5.53%;
  /* Затемнение начинается от описания, а не от низа снимка: выше
     идут рубрика и заголовок, и они читаются прямо на фотографии —
     её нижний край к этому месту уже приглушён маской. Доли
     считаются снизу обёртки, описание начинается примерно на 45 %
     её высоты. */
  background: linear-gradient(to top,
    rgba(6, 6, 6, .95) 0%,
    rgba(6, 6, 6, .92) 30%,
    rgba(6, 6, 6, .60) 38%,
    rgba(6, 6, 6, 0) 45%);
}

/* Поля задаёт обёртка — у строк внутри их быть не должно, иначе
   они складываются с полями и колонка уезжает. */
.photo-card__body > * { margin-inline: 0; }

/*
 * Полоса чистого снимка над текстом.
 *
 * Задана полем сверху, и поле это в процентах — а процент у
 * margin считается от ширины родителя, то есть от ширины самой
 * карточки. Это важнее, чем кажется: высоту нельзя привязывать
 * ни к vw, ни к числу. При vw карточка считается от ширины окна,
 * а не от своей: на 768 сетка схлопывается в одну колонку,
 * карточка становится во всю ширину, а высота остаётся
 * по-прежнему маленькой — снимка не видно вовсе. С процентом
 * пропорция макета (127 полосы на 470 ширины — 27 %) держится на
 * любой сетке и на любом экране.
 *
 * Поле не отъедает место у текста, а растит карточку: высота у
 * неё идёт от содержимого. Поэтому полоса остаётся на месте,
 * сколько бы текста ни было.
 *
 * На главной 21,7 % дают ровно макетные 470 × 379: 102 полосы
 * плюс 277 обёртки с текстом. Текст при этом начинается на 172
 * от верха — в макете фотография кончается на 179. В каталогах
 * текста заметно больше — у кейса плашка «того самого момента»,
 * у идеи перечень «что можно взять», — и там полоса шире, иначе
 * карточка выглядит текстовой, а не фотографической.
 */
/*
 * На главной карточка держит макетные 470 × 379 ровно, поэтому
 * высота задана пропорцией. Текст начинается на 187 от верха —
 * там же, где кончается полоса снимка (24,7 % поля плюс 70
 * растушёвки).
 *
 * Обёртка забирает весь остаток высоты, а слабину внутри берёт на
 * себя описание. Благодаря этому рубрика, заголовок и нижняя
 * строка стоят у всех карточек ряда на одних линиях — как в
 * макете, где в первой карточке две строки описания, а в двух
 * других три.
 */
.idea-card.photo-card,
.case-card.photo-card { aspect-ratio: 470 / 379; }

.photo-card > .photo-card__body { margin-top: 24.7%; }

.idea-card.photo-card > .photo-card__body,
.case-card.photo-card > .photo-card__body { flex: 1; }

.cs-card.photo-card > .photo-card__body,
.media-card.photo-card > .photo-card__body { margin-top: 34%; }

/* ---- Рубрика ------------------------------------------------
   Плашка 29 по высоте, ширина по надписи; заливка #9700FF на
   20 %, обводка им же в пиксель, кегль 13 Roboto Regular. */
.photo-card .case-card__type,
.photo-card .idea-card__type,
.photo-card .cs-card__type,
.photo-card .media-card__type {
  align-self: flex-start;
  width: fit-content;
  min-height: min(1.51vw, 29px);                 /* 29 на 1920 */
  margin: 0;
  padding: 0 min(.52vw, 10px);
  border: 1px solid var(--violet-line);
  border-radius: 6px;
  background: rgba(151, 0, 255, .2);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, .677vw, 13px);           /* 13 на 1920 */
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text);
}

/* ---- Заголовок ---------------------------------------------- */
.photo-card .case-card__title,
.photo-card .idea-card__title,
.photo-card .cs-card__title,
.photo-card .media-card__body > .h3 {
  margin: min(.58vw, 11px) 0 0;                  /* 11.2 между краской */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1rem, 1.083vw, 1.3rem);       /* 20.8 из макета */
  line-height: 1.25;
  letter-spacing: .048em;
  color: var(--text);
}

/* ---- Описание -----------------------------------------------
   Кегль у кейсов и у идей разный, и это не недосмотр: в «Широкие
   компы 3_2» описание кейса набрано 24-м, в «Широкие компы 5_2»
   описание идеи — 20-м. Оба числа взяты из текстового слоя
   макетов. Нижнее поле auto — оно отдаёт слабину высоты описанию,
   чтобы нижняя строка карточки стояла у низа. */
.photo-card .case-card__text,
.photo-card .idea-card__text,
.photo-card .cs-card__text,
.photo-card .media-card__body > .body-text {
  margin: min(.54vw, 10.4px) 0 auto;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.25vw, 24px);          /* 24 — кейсы */
  line-height: 1;                                /* 24 / 24 */
  color: #fff;
  /* Три строки вместо двух: кегль вырос, и в две строки анонс
     обрывался на полуслове чаще, чем читался. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  flex: none;
}

/* Идеи — 20-м, по «Широкие компы 5_2». */
.photo-card .idea-card__text,
.photo-card .media-card__body > .body-text {
  font-size: clamp(12px, 1.042vw, 20px);         /* 20 — идеи */
  line-height: 1;                                /* 20 / 20 */
}

/* ---- Нижняя строка ------------------------------------------ */
.photo-card .idea-card__foot,
.photo-card .media-card__foot {
  margin: min(.59vw, 11.3px) 0 0;
  gap: 8px 14px;
}

.photo-card .case-card__link,
.photo-card .cs-card__link,
.photo-card .idea-card__link,
.photo-card .media-card__foot .link-cta {
  margin-top: min(.59vw, 11.3px);
  font-size: clamp(10px, .677vw, 13px);          /* 13 из макета */
}
.photo-card .idea-card__link,
.photo-card .media-card__foot .link-cta { margin-top: 0; }

/* ---- Стоимость ----------------------------------------------
   Одна сумма без подписи. Плашка 165 × 29: ширина здесь задана,
   а не по надписи, — цены у идей разной длины, и без общей ширины
   плашки в ряду прыгали бы. Заливка #9700FF на 20 %, обводка им
   же в пиксель, сумма Unbounded Bold 15 цветом #F8EF01. */
.photo-card .idea-card__price,
.photo-card .concept-price {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 165 — макетная ширина, но только пока сумма в неё помещается:
     на узких экранах доля от vw ужимается быстрее текста, и без
     нижней границы по содержимому цена вылезала бы за плашку. */
  width: min(8.594vw, 165px);                    /* 165 на 1920 */
  min-width: fit-content;
  min-height: min(1.51vw, 29px);                 /* 29 на 1920 */
  padding: 0 min(.42vw, 8px);
  border: 1px solid var(--violet-line);
  border-radius: 6px;
  background: rgba(151, 0, 255, .2);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(11px, .781vw, 15px);          /* 15 на 1920 */
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #f8ef01;
}

/* Перечень «Что можно взять» в каталоге идей — на затемнении
   своя подложка ни к чему, она бы спорила с виньеткой. */
.photo-card .concept-card__mini {
  margin-top: min(.59vw, 11.3px);
  padding: 0;
  border: 0;
  background: none;
}
.photo-card .concept-card__mini li { color: var(--text); }

/* Номер идеи в каталоге стоял на углу обложки — теперь обложка
   это вся карточка, и он остаётся на её углу. */
.photo-card .media-card__index { top: 14px; right: 14px; z-index: 3; }

/* Наведение: снимок чуть приближается, как было у прежних карточек. */
.photo-card img { transition: transform var(--t-slow) var(--ease); }
.photo-card:hover > .case-card__media img,
.photo-card:hover > .idea-card__media img,
.photo-card:hover > .cs-card__media img,
.photo-card:hover > .media-card__media img { transform: scale(1.04); }

/* На узких экранах карточка перестаёт быть «широкой» из макета:
   кегль 24 там съедает всю высоту, а снимка не остаётся вовсе. */
@media (max-width: 719px) {
  .photo-card__body { padding: 56px 18px 18px; }
  .photo-card .case-card__text,
  .photo-card .idea-card__text,
  .photo-card .cs-card__text,
  .photo-card .media-card__body > .body-text { font-size: 15px; line-height: 1.25; }
}
