/*
Theme Name: Perkura
Theme URI: https://roman-purtow.ru/perkura/
Author: Perkura
Description: Тема студии интерьерного дизайна Perkura. Собрана из готовой вёрстки (home.html, about.html, services.html, services-2.html, portfolio.html, project.html, news.html, article.html). Портфолио — кастомный тип записей "Проекты", новости — стандартные записи блога WordPress. Этап 1: тема и шаблоны страниц, без ACF-полей.
Version: 1.0.0
Requires at least: 6.0
Requires PHP: 7.4
Text Domain: perkura
*/

/* Perkura — главная страница.

   Вёрстка full-width: композиция тянется на всю ширину окна и сохраняет
   пропорции макета (опорная ширина 1920). Чтобы не пересчитывать каждое
   значение в vw вручную, введена единица --px: один пиксель макета.
   Поэтому `calc(1224 * var(--px))` читается ровно как «1224 в макете». */

:root {
  --px: 0.05208333vw; /* 1920 * 0.05208333vw = 100vw */

  --ink: #171717;
  --paper: #ffffff;
  --font: "Oswald", system-ui, sans-serif;

  --accent: #b88247;

  /* Чистый чёрный: фон страницы и заливки. Он темнее «чернил» текста,
     поэтому это отдельный токен, а не --ink. В mask-image чёрный остаётся
     литералом: там это стоп градиента, непрозрачность маски, а не цвет. */
  --black: #000000;
  --mist: #f5f5f5; /* светлая подложка секций */
  --line: #d0d0d0; /* линейки и неактивные точки */

  --gutter: calc(60 * var(--px));
  /* Высота шапки. От неё считаются первые экраны обеих страниц, поэтому
     она вынесена в переменную: ниже 1200 шапка становится 59 настоящих
     пикселей, и оба первых экрана подхватывают это сами. */
  --header-h: calc(63 * var(--px));

  /* Приглушение при наведении. Ступени всего две: текстовые ссылки
     и мелкие элементы гаснут до --hover-soft, залитые кнопки — до
     --hover-strong. Раньше тот же приём давал пять разных значений. */
  --hover-soft: 0.6;
  --hover-strong: 0.8;

  /* Движение. Кривых две, и делят они работу по назначению.

     --ease-out — резкий выход, easeOutQuint: за первые 10% времени проходит
     40% пути. Это правильно для отклика на действие, где важно, чтобы
     интерфейс ответил мгновенно: подчёркивания меню, зум снимка под курсором.

     --ease-reveal — появления при прокрутке, easeInOutCubic. Там резкий выход
     читается как рывок: шторка распахивалась почти сразу, а оставшиеся
     полсекунды еле ползла. Мягкий вход и выход держит скорость ровной:
     на самом быстром участке шторка проходит 26% кадра за 100 мс против
     45% у более резкого easeInOutQuart и 40% в первые же 100 мс у easeOutQuint.

     Длительности названы по тому, что они двигают, а не числом: линейка
     прочерчивается, текст проявляется, снимок открывается шторкой. Хочется
     медленнее или быстрее — меняются эти три строки, больше ничего. */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-reveal: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-rule: 0.8s;
  --dur-text: 0.7s;
  --dur-media: 1s;

  /* Высота окна для первых экранов. svh — самая маленькая из динамических
     высот мобильного браузера: экран влезает целиком при любом положении
     адресной строки и не дёргается, когда она уезжает при скролле. */
  --vh: 100vh;
}

@supports (height: 100svh) {
  :root {
    --vh: 100svh;
  }
}

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

/* Отступ для якорей: шапка закреплена у верхней кромки, и без этой строки
   переход по «Контакты» ставил бы начало секции под неё. */
html {
  scroll-padding-top: var(--header-h);
}

body {
  margin: 0;
  background: var(--black);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: 100%;
}

/* Текст для поиска и экранных читалок, но не для глаза. Нужен там, где блоку
   по смыслу положен заголовок, а в макете его нет: h1 главной обязан описывать
   студию, тогда как крупная надпись первого экрана — название проекта в
   слайдере. Прячем не через display: none и не visibility: hidden — от них
   содержимое пропадает и для читалки; вырезаем рамкой в один пиксель, элемент
   остаётся в дереве доступности. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Появление блоков при прокрутке ---------- */

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

   Класс reveal сам по себе не делает ничего: и начальное состояние, и переход
   висят на атрибуте data-reveal, а его ставит только скрипт и только тем
   элементам, которые при загрузке оказались ниже кромки окна. Поэтому первый
   экран неподвижен на любой ширине, а без скрипта страница видна целиком.
   Подробности — в NOTES.md, раздел «Движение». */

.reveal[data-reveal] {
  transition-timing-function: var(--ease-reveal);
}

/* Снимок: шторка сверху вниз. Едет clip-path, а не размер, поэтому разметка
   не пересчитывается и соседи не двигаются. */
.reveal--media[data-reveal] {
  transition-property: clip-path;
  transition-duration: var(--dur-media);
}

.reveal--media[data-reveal="pending"] {
  clip-path: inset(0 0 100% 0);
}

.reveal--media[data-reveal="shown"] {
  clip-path: inset(0 0 0 0);
}

/* Текст: проявление со сдвигом снизу. Сдвиг в макетных пикселях — на 1440
   он должен быть не крупнее, чем на 1920. */
.reveal--text[data-reveal] {
  transition-property: opacity, transform;
  transition-duration: var(--dur-text);
}

.reveal--text[data-reveal="pending"] {
  opacity: 0;
  transform: translateY(calc(12 * var(--px)));
}

.reveal--text[data-reveal="shown"] {
  opacity: 1;
  transform: translateY(0);
}

/* Линейка прочерчивается от закреплённого края: горизонтальные — слева,
   вертикальные черты у верхней кромки секций — сверху вниз. Жест один,
   просто вдоль своей оси.

   Режет тоже clip-path, а не scaleX: масштаб в ноль схлопывает бокс, и
   IntersectionObserver перестаёт считать элемент видимым — линейка так и
   осталась бы спрятанной навсегда. Обрезка габаритов не трогает. */
.reveal--rule[data-reveal],
.reveal--rule-down[data-reveal] {
  transition-property: clip-path;
  transition-duration: var(--dur-rule);
}

.reveal--rule[data-reveal="pending"] {
  clip-path: inset(0 100% 0 0);
}

.reveal--rule-down[data-reveal="pending"] {
  clip-path: inset(0 0 100% 0);
}

.reveal--rule[data-reveal="shown"],
.reveal--rule-down[data-reveal="shown"] {
  clip-path: inset(0 0 0 0);
}

/* Лесенка. Задержки собраны здесь, а не разбросаны по секциям: ритм появления
   читается только целиком. Правил всего два — соседи по ряду разъезжаются на
   60 мс, подпись идёт следом за своим снимком через 120 мс. Всё остальное
   складывается из этих двух. */

/* About us: снимки в паре */
.about__photo--2[data-reveal],
.about__photo--4[data-reveal] {
  transition-delay: 60ms;
}

/* Blog на главной: три карточки в ряд */
.news__item:nth-child(1) .news__body[data-reveal] {
  transition-delay: 120ms;
}

.news__item:nth-child(2) .news__media[data-reveal] {
  transition-delay: 60ms;
}

.news__item:nth-child(2) .news__body[data-reveal] {
  transition-delay: 180ms;
}

.news__item:nth-child(3) .news__media[data-reveal] {
  transition-delay: 120ms;
}

.news__item:nth-child(3) .news__body[data-reveal] {
  transition-delay: 240ms;
}

/* Contact me: черта, заголовок, адрес, форма */
.contacts__info[data-reveal] {
  transition-delay: 60ms;
}

.form[data-reveal] {
  transition-delay: 120ms;
}

/* Портфолио: сетка в две колонки */
.card__text[data-reveal] {
  transition-delay: 120ms;
}

.card:nth-child(even) .card__media[data-reveal] {
  transition-delay: 60ms;
}

.card:nth-child(even) .card__text[data-reveal] {
  transition-delay: 180ms;
}

/* Новости: лента в две колонки */
.post__text[data-reveal] {
  transition-delay: 120ms;
}

.blog__grid .post:nth-child(even) .post__media[data-reveal] {
  transition-delay: 60ms;
}

.blog__grid .post:nth-child(even) .post__text[data-reveal] {
  transition-delay: 180ms;
}

/* Страница проекта: цифры об объекте */
.stat:nth-child(2)[data-reveal] {
  transition-delay: 60ms;
}

.stat:nth-child(3)[data-reveal] {
  transition-delay: 120ms;
}

.stat:nth-child(4)[data-reveal] {
  transition-delay: 180ms;
}

/* Страница проекта: до и после */
.project-plan__media[data-reveal] {
  transition-delay: 60ms;
}

.specs[data-reveal] {
  transition-delay: 120ms;
}

/* Страница проекта: наборы кадров */
.project-set__title[data-reveal],
.project-set__side--1[data-reveal] {
  transition-delay: 60ms;
}

.project-set__side--2[data-reveal] {
  transition-delay: 120ms;
}

.project-set__text[data-reveal] {
  transition-delay: 180ms;
}

.project-pair__media--2[data-reveal] {
  transition-delay: 60ms;
}

.project-pair__text[data-reveal] {
  transition-delay: 120ms;
}

.project-split__large[data-reveal] {
  transition-delay: 60ms;
}

.project-split__small-text[data-reveal] {
  transition-delay: 120ms;
}

.project-split__large-text[data-reveal] {
  transition-delay: 180ms;
}

.project-row__media:nth-child(2)[data-reveal] {
  transition-delay: 60ms;
}

.project-row__media:nth-child(3)[data-reveal] {
  transition-delay: 120ms;
}

/* Услуги: преимущества по три в ряд */
.pros__card:nth-child(2)[data-reveal] {
  transition-delay: 60ms;
}

.pros__card:nth-child(3)[data-reveal] {
  transition-delay: 120ms;
}

/* Страница проекта: лента других проектов */
.reel__card--2[data-reveal] {
  transition-delay: 60ms;
}

.reel__card--3[data-reveal] {
  transition-delay: 120ms;
}

.reel__card--4[data-reveal] {
  transition-delay: 180ms;
}

.reel__card--5[data-reveal] {
  transition-delay: 240ms;
}

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

/* Шапка держится у верхней кромки окна на всех трёх режимах. Из потока она при
   этом не выходит: высота остаётся за ней, и первый экран, который считается
   как `--vh` минус `--header-h`, занимает ровно остаток окна, как и раньше.

   z-index: 20 — выше всего, что лежит в секциях: там слои идут до 3.
   Ниже 1200 то же число уже стояло ради панели меню под бургером. */
.header {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--header-h);
  background: var(--ink);
  color: var(--paper);
}

.header__inner {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  height: 100%;
  padding: 0 var(--gutter);
}

/* Ряд шапки в макете сдвинут на 1 влево и начинается в 10 от верха. */
.logo {
  display: flex;
  align-items: stretch;
  height: calc(43 * var(--px));
  margin-top: calc(10 * var(--px));
  margin-left: calc(-1 * var(--px));
  color: inherit;
  text-decoration: none;
}

.logo__mark-box {
  display: flex;
  align-items: center;
  width: calc(90 * var(--px));
  flex: none;
}

.logo__mark {
  width: calc(85 * var(--px));
  height: calc(22 * var(--px));
}

.logo__divider {
  width: calc(1 * var(--px));
  background: currentColor;
  flex: none;
}

.logo__caption {
  display: flex;
  flex-direction: column;
  margin-top: calc(5 * var(--px));
  margin-left: calc(5 * var(--px));
}

/* Подпись в макете переведена в кривые, поэтому кегль и трекинг подобраны
   так, чтобы совпали габариты набора: 66x20 и 128x16. */
.logo__caption-top {
  white-space: nowrap;
  font-size: calc(20.5 * var(--px));
  font-weight: 400;
  line-height: 1;
  letter-spacing: calc(0.5 * var(--px));
  text-transform: uppercase;
}

.logo__caption-bottom {
  white-space: nowrap;
  margin-top: calc(2 * var(--px));
  font-size: calc(16 * var(--px));
  font-weight: 200;
  line-height: 1;
  letter-spacing: calc(0.3 * var(--px));
}

/* Свободное место шапки съедает auto-margin: логотип остаётся слева,
   а меню и кнопка языка за ним прижимаются вправо — space-between
   родителя на эту пару уже не влияет. */
.nav {
  display: flex;
  align-items: baseline;
  gap: calc(60 * var(--px));
  margin-top: calc(18 * var(--px));
  margin-left: auto;
}

.nav__link,
.nav__phone {
  position: relative;
  color: inherit;
  font-size: calc(18 * var(--px));
  font-weight: 600;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
}

/* Подчёркивание рисуем линией, а не text-decoration: её можно раскрыть
   слева направо. В покое линия сжата в точку у левого края и невидима.

   У телефона линию несёт вложенный span: бокс ссылки шире набора, и линия
   по боксу вылезала бы за номер с обеих сторон. */
.nav__link::after,
.nav__phone-label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(-3 * var(--px));
  height: max(1px, calc(1 * var(--px)));
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease-out);
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__phone:hover .nav__phone-label::after,
.nav__phone:focus-visible .nav__phone-label::after {
  transform: scaleX(1);
}

/* Текущий раздел выделен только насыщенностью: подчёркивание — состояние
   наведения и в покое его нет ни у одного пункта. */
.nav__link--active {
  font-weight: 700;
}

/* Телефон лежит в боксе фиксированной ширины с центровкой. */
.nav__phone {
  width: calc(154 * var(--px));
  text-align: center;
}

.nav__phone-label {
  position: relative;
  display: inline-block;
}

/* Бургер нужен только на узких экранах. */
.header__actions {
  display: none;
}

/* ---------- Переключатель языков ---------- */

/* Кнопка «Ru» стоит в строке меню последней. Отступ от колонки, который
   раньше нёс правый край меню, теперь на ней: правым элементом шапки
   стала она. Переключение пока визуальное — страниц-переводов нет,
   выбор хранится в localStorage (см. initLang в script.js). */
.lang {
  position: relative;
  margin-top: calc(18 * var(--px));
  margin-left: calc(60 * var(--px));
  margin-right: calc(24 * var(--px));
}

.lang__toggle {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: calc(18 * var(--px));
  font-weight: 600;
  line-height: 1.5;
  cursor: pointer;
}

/* Панелька опускается из-под кнопки той же механикой, что панель меню
   под бургером: в покое спрятана, проявляется с лёгким сдвигом. Кромку
   шапки она перекрывает — фон тот же, и выглядит это продолжением. */
.lang__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 10 * var(--px));
  z-index: 10;
  display: flex;
  flex-direction: column;
  min-width: calc(124 * var(--px));
  padding: calc(10 * var(--px)) calc(20 * var(--px)) calc(14 * var(--px));
  background: var(--ink);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
}

.lang[data-open="true"] .lang__menu {
  visibility: visible;
  opacity: 1;
  transform: none;
}

/* Язык в списке ведёт себя как пункт меню: активный выделен только
   насыщенностью, подчёркивание — состояние наведения. Линия по боксу
   набора, поэтому кнопка не тянется на ширину панельки. */
.lang__option {
  position: relative;
  align-self: flex-start;
  padding: calc(6 * var(--px)) 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: calc(16 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
}

.lang__option::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(3 * var(--px));
  height: max(1px, calc(1 * var(--px)));
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease-out);
}

.lang__option:hover::after,
.lang__option:focus-visible::after {
  transform: scaleX(1);
}

.lang__option--active {
  font-weight: 700;
}

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

/* Своей заливки у секции в макете нет — она берёт чёрный фон страницы.
   Без него белый заголовок и подпись «scroll to explore» пропали бы.

   Высота секции — окно минус шапка: первый экран виден целиком и ни на
   пиксель больше. Пропорции макета при этом сохраняются — внутри секции
   работает своя единица --u: тот же макетный пиксель, ужатый ровно
   настолько, чтобы 990 макетной высоты уложились в окно. Когда окно выше
   макета, --u упирается в --px, а лишнюю высоту забирает снимок: он
   кадрируется по `cover` и от этого не страдает.

   Поэтому всё внутри первого экрана считается в --u, а не в --px, а
   вертикали, привязанные к снимку, заданы долями его высоты. */
.hero {
  --hero-h: calc(var(--vh) - var(--header-h));
  --u: min(var(--px), calc(var(--hero-h) / 990));
  --media-top: calc(120 * var(--u));
  --media-h: calc(var(--hero-h) - 334 * var(--u)); /* 990 - 656 — всё, кроме снимка */
  position: relative;
  height: var(--hero-h);
  overflow: hidden;
  color: var(--paper);
}

/* Рамка слайдера: за её краем лента обрезается. Лежит там же, где раньше
   лежала сама лента, и тянется до правого края окна — из-под правого края
   выглядывает начало следующего проекта, как в макете. */
.hero__viewport {
  position: absolute;
  left: calc(-4 * var(--u));
  top: var(--media-top);
  width: calc(100vw + 4 * var(--u));
  height: var(--media-h);
  overflow: hidden;
  cursor: grab;
}

.hero__viewport[data-dragging="true"] {
  cursor: grabbing;
}

/* Ленту двигает Embla — своих transform и transition у неё нет.
   pan-y оставляет странице вертикальную прокрутку пальцем. */
.hero__track {
  display: flex;
  height: 100%;
  touch-action: pan-y pinch-zoom;
}

/* Промежуток задан полем слайда, а не gap: так библиотека учитывает его и
   на стыке последнего слайда с первым при зацикливании. */
.slide {
  position: relative;
  flex: none;
  width: calc(1224 * var(--u));
  height: 100%;
  margin-right: calc(276 * var(--u)); /* шаг 1500 минус ширина слайда 1224 */
}

/* Заголовок выходит за правый край снимка, поэтому обрезается только медиа. */
.slide__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.slide__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.25);
}

.slide__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.slide__button {
  position: absolute;
  left: calc(50 * var(--u));
  top: 45.122%; /* 296 / 656 — доля высоты снимка */
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(295 * var(--u));
  height: calc(64 * var(--u));
  background: var(--paper);
  color: var(--black);
  font-size: calc(30 * var(--u));
  font-weight: 400;
  line-height: 1.48;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.slide__button:hover {
  background: var(--ink);
  color: var(--paper);
}

.slide__title {
  position: absolute;
  left: calc(597 * var(--u));
  top: 11.585%; /* 76 / 656 — доля высоты снимка */
  z-index: 1;
  margin: 0;
  color: var(--paper);
  font-size: calc(150 * var(--u));
  font-weight: 400;
  line-height: 1.12;
  white-space: nowrap;
}

.hero__next {
  position: absolute;
  left: calc(1144 * var(--u));
  top: calc(var(--media-top) + var(--media-h) * 0.23628); /* 155 / 656 от верха снимка */
  width: calc(152 * var(--u));
  height: calc(152 * var(--u));
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--paper);
  color: var(--black);
  cursor: pointer;
  transition: transform 0.2s ease;
}

.hero__next:hover {
  transform: scale(1.04);
}

.hero__next svg {
  position: absolute;
  left: 27.632%; /* 42 / 152 */
  top: 30.921%; /* 47 / 152 */
  width: 46.053%; /* 70 / 152 */
  height: 38.816%; /* 59 / 152 */
  overflow: visible;
}

.hero__scroll {
  position: absolute;
  left: calc(810 * var(--u));
  top: calc(var(--media-top) + var(--media-h) + 50 * var(--u)); /* 50 под снимком */
  font-size: calc(30 * var(--u));
  font-weight: 400;
  line-height: 1.48;
  white-space: nowrap;
}

/* ---------- About us ---------- */

/* Секция-коллаж: снимки лежат абсолютно, порядок в разметке задаёт наложение. */
.about {
  position: relative;
  height: calc(1656 * var(--px));
  overflow: hidden;
  background: var(--paper);
  color: var(--black);
}

.about__head {
  position: absolute;
  left: var(--gutter);
  top: calc(120 * var(--px));
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: calc(1800 * var(--px));
}

.about__title {
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

/* Бокс ссылки шире набора: справа в макете остаётся воздух. */
.about__more {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--px));
  width: calc(215 * var(--px));
  color: inherit;
  font-size: calc(30 * var(--px));
  line-height: 1.48;
  text-decoration: none;
  white-space: nowrap;
  text-transform: uppercase;
  transition: opacity 0.2s ease;
}

.about__more:hover {
  opacity: var(--hover-soft);
}

.arrow-ne {
  width: calc(35 * var(--px));
  height: calc(35 * var(--px));
  flex: none;
}

.about__count {
  position: absolute;
  left: calc(1196 * var(--px));
  top: calc(450 * var(--px));
  color: var(--mist);
  font-size: calc(500 * var(--px));
  font-weight: 700;
  line-height: 1;
}

.about__photo {
  position: absolute;
  margin: 0;
  overflow: hidden;
}

.about__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about__photo--1 {
  left: calc(340 * var(--px));
  top: calc(288 * var(--px));
  width: calc(585 * var(--px));
  height: calc(464 * var(--px));
}

.about__photo--2 {
  left: calc(60 * var(--px));
  top: calc(426 * var(--px));
  width: calc(542 * var(--px));
  height: calc(591 * var(--px));
}

.about__photo--3 {
  left: calc(860 * var(--px));
  top: calc(824 * var(--px));
  width: calc(574 * var(--px));
  height: calc(417 * var(--px));
}

.about__photo--4 {
  left: calc(1286 * var(--px));
  top: calc(1023 * var(--px));
  width: calc(574 * var(--px));
  height: calc(513 * var(--px));
}

.about__text {
  position: absolute;
  z-index: 2;
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
  text-transform: uppercase;
}

.about__text--right {
  left: calc(995 * var(--px));
  top: calc(380 * var(--px));
}

.about__text--left {
  left: calc(106 * var(--px));
  top: calc(1087 * var(--px));
}

/* ---------- We are full-service ---------- */

.fullservice {
  position: relative;
  height: calc(956 * var(--px));
  overflow: hidden;
  background: var(--black);
  color: var(--paper);
}

/* Короткая вертикальная черта у верхней кромки — общий мотив двух секций. */
.fullservice__rule,
.works__rule {
  position: absolute;
  left: calc(1402 * var(--px));
  top: 0;
  width: calc(3 * var(--px));
  height: calc(120 * var(--px));
  background: var(--paper);
}

.fullservice__lockup {
  position: absolute;
  left: calc(397 * var(--px));
  top: calc(120 * var(--px));
}

.fullservice__title {
  width: calc(853 * var(--px));
  margin: 0;
  font-size: calc(150 * var(--px));
  font-weight: 400;
  line-height: 1.033333;
  letter-spacing: calc(7.5 * var(--px));
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
}

.fullservice__row {
  position: absolute;
  left: calc(228 * var(--px));
  top: calc(300 * var(--px));
  display: flex;
  align-items: flex-start;
  gap: calc(53 * var(--px));
}

.fullservice__accent {
  font-family: "Playfair Display", Georgia, serif;
  font-size: calc(120 * var(--px));
  font-weight: 400;
  line-height: 1.333333;
  letter-spacing: calc(4.8 * var(--px));
  text-transform: uppercase;
  white-space: nowrap;
}

/* Первая строка сдвинута — в макете отступ набран пробелами. */
.fullservice__text {
  width: calc(466 * var(--px));
  margin: calc(31 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
  text-indent: calc(44 * var(--px));
}

.fullservice__scroll {
  position: absolute;
  left: calc(852 * var(--px));
  top: calc(660 * var(--px));
  width: calc(216 * var(--px));
  height: calc(216 * var(--px));
  font-family: var(--font);
  color: var(--paper);
  overflow: visible;
}

/* Крутится только кольцо надписи — стрелка в центре стоит на месте.
   Центр вращения задан в координатах viewBox: 216 / 2. */
.fullservice__scroll-ring {
  transform-box: view-box;
  transform-origin: 108px 108px;
  animation: scroll-ring-spin 26s linear infinite;
}

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

/* ---------- Works ---------- */

.works {
  position: relative;
  height: calc(956 * var(--px));
  overflow: hidden;
  background: var(--mist);
  color: var(--black);
}

.works__photo {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(907 * var(--px));
  height: 100%;
  margin: 0;
  overflow: hidden;
}

/* Снимки лежат друг на друге и переводятся прозрачностью: скрипт кладёт
   поверх первого второй слой и меняет их местами при смене проекта.
   Входящий кадр чуть подан вперёд — движение читается даже на похожих
   интерьерах. */
.works__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.works__shot {
  opacity: 0;
  transform: scale(1.03);
  transition: opacity 0.7s ease, transform 0.9s ease;
}

.works__shot.is-active {
  opacity: 1;
  transform: none;
}

.works__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.2);
}

.works__title {
  position: absolute;
  left: calc(60 * var(--px));
  top: calc(768 * var(--px));
  z-index: 1;
  margin: 0;
  color: var(--paper);
  font-size: calc(150 * var(--px));
  font-weight: 400;
  line-height: 1.12;
  text-transform: uppercase;
}

.works__orbit {
  position: absolute;
  left: calc(470 * var(--px));
  top: calc(63 * var(--px));
  width: calc(849 * var(--px));
  height: calc(828 * var(--px));
  overflow: visible;
}

.works__cta {
  position: absolute;
  left: calc(799 * var(--px));
  top: calc(375 * var(--px));
  width: calc(206 * var(--px));
  height: calc(206 * var(--px));
  border: calc(2 * var(--px)) solid var(--paper);
  border-radius: 50%;
  color: var(--black);
  text-decoration: none;
  transition: background-color 0.2s ease;
}

.works__cta:hover {
  background: rgba(255, 255, 255, 0.55);
}

.works__cta-label {
  position: absolute;
  left: calc(20 * var(--px));
  top: calc(87 * var(--px));
  display: flex;
  align-items: flex-start;
  gap: calc(8 * var(--px));
  font-size: calc(22 * var(--px));
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

.works__cta-arrow {
  width: calc(22 * var(--px));
  height: calc(17 * var(--px));
  margin-top: calc(8 * var(--px));
  flex: none;
}

/* Названия проектов лежат на дуге. Рамка обрезает ленту по высоте области
   из макета (732) и растворяет названия у верхнего и нижнего края, чтобы они
   не обрубались линейкой. Ширину рамка берёт до правого поля страницы,
   а не по самому длинному названию макета: иначе имя подлиннее срезалось бы
   справа. Дуга от этого не съезжает — её отсчёт идёт от левого края рамки. */
.works__viewport {
  position: absolute;
  left: calc(1210 * var(--px));
  top: calc(120 * var(--px));
  width: calc(650 * var(--px));
  height: calc(732 * var(--px));
  overflow: hidden;
  /* Девять слайдов по шагу дуги на пятнадцать пикселей выше рамки. Живой
     карусели это не мешает — она их и прокручивает, — а в статике нижнее
     название срезалось бы по подпись, поэтому там рамка не обрезает. */
  /* Лента едет по вертикали, поэтому пальцу здесь оставлена горизонтальная
     прокрутка и щипок; Embla это правило за нас не пишет. Ниже 1200 ось
     меняется, вместе с ней и разрешённый жест. */
  touch-action: pan-x pinch-zoom;
  user-select: none;
  -webkit-user-select: none;
}

.works:not([data-ready="true"]) .works__viewport {
  overflow: visible;
}

/* Всё, что имеет смысл только у живой карусели, включается меткой готовности:
   её ставит скрипт. Без него секция остаётся статичной витриной — девять
   названий на дуге, все одинаково чёрные и целиком видны. */
.works[data-ready="true"] .works__viewport {
  cursor: grab;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
}

/* Курсор-ладонь над лентой названий — как у слайдера первого экрана. */
.works__viewport[data-dragging="true"] {
  cursor: grabbing;
}

/* Высота ленты равна высоте рамки, хотя названий в ней на пятнадцать пикселей
   макета больше: Embla считает видимой областью именно ленту, и без этой
   строки она центрировала бы названия по всей их длине, а не по рамке. */
.works__list {
  display: flex;
  flex-direction: column;
  height: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Шаг между названиями в макете — 83, сам блок названия занимает 68.
   Слайд высотой в шаг, содержимое по центру: тогда Embla с выравниванием
   по центру ставит все девять ровно туда, где они стоят в макете. */
.works__item {
  height: calc(83 * var(--px));
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: opacity 0.35s ease;
}

/* Выбранный проект — чёрный, остальные приглушены: точка на орбите
   указывает на него, цвет это подтверждает. */
.works[data-ready="true"] .works__item {
  opacity: 0.5;
  cursor: pointer;
}

.works[data-ready="true"] .works__item.is-active {
  opacity: 1;
}

/* Горизонтальный сдвиг названия. Здесь он задан для статики — так секция
   выглядит и без скрипта, — а живую дугу скрипт пишет инлайном поверх. */
.works__item-inner {
  display: block;
  will-change: transform;
}

/* Те же девять чисел лежат в script.js константой OFFSETS: здесь они держат
   статичную витрину, там двигают живую дугу. Правите одно — правьте и второе. */
.works__item:nth-child(1) .works__item-inner { transform: translate3d(0, 0, 0); }
.works__item:nth-child(2) .works__item-inner { transform: translate3d(calc(60 * var(--px)), 0, 0); }
.works__item:nth-child(3) .works__item-inner { transform: translate3d(calc(90 * var(--px)), 0, 0); }
.works__item:nth-child(4) .works__item-inner { transform: translate3d(calc(120 * var(--px)), 0, 0); }
.works__item:nth-child(5) .works__item-inner { transform: translate3d(calc(159 * var(--px)), 0, 0); }
.works__item:nth-child(6) .works__item-inner { transform: translate3d(calc(129 * var(--px)), 0, 0); }
.works__item:nth-child(7) .works__item-inner { transform: translate3d(calc(99 * var(--px)), 0, 0); }
.works__item:nth-child(8) .works__item-inner { transform: translate3d(calc(69 * var(--px)), 0, 0); }
.works__item:nth-child(9) .works__item-inner { transform: translate3d(calc(9 * var(--px)), 0, 0); }

.works__name {
  margin: 0;
  font-size: calc(28 * var(--px));
  font-weight: 500;
  line-height: 1.464286;
  white-space: nowrap;
}

/* Название — кнопка выбора проекта, но выглядит обычным текстом.
   Мышью попадает и мимо букв: клик ловит вся строка. */
.works__pick {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

.works__pick:focus-visible {
  outline: calc(2 * var(--px)) solid var(--black);
  outline-offset: calc(4 * var(--px));
}

.works__meta {
  margin: 0 0 0 calc(22 * var(--px));
  font-size: calc(18 * var(--px));
  font-weight: 400;
  line-height: 1.5;
  white-space: nowrap;
}

/* Стрелки на дуге. Живут внутри орбиты, поэтому на узком экране
   поворачиваются вместе с ней и всегда смотрят вдоль дуги. Нажимается
   не тонкий контур, а прозрачный круг под ним. */
.works__nav {
  cursor: pointer;
  transition: opacity 0.25s ease;
}

.works__nav:hover {
  opacity: var(--hover-soft);
}

/* Своей рамки фокуса у стрелок нет: браузер рисует вокруг группы в SVG
   прямоугольник со скруглёнными углами, чужой этому макету. Клавиатурный
   фокус показывает сам круг под стрелкой. */
.works__nav:focus,
.works__nav:focus-visible {
  outline: none;
}

.works__nav:focus-visible .works__nav-hit {
  fill: rgba(0, 0, 0, 0.08);
}


/* ---------- Новости ---------- */

.news {
  padding: calc(120 * var(--px)) var(--gutter) calc(93 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.news__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.news__title {
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

/* Бокс ссылки шире набора: справа в макете остаётся воздух. */
.news__more {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--px));
  color: inherit;
  font-size: calc(30 * var(--px));
  line-height: 1.48;
  text-decoration: none;
  white-space: nowrap;
  text-transform: uppercase;
  transition: opacity 0.2s ease;
}

.news__more:hover {
  opacity: var(--hover-soft);
}

.news__intro {
  width: calc(1140 * var(--px));
  margin: calc(30 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.news__list {
  display: grid;
  grid-template-columns: repeat(3, calc(480 * var(--px)));
  gap: 0 calc(180 * var(--px));
  align-items: start;
  margin: calc(50 * var(--px)) 0 0;
  padding: 0;
  list-style: none;
}

.news__card {
  display: block;
  color: inherit;
  text-decoration: none;
}

.news__media {
  margin: 0;
  overflow: hidden;
}

.news__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease-out);
}

.news__card:hover .news__media img {
  transform: scale(1.04);
}

/* Разная высота кадров даёт ступенчатый ритм ленты — как в макете. */
.news__media--s {
  height: calc(606 * var(--px));
}

.news__media--l {
  height: calc(731 * var(--px));
}

.news__body {
  margin-top: calc(43 * var(--px));
}

.news__heading {
  display: flex;
  align-items: flex-start;
  gap: calc(30 * var(--px));
}

.news__rule {
  flex: none;
  width: calc(98 * var(--px));
  height: calc(2 * var(--px));
  margin-top: calc(20 * var(--px));
  background: var(--accent);
}

/* У третьей карточки черта в макете чёрная. */
.news__rule--ink {
  background: var(--black);
}

.news__name {
  width: calc(352 * var(--px));
  margin: 0;
  font-size: calc(28 * var(--px));
  font-weight: 500;
  line-height: 1.464286;
  text-transform: uppercase;
}

.news__text {
  margin: calc(20 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Description ---------- */

.seo {
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--mist);
  color: var(--black);
}

.seo__title {
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

.seo__text {
  margin: calc(30 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Contact me ---------- */

.contacts {
  position: relative;
  height: calc(1225 * var(--px));
  overflow: hidden;
  background: var(--black);
  color: var(--paper);
}

.contacts__rule {
  position: absolute;
  left: calc(1402 * var(--px));
  top: 0;
  width: calc(3 * var(--px));
  height: calc(120 * var(--px));
  background: var(--paper);
}

.contacts__inner {
  position: absolute;
  left: var(--gutter);
  top: calc(120 * var(--px));
  width: calc(1800 * var(--px));
}

.contacts__title {
  margin: 0;
  font-size: calc(300 * var(--px));
  font-weight: 700;
  line-height: 1.483333;
  text-align: center;
}

.contacts__info {
  position: absolute;
  left: var(--gutter);
  top: calc(595 * var(--px));
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
  width: calc(256 * var(--px));
  font-style: normal;
}

.contacts__mail,
.contacts__note {
  color: inherit;
  font-weight: 300;
  line-height: 1.5;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.contacts__mail {
  font-size: calc(22 * var(--px));
}

.contacts__note {
  font-size: calc(18 * var(--px));
}

a.contacts__mail:hover,
a.contacts__note:hover {
  opacity: var(--hover-soft);
}

/* ---------- Форма обратной связи ---------- */

.form {
  position: absolute;
  left: calc(1129 * var(--px));
  top: calc(595 * var(--px));
  width: calc(732 * var(--px));
}

.form__title {
  margin: 0;
  font-size: calc(28 * var(--px));
  font-weight: 500;
  line-height: 1.464286;
}

.form__fields {
  display: flex;
  flex-direction: column;
  gap: calc(40 * var(--px));
  margin-top: calc(30 * var(--px));
}

/* Поле — это label с двумя блоками внутри, поэтому ему нужен блочный бокс. */
.field {
  display: block;
}

.field__label {
  display: block;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* Подпись под полем в макете — подсказка, поэтому здесь placeholder. */
.field__input {
  display: block;
  width: 100%;
  height: calc(44 * var(--px)); /* подпись 33 + отступ 10 + поле 44 = 87, как в макете */
  margin-top: calc(10 * var(--px));
  padding: 0 0 calc(10 * var(--px));
  border: 0;
  border-bottom: calc(2 * var(--px)) solid var(--paper);
  border-radius: 0;
  background: transparent;
  color: var(--paper);
  font-family: inherit;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
  transition: border-bottom-color 0.15s ease;
}

.field__input::placeholder {
  color: rgba(255, 255, 255, 0.5);
  opacity: 1;
}

.field__input:focus {
  outline: none;
  border-bottom-color: var(--accent);
}

.form__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: calc(40 * var(--px));
  height: calc(59 * var(--px));
}

.consent {
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
  margin-left: calc(-1 * var(--px));
  cursor: pointer;
}

/* Нативный чекбокс спрятан, но остаётся фокусируемым с клавиатуры. */
.consent__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.consent__box {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(23 * var(--px));
  height: calc(23 * var(--px));
  border: calc(1 * var(--px)) solid var(--paper);
  color: var(--paper);
}

.consent__check {
  width: calc(14.5 * var(--px));
  height: calc(14.5 * var(--px));
  overflow: visible;
}

/* Галочка не проявляется, а прочерчивается от угла: контур длиной 26.03
   в координатах viewBox, поэтому штрих 27 закрывает его целиком. Обратный
   ход — тем же путём, галочка стирается туда же, откуда пришла. */
.consent__check path {
  stroke-dasharray: 27;
  stroke-dashoffset: 27;
  transition: stroke-dashoffset 0.2s var(--ease-out);
}

.consent__input:checked + .consent__box .consent__check path {
  stroke-dashoffset: 0;
}

.consent__input:focus-visible + .consent__box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.consent__text {
  font-size: calc(16 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.consent__text a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: calc(1 * var(--px));
  text-underline-offset: calc(3 * var(--px));
}

.form__submit {
  flex: none;
  width: calc(277 * var(--px));
  height: calc(59 * var(--px));
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--paper);
  color: var(--black);
  font-family: inherit;
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.12s ease;
}

.form__submit:hover {
  background: var(--accent);
  color: var(--paper);
}

/* Кнопка проседает под пальцем — единственная задача этого движения
   в том, чтобы нажатие было замечено. */
.form__submit:active {
  transform: scale(0.98);
}

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

/* Линия в макете нулевой высоты с обводкой 2, поэтому верхнее поле на 1 меньше:
   так черта ложится ровно на 60, а строка — на 90, и секция выходит 190. */
.footer {
  padding: calc(59 * var(--px)) var(--gutter) calc(60 * var(--px));
  background: var(--ink);
  color: var(--paper);
}

.footer__rule {
  display: block;
  height: calc(2 * var(--px));
  background: currentColor;
}

/* Три колонки: бренд слева, правовая ссылка строго по центру, соцсети справа. */
.footer__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  margin-top: calc(29 * var(--px));
  height: calc(40 * var(--px));
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
}

.footer__logo {
  width: calc(85 * var(--px));
  height: calc(22 * var(--px));
  flex: none;
}

.footer__rights,
.footer__legal {
  font-size: calc(18 * var(--px));
  line-height: 1.5;
  white-space: nowrap;
}

.footer__legal {
  justify-self: center;
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: calc(1 * var(--px));
  text-underline-offset: calc(3 * var(--px));
  transition: opacity 0.2s ease;
}

.footer__legal:hover {
  opacity: var(--hover-soft);
}

.footer__social {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: calc(16 * var(--px));
}

.social {
  display: block;
  width: calc(40 * var(--px));
  height: calc(40 * var(--px));
  transition: transform 0.2s ease;
}

.social svg {
  display: block;
  width: 100%;
  height: 100%;
}

.social:hover {
  transform: translateY(calc(-3 * var(--px)));
}

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

   Ниже 1200 десктопная композиция разбирается: абсолютные координаты
   уступают потоку, макет идёт в одну колонку. Опора — мобильный фрейм
   «Главная (моб)» шириной 320 с полями по 15.

   Кегли здесь заданы в реальных пикселях и не растут вместе с окном,
   а контейнеры и снимки тянутся на ширину. Коллажи — исключение: они
   обязаны держать пропорцию, поэтому внутри них размеры считаются от
   ширины колонки (--col).
   ====================================================================== */

@media (max-width: 1199px) {
  :root {
    /* Ниже 1200 единица макета равна настоящему пикселю: всё, что не
       переопределено ниже явно, сохраняет размер из десктопного макета —
       мелкий текст, линии, отступы внутри карточек. Тянутся только
       контейнеры и снимки. */
    --px: 1px;
    --gutter: 15px;
    --header-h: 59px;
    --col: calc(100vw - 30px); /* ширина колонки контента */
  }

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

  /* Закрепление и слой берутся из базового правила: своё position здесь
     отменило бы липкость, а z-index там уже тот же самый. */
  .header {
    height: var(--header-h);
  }

  .header__inner {
    align-items: center;
  }

  .logo {
    height: 33px;
    margin: 0;
  }

  .logo__mark-box {
    width: 61px;
  }

  .logo__mark {
    width: 56px;
    height: 14px;
  }

  .logo__caption {
    margin-left: 6px;
    margin-top: 0;
    justify-content: center;
  }

  .logo__caption-top {
    font-size: 13.4px;
    letter-spacing: 0.33px;
  }

  .logo__caption-bottom {
    margin-top: 2px;
    font-size: 10.4px;
    letter-spacing: 0.2px;
  }

  /* order переставляет бургер за кнопку языка: в разметке она последняя,
     а стоять должна слева от него. */
  .header__actions {
    display: flex;
    align-items: center;
    order: 1;
  }

  .burger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5.5px;
    width: 34px;
    height: 24px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    cursor: pointer;
  }

  .burger__bar {
    display: block;
    width: 24px;
    height: 1.5px;
    margin-left: auto;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.25s ease;
  }

  .burger[aria-expanded="true"] .burger__bar:first-child {
    transform: translateY(3.5px) rotate(45deg);
  }

  .burger[aria-expanded="true"] .burger__bar:last-child {
    transform: translateY(-3.5px) rotate(-45deg);
  }

  /* Кнопка языка прижимается к бургеру: auto-margin съедает свободное
     место шапки, логотип остаётся слева. */
  .lang {
    margin: 0 20px 0 auto;
  }

  .lang__toggle {
    font-size: 16px;
  }

  .lang__menu {
    top: calc(100% + 10px);
    min-width: 124px;
    padding: 8px 16px 12px;
  }

  .lang__option {
    padding: 8px 0;
    font-size: 16px;
  }

  .lang__option::after {
    bottom: 5px;
  }

  /* Меню выезжает панелью из-под шапки. */
  .nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 10;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    padding: 6px var(--gutter) 18px;
    background: var(--ink);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-10px);
    transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
  }

  .nav[data-open="true"] {
    visibility: visible;
    opacity: 1;
    transform: none;
  }

  /* В панели пункты идут колонкой: без align-self линия растянулась бы на
     всю ширину экрана, а подчеркнуть надо набор. */
  .nav__link,
  .nav__phone {
    align-self: flex-start;
    padding: 11px 0;
    font-size: 18px;
    font-weight: 500;
  }

  /* У пункта линия поднята на высоту нижнего поля, у телефона она висит
     под самим набором — поле лежит на ссылке, а не на span. */
  .nav__link::after {
    bottom: 8px;
  }

  .nav__phone-label::after {
    bottom: -3px;
  }

  .nav__phone {
    width: auto;
    text-align: left;
  }

  .nav__link--active {
    font-weight: 700;
  }

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

  /* Ниже 1200 первый экран в окно не вписывается — и не должен. Кадры
     проектов горизонтальные, и если тянуть снимок на всю оставшуюся
     высоту окна, он превращается в портретную полосу, обрезанную по
     бокам. Поэтому высота считается от ширины колонки в пропорции
     мобильного макета (305 x 191), а секция растёт по содержимому. */
  .hero {
    --media-h: calc(var(--col) * 191 / 305);
    height: auto;
    padding: 50px 0 50px;
  }

  .hero__viewport {
    position: static;
    width: auto;
    height: auto;
  }

  .hero__track {
    height: auto;
  }

  .slide {
    width: calc(100vw - 15px);
    height: auto;
    margin-right: 15px;
  }

  .slide__media {
    position: relative;
    inset: auto;
    height: var(--media-h);
  }

  /* Кнопка стоит по центру снимка (снимок здесь в потоке и начинается от
     верха слайда, поэтому отсчёт от top). Но не ниже предела: название
     кейса заходит на снимок на 67px, и между ним и кнопкой остаётся 12px
     воздуха — 67 + 12 + 30 (высота кнопки) = 109 от нижнего края снимка.
     На узком телефоне срабатывает именно предел, а не центр. */
  .slide__button {
    left: 50%;
    top: min(calc(var(--media-h) / 2 - 15px), calc(var(--media-h) - 109px));
    bottom: auto;
    width: 140px;
    height: 30px;
    font-size: 16px;
    transform: translateX(-50%);
  }

  /* Заголовок заходит на нижний край снимка — как в макете. Он в потоке, а
     снимок позиционирован, поэтому без z-index первая строка уезжает под
     фотографию: на десктопе тот же z-index: 1 стоит в базовом правиле. */
  .slide__title {
    position: relative;
    left: auto; /* иначе смещения из десктопного правила поедут в relative */
    top: auto;
    z-index: 1;
    margin: -67px 0 0 var(--gutter);
    font-size: 42px;
    line-height: 1.05;
  }

  .hero__next {
    left: auto;
    right: 0;
    top: calc(50px + var(--media-h) / 2 - 25px);
    width: 50px;
    height: 50px;
  }

  .hero__scroll {
    position: static;
    display: block;
    margin-top: 30px;
    font-size: 16px;
    text-align: center;
  }

  /* ---------- About us ---------- */

  .about {
    height: auto;
    padding: 50px var(--gutter) 60px;
  }

  .about__head {
    position: static;
    width: auto;
  }

  .about__title {
    font-size: 32px;
  }

  .about__more {
    width: auto;
    gap: 9px;
    font-size: 16px;
  }

  .arrow-ne {
    width: 19px;
    height: 19px;
  }

  /* Коллаж держит пропорцию макета, поэтому его размеры считаются от --col. */
  .about__pair {
    position: relative;
    margin-top: 30px;
  }

  .about__pair--top {
    padding-top: calc(var(--col) * 244 / 290);
  }

  .about__pair--bottom {
    margin-top: 78px;
    padding-top: calc(var(--col) * 206 / 290);
  }

  .about__photo {
    top: 0;
    height: auto;
  }

  .about__photo--1 {
    left: 32.07%;
    width: 67.93%;
    aspect-ratio: 197 / 156;
  }

  .about__photo--2 {
    left: 0;
    top: calc(var(--col) * 46 / 290);
    width: 62.76%;
    aspect-ratio: 182 / 198;
  }

  .about__photo--3 {
    left: 0;
    width: 57.24%;
    aspect-ratio: 166 / 121;
  }

  .about__photo--4 {
    left: 42.41%;
    top: calc(var(--col) * 58 / 290);
    width: 57.59%;
    aspect-ratio: 167 / 148;
  }

  .about__text {
    position: static;
    margin-top: 30px;
    font-size: 16px;
  }

  .about__count {
    left: 56.9%;
    top: -60px;
    font-size: 120px;
  }

  /* ---------- We are full-service ---------- */

  .fullservice {
    height: auto;
    padding: 100px var(--gutter);
  }

  .fullservice__rule,
  .works__rule,
  .contacts__rule {
    left: auto;
    right: 63px;
    width: 2px;
    height: 55px;
  }

  .fullservice__lockup {
    position: static;
  }

  .fullservice__title {
    width: auto;
    font-size: 50px;
    letter-spacing: 2.5px;
  }

  /* «agency» дочитывает фразу с предыдущей строки, поэтому идёт вплотную к
     ней: собственный интерлиньяж строки уже даёт нужный просвет. */
  .fullservice__row {
    position: static;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    margin-top: 0;
  }

  /* В одну колонку «agency» дочитывает фразу с предыдущей строки, поэтому
     стоит по центру под заголовком, а не у правого края, как в макете. */
  .fullservice__accent {
    font-size: 50px;
    letter-spacing: 2px;
    text-align: center;
  }

  /* Абзац тоже по центру; отступ первой строки при этом теряет смысл.
     Переносы в разметке расставлены под ширину десктопной колонки — здесь
     они рвут текст на куски, поэтому гасим их и даём тексту течь. Ширина
     ограничена, иначе на планшете строка растягивается через весь экран. */
  .fullservice__text {
    width: auto;
    max-width: 480px;
    margin: 0 auto;
    font-size: 16px;
    text-align: center;
    text-indent: 0;
  }

  .fullservice__text br {
    display: none;
  }

  .fullservice__scroll {
    position: static;
    display: block;
    width: 175px;
    height: 175px;
    margin: 50px auto 0;
  }

  /* ---------- Works ---------- */

  /* Круговая композиция та же, что на десктопе: большая окружность, дуга со
     стрелками внутри неё и круглая кнопка — всё вокруг одного центра. На
     десктопе центр лежит на середине правой кромки снимка; здесь колонка
     одна, поэтому он переезжает на середину нижней кромки, а композиция
     разворачивается на 90° — точка на окружности и стрелка в кнопке
     смотрят вниз, на список проектов.

     Размеры считаются от ширины секции, а не заданы пикселями макета: иначе
     круги прилипают к левому краю и сплющиваются в овалы. Диаметр большой
     окружности равен ширине секции — её края касаются нижней кромки снимка
     и не уходят за экран; дуга внутри уменьшается вместе с ней. Кнопка и
     высота снимка — линейная интерполяция между 320 и 1199: кнопка растёт
     от 147 до 240, снимок от 262 до 620. */
  .works {
    --cta: calc(10.6vw + 113px);
    --photo-h: calc(40.7vw + 132px);

    height: auto;
    padding-bottom: 60px;
  }

  /* Черта у верхней кромки идёт по разметке раньше снимка, поэтому ей нужен
     слой поверх него. */
  .works__rule {
    z-index: 1;
  }

  /* position: relative — снимок перекрывает орбиту, как на десктопе, и
     затемнение ::after ложится на него, а не на всю секцию. */
  .works__photo {
    position: relative;
    width: 100%;
    height: var(--photo-h);
    aspect-ratio: auto;
  }

  .works__title {
    left: 17px;
    top: 50px;
    font-size: 50px;
  }

  /* Сама окружность занимает 0.9435 стороны рамки, поэтому рамку берём с
     запасом — тогда окружность выходит ровно в ширину секции. Центр
     окружности внутри рамки лежит на 48.79% / 49.99% её стороны: сдвигаем
     рамку на эту долю, и центр попадает в точку left/top, вокруг него же
     идёт поворот. Пропорция 849:828 держится aspect-ratio, иначе круг
     превращается в овал. */
  .works__orbit {
    left: 50%;
    top: var(--photo-h);
    width: calc(100% / 0.9435);
    height: auto;
    aspect-ratio: 849 / 828;
    transform-origin: 48.79% 49.99%;
    transform: translate(-48.79%, -49.99%) rotate(90deg);
  }

  .works__cta {
    left: 50%;
    top: var(--photo-h);
    width: var(--cta);
    height: var(--cta);
    margin: calc(var(--cta) / -2) 0 0 calc(var(--cta) / -2);
  }

  /* Кнопка стоит на снимке, а не на светлом фоне секции, как на десктопе,
     поэтому надпись и стрелка внутри неё белые. Стрелка берёт цвет через
     currentColor. */
  .works__cta-label {
    left: 50%;
    top: 50%;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    color: var(--paper);
    font-size: 16px;
    transform: translate(-50%, -50%);
  }

  /* На узком экране стрелка в круге смотрит вниз. */
  .works__cta-arrow {
    width: 22px;
    height: 17px;
    margin: 0;
    transform: rotate(90deg);
  }

  /* Дуга здесь лежит внизу, точка — под окружностью, и названия идут не
     столбиком, а лентой поперёк: под точкой стоит выбранный проект, соседние
     выглядывают краешками по бокам. Отступ рамки считается от ширины секции:
     50% — радиус окружности, ещё 2% — точка на ней. */
  .works__viewport {
    position: static;
    width: 100%;
    height: auto;
    margin-top: calc(52% + 26px);
    touch-action: pan-y pinch-zoom;
  }

  .works[data-ready="true"] .works__viewport {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 18%, #000 82%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 18%, #000 82%, transparent 100%);
  }

  .works__list {
    flex-direction: row;
    height: auto;
  }

  /* Слайд уже секции — потому соседние названия и видны по краям. Текст
     внутри по центру, под точкой. */
  /* Ширина слайда — это и расстояние между названиями. Доля от секции нужна,
     чтобы на телефоне соседи выглядывали по краям; потолок в 320 — чтобы на
     планшете они не уехали за экран и подсказка листания не пропала. */
  .works__item {
    width: min(66%, 320px);
    height: auto;
    padding: 0 10px;
    text-align: center;
  }

  /* Соседние названия здесь приглушены сильнее десктопных: их видно
     краешками, и на светлом фоне они не должны спорить с выбранным. */
  .works[data-ready="true"] .works__item {
    opacity: 0.3;
  }

  /* Дуга — забота десктопа; здесь названия стоят ровно. Селектор повторяет
     вес правил статической дуги выше и идёт после них, иначе не перебьёт. */
  .works__item:nth-child(n) .works__item-inner {
    transform: none;
  }

  .works__name {
    font-size: 28px;
  }

  .works__meta {
    margin-left: 0;
    font-size: 18px;
  }

  .works__pick:focus-visible {
    outline-width: 2px;
    outline-offset: 4px;
  }

  /* ---------- Новости ---------- */

  .news {
    padding: 50px var(--gutter);
  }

  .news__title {
    font-size: 32px;
  }

  .news__more {
    gap: 9px;
    font-size: 16px;
  }

  .news__intro {
    width: auto;
    font-size: 16px;
  }

  .news__list {
    grid-template-columns: 1fr;
    gap: 50px 0;
  }

  .news__media--s,
  .news__media--l {
    height: auto;
  }

  .news__media--s {
    aspect-ratio: 290 / 396;
  }

  .news__media--l {
    aspect-ratio: 290 / 519;
  }

  .news__name {
    width: auto;
  }

  .news__text {
    font-size: 16px;
  }

  /* ---------- Description ---------- */

  .seo {
    padding: 50px var(--gutter);
  }

  .seo__title {
    font-size: 32px;
  }

  .seo__text {
    font-size: 16px;
  }

  /* ---------- Contact me ---------- */

  /* Порядок как в макете: титул, форма, реквизиты. */
  .contacts {
    display: flex;
    flex-direction: column;
    height: auto;
    padding: 100px var(--gutter) 60px;
  }

  .contacts__inner {
    position: static;
    order: 1;
    width: auto;
  }

  .contacts__title {
    font-size: 60px;
  }

  .form {
    position: static;
    order: 2;
    width: auto;
    margin-top: 50px;
  }

  /* Подпись и кнопка встают друг под друга, кнопка — во всю ширину. */
  .form__foot {
    flex-direction: column;
    align-items: stretch;
    gap: 32px;
    height: auto;
  }

  .consent {
    align-items: flex-start;
    margin-left: 0;
  }

  .consent__box {
    margin-top: 12px;
  }

  .form__submit {
    width: 100%;
    font-size: 16px;
  }

  .contacts__info {
    position: static;
    order: 3;
    width: auto;
    margin-top: 50px;
    gap: 20px;
  }

  .contacts__mail,
  .contacts__note {
    font-size: 16px;
  }

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

  .footer {
    padding: 30px var(--gutter);
  }

  .footer__inner {
    display: flex;
    flex-direction: column;
    gap: 20px;
  }

  /* Логотип и соцсети в первой строке, копирайт и ссылка — во второй. */
  .footer__row {
    grid-template-columns: 1fr auto;
    gap: 20px 16px;
    height: auto;
    margin-top: 0;
  }

  .footer__brand {
    display: contents;
  }

  .footer__logo {
    grid-area: 1 / 1;
    width: 56px;
    height: 14px;
  }

  .footer__social {
    grid-area: 1 / 2;
    gap: 16px;
  }

  .footer__rights {
    grid-area: 2 / 1;
  }

  .footer__legal {
    grid-area: 2 / 2;
    justify-self: end;
  }

  .footer__rights,
  .footer__legal {
    font-size: 16px;
  }

  .social {
    width: 26px;
    height: 26px;
  }
}

/* ======================================================================
   Планшет (768–1199px)

   Та же одноколоночная схема, но поля шире, кегли крупнее, лента новостей
   в две колонки. Меню здесь ещё под бургером: строкой оно разворачивается
   не отсюда, а с 900 — см. следующий блок.
   ====================================================================== */

@media (min-width: 768px) and (max-width: 1199px) {
  :root {
    --gutter: 30px;
    --col: calc(100vw - 60px);
  }

  /* Та же пропорция снимка, что на телефоне, только поля крупнее. */
  .hero {
    --media-h: calc(var(--col) * 191 / 305);
    height: auto;
    padding: 60px 0 60px;
  }

  .slide {
    width: calc(100vw - 30px);
    margin-right: 30px;
  }

  .slide__title {
    margin: -96px 0 0 var(--gutter);
    font-size: 76px;
  }

  /* Тот же расчёт, что на телефоне, под здешние размеры: название заходит
     на снимок на 96px, кнопка выше 48px, воздуха между ними 16. */
  .slide__button {
    top: min(calc(var(--media-h) / 2 - 24px), calc(var(--media-h) - 160px));
    width: 220px;
    height: 48px;
    font-size: 22px;
  }

  .hero__next {
    top: calc(60px + var(--media-h) / 2 - 44px);
    width: 88px;
    height: 88px;
  }

  .hero__scroll {
    font-size: 22px;
  }

  .about {
    padding: 80px var(--gutter) 90px;
  }

  .about__title,
  .news__title,
  .seo__title {
    font-size: 56px;
  }

  .about__more,
  .news__more {
    font-size: 22px;
  }

  .arrow-ne {
    width: 26px;
    height: 26px;
  }

  .about__text,
  .news__intro,
  .news__text,
  .seo__text,
  .fullservice__text,
  .contacts__mail,
  .contacts__note {
    font-size: 18px;
  }

  .about__count {
    top: -110px;
    font-size: 220px;
  }

  .about__pair--bottom {
    margin-top: 130px;
  }

  .fullservice {
    padding: 120px var(--gutter);
  }

  .fullservice__title,
  .fullservice__accent {
    font-size: 88px;
  }

  .fullservice__scroll {
    width: 216px;
    height: 216px;
  }

  .works__title {
    left: var(--gutter);
    top: 90px;
    font-size: 96px;
  }

  .works__cta-label {
    font-size: 20px;
  }

  /* Лента новостей — две колонки. */
  .news {
    padding: 80px var(--gutter);
  }

  .news__list {
    grid-template-columns: repeat(2, 1fr);
    gap: 60px 40px;
  }

  .news__media--s {
    aspect-ratio: 480 / 606;
  }

  .news__media--l {
    aspect-ratio: 480 / 731;
  }

  .seo {
    padding: 80px var(--gutter);
  }

  .contacts {
    padding: 120px var(--gutter) 90px;
  }

  .contacts__title {
    font-size: 130px;
  }

  .form__foot {
    flex-direction: row;
    align-items: center;
    gap: 24px;
  }

  .consent {
    align-items: center;
  }

  .consent__box {
    margin-top: 0;
  }

  .form__submit {
    width: 277px;
    font-size: 22px;
  }

  .footer {
    padding: 40px var(--gutter);
  }

  .footer__logo {
    width: 85px;
    height: 22px;
  }

  .footer__rights,
  .footer__legal {
    font-size: 18px;
  }

  .social {
    width: 34px;
    height: 34px;
  }
}

/* ======================================================================
   Широкий планшет (900–1199px) — только шапка

   Меню разворачивается строкой и бургер прячется не с 768, а с 900:
   семь пунктов вместе с номером занимают 566px, и до 887 они не влезают
   между логотипом и полем. Раньше их было шесть, и на 768 номер уже
   срезался на десяток пикселей — просто этого никто не измерял.

   Кнопка языка удлинила строку ещё на ~55px, поэтому промежутки ужаты
   с 24 до 16: шесть промежутков возвращают 48px, и на 900 всё влезает
   по-прежнему — но с запасом уже в считанные пиксели.

   Ниже 900 шапка остаётся телефонной: высота 59, логотип мельче, пункты
   под бургером. Поля и колонки при этом переключаются по-прежнему на 768 —
   поехал порог меню, а не порог планшетной раскладки.
   ====================================================================== */

@media (min-width: 900px) and (max-width: 1199px) {
  /* Со строчным меню шапка выше. Обратите внимание, что --header-h здесь
     намеренно оставлена равной 59px — первый экран страницы проекта
     отсчитывается именно от неё, и так было до появления переменной.
     Приравняете одно к другому — .project-hero станет на 13px короче,
     а это уже правка вёрстки, а не рефакторинг. */
  .header {
    height: 72px;
  }

  /* Здесь шапка выше своей переменной, поэтому и отступ для якорей свой. */
  html {
    scroll-padding-top: 72px;
  }

  .header__actions {
    display: none;
  }

  .logo {
    height: 43px;
  }

  .logo__mark-box {
    width: 90px;
  }

  .logo__mark {
    width: 85px;
    height: 22px;
  }

  .logo__caption-top {
    font-size: 20.5px;
    letter-spacing: 0.5px;
  }

  .logo__caption-bottom {
    font-size: 16px;
    letter-spacing: 0.3px;
  }

  /* Меню снова обычная строка. */
  .header__inner {
    gap: 20px;
  }

  .nav {
    position: static;
    flex-direction: row;
    align-items: center;
    gap: 16px;
    padding: 0;
    background: none;
    visibility: visible;
    opacity: 1;
    transform: none;
  }

  .nav__link,
  .nav__phone {
    align-self: center;
    padding: 0;
    font-size: 16px;
    font-weight: 600;
  }

  .nav__link::after,
  .nav__phone-label::after {
    bottom: -3px;
  }

  /* Кнопка языка возвращается из угла у бургера в конец строки меню. */
  .lang {
    margin: 0 0 0 20px;
  }
}

/* ======================================================================
   Страница проекта — первый экран и описание

   Шапка, меню и типографика общие с главной, поэтому здесь только два
   блока. Размеры, как и везде, в единицах макета: `calc(N * var(--px))`.
   ====================================================================== */

/* ---------- Главное фото ---------- */

/* Высота — окно минус шапка: снимок открывается ровно на экран и ни на
   пиксель больше. Пересчитывать внутренности не пришлось: в макете заголовок
   и кружок стоят точно по центру блока (414 + 74 = 488 = 976 / 2), точки — в
   60 от низа, крошки — в 30 от верха. Все четыре привязаны к краям и потому
   переживают любую высоту. */
.project-hero {
  position: relative;
  height: calc(var(--vh) - var(--header-h));
  overflow: hidden;
  color: var(--paper);
}

.project-hero__media {
  position: absolute;
  inset: 0;
}

/* В макете снимок растянут на блок, а не обрезан. Но там высота блока была
   известна заранее, а теперь она равна окну: растяжение искажало бы кадр тем
   сильнее, чем ниже окно. Поэтому снимок кадрируется по центру. */
.project-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.project-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
}

.breadcrumbs {
  position: absolute;
  left: var(--gutter);
  top: calc(30 * var(--px));
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: calc(10 * var(--px));
  font-size: calc(22 * var(--px));
  line-height: 1.5;
}

.breadcrumbs__link,
.breadcrumbs__sep {
  color: inherit;
  font-weight: 300;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.breadcrumbs__link:hover {
  opacity: var(--hover-soft);
}

.breadcrumbs__current {
  font-weight: 500;
}

.project-hero__title {
  position: absolute;
  left: calc(428 * var(--px));
  top: 50%; /* в макете 414: строка высотой 148, её середина — середина блока */
  transform: translateY(-50%);
  z-index: 1;
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 400;
  line-height: 1.48;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Обведённый круг со стрелкой. Общий компонент: он же стоит на первом
   экране страницы проекта и на карточках портфолио. Размер задаёт хозяин
   блока, внутренности тянутся за viewBox сами.

   Круг здесь не залит, а обведён — в отличие от такого же на главной.
   При наведении круг заливается белым, а стрелка вырезается маской:
   сквозь неё видно снимок. Маска нужна не всегда: где заливки нет,
   в разметке просто не рисуют .ring-arrow__fill. */
.ring-arrow {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--paper);
  cursor: pointer;
}

.ring-arrow svg {
  display: block;
  width: 100%;
  height: 100%;
}

.ring-arrow__ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  transition: opacity 0.2s ease;
}

.ring-arrow__arrow {
  transition: opacity 0.2s ease;
}

.ring-arrow__fill {
  fill: var(--paper);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.ring-arrow:hover .ring-arrow__ring,
.ring-arrow:hover .ring-arrow__arrow,
.ring-arrow:focus-visible .ring-arrow__ring,
.ring-arrow:focus-visible .ring-arrow__arrow {
  opacity: 0;
}

.ring-arrow:hover .ring-arrow__fill,
.ring-arrow:focus-visible .ring-arrow__fill {
  opacity: 1;
}

.project-hero__next {
  position: absolute;
  left: calc(1708 * var(--px));
  top: 50%; /* в макете 412 + 76 = 488 — середина блока */
  transform: translateY(-50%);
  z-index: 2;
  width: calc(152 * var(--px));
  height: calc(152 * var(--px));
}

.project-hero__dots {
  position: absolute;
  left: calc(911 * var(--px));
  bottom: calc(60 * var(--px)); /* в макете 889 сверху: 976 - 889 - 27 */
  z-index: 2;
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
}

.dot {
  width: calc(16 * var(--px));
  height: calc(16 * var(--px));
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--line);
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.dot:hover {
  background: var(--paper);
}

.dot--active {
  width: calc(27 * var(--px));
  height: calc(27 * var(--px));
  background: var(--paper);
}

/* ---------- Описание проекта ---------- */

.project-info {
  position: relative;
  height: calc(768 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.project-info__head {
  position: absolute;
  left: var(--gutter);
  top: calc(120 * var(--px));
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  width: calc(1800 * var(--px));
}

.project-info__text {
  width: calc(885 * var(--px));
}

.project-info__title {
  margin: 0;
  font-size: calc(28 * var(--px));
  font-weight: 500;
  line-height: 1.464286;
  text-transform: uppercase;
}

.project-info__body {
  display: flex;
  flex-direction: column;
  gap: calc(40 * var(--px));
  margin-top: calc(60 * var(--px));
}

.project-info__body p {
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* Бокс ссылки шире набора: справа в макете остаётся воздух. */
.project-info__more {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--px));
  min-width: calc(235 * var(--px)); /* капс занимает почти весь бокс — пусть растёт влево */
  color: inherit;
  font-size: calc(30 * var(--px));
  line-height: 1.48;
  text-decoration: none;
  white-space: nowrap;
  text-transform: uppercase;
  transition: opacity 0.2s ease;
}

.project-info__more:hover {
  opacity: var(--hover-soft);
}

/* ---------- Цифры об объекте ---------- */

.project-stats {
  position: absolute;
  left: calc(1128 * var(--px));
  top: calc(221 * var(--px));
  display: grid;
  grid-template-columns: repeat(2, calc(138 * var(--px)));
  gap: calc(100 * var(--px));
}

.stat {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--px));
}

.stat__value {
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 400;
  line-height: 1.48;
}

.stat__unit {
  font-size: calc(24 * var(--px));
  line-height: 1.5;
  vertical-align: top;
}

.stat__label {
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  .breadcrumbs {
    top: calc(20 * var(--px));
    font-size: 16px;
  }

  .project-hero__title {
    left: var(--gutter);
    top: auto;
    bottom: calc(70 * var(--px));
    font-size: 42px;
    line-height: 1.12;
    white-space: normal;
    transform: none;
  }

  .project-hero__next {
    left: auto;
    right: var(--gutter);
    top: calc(70 * var(--px));
    width: 50px;
    height: 50px;
    transform: none;
  }

  .ring-arrow__ring {
    stroke-width: 6;
  }

  .project-hero__dots {
    left: 50%;
    top: auto;
    bottom: calc(25 * var(--px));
    gap: 10px;
    transform: translateX(-50%);
  }

  .dot {
    width: 10px;
    height: 10px;
  }

  .dot--active {
    width: 16px;
    height: 16px;
  }

  .project-info {
    height: auto;
    padding: 50px var(--gutter);
  }

  .project-info__head {
    position: static;
    flex-direction: column;
    gap: 40px;
    width: auto;
  }

  .project-info__text {
    width: auto;
  }

  .project-info__body {
    gap: 30px;
    margin-top: 30px;
  }

  .project-info__body p {
    font-size: 16px;
  }

  .project-info__more {
    width: auto;
    font-size: 22px;
  }

  .project-stats {
    position: static;
    grid-template-columns: repeat(2, 1fr);
    gap: 40px 20px;
    margin-top: 50px;
  }

  .stat__value {
    font-size: 40px;
  }

  .stat__label {
    font-size: 16px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .project-hero__title {
    bottom: calc(90 * var(--px));
    font-size: 76px;
  }

  .project-hero__next {
    width: 88px;
    height: 88px;
  }

  .ring-arrow__ring {
    stroke-width: 4;
  }

  .project-info {
    padding: 80px var(--gutter);
  }

  .project-info__title {
    font-size: 36px;
  }

  .project-info__body p,
  .project-info__more,
  .stat__label {
    font-size: 18px;
  }

  .project-info__more {
    font-size: 26px;
  }

  .project-stats {
    grid-template-columns: repeat(4, 1fr);
    gap: 30px;
  }

  .stat__value {
    font-size: 50px;
  }
}

/* ---------- До и после ---------- */

.project-plan {
  height: calc(1016 * var(--px));
  padding: calc(120 * var(--px)) var(--gutter) 0;
  background: var(--paper);
  color: var(--black);
}

.project-plan__title {
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

.project-plan__row {
  display: flex;
  justify-content: space-between;
  margin-top: calc(30 * var(--px));
}

.project-plan__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(30 * var(--px));
  width: calc(733 * var(--px));
}

.project-plan__media {
  width: 100%;
  height: calc(551 * var(--px));
  margin: 0;
  overflow: hidden;
}

/* План, как и снимки на этой странице, в макете растянут на блок. */
.project-plan__media img {
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.project-plan__dots {
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
}

/* На светлом фоне активная точка чёрная. */
.dot--ink,
.dot--ink:hover {
  background: var(--black);
}

/* ---------- Характеристики объекта ---------- */

.specs {
  width: calc(885 * var(--px));
  margin: 0;
}

.specs__title {
  margin: 0 0 calc(40 * var(--px));
  font-size: calc(28 * var(--px));
  font-weight: 500;
  line-height: 1.464286;
  text-transform: uppercase;
}

.spec {
  display: flex;
  align-items: baseline;
  padding-bottom: calc(29 * var(--px)); /* строка вместе с чертой — 64, как в макете */
  border-bottom: calc(2 * var(--px)) solid var(--black);
}

.spec + .spec {
  margin-top: calc(40 * var(--px));
}

.spec__name,
.spec__value {
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.spec__name {
  width: calc(698 * var(--px));
  flex: none;
}

/* ---------- Проект: крупный кадр и два боковых ---------- */

.project-set {
  position: relative;
  height: calc(950 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.project-set__main,
.project-set__side {
  position: absolute;
  margin: 0;
  overflow: hidden;
}

.project-set__main img,
.project-set__side img {
  width: 100%;
  height: 100%;
}

.project-set__main {
  left: var(--gutter);
  top: calc(120 * var(--px));
  width: calc(915 * var(--px));
  height: calc(551 * var(--px));
}

.project-set__main img {
  object-fit: fill;
}

.project-set__side {
  top: calc(163 * var(--px));
  width: calc(350 * var(--px));
  height: calc(465 * var(--px));
}

.project-set__side img {
  object-fit: cover;
}

.project-set__side--1 {
  left: calc(1130 * var(--px));
}

.project-set__side--2 {
  left: calc(1510 * var(--px));
}

/* Заголовок лежит поверх кадров — так в макете. */
.project-set__title {
  position: absolute;
  left: calc(663 * var(--px));
  top: calc(359 * var(--px));
  z-index: 1;
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 400;
  line-height: 1.48;
  text-transform: uppercase;
  white-space: nowrap;
}

.project-set__text {
  position: absolute;
  left: var(--gutter);
  top: calc(731 * var(--px));
  width: calc(915 * var(--px));
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Проект: пара кадров ---------- */

.project-pair {
  position: relative;
  height: calc(1144 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.project-pair__media {
  position: absolute;
  top: calc(120 * var(--px));
  width: calc(572 * var(--px));
  height: calc(679 * var(--px));
  margin: 0;
  overflow: hidden;
}

.project-pair__media img {
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.project-pair__media--1 {
  left: calc(368 * var(--px));
}

.project-pair__media--2 {
  left: calc(980 * var(--px));
}

/* Заголовок заходит на левый снимок и должен лежать поверх него. */
.project-pair__title {
  position: absolute;
  left: var(--gutter);
  top: calc(423 * var(--px));
  z-index: 1;
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 400;
  line-height: 1.48;
  text-transform: uppercase;
  white-space: nowrap;
}

.project-pair__text {
  position: absolute;
  left: var(--gutter);
  top: calc(859 * var(--px));
  width: calc(915 * var(--px));
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  .project-plan {
    height: auto;
    padding: 50px var(--gutter);
  }

  .project-plan__title {
    font-size: 32px;
  }

  .project-plan__row {
    flex-direction: column;
    gap: 50px;
  }

  .project-plan__figure {
    width: auto;
  }

  .project-plan__media {
    height: auto;
    aspect-ratio: 733 / 551;
  }

  .specs {
    width: auto;
  }

  .specs__title {
    margin-bottom: 30px;
  }

  .spec {
    justify-content: space-between;
    padding-bottom: 12px;
  }

  .spec + .spec {
    margin-top: 20px;
  }

  .spec__name {
    width: auto;
    flex: 1 1 auto;
    padding-right: 20px;
  }

  .spec__value {
    text-align: right;
  }

  .spec__name,
  .spec__value {
    font-size: 16px;
  }

  /* Кадры выстраиваются в столбик, заголовок уходит над ними. */
  .project-set,
  .project-pair {
    display: flex;
    flex-direction: column;
    height: auto;
    padding: 50px var(--gutter);
  }

  .project-set__main,
  .project-set__side,
  .project-pair__media {
    position: static;
    width: auto;
    height: auto;
  }

  .project-set__main img,
  .project-pair__media img {
    object-fit: cover;
  }

  .project-set__main {
    order: 2;
    aspect-ratio: 915 / 551;
    margin-top: 30px;
  }

  .project-set__side {
    order: 3;
    aspect-ratio: 350 / 465;
    margin-top: 20px;
  }

  .project-set__text {
    order: 4;
  }

  .project-pair__media--1 {
    order: 2;
    margin-top: 30px;
  }

  .project-pair__media--2 {
    order: 3;
    margin-top: 20px;
  }

  .project-pair__media {
    aspect-ratio: 572 / 679;
  }

  .project-pair__text {
    order: 4;
  }

  .project-set__title,
  .project-pair__title {
    position: static;
    order: 1;
    font-size: 32px;
    white-space: normal;
  }

  .project-set__text,
  .project-pair__text {
    position: static;
    width: auto;
    margin-top: 30px;
    font-size: 16px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .project-plan {
    padding: 80px var(--gutter);
  }

  .project-plan__title {
    font-size: 56px;
  }

  .spec__name,
  .spec__value,
  .project-set__text,
  .project-pair__text {
    font-size: 18px;
  }

  .specs__title {
    font-size: 32px;
  }

  .project-set,
  .project-pair {
    padding: 80px var(--gutter);
  }

  .project-set__title,
  .project-pair__title {
    font-size: 50px;
  }
}

/* ---------- Проект: малый и крупный кадр ---------- */

.project-split {
  position: relative;
  height: calc(1049 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.project-split__small,
.project-split__large {
  position: absolute;
  margin: 0;
  overflow: hidden;
}

.project-split__small img,
.project-split__large img {
  width: 100%;
  height: 100%;
  object-fit: fill; /* в макете кадры растянуты на бокс */
}

.project-split__small {
  left: var(--gutter);
  top: calc(219 * var(--px));
  width: calc(580 * var(--px));
  height: calc(354 * var(--px));
}

.project-split__large {
  left: calc(960 * var(--px));
  top: calc(120 * var(--px));
  width: calc(915 * var(--px));
  height: calc(551 * var(--px));
}

/* Заголовок заходит на левый кадр и должен лежать поверх него. */
.project-split__title {
  position: absolute;
  left: calc(408 * var(--px));
  top: calc(359 * var(--px));
  z-index: 1;
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 400;
  line-height: 1.48;
  text-transform: uppercase;
  white-space: nowrap;
}

.project-split__small-text,
.project-split__large-text {
  position: absolute;
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.project-split__small-text {
  left: var(--gutter);
  top: calc(633 * var(--px));
  width: calc(580 * var(--px));
}

/* Подпись под крупным кадром центрирована по нему. */
.project-split__large-text {
  left: calc(1044 * var(--px));
  top: calc(731 * var(--px));
  width: calc(748 * var(--px));
}

/* ---------- Проект: три кадра в ряд ---------- */

.project-row {
  display: flex;
  gap: calc(30 * var(--px));
  height: calc(919 * var(--px));
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--paper);
}

.project-row__media {
  width: calc(580 * var(--px));
  height: calc(679 * var(--px));
  margin: 0;
  overflow: hidden;
  flex: none;
}

.project-row__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- Лента проектов ---------- */

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

   Крупность — свойство места, а не снимка. В центре кадр всегда самый большой,
   к краям мельчает и опускается; при листании следующий снимок вырастает, а
   прежний уменьшается, — и никакой кадр не «носит» свой размер с собой.

   Держится это так. Лента набрана одинаковыми слотами по 512 — столько между
   центрами соседних кадров в макете. Кадр внутри слота один и тот же, 580x679,
   а скрипт на каждом кадре прокрутки читает, насколько слот отошёл от середины
   рамки, и пишет кадру четыре числа: масштаб, спуск, поправку вбок и кегль
   подписи. В покое числа дают ровно макет.

   Поправка вбок нужна оттого, что слоты равномерны, а кадры — нет: между
   центрами крайних 385, а не 512. Разница ровно 127, и она же держит зазор
   между кадрами: 512 + поправка - (полуширины соседей) = 30 при любом
   положении ленты, не только в узлах. Поэтому кадры никогда не наезжают.

   Высота 736 — от верха центрального кадра до низа ряда точек. */
.reel {
  position: relative;
  height: calc(736 * var(--px));
}

/* Рамка слайдера: за её краем лента обрезается. Отдельным уровнем, а не на
   самом .reel, потому что круг и точки лежат снаружи ленты — внутри рамки их
   срезало бы. */
.reel__viewport {
  position: relative;
  height: calc(679 * var(--px));
  overflow: hidden;
}

/* Ленту двигает Embla — своих transform и transition у неё нет. touch-action
   библиотека не выставляет, это пишется руками: без него палец на ленте спорит
   с вертикальной прокруткой страницы. */
.reel__track {
  display: flex;
  height: 100%;
  touch-action: pan-y pinch-zoom;
}

/* Без скрипта лента остаётся витриной: слотов пять, средний приходится на
   середину строки — центрирование даёт ровно макет. */
.reel:not([data-ready="true"]) .reel__track {
  justify-content: center;
}

.reel[data-ready="true"] .reel__viewport {
  cursor: grab;
}

.reel__viewport[data-dragging="true"] {
  cursor: grabbing;
}

/* Боковой кадр щелчком уезжает в середину, и курсор об этом говорит. На
   центральном остаётся ладонь: ехать ему некуда, а вход в проект — круг
   поверх него. Указатель стоит ровно на зоне нажатия — на самом кадре;
   пустое место слота над уменьшенным кадром щелчок не ловит. */
.reel[data-ready="true"] .reel__slot:not(.is-active) .reel__card {
  cursor: pointer;
}

/* На время перетаскивания указатель уступает сжатой ладони: иначе он спорил
   бы с ней ровно там, где лежит палец. Специфичность та же, что у правила
   выше, — держится порядком, поэтому переставлять их нельзя. */
.reel__viewport[data-dragging="true"] .reel__slot:not(.is-active) .reel__card {
  cursor: grabbing;
}

/* Слот — место в ленте. Шаг между слотами постоянный, кадр внутри шире слота
   и свободно на него наезжает: обрезает только рамка. */
.reel__slot {
  position: relative;
  flex: 0 0 auto;
  width: calc(512 * var(--px));
  height: 100%;
}

/* Лента шире экрана и уходит за оба края — как в макете. */
.other {
  position: relative;
  height: calc(1154 * var(--px));
  overflow: hidden;
  background: var(--paper);
  color: var(--black);
}

/* В этой секции заголовок лежит поверх ленты, поэтому лента выставлена
   от верха секции: 298 — столько до верха центрального кадра в макете. */
.other .reel {
  position: absolute;
  left: 0;
  top: calc(298 * var(--px));
  width: 100%;
}

.other__title {
  position: absolute;
  left: var(--gutter);
  top: calc(120 * var(--px));
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

/* Кадр всегда одного размера — 580x679, размер центрального. Всё остальное
   делает transform: он ужимает кадр к краям ленты и опускает его. Масштаб взят
   отношением ширин из макета (384/580 и 326/580); высоты при этих множителях
   дают 449.5 и 381.6 против макетных 450 и 382 — кадры в макете подобны с
   точностью до полпикселя, поэтому одного множителя хватает на обе стороны.

   Начало отсчёта — верх и середина: тогда масштаб не тянет кадр вниз, и спуск
   задаётся тем же числом, что стояло в макете координатой top. */
.reel__card {
  --s: 1;
  --dx: 0;
  --dy: 0;
  --cap: 22;
  --pad: 30;

  position: absolute;
  left: 50%;
  top: 0;
  width: calc(580 * var(--px));
  height: calc(679 * var(--px));
  margin: 0;
  overflow: hidden;
  transform: translateX(-50%) translate(calc(var(--dx) * var(--px)), calc(var(--dy) * var(--px)))
    scale(var(--s));
  transform-origin: top center;
}

/* Пока скрипт не сказал иначе, кадры разложены по местам в макете. Это же
   состояние страница показывает без скрипта. */
.reel__slot:nth-child(2) .reel__card,
.reel__slot:nth-child(4) .reel__card {
  --s: 0.662069;
  --dy: 115;
  --cap: 20;
}

.reel__slot:nth-child(1) .reel__card,
.reel__slot:nth-child(5) .reel__card {
  --s: 0.562069;
  --dy: 149;
  --cap: 18;
  --pad: 27;
}

.reel__slot:nth-child(1) .reel__card {
  --dx: 127;
}

.reel__slot:nth-child(5) .reel__card {
  --dx: -127;
}

.reel__card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Подпись лежит плашкой по нижней кромке кадра. Есть не везде: на странице
   проекта лента идёт без подписей, и правило просто не на что применить.

   Кегль убывает медленнее кадра — в макете 22 / 20 / 18, а масштаб дал бы
   22 / 14.6 / 12.4. Поэтому нужный экранный кегль делится на масштаб: то, что
   transform потом умножит, здесь заранее поделено. */
.reel__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: calc(var(--pad) * var(--px) / var(--s));
  background: #00000080;
  color: var(--paper);
  font-size: calc(var(--cap) * var(--px) / var(--s));
  font-weight: 300;
  line-height: 1.5;
  text-align: center;
}

/* Круг залит чёрным, набор белый. Он стоит не на снимке, а в рамке: место
   центрального кадра, 994 от левого края макета, — это 34 правее середины. */
.reel__cta {
  position: absolute;
  left: calc(50% + 34 * var(--px));
  top: calc(50 * var(--px));
  z-index: 1;
  width: calc(206 * var(--px));
  height: calc(206 * var(--px));
  border-radius: 50%;
  background: var(--black);
  color: var(--paper);
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.reel__cta:hover {
  background: var(--paper);
  color: var(--black);
}

.reel__cta-label {
  position: absolute;
  left: calc(20 * var(--px));
  top: calc(87 * var(--px));
  display: flex;
  align-items: flex-start;
  gap: calc(8 * var(--px));
  font-size: calc(22 * var(--px));
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

.reel__cta-arrow {
  width: calc(22 * var(--px));
  height: calc(17 * var(--px));
  margin-top: calc(8 * var(--px));
  flex: none;
}

/* Ряд точек стоит по центру ленты, под средним кадром. Не координатой из
   макета: точек теперь пять вместо трёх, ряд стал шире, а центр обязан
   остаться тем же. Ширина ряда от того, какая точка активна, не зависит —
   активная всегда одна. */
.reel__dots {
  position: absolute;
  left: 50%;
  top: calc(709 * var(--px));
  display: flex;
  align-items: center;
  gap: calc(20 * var(--px));
  transform: translateX(-50%);
}

/* Фон обеих секций светлый, поэтому активная и наведённая точка тут чёрные:
   белая, как на тёмном первом экране, на светлом просто пропадала бы. */
.reel__dots .dot--active,
.reel__dots .dot:hover {
  background: var(--black);
}

/* Точка в 16 пикселей мелка для пальца — зона нажатия расширена невидимым
   псевдоэлементом. По горизонтали ровно половина промежутка: соседние зоны
   смыкаются, но не перекрываются. */
.reel__dots .dot {
  position: relative;
}

.reel__dots .dot::after {
  content: "";
  position: absolute;
  inset: calc(-10 * var(--px));
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Кадры и подписи выстраиваются в столбик, заголовок уходит наверх. */
  .project-split {
    display: flex;
    flex-direction: column;
    height: auto;
    padding: 50px var(--gutter);
  }

  .project-split__small,
  .project-split__large {
    position: static;
    width: auto;
    height: auto;
  }

  .project-split__small img,
  .project-split__large img {
    object-fit: cover;
  }

  .project-split__small {
    order: 2;
    aspect-ratio: 580 / 354;
    margin-top: 30px;
  }

  .project-split__small-text {
    order: 3;
  }

  .project-split__large {
    order: 4;
    aspect-ratio: 915 / 551;
    margin-top: 40px;
  }

  .project-split__large-text {
    order: 5;
  }

  .project-split__title {
    position: static;
    order: 1;
    font-size: 32px;
    white-space: normal;
  }

  .project-split__small-text,
  .project-split__large-text {
    position: static;
    width: auto;
    margin-top: 30px;
    font-size: 16px;
  }

  .project-row {
    flex-direction: column;
    gap: 20px;
    height: auto;
    padding: 50px var(--gutter);
  }

  .project-row__media {
    width: auto;
    height: auto;
    aspect-ratio: 580 / 679;
  }

  /* Лента «other projects» не перестраивается в столбик, а остаётся той же
     композицией, что на десктопе, — просто крупнее. Макетная единица живёт
     теперь на самой рамке ленты (см. .reel__viewport ниже), а не на секции:
     нужна она ровно там, где считается пропорция кадров. --gutter остаётся
     общим для страницы: заголовок отступает от края как у соседних секций. */
  .other {
    height: auto;
    padding: 50px 0;
  }

  /* Заголовок из масштабирования исключён: в макетных долях он ужимался бы
     до нечитаемого, поэтому набирается тем же кеглем, что заголовки
     соседних секций. */
  .other__title {
    position: static;
    padding: 0 var(--gutter);
    font-size: 32px;
  }

  /* Раз заголовок встал в поток, лента встаёт следом за ним, а не поверх
     секции. Точки уходят из ленты в поток, поэтому её высота — это высота
     центрального кадра, самого высокого из пяти. */
  .other .reel {
    position: static;
    margin-top: 30px;
  }

  .reel {
    height: auto;
  }

  /* Кадры укрупняются втрое против макетной единицы страницы. При 320 средний
     выходит 290 при полях по 15 — ровно мобильный макет, где лента вдвое
     вылезает за оба края экрана. Потолок в 1.2px держит планшет: выше 768 кадр
     больше не растёт и к 1199 занимает 58% ширины, соседи выглядывают целиком.
     Без укрупнения ход ленты был бы 45px на телефоне — свайпать нечего. */
  .reel__viewport {
    --px: min(0.15625vw, 1.2px);

    height: calc(679 * var(--px));
  }

  /* На десктопе точки стоят под центральным кадром, а он лежит ровно по
     середине ленты — статичный ряд по центру даёт ту же картину.

     Из масштабирования они исключены тем же приёмом, что .other__title: это
     кнопки, им нужен палец, а в макетных долях они выходили бы по три пикселя. */
  .reel__dots {
    --px: 1px;

    position: static;
    justify-content: center;
    margin-top: 30px;
    gap: 10px;
    transform: none;
  }

  .reel__dots .dot::after {
    inset: -12px -5px;
  }

  /* Круглая кнопка на центральном кадре в таком масштабе нечитаема. */
  .reel__cta {
    display: none;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .project-split,
  .project-row,
  .other {
    padding-top: 80px;
    padding-bottom: 80px;
  }

  .project-split__title,
  .other__title {
    font-size: 56px;
  }

  .project-split__small-text,
  .project-split__large-text {
    font-size: 18px;
  }

  /* Три кадра снова встают в ряд. */
  .project-row {
    flex-direction: row;
    gap: 20px;
  }

  .project-row__media {
    width: calc((100% - 40px) / 3);
    aspect-ratio: 580 / 679;
  }
}

/* ======================================================================
   ПОРТФОЛИО (portfolio.html)

   Список проектов: две колонки карточек, под ними кнопка «смотреть все».
   Шапка, крошки, кружок со стрелкой, Contact me и футер здесь общие —
   взяты со страниц home.html и project.html и живут выше по файлу.
   ====================================================================== */

.portfolio {
  padding: 0 var(--gutter) calc(60 * var(--px));
  background: var(--paper);
  color: var(--ink);
}

/* Тут крошки идут обычной строкой по потоку, а не поверх снимка,
   как на странице проекта. Отступы задаёт страница: они у всех свои. */
.breadcrumbs--flow {
  position: static;
}

.portfolio > .breadcrumbs {
  margin-bottom: calc(60 * var(--px));
  padding-top: calc(60 * var(--px));
}

/* Заголовок слева, вводный абзац — во второй колонке той же сетки,
   что и карточки. */
.portfolio__head {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: calc(30 * var(--px));
}

.portfolio__title {
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

.portfolio__lead {
  margin: calc(25 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.portfolio__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: calc(60 * var(--px));
  column-gap: calc(30 * var(--px));
  row-gap: calc(60 * var(--px));
}

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

.card {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
}

.card__media {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 885 / 533;
  color: var(--paper);
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* В макете это состояние нарисовано на первой карточке: снимок уходит
   под чёрное полупрозрачное полотно, поверх выходят название и стрелка. */
.card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #00000080;
  opacity: 0;
  transition: opacity 0.25s ease;
}

.card__media:hover .card__overlay,
.card__media:focus-visible .card__overlay {
  opacity: 1;
}

.card__name {
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
}

.card__arrow {
  position: absolute;
  right: calc(30 * var(--px));
  bottom: calc(30 * var(--px));
  width: calc(152 * var(--px));
  height: calc(152 * var(--px));
}

/* Метка видео: полупрозрачный круг с треугольником, ровно по центру кадра.
   Пропорции круга и треугольника заданы долей, чтобы метка сжималась
   вместе с кадром. Блок общий: стоит и на карточке портфолио, и на кадрах
   страницы услуг — размер задаёт хозяин. */
.play {
  position: absolute;
  left: 50%;
  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(152 * var(--px));
  height: calc(152 * var(--px));
  border-radius: 50%;
  background: #ffffff80;
  transform: translate(-50%, -50%);
}

/* Треугольник тяжёлый слева: основание — сплошная стена, остриё сходит в точку.
   Поставленный серединой бокса, он выглядит уехавшим влево, поэтому в центр
   круга сажается его центр тяжести. У треугольника тот лежит на трети ширины
   от основания — значит бокс сдвигается вправо на шестую часть, 8 из 48.
   Так же устроена play_arrow в Material: там центр бокса тоже правее центра
   сетки. Обрезки нет: у круга border-radius, но не overflow. */
.play svg {
  width: 31.6%; /* 48 из 152 в макете */
  height: 31.6%;
  fill: #00000080;
  transform: translateX(16.667%);
}

.card__text {
  display: flex;
  flex-direction: column;
  gap: calc(10 * var(--px));
}

.card__title {
  margin: 0;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
}

/* Две строки держим всегда: в макете подпись занимает ровно этот бокс,
   и без него ряды карточек разъезжаются по высоте. */
.card__desc {
  min-height: calc(66 * var(--px));
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.portfolio__more {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(580 * var(--px));
  height: calc(59 * var(--px));
  margin: calc(60 * var(--px)) auto 0;
  background: var(--black);
  color: var(--paper);
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.portfolio__more:hover {
  opacity: var(--hover-strong);
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: одна колонка, ритм блока сжимается с 60 до 30. */
  .portfolio {
    padding-bottom: 60px;
  }

  .portfolio > .breadcrumbs {
    margin-bottom: 30px;
    padding-top: 30px;
  }

  .portfolio__head {
    grid-template-columns: minmax(0, 1fr);
  }

  .portfolio__title {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.4667;
  }

  .portfolio__lead {
    margin-top: 30px;
    font-size: 16px;
  }

  .portfolio__grid {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 30px;
    row-gap: 30px;
  }

  .card__media {
    aspect-ratio: 290 / 205;
  }

  .card__name {
    font-size: 22px;
  }

  .card__arrow {
    right: 15px;
    bottom: 15px;
    width: 50px;
    height: 50px;
  }

  .play {
    width: 72px;
    height: 72px;
  }

  .card__title {
    font-size: 22px;
  }

  .card__desc {
    min-height: 72px; /* три строки по 24 */
    font-size: 16px;
  }

  .portfolio__more {
    width: 100%;
    height: 30px;
    margin-top: 30px;
    font-size: 16px;
    font-weight: 400;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: карточки возвращаются в две колонки, набор крупнее. */
  .portfolio__head {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 30px;
  }

  .portfolio__title {
    font-size: 56px;
    font-weight: 600;
  }

  .portfolio__lead {
    margin-top: 10px;
    font-size: 18px;
  }

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

  .card__media {
    aspect-ratio: 885 / 533;
  }

  .card__arrow {
    right: 20px;
    bottom: 20px;
    width: 72px;
    height: 72px;
  }

  .play {
    width: 72px;
    height: 72px;
  }

  .card__desc {
    min-height: 54px; /* две строки по 27 */
    font-size: 18px;
  }

  .portfolio__more {
    width: 380px;
    height: 48px;
    font-size: 18px;
    font-weight: 500;
  }
}

/* ======================================================================
   НОВОСТЬ (article.html)

   Одна публикация: снимок во всю колонку, заголовок, текст и кнопка
   «поделиться» в правом нижнем углу. Шапка, крошки, Contact me и футер —
   общие, живут выше по файлу.
   ====================================================================== */

.article {
  display: block;
  padding: 0 var(--gutter) calc(60 * var(--px));
  background: var(--paper);
  color: var(--ink);
}

/* Здесь крошки прижаты к шапке плотнее, чем на портфолио: в макете 30. */
.article > .breadcrumbs {
  padding-top: calc(30 * var(--px));
}

.article__media {
  margin: calc(60 * var(--px)) 0 0;
  aspect-ratio: 1800 / 726;
}

/* Снимок растянут на блок, а не обрезан, — как в макете и как план на
   странице проекта. Кадрирование тут не подходит: исходник почти
   квадратный, и в полосу 1800x726 попала бы либо люстра, либо диван. */
.article__media img {
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.article__title {
  margin: calc(60 * var(--px)) 0 0;
  font-size: calc(50 * var(--px));
  font-weight: 400;
  line-height: 1.48;
  text-transform: uppercase;
}

.article__text {
  margin-top: calc(30 * var(--px));
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.article__text p {
  margin: 0;
}

.article__text p + p {
  margin-top: calc(33 * var(--px));
}

/* Кнопка прижата к правому краю колонки — в макете так же. */
.article__share {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(20 * var(--px));
  width: calc(580 * var(--px));
  height: calc(59 * var(--px));
  margin: calc(30 * var(--px)) 0 0 auto;
  padding: 0;
  border: 0;
  background: var(--black);
  color: var(--paper);
  font-family: inherit;
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.12s ease;
}

.article__share:hover {
  opacity: var(--hover-strong);
}

.article__share:active {
  transform: scale(0.98);
}

.article__share svg {
  flex: none;
  width: calc(30 * var(--px));
  height: calc(30 * var(--px));
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: ритм блока сжимается с 60 до 30, кнопка занимает всю ширину. */
  .article {
    padding-bottom: 60px;
  }

  .article__media {
    margin-top: 30px;
    aspect-ratio: 290 / 167;
  }

  .article__title {
    margin-top: 30px;
    font-size: 25px;
  }

  .article__text {
    margin-top: 30px;
    font-size: 16px;
  }

  .article__text p + p {
    margin-top: 24px;
  }

  .article__share {
    gap: 10px;
    width: 100%;
    height: 30px;
    margin-top: 30px;
    font-size: 16px;
    font-weight: 400;
  }

  .article__share svg {
    width: 18px;
    height: 18px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: набор крупнее, кнопка снова уходит вправо. */
  .article__media {
    margin-top: 40px;
    aspect-ratio: 1800 / 726;
  }

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

  .article__text {
    font-size: 18px;
  }

  .article__text p + p {
    margin-top: 27px;
  }

  .article__share {
    gap: 16px;
    width: 380px;
    height: 48px;
    font-size: 18px;
    font-weight: 500;
  }

  .article__share svg {
    width: 24px;
    height: 24px;
  }
}

/* ======================================================================
   НОВОСТИ (news.html)

   Лента публикаций: первая крупная — заголовок и текст слева, снимок
   справа, — под ней четыре обычные в две колонки и кнопка «смотреть все».
   Шапка, крошки, Contact me и футер — общие, живут выше по файлу.
   ====================================================================== */

.blog {
  padding: 0 var(--gutter) calc(120 * var(--px));
  background: var(--paper);
  color: var(--ink);
}

.blog > .breadcrumbs {
  margin-bottom: calc(120 * var(--px));
  padding-top: calc(30 * var(--px));
}

/* Первая публикация занимает две колонки: слева заголовок и текст,
   справа снимок во всю высоту блока. */
.blog__head {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: calc(148 * var(--px)) auto; /* строка заголовка: 100 * 1.48 */
  align-items: start;
  column-gap: calc(30 * var(--px));
}

.blog__title {
  grid-column: 1;
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 600;
  line-height: 1.48;
  text-transform: uppercase;
}

.blog__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: calc(30 * var(--px));
  column-gap: calc(30 * var(--px));
  row-gap: calc(30 * var(--px));
}

.blog__more {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(580 * var(--px));
  height: calc(59 * var(--px));
  margin: calc(60 * var(--px)) auto 0;
  background: var(--black);
  color: var(--paper);
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.blog__more:hover {
  opacity: var(--hover-strong);
}

/* ---------- Карточка публикации ---------- */

.post__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 885 / 533;
}

.post__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.post__media:hover img {
  transform: scale(1.03);
}

.post__text {
  margin-top: calc(30 * var(--px));
}

.post__excerpt {
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* Ссылка прижата к правому краю карточки — в макете так же. */
.post__more {
  display: block;
  margin-top: calc(10 * var(--px));
  color: inherit;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
  text-align: right;
  text-decoration: none;
  text-transform: uppercase;
  transition: opacity 0.2s ease;
}

.post__more:hover {
  opacity: var(--hover-soft);
}

/* Первая публикация: снимок другой пропорции, набор мельче, а текст
   отбит от заголовка так, чтобы низ колонки сошёлся с низом снимка. */
.post--lead .post__media {
  grid-column: 2;
  grid-row: 1 / span 2;
  aspect-ratio: 885 / 589;
}

.post--lead .post__text {
  grid-column: 1;
  margin-top: calc(51 * var(--px));
}

.post--lead .post__excerpt {
  min-height: calc(99 * var(--px)); /* три строки по 33 */
}

.post--lead .post__more {
  margin-top: calc(60 * var(--px));
  font-size: calc(22 * var(--px));
  font-weight: 500;
}

/* В карточках ленты под текст отведено четыре строки, занято три —
   так в макете, и ряды от этого стоят ровно. */
.blog__grid .post__excerpt {
  min-height: calc(132 * var(--px));
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: одна колонка, ритм 30, заголовок над снимком первой публикации. */
  .blog {
    padding-bottom: 60px;
  }

  .blog > .breadcrumbs {
    margin-bottom: 30px;
    padding-top: 30px;
  }

  .blog__head {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
  }

  .blog__title {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.4667;
  }

  .blog__grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 30px;
  }

  .post__media {
    aspect-ratio: 290 / 205;
  }

  .post__excerpt {
    font-size: 16px;
  }

  .post__more {
    margin-top: 20px;
    font-size: 16px;
    font-weight: 600;
  }

  .post--lead .post__media {
    grid-column: auto;
    grid-row: auto;
    margin-top: 30px;
    aspect-ratio: 290 / 205;
  }

  .post--lead .post__text {
    grid-column: auto;
    margin-top: 30px;
  }

  .post--lead .post__excerpt,
  .blog__grid .post__excerpt {
    min-height: 168px; /* семь строк по 24 */
  }

  .post--lead .post__more {
    margin-top: 20px;
    font-size: 16px;
    font-weight: 500;
  }

  .blog__more {
    width: 100%;
    height: 30px;
    margin-top: 30px;
    font-size: 16px;
    font-weight: 400;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: обе сетки возвращаются в две колонки, набор крупнее. */
  .blog {
    padding-bottom: 80px;
  }

  .blog > .breadcrumbs {
    margin-bottom: 60px;
  }

  .blog__head {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: 83px auto; /* строка заголовка: 56 * 1.48 */
    column-gap: 30px;
  }

  .blog__title {
    font-size: 56px;
    font-weight: 600;
  }

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

  .post__media {
    aspect-ratio: 885 / 533;
  }

  .post__excerpt {
    font-size: 18px;
  }

  .post__more {
    margin-top: 10px;
    font-size: 20px;
  }

  .post--lead .post__media {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin-top: 0;
    aspect-ratio: 885 / 589;
  }

  .post--lead .post__text {
    grid-column: 1;
    margin-top: 24px;
  }

  .post--lead .post__excerpt,
  .blog__grid .post__excerpt {
    min-height: 0;
  }

  .post--lead .post__more {
    margin-top: 24px;
    font-size: 18px;
  }

  .blog__more {
    width: 380px;
    height: 48px;
    margin-top: 40px;
    font-size: 18px;
    font-weight: 500;
  }
}

/* ======================================================================
   УСЛУГИ (services.html)

   Первый экран со снимком под затемнением, шесть преимуществ в рамках,
   два разворота про услугу и авторский надзор, лента проектов. Шапка,
   крошки, метка видео, лента, Contact me и футер — общие блоки, живут
   выше по файлу.
   ====================================================================== */

/* Крошки лежат на белой полосе между шапкой и снимком: 30 сверху, 60 снизу
   до кромки первого экрана — так в макете. */
.svc-crumbs {
  padding: calc(30 * var(--px)) var(--gutter) calc(60 * var(--px));
  background: var(--paper);
}

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

/* Снимок уходит под затемнение: без него белый набор на светлой гостиной
   не читается. 99 в конце — те самые 60% чёрного из макета. */
.svc-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: calc(952 * var(--px));
  padding: 0 var(--gutter);
  overflow: hidden;
  background: var(--black);
  color: var(--paper);
  text-align: center;
}

.svc-hero__media {
  position: absolute;
  inset: 0;
  margin: 0;
}

.svc-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.svc-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: #00000099;
}

.svc-hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(60 * var(--px));
  width: calc(1332 * var(--px));
}

.svc-hero__head {
  width: 100%;
}

.svc-hero__kicker {
  margin: 0;
  font-family: "Playfair Display", Georgia, serif;
  font-size: calc(80 * var(--px));
  font-style: italic;
  font-weight: 600;
  line-height: 1.3375;
}

.svc-hero__title {
  margin: calc(30 * var(--px)) 0 0;
  font-size: calc(80 * var(--px));
  font-weight: 600;
  line-height: 1.4875;
}

.svc-hero__lead {
  margin: 0;
  font-size: calc(40 * var(--px));
  font-weight: 500;
  line-height: 1.475;
}

.svc-hero__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(580 * var(--px));
  height: calc(59 * var(--px));
  background: var(--paper);
  color: var(--black);
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  transition: opacity 0.2s var(--ease-out);
}

.svc-hero__cta:hover {
  opacity: var(--hover-strong);
}

/* ---------- Преимущества ---------- */

.pros {
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--paper);
  color: var(--black);
}

.pros__title {
  margin: 0 0 calc(30 * var(--px));
  font-size: calc(50 * var(--px));
  font-weight: 700;
  line-height: 1.48;
  text-transform: uppercase;
}

.pros__row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: calc(30 * var(--px));
}

.pros__row + .pros__row {
  margin-top: calc(30 * var(--px));
}

/* Высота задана явно, чтобы рамка легла внутрь бокса: в макете обводка
   внутренняя и в 174 уже входит, а при height:auto CSS прибавил бы её
   к содержимому и ряд стал бы выше на два пикселя. */
.pros__card {
  height: calc(174 * var(--px));
  padding: calc(30 * var(--px));
  border: 1px solid currentColor;
}

.pros__card-title {
  margin: 0;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
}

.pros__card-text {
  margin: calc(10 * var(--px)) 0 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Что входит в услугу ---------- */

/* Две колонки без промежутка: правый кадр начинается ровно там, где
   кончается левая. Высота левой колонки сходится с высотой кадра —
   74 + 120 + 463 + 60 + 228 = 945. */
.svc-what {
  display: grid;
  grid-template-columns: calc(1030 * var(--px)) calc(770 * var(--px));
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--paper);
  color: var(--black);
}

/* Левая колонка разворота: заголовок, кадр и текст идут обычным потоком,
   отступы между ними разные, поэтому заданы полями у самих элементов. */
.svc-what__col {
  min-width: 0;
}

.svc-what__title {
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 700;
  line-height: 1.48;
  text-transform: uppercase;
}

.svc-what__small {
  width: calc(463 * var(--px));
  height: calc(463 * var(--px));
  margin: calc(120 * var(--px)) 0 0;
  overflow: hidden;
}

.svc-what__text {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
  width: calc(920 * var(--px));
  margin-top: calc(60 * var(--px));
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.svc-what__text p {
  margin: 0;
}

.svc-what__media {
  position: relative;
  height: calc(945 * var(--px));
  margin: 0;
  overflow: hidden;
}

.svc-what__small img,
.svc-what__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- Что такое авторский надзор ---------- */

/* Лента кадров выходит за оба края экрана, поэтому лишнее режется здесь. */
.svc-super {
  padding: calc(120 * var(--px)) 0;
  overflow: hidden;
  background: var(--paper);
  color: var(--black);
}

.svc-super__title {
  margin: 0 var(--gutter);
  font-size: calc(50 * var(--px));
  font-weight: 700;
  line-height: 1.48;
  text-transform: uppercase;
}

.svc-super__lead {
  width: calc(885 * var(--px));
  margin: calc(20 * var(--px)) var(--gutter) 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.svc-super__media {
  position: relative;
  height: calc(945 * var(--px));
  margin: calc(30 * var(--px)) var(--gutter) 0;
  overflow: hidden;
}

.svc-super__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.svc-super__text {
  margin: calc(60 * var(--px)) var(--gutter) 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.svc-super .reel {
  margin-top: calc(60 * var(--px));
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: одна колонка, ритм секций 60, внутри блоков 30. */
  .svc-crumbs {
    padding: 30px var(--gutter);
  }

  .svc-hero {
    height: auto;
    padding: 30px var(--gutter);
  }

  .svc-hero__inner {
    gap: 30px;
    width: 100%;
  }

  .svc-hero__kicker {
    font-size: 30px;
  }

  .svc-hero__title {
    margin-top: 0;
    font-size: 29px;
  }

  .svc-hero__lead {
    font-size: 18px;
  }

  .svc-hero__cta {
    width: 100%;
    height: auto;
    padding: 15px;
    font-size: 16px;
    font-weight: 400;
  }

  .pros,
  .svc-what,
  .svc-super {
    padding-top: 60px;
    padding-bottom: 60px;
  }

  .pros__title,
  .svc-what__title,
  .svc-super__title {
    font-size: 30px;
  }

  .pros__title {
    margin-bottom: 30px;
  }

  /* Карточки встают столбиком, высоту им задаёт текст. */
  .pros__row {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .pros__row + .pros__row {
    margin-top: 20px;
  }

  /* Высоту карточке снова задаёт текст: на узком экране он длиннее. */
  .pros__card {
    height: auto;
  }

  .pros__card-title {
    font-size: 20px;
  }

  .pros__card-text {
    font-size: 16px;
  }

  /* Разворот разбирается на столбик: заголовок, квадратный кадр, текст,
     широкий кадр — как в мобильном макете. */
  .svc-what {
    display: block;
  }

  .svc-what__small {
    width: 100%;
    height: auto;
    margin-top: 30px;
    aspect-ratio: 1 / 1;
  }

  .svc-what__text {
    width: 100%;
    margin-top: 30px;
    font-size: 22px;
  }

  .svc-what__media {
    height: auto;
    margin-top: 30px;
    aspect-ratio: 290 / 356;
  }

  .svc-super__lead {
    width: auto;
    margin-top: 30px;
    font-size: 16px;
  }

  .svc-super__media {
    height: auto;
    aspect-ratio: 290 / 152;
  }

  .svc-super__text {
    margin-top: 30px;
    font-size: 16px;
  }

  /* Всё про масштаб ленты — на .reel__viewport, общем для этой страницы и
     страницы проекта. Секции остаётся только отступ. */
  .svc-super .reel {
    margin-top: 30px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: преимущества снова в три колонки, набор крупнее. */
  .svc-crumbs {
    padding: 30px var(--gutter) 40px;
  }

  .svc-hero {
    padding: 80px var(--gutter);
  }

  .svc-hero__inner {
    gap: 40px;
    width: 100%;
    max-width: 900px;
  }

  .svc-hero__kicker,
  .svc-hero__title {
    font-size: 48px;
  }

  .svc-hero__title {
    margin-top: 16px;
  }

  .svc-hero__lead {
    font-size: 24px;
  }

  .svc-hero__cta {
    width: 480px;
    height: 56px;
    padding: 0;
    font-size: 18px;
    font-weight: 500;
  }

  .pros,
  .svc-what,
  .svc-super {
    padding-top: 80px;
    padding-bottom: 80px;
  }

  .pros__title,
  .svc-what__title,
  .svc-super__title {
    font-size: 56px;
  }

  .pros__row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
  }

  .pros__row + .pros__row {
    margin-top: 20px;
  }

  .pros__card-text {
    font-size: 18px;
  }

  .svc-what__small {
    width: 60%;
    aspect-ratio: 1 / 1;
  }

  .svc-what__text {
    font-size: 18px;
  }

  .svc-what__media {
    aspect-ratio: 770 / 945;
  }

  .svc-super__lead,
  .svc-super__text {
    font-size: 18px;
  }

  .svc-super__media {
    aspect-ratio: 1800 / 945;
  }
}

/* ======================================================================
   УСЛУГИ, ВАРИАНТ 2 (services-2.html)

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

   Шапка, крошки, Description, Contact me и футер — общие блоки, живут выше
   по файлу. Своего здесь два: первый экран и гармошка.
   ====================================================================== */

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

/* Композиция собрана координатами: заголовок и снимок держатся левого края,
   два примечания — правого, и заезжают друг на друга по вертикали. */
.svc2-hero {
  position: relative;
  height: calc(1105 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.svc2-hero__title {
  position: absolute;
  left: var(--gutter);
  top: 0;
  width: calc(1190 * var(--px));
  margin: 0;
  font-size: calc(130 * var(--px));
  font-weight: 400;
  line-height: 1.4846; /* 193 / 130 */
  text-transform: uppercase;
}

/* Строки заходят одна на другую: в макете между ними отрицательный
   промежуток 49, поэтому шаг строки 144, а не 193. */
.svc2-hero__line {
  display: block;
}

.svc2-hero__line + .svc2-hero__line {
  margin-top: calc(-49 * var(--px));
}

.svc2-hero__note {
  position: absolute;
  top: calc(351 * var(--px));
  width: calc(580 * var(--px));
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.svc2-hero__note--1 {
  left: calc(620 * var(--px));
}

.svc2-hero__note--2 {
  left: calc(1280 * var(--px));
}

/* Снимок в макете растянут на полосу, а не обрезан, — как в новости.
   Кадрировать нечем: исходник почти квадратный, а полоса втрое шире. */
.svc2-hero__media {
  position: absolute;
  left: var(--gutter);
  top: calc(521 * var(--px));
  width: calc(1800 * var(--px));
  height: calc(584 * var(--px));
  margin: 0;
  overflow: hidden;
}

.svc2-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* ---------- Гармошка услуг ---------- */

.svc2-services {
  padding: calc(104 * var(--px)) var(--gutter) calc(120 * var(--px));
  background: var(--paper);
  color: var(--black);
}

/* Единственный на сайте секционный заголовок строчными: так он набран
   в исходной Figma, оттуда же и кегль. */
.svc2-services__title {
  margin: 0;
  font-size: calc(60 * var(--px));
  font-weight: 700;
  line-height: 1.48;
}

.svc2-list {
  margin-top: calc(28 * var(--px));
}

/* Раскрытие держится на <details name>: браузер сам закрывает соседей,
   когда открывают одну строку, и сам даёт клавиатуру и чтение с экрана.
   Скрипта здесь нет вовсе. */
.svc2-item {
  position: relative;
  border-top: 1px solid #00000080;
}

/* Свёрнутые строки заходят друг на друга: в макете шаг 125 при высоте
   содержимого 149, поэтому названия почти касаются линеек. */
.svc2-item:not([open]) {
  height: calc(125 * var(--px));
}

.svc2-item:last-child {
  height: auto;
}

.svc2-item[open] {
  margin-bottom: calc(60 * var(--px));
}

.svc2-item__head {
  display: flex;
  align-items: flex-start;
  padding-top: calc(30 * var(--px));
  list-style: none;
  cursor: pointer;
}

.svc2-item__head::-webkit-details-marker {
  display: none;
}

.svc2-item__num {
  width: calc(36 * var(--px));
  margin-right: calc(20 * var(--px));
  color: #00000080;
  font-size: calc(30 * var(--px));
  font-weight: 600;
  line-height: 1.5;
}

.svc2-item__name {
  font-size: calc(80 * var(--px));
  font-weight: 400;
  line-height: 1.4875;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Метка справа: у свёрнутой строки кружок с плюсом, у раскрытой — голая
   галка вверх. Размер и отступ у них разные, поэтому переключается всё. */
.svc2-item__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: calc(39 * var(--px));
  height: calc(39 * var(--px));
  margin: 0 0 0 auto;
  border: 1px solid #00000080;
  border-radius: 50%;
  color: #00000080;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1;
  transition: color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}

.svc2-item__head:hover .svc2-item__mark {
  color: var(--black);
  border-color: var(--black);
}

.svc2-item[open] .svc2-item__mark {
  position: relative;
  z-index: 1;
  width: calc(16 * var(--px));
  height: calc(10 * var(--px));
  margin: calc(91 * var(--px)) 0 0 auto;
  border: 0;
}

/* Текст раскрытой строки лежит поверх правого края заголовка и перехватывает
   нажатие на галку — поэтому она поднята над панелью. Сама галка мельче
   ногтя, площадь нажатия ей растит невидимый квадрат размером со свёрнутый
   кружок: закрыть строку галкой должно быть так же легко, как открыть. */
.svc2-item[open] .svc2-item__mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(39 * var(--px));
  height: calc(39 * var(--px));
  transform: translate(-50%, -50%);
}

.svc2-item__chevron {
  display: none;
}

.svc2-item[open] .svc2-item__chevron {
  display: block;
  width: 100%;
  height: 100%;
}

.svc2-item[open] .svc2-item__plus {
  display: none;
}

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

   Отступ 49 вместо макетных 58: раскрытая шапка стала на 9 выше свёрнутой,
   когда её отступ и межстрочный воздух сравняли с остальными строками.
   Разницу отдали панели, и низ раскрытой строки остался там же, где в макете. */
.svc2-item__panel {
  height: calc(406 * var(--px));
  margin-top: calc(49 * var(--px));
}

.svc2-item__media {
  position: absolute;
  left: 0;
  top: calc(199 * var(--px));
  width: calc(758 * var(--px));
  height: calc(406 * var(--px));
  margin: 0;
  overflow: hidden;
}

/* Точку кадра опускаем: в Figma в полосу попадает диван с ковром, а не
   потолок с кольцами. */
.svc2-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center bottom;
}

.svc2-item__excerpt {
  position: absolute;
  left: calc(869 * var(--px));
  right: 0;
  top: calc(60 * var(--px));
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.svc2-item__more {
  position: absolute;
  left: calc(869 * var(--px));
  top: calc(292 * var(--px));
  color: inherit;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  transition: opacity 0.2s var(--ease-out);
}

.svc2-item__more:hover {
  opacity: var(--hover-soft);
}

.svc2-item__order {
  position: absolute;
  right: 0;
  top: calc(546 * var(--px));
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(580 * var(--px));
  height: calc(59 * var(--px));
  background: var(--black);
  color: var(--paper);
  font-size: calc(22 * var(--px));
  font-weight: 500;
  line-height: 1.5;
  text-decoration: none;
  text-transform: uppercase;
  transition: opacity 0.2s var(--ease-out);
}

.svc2-item__order:hover {
  opacity: var(--hover-strong);
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: композиция первого экрана разбирается в столбик, и снимок
     встаёт между двумя примечаниями — как в мобильном макете. */
  .svc2-hero {
    display: flex;
    flex-direction: column;
    gap: 20px;
    height: auto;
    padding: 0 var(--gutter) 60px;
  }

  .svc2-hero__title,
  .svc2-hero__note,
  .svc2-hero__media {
    position: static;
    width: auto;
  }

  .svc2-hero__title {
    font-size: 35px;
    line-height: 1.42;
  }

  .svc2-hero__line + .svc2-hero__line {
    margin-top: 0;
  }

  .svc2-hero__note {
    font-size: 16px;
  }

  .svc2-hero__media {
    height: auto;
    aspect-ratio: 1800 / 584;
  }

  .svc2-services {
    padding-top: 0;
    padding-bottom: 60px;
  }

  .svc2-services__title {
    font-size: 30px;
  }

  /* Названия услуг на телефоне в одну строку не влезают. */
  .svc2-item__name {
    white-space: normal;
  }

  .svc2-list {
    margin-top: 30px;
  }

  /* Строки больше не заходят друг на друга: набор мельче, и высоты хватает. */
  .svc2-item:not([open]) {
    height: auto;
  }

  .svc2-item[open] {
    margin-bottom: 30px;
  }

  .svc2-item__head {
    align-items: center;
    padding-top: 30px;
  }

  .svc2-item__num {
    width: 36px;
    margin-right: 10px;
    font-size: 16px;
  }

  .svc2-item__name {
    width: auto;
    font-size: 22px;
    line-height: 1.5;
  }

  .svc2-item__mark {
    width: 24px;
    height: 24px;
    margin-right: 0;
    font-size: 16px;
  }

  .svc2-item[open] .svc2-item__mark {
    width: 16px;
    height: 10px;
    margin-top: 0;
  }

  /* Панель встаёт обычным столбиком: снимок, текст, ссылка, кнопка. */
  .svc2-item__panel {
    display: flex;
    flex-direction: column;
    gap: 20px;
    height: auto;
    margin-top: 20px;
  }

  .svc2-item__media,
  .svc2-item__excerpt,
  .svc2-item__more,
  .svc2-item__order {
    position: static;
    width: auto;
  }

  .svc2-item__media {
    height: auto;
    aspect-ratio: 290 / 155;
  }

  .svc2-item__excerpt {
    font-size: 16px;
  }

  .svc2-item__more {
    font-size: 16px;
  }

  .svc2-item__order {
    height: 30px;
    font-size: 16px;
    font-weight: 400;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: набор крупнее, панель услуги снова в две колонки. */
  .svc2-hero {
    gap: 30px;
    padding-bottom: 80px;
  }

  .svc2-hero__title {
    font-size: 64px;
  }

  .svc2-hero__note {
    font-size: 18px;
  }

  .svc2-services {
    padding-bottom: 80px;
  }

  .svc2-services__title {
    font-size: 56px;
  }

  .svc2-item__num {
    font-size: 20px;
  }

  .svc2-item__name {
    font-size: 40px;
  }

  .svc2-item__mark {
    width: 32px;
    height: 32px;
    font-size: 20px;
  }

  .svc2-item__panel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: 20px 30px;
  }

  .svc2-item__media {
    grid-row: 1 / span 3;
    aspect-ratio: 758 / 406;
  }

  .svc2-item__excerpt,
  .svc2-item__more {
    font-size: 18px;
  }

  .svc2-item__order {
    height: 48px;
    font-size: 18px;
    font-weight: 500;
  }
}

/* ======================================================================
   О НАС (about.html)

   Три своих блока: первый экран с портретом, «почему ко мне обращаются»
   и чёрный разворот «Innovate Architecture». Шапка, крошки, лента проектов,
   Contact me и футер — общие, живут выше по файлу.
   ====================================================================== */

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

/* Портрет по центру, слова разложены вокруг него по координатам макета:
   ни сеткой, ни потоком такую раскладку не собрать. */
.about-hero {
  position: relative;
  height: calc(1076 * var(--px));
  background: var(--paper);
  color: var(--black);
}

.about-hero__portrait {
  position: absolute;
  left: calc(622 * var(--px));
  top: calc(60 * var(--px));
  width: calc(676 * var(--px));
  height: calc(956 * var(--px));
  margin: 0;
  overflow: hidden;
}

.about-hero__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Регистр у слов разный — Decorator с прописной, designer со строчной.
   Так в макете, и это художественный набор, а не опечатка. */
.about-hero__word,
.about-hero__name {
  position: absolute;
  margin: 0;
  font-size: calc(80 * var(--px));
  font-weight: 400;
  line-height: 1.4875; /* 119 / 80 */
  text-align: center;
}

.about-hero__word--decorator {
  left: calc(319 * var(--px));
  top: calc(150 * var(--px));
  width: calc(285 * var(--px));
}

.about-hero__word--architect {
  left: calc(230 * var(--px));
  top: calc(450 * var(--px));
  width: calc(306 * var(--px));
  font-weight: 700;
}

.about-hero__word--designer {
  left: calc(1200 * var(--px));
  top: calc(637 * var(--px));
  width: calc(282 * var(--px));
  font-weight: 700;
}

.about-hero__name {
  left: calc(1233 * var(--px));
  top: calc(307 * var(--px));
  width: calc(536 * var(--px));
}

.about-hero__video {
  position: absolute;
  left: calc(1398 * var(--px));
  top: calc(492 * var(--px));
  display: flex;
  align-items: center;
  gap: calc(21 * var(--px));
  color: inherit;
  text-decoration: none;
  transition: opacity 0.2s var(--ease-out);
}

.about-hero__video:hover {
  opacity: var(--hover-soft);
}

.about-hero__play {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: calc(80 * var(--px));
  height: calc(80 * var(--px));
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
}

/* Тот же приём, что и у метки видео на карточках (см. `.play svg`):
   треугольник тяжёлый слева, и поставленный серединой бокса он выглядит
   уехавшим влево. В центр круга сажается его центр тяжести — тот лежит
   на трети ширины от основания, значит бокс едет вправо на шестую часть. */
.about-hero__play-icon {
  width: calc(26 * var(--px));
  height: calc(30 * var(--px));
  transform: translateX(16.667%);
}

.about-hero__video-label {
  font-size: calc(30 * var(--px));
  font-weight: 300;
  line-height: 1.4667;
  white-space: nowrap;
}

.about-hero__note {
  position: absolute;
  margin: 0;
  color: var(--ink);
  font-size: calc(16 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

.about-hero__note--left {
  left: calc(229 * var(--px));
  top: calc(769 * var(--px));
  width: calc(293 * var(--px));
}

.about-hero__note--right {
  left: calc(1398 * var(--px));
  top: calc(959 * var(--px));
  width: calc(457 * var(--px));
}

/* ---------- Почему ко мне обращаются ---------- */

.about-why {
  position: relative;
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--mist);
  color: var(--black);
}

.about-why__label {
  margin: 0;
  font-size: calc(50 * var(--px));
  font-weight: 700;
  line-height: 1.48;
}

/* Крупный заголовок стоит во второй колонке и по верху выравнен с подписью,
   поэтому вынут из потока: иначе пришлось бы городить сетку ради двух строк. */
.about-why__title {
  position: absolute;
  left: calc(824 * var(--px));
  top: calc(120 * var(--px));
  width: calc(903 * var(--px));
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 400;
  line-height: 1.1; /* 110 на строку, две строки — 220 */
}

.about-why__list {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
  margin: calc(208 * var(--px)) 0 0;
  padding: 0;
  list-style: none;
}

/* Три колонки ряда складываются в ширину контента: 460 + 720 + 580 = 1760.
   Иконка живёт в первой, название во второй, описание в третьей. */
.why-row {
  display: grid;
  grid-template-columns: calc(460 * var(--px)) calc(720 * var(--px)) calc(580 * var(--px));
  align-items: center;
  padding: calc(29 * var(--px)) calc(20 * var(--px)) 0;
  border-top: 1px solid #00000080;
}

/* У последнего ряда линейка есть и снизу — так закрывается таблица. */
.why-row:last-child {
  padding-bottom: calc(29 * var(--px));
  border-bottom: 1px solid #00000080;
}

/* Рисунок 48 живёт в боксе 60 — так он стоит в макете, с воздухом вокруг. */
.why-row__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(60 * var(--px));
  height: calc(60 * var(--px));
  color: #00000080;
}

.why-row__icon svg {
  display: block;
  width: calc(48 * var(--px));
  height: calc(48 * var(--px));
}

.why-row__name {
  margin: 0;
  font-size: calc(26 * var(--px));
  font-weight: 600;
  line-height: 1.5;
}

.why-row__text {
  margin: 0;
  font-size: calc(22 * var(--px));
  font-weight: 300;
  line-height: 1.5;
}

/* ---------- Innovate Architecture ---------- */

/* Чёрный разворот: слева крупный светлый заголовок, справа два абзаца
   разного кегля. Правый край колонки текста лежит на линии гаттера. */
.about-seo {
  display: grid;
  grid-template-columns: calc(1065 * var(--px)) calc(735 * var(--px));
  padding: calc(120 * var(--px)) var(--gutter);
  background: var(--black);
  color: var(--paper);
}

.about-seo__title {
  width: calc(750 * var(--px));
  margin: 0;
  font-size: calc(100 * var(--px));
  font-weight: 300;
  line-height: 1.48;
}

.about-seo__text {
  display: flex;
  flex-direction: column;
  gap: calc(30 * var(--px));
}

.about-seo__lead,
.about-seo__small {
  margin: 0;
  line-height: 1.5;
}

.about-seo__lead {
  font-size: calc(22 * var(--px));
  font-weight: 400;
}

.about-seo__small {
  font-size: calc(18 * var(--px));
  font-weight: 300;
}

/* ---------- Планшет и телефон ---------- */

@media (max-width: 1199px) {
  /* Телефон: композиция первого экрана разбирается в столбик. Порядок в
     мобильном макете свой — слово, абзац, слово, портрет и так далее, —
     поэтому элементы переставлены свойством order, а не разметкой. */
  .about-hero {
    display: flex;
    flex-direction: column;
    gap: 20px;
    height: auto;
    padding: 0 var(--gutter) 60px;
  }

  .about-hero__portrait,
  .about-hero__word,
  .about-hero__name,
  .about-hero__video,
  .about-hero__note {
    position: static;
    width: auto;
  }

  .about-hero__word--decorator {
    order: 1;
  }

  .about-hero__note--left {
    order: 2;
  }

  .about-hero__word--architect {
    order: 3;
  }

  .about-hero__portrait {
    order: 4;
    height: auto;
    aspect-ratio: 290 / 385;
  }

  .about-hero__name {
    order: 5;
  }

  .about-hero__video {
    order: 6;
  }

  .about-hero__word--designer {
    order: 7;
  }

  .about-hero__note--right {
    order: 8;
  }

  .about-hero__word,
  .about-hero__name {
    font-size: 40px;
    text-align: left;
  }

  /* Два слова из четырёх в макете прижаты к правому краю колонки. */
  .about-hero__word--architect,
  .about-hero__word--designer {
    text-align: right;
  }

  .about-hero__note {
    font-size: 16px;
  }

  .about-hero__video {
    gap: 12px;
  }

  .about-hero__play {
    width: 46px;
    height: 46px;
  }

  .about-hero__play-icon {
    width: 15px;
    height: 17px;
  }

  .about-hero__video-label {
    font-size: 22px;
  }

  /* Преимущества: заголовок над списком, строки становятся карточками. */
  .about-why {
    padding: 30px var(--gutter);
  }

  .about-why__label {
    font-size: 30px;
  }

  .about-why__title {
    position: static;
    width: auto;
    margin-top: 60px;
    font-size: 50px;
  }

  .about-why__list {
    margin-top: 60px;
  }

  .why-row {
    display: block;
    padding: 0;
    border: 0;
  }

  .why-row:last-child {
    padding-bottom: 0;
    border: 0;
  }

  .why-row__icon {
    width: 36px;
    height: 36px;
  }

  .why-row__icon svg {
    width: 36px;
    height: 36px;
  }

  .why-row__name {
    margin-top: 20px;
    font-size: 22px;
  }

  .why-row__text {
    margin-top: 20px;
    font-size: 22px;
  }

  .about-seo {
    display: block;
    padding: 50px var(--gutter);
  }

  .about-seo__title {
    width: auto;
    font-size: 43px;
    font-weight: 300;
  }

  .about-seo__text {
    margin-top: 30px;
  }

  .about-seo__lead,
  .about-seo__small {
    font-size: 16px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  /* Планшет: набор крупнее, иконка и название строки снова в одну линию. */
  .about-hero {
    gap: 30px;
    padding-bottom: 80px;
  }

  .about-hero__word,
  .about-hero__name {
    font-size: 64px;
  }

  .about-hero__note {
    font-size: 18px;
  }

  .about-hero__play {
    width: 60px;
    height: 60px;
  }

  .about-hero__play-icon {
    width: 20px;
    height: 23px;
  }

  .about-hero__video-label {
    font-size: 26px;
  }

  .about-why {
    padding: 80px var(--gutter);
  }

  .about-why__label {
    font-size: 40px;
  }

  .about-why__title {
    font-size: 64px;
  }

  .why-row {
    display: grid;
    grid-template-columns: 60px minmax(0, 1fr) minmax(0, 1.4fr);
    align-items: center;
    gap: 30px;
    padding: 29px 0 0;
    border-top: 1px solid #00000080;
  }

  .why-row:last-child {
    padding-bottom: 29px;
    border-bottom: 1px solid #00000080;
  }

  .why-row__name,
  .why-row__text {
    margin-top: 0;
    font-size: 18px;
  }

  .about-seo {
    padding: 80px var(--gutter);
  }

  .about-seo__title {
    font-size: 64px;
  }

  .about-seo__lead,
  .about-seo__small {
    font-size: 18px;
  }
}

/* ======================================================================
   Оглавление (index.html)

   Служебная страница: показывает клиенту, какие страницы уже свёрстаны.
   Не часть дизайна сайта, поэтому набирается по-своему — светлая сетка
   плиток на белом. Размеры здесь в обычных пикселях: страница не
   повторяет макет, ей незачем тянуться вместе с ним.

   Все селекторы ниже начинаются с .dir — блок изолирован от home.html и
   project.html. Единственный общий класс, .arrow-ne, переопределяется
   только внутри .dir, базовое правило выше не трогаем.
   ====================================================================== */

.dir {
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
}

.dir__inner {
  max-width: 1040px;
  margin: 0 auto;
  padding: 72px 32px 120px;
}

.dir__head {
  display: flex;
  align-items: center;
  gap: 16px;
}

.dir__logo {
  width: 118px;
  height: 30px;
  flex: none;
}

.dir__caption {
  margin: 0;
  padding-left: 16px;
  border-left: 1px solid currentColor;
  font-size: 15px;
  font-weight: 200;
  line-height: 1.3;
}

.dir__title {
  margin: 56px 0 0;
  font-size: 88px;
  font-weight: 600;
  line-height: 1.1;
  text-transform: uppercase;
}

.dir__lead {
  max-width: 46ch;
  margin: 20px 0 0;
  color: #6b6b6b;
  font-size: 18px;
  font-weight: 300;
  line-height: 1.55;
}

.dir__section {
  margin-top: 64px;
}

/* Заголовок группы — строка на линии: название слева, счётчик рядом. */
.dir__group {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 24px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(23, 23, 23, 0.14);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.dir__count {
  color: #a0a0a0;
  font-weight: 300;
  letter-spacing: 0;
}

.dir__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Ячейке нужен min-width: иначе длинное слово в подписи распирает колонку. */
.dir__cell {
  min-width: 0;
}

.dir__card {
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
}

/* Плитка: квадрат с крупным номером. Стрелка в углу — признак того,
   что страница открывается. */
.dir__tile {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border: 1px solid rgba(23, 23, 23, 0.14);
  background: #f6f6f6;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease,
    transform 0.2s ease;
}

.dir__num {
  font-size: 56px;
  font-weight: 200;
  line-height: 1;
  letter-spacing: 0.02em;
}

.dir .arrow-ne {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 18px;
  height: 18px;
  opacity: 0.3;
  transition: opacity 0.2s ease;
}

.dir__name {
  margin-top: 14px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1.25;
  text-transform: uppercase;
}

.dir__note {
  margin-top: 6px;
  color: #8a8a8a;
  font-size: 13px;
  font-weight: 300;
  line-height: 1.45;
}

/* Наведение только там, где есть курсор: на тачскрине состояние залипает
   после тапа и плитка остаётся чёрной. */
@media (hover: hover) {
  a.dir__card:hover .dir__tile {
    transform: translateY(-4px);
    border-color: var(--ink);
    background: var(--ink);
    color: var(--paper);
  }

  a.dir__card:hover .arrow-ne {
    opacity: 1;
  }
}

/* Обводку по фокусу вешаем на плитку, а не на карточку целиком:
   иначе рамка обхватывает и подпись под ней. */
a.dir__card:focus-visible {
  outline: none;
}

a.dir__card:focus-visible .dir__tile {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

a.dir__card:focus-visible .arrow-ne {
  opacity: 1;
}

/* Несвёрстанные страницы не кликаются: пунктир вместо рамки, приглушённый тон. */
.dir__card--soon {
  cursor: default;
}

.dir__card--soon .dir__tile {
  border-style: dashed;
  background: transparent;
  color: #c4c4c4;
}

.dir__card--soon .dir__name {
  color: #a0a0a0;
}

.dir__card--soon .dir__note {
  color: #b4b4b4;
}

/* Планшет: колонок три, поля уже. */
@media (max-width: 1000px) {
  .dir__inner {
    max-width: none;
    padding: 64px 30px 96px;
  }

  .dir__title {
    font-size: 72px;
  }

  .dir__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Телефон: две колонки, кегли задаём явно — иначе приедут десктопные. */
@media (max-width: 640px) {
  .dir__inner {
    padding: 44px 20px 72px;
  }

  .dir__head {
    gap: 12px;
  }

  .dir__logo {
    width: 100px;
    height: 26px;
  }

  .dir__caption {
    padding-left: 12px;
    font-size: 13px;
  }

  .dir__title {
    margin-top: 36px;
    font-size: 46px;
  }

  .dir__lead {
    font-size: 16px;
  }

  .dir__section {
    margin-top: 44px;
  }

  .dir__group {
    margin-bottom: 20px;
    font-size: 13px;
  }

  .dir__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 24px 16px;
  }

  .dir__num {
    font-size: 40px;
  }

  .dir .arrow-ne {
    top: 10px;
    right: 10px;
    width: 15px;
    height: 15px;
  }

  .dir__name {
    margin-top: 12px;
    font-size: 16px;
  }

  .dir__note {
    margin-top: 4px;
    font-size: 12px;
  }
}

/* ======================================================================
   Поменьше движения

   Все ответы на prefers-reduced-motion собраны здесь, а не разбросаны
   по секциям: так видно разом, что именно замирает. Блок стоит последним
   и потому выигрывает у одинаково весомых правил по порядку следования.

   Режим не означает «ничего не двигается вообще»: цвет, прозрачность
   и смена состояний остаются — уходят перемещения, наезды и раскрытия.
   ====================================================================== */

@media (prefers-reduced-motion: reduce) {
  /* Раскрытия при прокрутке здесь нет вовсе: скрипт выходит из initReveal
     до того, как хоть что-то спрячет. Правило ниже — страховка на случай,
     когда режим включили при уже открытой странице: спрятанное показываем
     как есть, без перехода. */
  .reveal[data-reveal] {
    transition: none;
  }

  .reveal[data-reveal="pending"] {
    clip-path: none;
    opacity: 1;
    transform: none;
  }

  /* Кольцо «page scroll» останавливается. */
  .fullservice__scroll-ring {
    animation: none;
  }

  /* Подчёркивания в меню гасятся не в none, а в 0.01ms: событие
     transitionend должно дойти. */
  .nav__link::after,
  .nav__phone-label::after,
  .lang__option::after {
    transition-duration: 0.01ms;
  }

  /* Состояния меняются мгновенно. */
  .about__more,
  .article__share,
  .blog__more,
  .breadcrumbs__link,
  .breadcrumbs__sep,
  .burger__bar,
  .card__overlay,
  .consent__check path,
  .contacts__mail,
  .contacts__note,
  .dir .arrow-ne,
  .dir__tile,
  .dot,
  .field__input,
  .footer__legal,
  .form__submit,
  .hero__next,
  .lang__menu,
  .nav,
  .news__media img,
  .news__more,
  .reel__cta,
  .portfolio__more,
  .post__media img,
  .post__more,
  .project-info__more,
  .ring-arrow__arrow,
  .ring-arrow__fill,
  .ring-arrow__ring,
  .slide__button,
  .social,
  .works__cta,
  .works__item,
  .works__nav {
    transition: none;
  }

  /* А здесь уходит и само перемещение: мгновенный скачок на 4 пикселя
     ничем не лучше плавного. */
  .hero__next:hover,
  .social:hover,
  .news__card:hover .news__media img,
  .post__media:hover img,
  .form__submit:active,
  .article__share:active {
    transform: none;
  }

  a.dir__card:hover .dir__tile {
    transform: none;
  }

  /* Кадры проектов в Works меняются сразу и без наезда: скрипт в этом
     режиме и сам список листает без подъезда. */
  .works__shot {
    transform: none;
    transition: none;
  }
}
