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

.intro {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100svh;

  /* Кнопка вынута из потока и прижата к низу блока, но её место
     в вертикальном ритме сохраняется: нижний отступ вырос ровно
     на высоту кнопки и её прежний зазор. Без этого заголовок с именем
     съехали бы вниз на половину освободившегося места.
     Высота кнопки: тумблер 1.2em + паддинги 2 x 0.73em + обводка. */
  --cta-gap: clamp(2rem, 4.5vw, 4rem);
  --cta-reserve: calc(var(--subtitle-size) * 2.66 + 2px + var(--cta-gap));

  /* Верхний отступ больше нижнего: шапка лежит поверх экрана и высоты
     не занимает, поэтому место под неё резервируем здесь. Разница
     небольшая — иначе блок заметно съезжает вниз от центра экрана. */
  padding: calc(var(--gutter) * 2.5) var(--gutter) calc(var(--gutter) * 2 + var(--cta-reserve));
  text-align: center;
  /* Волна шире и выше экрана — лишнее срезаем по границам блока. */
  overflow: hidden;
}

/* Волна из нулей и единиц во всю ширину блока.
   Сетка 150x54 знакоместа. Ширина знакоместа у моноширинного шрифта —
   примерно 0.6 кегля, значит 150 колонок это 90em: отсюда кегль
   в сотых долях ширины экрана. Шрифт системный моноширинный: своего
   моноширинного в проекте нет, а тянуть второй файл ради графики
   не хочу — цифры и пробелы обязаны быть одной ширины, иначе
   столбцы разъезжаются.
   Блок центрируется по обеим осям: на экранах другой пропорции лишнее
   уходит под срез сверху и снизу, а не сдвигает волну вбок. */
.intro__wave {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 0;
  transform: translate(-50%, -50%);
  margin: 0;
  font-family: ui-monospace, "SF Mono", "Menlo", "Consolas", monospace;
  /* 90 = 150 колонок по 0.6 кегля, 54 = число строк. Берём меньшее:
     на вытянутом по высоте экране волна иначе вылезла бы за верх и низ
     и наехала бы на кнопку, которая прижата к нижнему краю. */
  font-size: min(calc(100vw / 90), calc(100svh / 54));
  line-height: 1;
  color: var(--color-text-muted);
  white-space: pre;
  /* Блок наследует центрирование от секции, а оно центрует каждую
     строку по отдельности и разваливает рисунок. Строки только слева. */
  text-align: left;
  user-select: none;
}

/* Ядро полосы: тот же тон, что у светлой части заголовка. Края остаются
   серыми — от этого полоса читается объёмной, а не плоской заливкой. */
.intro__wave-core {
  color: var(--color-text);
}

/* Круглое фото и подпись имени в одну строку под заголовком:
   фото слева, имя справа. */
.intro__person {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.9em;
  margin-top: clamp(1.5rem, 3vw, 2.75rem);
  font-size: var(--subtitle-size);
  font-weight: 500;
  letter-spacing: 0.01em;
}

.intro__photo {
  flex: none;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: 50%;
  object-fit: cover;
}

/* Заголовок — главный визуальный элемент экрана.
   Ширина ограничена в ch, чтобы строки ломались как в референсе:
   плотный центрированный блок в три-четыре строки. Предел в ch
   привязан к кеглю, поэтому строки ломаются одинаково при любом
   размере экрана. */
.intro__title {
  position: relative;
  z-index: 1;
  max-width: 19ch;
  font-size: var(--title-size);
  font-weight: 700;
  line-height: var(--title-leading);
  letter-spacing: var(--title-tracking);
  text-wrap: balance;
}

/* Вторая половина фразы: тот же кегль, приглушённый тон.
   На тёмном фоне контраст строится наоборот, чем в референсе —
   там серые буквы темнее чёрных, здесь темнее белых. */
.intro__title-muted {
  color: var(--color-text-muted);
}

/* Табы с ключевыми словами: две россыпи по диагонали от заголовка —
   сверху слева и снизу справа. Раскладка ручная, координаты в процентах
   от блока, поэтому россыпь держит рисунок на любой ширине.
   Список не ловит клики целиком — иначе прозрачный слой поверх экрана
   перехватывал бы наведение на кнопку; ловят только сами табы. */
.intro__tags {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: 0;
  padding: 0;
  list-style: none;
  pointer-events: none;
}

.intro__tag {
  position: absolute;
  left: var(--x);
  top: var(--y);
  padding: 0.5em 0.9em;
  border: 1px solid rgba(244, 244, 244, 0.35);
  /* У папок на главной радиус задан в процентах, но бокс там втрое
     крупнее, поэтому те же 3% дают заметно более круглый угол.
     Здесь процент считался бы от сторон таба: по горизонтали 2.5px,
     по вертикали меньше миллиметра — угол выходил вытянутым и почти
     прямым. Поэтому радиус в em: он круглый по обеим осям и растёт
     вместе с кеглем. 0.28em дают ту же относительную скруглённость,
     что у папок на главной. */
  border-radius: 0.28em;
  background-color: transparent;
  color: var(--color-text);
  font-size: var(--tag-size);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.01em;
  white-space: nowrap;
  pointer-events: auto;
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease);
}

.intro__tag:hover {
  background-color: var(--color-text);
  border-color: var(--color-text);
  color: var(--color-bg);
}

/* Координаты россыпи. Сверху слева — колонка левее заголовка, ступенями
   вниз-вправо. Снизу справа — три сбитых ряда правее кнопки контакта.
   Обе зоны выбраны там, где не проходит волна. */
.intro__tags--start .intro__tag:nth-child(1) { --x: 14%;   --y: 13%; }
.intro__tags--start .intro__tag:nth-child(2) { --x: 30.3%; --y: 11.8%; }
.intro__tags--start .intro__tag:nth-child(3) { --x: 5%;    --y: 17.5%; }
.intro__tags--start .intro__tag:nth-child(4) { --x: 21.5%; --y: 19.3%; }
.intro__tags--start .intro__tag:nth-child(5) { --x: 13%;   --y: 26%; }
.intro__tags--start .intro__tag:nth-child(6) { --x: 4.8%;  --y: 33%; }

.intro__tags--end .intro__tag:nth-child(1)  { --x: 68%;   --y: 77.2%; }
.intro__tags--end .intro__tag:nth-child(2)  { --x: 77%;   --y: 76.6%; }
.intro__tags--end .intro__tag:nth-child(3)  { --x: 85.3%; --y: 78%; }
.intro__tags--end .intro__tag:nth-child(4)  { --x: 71.5%; --y: 84%; }
.intro__tags--end .intro__tag:nth-child(5)  { --x: 78%;   --y: 83.2%; }
.intro__tags--end .intro__tag:nth-child(6)  { --x: 86.3%; --y: 84.5%; }
.intro__tags--end .intro__tag:nth-child(7)  { --x: 91.8%; --y: 81%; }
.intro__tags--end .intro__tag:nth-child(8)  { --x: 70%;   --y: 90%; }
.intro__tags--end .intro__tag:nth-child(9)  { --x: 77%;   --y: 89.5%; }
.intro__tags--end .intro__tag:nth-child(10) { --x: 84%;   --y: 90.5%; }
.intro__tags--end .intro__tag:nth-child(11) { --x: 92%;   --y: 89.5%; }

/* Кнопка контакта — та же, что на главной: внешний вид берётся
   из компонента .talk, здесь только место на экране. Прижата к низу
   блока по той же линии, что и нижний отступ секции. Место под неё
   зарезервировано паддингом — см. --cta-reserve выше. */
.intro__cta {
  position: absolute;
  left: 50%;
  bottom: calc(var(--gutter) * 2);
  z-index: 1;
  transform: translateX(-50%);
}

@media (max-width: 767px) {
  /* На узком экране заголовок и так занимает всю ширину — предел в ch
     только мешал бы, ломая строки раньше времени. */
  .intro__title {
    max-width: none;
  }

  /* Волна рассчитана под горизонтальный экран: её пропорция 150:54,
     на мобильном она сжалась бы до нечитаемой полоски в 4px кеглем
     и полезла бы на текст. Мобильный вариант делаем отдельно.
     Россыпь табов туда же: её координаты разложены по широкому экрану,
     на узком табы сели бы друг на друга и на заголовок. */
  .intro__wave,
  .intro__tags {
    display: none;
  }
}

/* Волна проходит в коридоре между именем и кнопкой. Коридор сужается
   тем сильнее, чем ниже экран: у сетки волны пропорция постоянная,
   а блок с текстом сжимается быстрее. Замеры знак за знаком показали,
   что при отношении сторон шире 2.05 : 1 зазоры уходят в ноль и волна
   начинает задевать текст — там её убираем. */
@media (min-aspect-ratio: 41 / 20) {
  .intro__wave {
    display: none;
  }
}
