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

/* Боковые колонки равны, поэтому заголовок стоит ровно по центру
   экрана, а не по центру остатка. */
.projects {
  position: relative; /* отсчёт для куба в углу */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  padding: clamp(3rem, 8vw, 7rem) var(--gutter) clamp(4rem, 9vw, 8rem);
}

/* Три платформы одна над другой в правом нижнем углу — из того же
   материала, что волна на первом экране и рисунки на втором
   и четвёртом: моноширинные нули и единицы, приглушённый серый.
   Шрифт только моноширинный: цифры и пробелы обязаны быть одной ширины,
   иначе изометрия разъезжается.
   Стоит на месте пустой ячейки последнего ряда карточек: их нечётное
   число, и справа внизу остаётся свободная колонка. Кегль привязан
   к ширине экрана, сетка 52 знакоместа по 0.6 кегля. */
.projects__chart {
  position: absolute;
  /* Почти по центру той самой пустой ячейки: правая колонка ряда
     начинается на половине ширины ряда, её середина — ещё четверть,
     и от этой точки рисунок сдвинут вправо на колонку отступа.
     transform сдвигает бокс на половину его ширины, поэтому в расчёт
     идёт именно центр рисунка. */
  right: calc((100% - 2 * var(--gutter) - var(--project-gap)) / 4);
  bottom: var(--gutter);
  transform: translateX(50%);
  z-index: 0;
  margin: 0;
  font-family: var(--font-mono);
  font-size: min(0.58vw, 8.4px);
  line-height: 1;
  color: var(--color-text-muted);
  white-space: pre;
  user-select: none;
}

/* Подпись слева. Та же, что «(Продукт)» и «(Ценность)» на прошлых
   экранах. Отступ сверху ставит её на линию прописных заголовка:
   при интерлиньяже 1 верх прописных Manrope отстоит от верха строки
   на 0.165 кегля — (1 - 1.37) / 2 + (1.07 - 0.72). */
.projects__label {
  margin: 0;
  padding-top: calc(var(--projects-size) * 0.165);
  color: var(--color-text-muted);
  font-size: var(--subtitle-size);
  font-weight: 500;
  letter-spacing: 0.01em;
}

.projects__title {
  margin: 0;
  font-size: var(--projects-size);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  white-space: nowrap;
}

/* Текст справа. Прижат к правому краю и посажен так, чтобы его нижняя
   строка стояла на базовой линии заголовка: базовая линия отстоит
   от низа строки на 0.115 кегля. */
.projects__note {
  justify-self: end;
  align-self: end;
  width: var(--projects-note);
  margin: 0;
  padding-bottom: calc(var(--projects-size) * 0.115);
  color: var(--color-text-muted);
  font-size: var(--subtitle-size);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0.01em;
}

/* Ряд карточек стоит под шапкой раздела и занимает все три её колонки. */
.projects__list {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--project-row-gap) var(--project-gap);
  margin: clamp(2rem, 6vw, 5rem) 0 0;
  padding: 0;
  list-style: none;
}

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

   Но число карточек меняется, и на чётном свободной ячейки справа внизу
   нет — рисунок из нулей и единиц лёг бы поверх карточки. Поэтому,
   если последняя карточка стоит второй в ряду, рисунок убирается. */
.projects__list:has(.project:last-child:nth-child(even)) ~ .projects__chart {
  display: none;
}

/* Карточка кейса, у которого есть своя страница, кликабельна целиком.
   Ссылка одна — на заголовке, а её растяжка накрывает и фигуру
   со снимком: так у карточки один таб-стоп и осмысленный текст
   для читалки, а кликается она вся.
   Карточки без своей страницы остаются обычными — у них просто нет
   ссылки внутри. */
.project {
  position: relative;
}

.project__link {
  color: inherit;
  text-decoration: none;
}

.project__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.project__link:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 4px;
}

/* Отклик на наведение: обводка фигуры светлеет — тот же приём, что
   у папок с проектами на главной, только без заливки. */
.project:has(.project__link:hover) .project__outline,
.project:has(.project__link:focus-visible) .project__outline {
  stroke: var(--color-text);
}

.project__outline {
  transition: stroke 0.3s var(--ease);
}

/* Фигура проекта. Приём тот же, что у папок на главной
   (ARCHITECTURE.md, 3.3): линию со срезанным углом обычной рамкой
   не нарисовать, поэтому контур — отдельный SVG-слой.
   Пропорция бокса задана жёстко и совпадает с viewBox — иначе срез
   поедет при растяжении. Паддинг в процентах ширины отодвигает фото
   от обводки на одинаковый зазор со всех сторон. */
.project__frame {
  position: relative;
  aspect-ratio: 100 / 80;
  padding: var(--project-inset);
}

/* Контур. Холст 100x80, срез идёт от точки 74 на верхней кромке
   до точки 26 на правой — при равной пропорции холста и бокса это
   ровно 45°. Углы скруглены радиусом 4; точки касания дуг отодвинуты
   от вершины на r у прямых углов и на r*tg(22.5°) = 1.657 у тупых
   углов среза. non-scaling-stroke держит линию в 1px при любом
   размере карточки, overflow: visible не даёт срезать её по краям. */
.project__outline {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke: rgba(244, 244, 244, 0.35);
  stroke-width: 1;
}

/* Фото повторяет форму контура, уменьшенную на зазор со всех сторон.
   Маска нарисована на холсте 94x74 — это внутренний бокс фигуры при
   зазоре в 3% ширины. Срез смещён внутрь по перпендикуляру на тот же
   зазор, поэтому диагональ фото идёт параллельно диагонали контура,
   а радиусы уменьшены на величину зазора: 4 - 3 = 1. */
.project__photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mask-image: var(--project-photo-mask);
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
}

/* Зерно поверх фото — то же, что на фоне страницы, только слабее.
   Слой повторяет бокс фотографии, а не рамку: по горизонтали это тот же
   зазор 3%, а по вертикали — 3% / 0.8, потому что проценты в inset сверху
   и снизу считаются от высоты, а высота карточки равна 0.8 её ширины.
   Совпадение с боксом фото обязательно: маска растянута на 100% слоя,
   и при другом боксе срезанный угол разъехался бы с углом фотографии.
   Плитка не fixed, в отличие от фона страницы: зерно на снимке должно
   ехать вместе со снимком, иначе на скролле оно по нему «плывёт». */
.project__frame::after {
  content: "";
  position: absolute;
  inset: calc(var(--project-inset) / 0.8) var(--project-inset);
  background-image: url("/assets/img/grain.png");
  background-size: 93.5px;
  background-repeat: repeat;
  opacity: var(--project-grain-opacity);
  mask-image: var(--project-photo-mask);
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
  pointer-events: none;
}

/* Заливка вместо снимка — у карточки-приписки в конце списка своей
   обложки нет. Форму берёт от фигуры: та же маска со срезанным углом,
   тот же зазор, сверху ложится то же зерно. Тон — общая тёмная
   поверхность сайта, та же, что у карточек-правил ниже. */
.project__blank {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: var(--color-surface);
  mask-image: var(--project-photo-mask);
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
}

/* Слово на заливке — вместо снимка. Набрано крупно, но приглушённым
   тоном: это метка, а не заголовок, и кричать ей незачем. */
.project__blank-mark {
  color: var(--color-text-muted);
  font-size: var(--project-blank-size);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
}

/* Подпись под фигурой. Левый край — вровень с контуром, а не
   с фотографией: название равняется по самой фигуре. */
.project__body {
  margin-top: clamp(1rem, 1.8vw, 1.75rem);
}

.project__title {
  margin: 0;
  font-size: var(--project-title-size);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: var(--statement-tracking);
}

/* Подпись карточки-приписки. Кегль и вес те же, что у названий кейсов —
   ряд держит один ритм, — но тон приглушён: это не проект, а пояснение
   к списку. */
.project__note {
  margin: 0;
  color: var(--color-text-soft);
  font-size: var(--project-title-size);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: var(--statement-tracking);
}

/* Порог тот же, что у остальных украшений: ниже 1024 карточки идут
   в одну колонку, свободной ячейки справа внизу больше нет —
   платформа встала бы поверх карточки. */
@media (max-width: 1023px) {
  .projects__chart {
    display: none;
  }
}

@media (max-width: 767px) {
  /* На телефоне три колонки не расходятся: подпись, заголовок и текст
     встают друг под другом, оптические довороты по базовым линиям
     теряют смысл. */
  .projects {
    grid-template-columns: 1fr;
    gap: clamp(1rem, 5vw, 2rem);
  }

  .projects__label {
    padding-top: 0;
  }

  /* Кегль крупнее десктопных 10vw: на телефоне заголовок стоит
     не в средней колонке, а во всю ширину, и места ему хватает. */
  .projects__title {
    font-size: 14vw;
  }

  .projects__note {
    justify-self: start;
    width: auto;
    max-width: 32ch;
    padding-bottom: 0;
  }

  /* Две карточки в ряд на телефоне — это две открытки шириной в палец:
     ни фото, ни описание не читаются. Ряд разворачивается в столбик. */
  .projects__list {
    grid-template-columns: 1fr;
  }

  /* Кегль завязан на ширину экрана, а карточка на телефоне занимает
     его целиком — берём размер покрупнее. */
  .project__title {
    font-size: clamp(1.35rem, 6vw, 1.75rem);
  }
}
