/* ==========================================================================
   Компоненты проекта — атомы/молекулы/организмы, извлечённые из Figma
   «Сайт» (node 6:118). Неймспейс `gk__` (Gesamtkunstwerk), чтобы не
   конфликтовать с классами `ids__`, скопированными из IDS в base.css/
   tokens.css. Те же структурные соглашения, что у IDS: голые классы-
   модификаторы поверх базового класса (`.small`, `.est`), значения —
   только через токены (tokens.css) или мост IDS (theme.css), никаких
   сырых hex/px здесь. Четыре брейкпоинта — по ширинам Figma-фреймов:
   mobile (< --breakpoint-tablet, 375px), tablet (--breakpoint-tablet,
   1024px), regular (--breakpoint-regular, 1440px), desktop
   (--breakpoint-desktop, 1920px). Текст, отступы (content/logo/footer) и
   иллюстрация guy между соседними брейкпоинтами не прыгают, а плавно
   интерполируются через --fluid-ratio-mobile-tablet/-tablet-regular/
   -regular-desktop (calc() + vw, приём из IDS — см. html font-size в
   base.css — но с непрерывными участками без разрывов между ними, см.
   комментарий у --fluid-ratio-* ниже). Вне 375–1920 — плоские значения
   крайних фреймов, дальше не масштабируются.
   ========================================================================== */

/* --- fluid-ratio-* — линейная интерполяция между соседними Figma-фреймами,
   0 в начале диапазона и 1 в конце. Тот же приём, что в IDS для html
   font-size (см. base.css: calc() с vw вместо резкого прыжка на
   брейкпоинте) — но три непрерывных участка стыкуются друг с другом без
   разрыва (в отличие от IDS: там формулы мобильного и десктопного
   диапазонов не стыкуются в точке 768, font-size прыгает с ~32px на
   ~11.5px ровно на брейкпоинте — то самое поведение, которого мы здесь
   избегаем). Общие переменные — чтобы не повторять формулу интерполяции в
   каждом месте, где меняется размер/отступ/положение (тип, .gk__logo,
   .gk__content, .gk__footer, .gk__illustration-guy): у всех один и тот же
   переходный диапазон на каждом участке. Вне 375–1920 используются плоские
   значения крайних фреймов (см. правила ниже) — за пределами реального
   дизайна дальше не масштабируется. */
@media (min-width: 375px) and (max-width: 1023.98px) {
  :root {
    --fluid-ratio-mobile-tablet: calc(
      (100vw - var(--layout-device-width-mobile)) /
        (var(--layout-device-width-tablet) - var(--layout-device-width-mobile))
    );
  }
}
@media (min-width: 1024px) and (max-width: 1439.98px) {
  :root {
    --fluid-ratio-tablet-regular: calc(
      (100vw - var(--layout-device-width-tablet)) /
        (var(--layout-device-width-regular) - var(--layout-device-width-tablet))
    );
  }
}
@media (min-width: 1440px) and (max-width: 1919.98px) {
  :root {
    --fluid-ratio-regular-desktop: calc(
      (100vw - var(--layout-device-width-regular)) /
        (var(--layout-device-width-desktop) - var(--layout-device-width-regular))
    );
  }
}

/* --- type/heading — единственная подтверждённая роль заголовка в исходном
   фрейме (Times New Roman, uppercase). Применять явно, не переопределяет
   h1–h6 IDS по умолчанию — для остальных уровней заголовков дизайн ещё не
   описан, они остаются на типографике IDS до дизайна. --------------------- */
.gk__text-heading {
  font-family: var(--font-heading-family);
  font-weight: var(--font-heading-weight);
  text-transform: uppercase;
  color: var(--color-text-default);
  font-size: var(--font-heading-size-extra-extra-small);
  line-height: var(--line-height-heading-extra-extra-small);
}
/* Плавный переход small → base между tablet (1024) и regular (1440) — в
   Figma фрейм tablet всё ещё мобильного (small) размера, а regular уже
   базового; между ними отдельного дизайна нет, поэтому размер
   интерполируется, а не прыгает. */
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__text-heading {
    font-size: calc(
      var(--font-heading-size-extra-extra-small) +
        (var(--font-heading-size-extra-small) - var(--font-heading-size-extra-extra-small)) *
        var(--fluid-ratio-tablet-regular)
    );
    line-height: calc(
      var(--line-height-heading-extra-extra-small) +
        (var(--line-height-heading-extra-small) - var(--line-height-heading-extra-extra-small)) *
        var(--fluid-ratio-tablet-regular)
    );
  }
}
@media (min-width: 1440px) {
  .gk__text-heading {
    font-size: var(--font-heading-size-extra-small);
    line-height: var(--line-height-heading-extra-small);
  }
}

/* --- type/body — переиспользуемая роль тела текста (Body/Size Base·Small) */
.gk__text-body {
  font-family: var(--font-body-family);
  font-weight: var(--font-body-weight);
  color: var(--color-text-default);
  font-size: var(--font-body-size-small);
  line-height: var(--line-height-body-small);
}
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__text-body {
    font-size: calc(
      var(--font-body-size-small) +
        (var(--font-body-size-base) - var(--font-body-size-small)) * var(--fluid-ratio-tablet-regular)
    );
    line-height: calc(
      var(--line-height-body-small) +
        (var(--line-height-body-base) - var(--line-height-body-small)) * var(--fluid-ratio-tablet-regular)
    );
  }
}
@media (min-width: 1440px) {
  .gk__text-body {
    font-size: var(--font-body-size-base);
    line-height: var(--line-height-body-base);
  }
}

/* --- atom/link — состояния default/hover/press (ds_molecules → links).
   Цвет — из IDS-моста (theme.css), тайминг — переиспользуем IDS-токены
   длительности/easing вместо своих, они не завязаны на конкретный бренд. */
.gk__link {
  text-decoration: underline;
  text-decoration-thickness: var(--link-underline-offset);
  color: var(--ids__link);
  transition: color var(--ids__duration-base) var(--ids__easing-base);
}
.gk__link:hover {
  color: var(--ids__hover);
  cursor: pointer;
  transition: color var(--ids__duration-instant) var(--ids__easing-base);
}
.gk__link:active {
  color: var(--ids__press);
}
/* Размер — самостоятельное использование вне контекста, который уже задаёт
   размер текста (например .gk__footer). По умолчанию наследует font-size. */
.gk__link.medium {
  font-size: var(--font-body-size-base);
  line-height: var(--line-height-body-base);
}
.gk__link.small {
  font-size: var(--font-body-size-small);
  line-height: var(--line-height-body-small);
}

/* --- atom/logo — brand elements → logo (small = мобильный, medium = десктоп) */
.gk__logo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: var(--space-200);
}
/* mobile/tablet (--space-200) совпадают — плавный участок здесь не нужен,
   переход начинается только с tablet→regular. */
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__logo {
    padding: calc(
      var(--space-200) + (var(--space-300) - var(--space-200)) * var(--fluid-ratio-tablet-regular)
    );
  }
}
@media (min-width: 1440px) and (max-width: 1919.98px) {
  .gk__logo {
    padding: calc(
      var(--space-300) + (var(--space-400) - var(--space-300)) * var(--fluid-ratio-regular-desktop)
    );
  }
}
@media (min-width: 1920px) {
  .gk__logo {
    padding: var(--space-400);
  }
}
.gk__logo__image {
  display: block;
  width: 100%;
  height: auto;
}

/* --- atom/illustration-guy — brand elements → guy (small = мобильный,
   medium = десктоп). Единый ассет, масштабируется по контейнеру — в Figma
   мобильная/десктопная версии это один и тот же силуэт в двух размерах. */
.gk__illustration-guy {
  display: block;
  width: 100%;
  height: auto;
}

/* --- organism/content — ds → «Coming Soon» → content: текст заголовка +
   illustration-guy, вылезающий за край фрейма (силуэт обрезается вьюпортом
   намеренно, по абсолютному позиционированию в исходном фрейме).
   flex: 1 растягивает блок между лого и футером (body — full-height
   flex-column, см. base.css), воспроизводя замысел фиксированной высоты
   Figma-фрейма без жёсткого задания высоты вьюпорта. */
.gk__content {
  position: relative;
  flex: 1 0 auto;
  padding: var(--space-600) var(--space-200) var(--space-6700);
}
@media (min-width: 375px) and (max-width: 1023.98px) {
  .gk__content {
    padding: calc(
        var(--space-600) + (var(--space-2400) - var(--space-600)) * var(--fluid-ratio-mobile-tablet)
      )
      var(--space-200)
      calc(var(--space-6700) + (var(--space-1200) - var(--space-6700)) * var(--fluid-ratio-mobile-tablet));
  }
}
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__content {
    padding: calc(
        var(--space-2400) + (var(--space-4000) - var(--space-2400)) * var(--fluid-ratio-tablet-regular)
      )
      calc(var(--space-200) + (var(--space-300) - var(--space-200)) * var(--fluid-ratio-tablet-regular))
      calc(var(--space-1200) + (var(--space-1600) - var(--space-1200)) * var(--fluid-ratio-tablet-regular));
  }
}
@media (min-width: 1440px) and (max-width: 1919.98px) {
  .gk__content {
    padding: var(--space-4000)
      calc(var(--space-300) + (var(--space-400) - var(--space-300)) * var(--fluid-ratio-regular-desktop))
      calc(var(--space-1600) + (var(--space-2400) - var(--space-1600)) * var(--fluid-ratio-regular-desktop));
  }
}
@media (min-width: 1920px) {
  .gk__content {
    padding: var(--space-4000) var(--space-400) var(--space-2400);
  }
}

.gk__content__text {
  position: relative;
  z-index: 1;
}
/* Figma: 1346px — фиксированный px, не процент. На фрейме regular (1440)
   это то же самое значение 1346px, скопированное как есть с desktop
   (1920) без пересчёта под новую ширину — там оно почти не ограничивает
   текст (1346 из ~1416 доступных), а не масштабируется пропорционально. */
@media (min-width: 1440px) {
  .gk__content__text {
    max-width: 1346px;
  }
}

/* Размер/смещение/высота — линейная интерполяция между px-координатами
   силуэта на четырёх Figma-фреймах (--illustration-guy-*, см. tokens.css),
   тем же приёмом и на тех же диапазонах, что и текст/отступы выше
   (--fluid-ratio-*). Раньше здесь были vw-пропорции от ширины референсного
   фрейма — тот подход экстраполирует одну пропорцию за пределы её точки
   калибровки и на широком диапазоне может "раздуть" силуэт (так и
   случилось при попытке растянуть мобильную vw-формулу до 1023px, см.
   историю в DESIGN-SYSTEM.md); интерполяция между двумя реальными
   Figma-точками по построению не выходит за их пределы. height — не через
   aspect-ratio: он тоже интерполируется, а не переключается на брейкпоинте
   (все четыре пропорции близки к 1.25, но не совпадают в точности). */
.gk__content .gk__illustration-guy {
  position: absolute;
  width: var(--illustration-guy-mobile-width);
  right: var(--illustration-guy-mobile-right);
  bottom: var(--illustration-guy-mobile-bottom);
  height: var(--illustration-guy-mobile-height);
}
@media (min-width: 375px) and (max-width: 1023.98px) {
  .gk__content .gk__illustration-guy {
    width: calc(
      var(--illustration-guy-mobile-width) +
        (var(--illustration-guy-tablet-width) - var(--illustration-guy-mobile-width)) *
        var(--fluid-ratio-mobile-tablet)
    );
    right: calc(
      var(--illustration-guy-mobile-right) +
        (var(--illustration-guy-tablet-right) - var(--illustration-guy-mobile-right)) *
        var(--fluid-ratio-mobile-tablet)
    );
    bottom: calc(
      var(--illustration-guy-mobile-bottom) +
        (var(--illustration-guy-tablet-bottom) - var(--illustration-guy-mobile-bottom)) *
        var(--fluid-ratio-mobile-tablet)
    );
    height: calc(
      var(--illustration-guy-mobile-height) +
        (var(--illustration-guy-tablet-height) - var(--illustration-guy-mobile-height)) *
        var(--fluid-ratio-mobile-tablet)
    );
  }
}
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__content .gk__illustration-guy {
    width: calc(
      var(--illustration-guy-tablet-width) +
        (var(--illustration-guy-regular-width) - var(--illustration-guy-tablet-width)) *
        var(--fluid-ratio-tablet-regular)
    );
    right: calc(
      var(--illustration-guy-tablet-right) +
        (var(--illustration-guy-regular-right) - var(--illustration-guy-tablet-right)) *
        var(--fluid-ratio-tablet-regular)
    );
    bottom: calc(
      var(--illustration-guy-tablet-bottom) +
        (var(--illustration-guy-regular-bottom) - var(--illustration-guy-tablet-bottom)) *
        var(--fluid-ratio-tablet-regular)
    );
    height: calc(
      var(--illustration-guy-tablet-height) +
        (var(--illustration-guy-regular-height) - var(--illustration-guy-tablet-height)) *
        var(--fluid-ratio-tablet-regular)
    );
  }
}
@media (min-width: 1440px) and (max-width: 1919.98px) {
  .gk__content .gk__illustration-guy {
    width: calc(
      var(--illustration-guy-regular-width) +
        (var(--illustration-guy-desktop-width) - var(--illustration-guy-regular-width)) *
        var(--fluid-ratio-regular-desktop)
    );
    right: calc(
      var(--illustration-guy-regular-right) +
        (var(--illustration-guy-desktop-right) - var(--illustration-guy-regular-right)) *
        var(--fluid-ratio-regular-desktop)
    );
    bottom: calc(
      var(--illustration-guy-regular-bottom) +
        (var(--illustration-guy-desktop-bottom) - var(--illustration-guy-regular-bottom)) *
        var(--fluid-ratio-regular-desktop)
    );
    height: calc(
      var(--illustration-guy-regular-height) +
        (var(--illustration-guy-desktop-height) - var(--illustration-guy-regular-height)) *
        var(--fluid-ratio-regular-desktop)
    );
  }
}
@media (min-width: 1920px) {
  .gk__content .gk__illustration-guy {
    width: var(--illustration-guy-desktop-width);
    right: var(--illustration-guy-desktop-right);
    bottom: var(--illustration-guy-desktop-bottom);
    height: var(--illustration-guy-desktop-height);
  }
}

/* --- organism/footer — ds_organisms → footer (Responsive=desktop/mobile).
   Слоты est/about/email — из дизайна; три слота "space" под будущую
   навигацию (Блог/Архив) в исходном фрейме скрыты/не спроектированы —
   не рендерятся здесь, добавить, когда появятся в Figma.
   Ширины отдельных слотов (256/528/343 в Figma) — не токены, поэтому не
   зафиксированы пиксельно: слоты просто растягиваются во flex-строке. */
.gk__footer {
  /* position: relative (а не просто static), чтобы футер красился поверх
     абсолютно спозиционированного оверлея illustration-guy из .gk__content
     — в CSS-стеке спозиционированные элементы всегда выше статичных
     независимо от порядка в DOM, поэтому без этого вылет силуэта
     перекрывал бы текст футера. Фона здесь нет намеренно: в исходном
     фрейме иллюстрация остаётся видна сквозь футер (поверх неё лежит
     только сам текст) — непрозрачный фон перекрыл бы всю зону нахлёста
     целиком вместо одних глифов. */
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-100);
  padding: var(--space-400) var(--space-200);
  /* Контейнер для выравнивания .email ниже — оно должно включаться не по
     ширине экрана, а по тому, помещаются ли все три блока футера в одну
     строку физически (см. комментарий у .gk__footer__item.email). */
  container-type: inline-size;
  container-name: gk-footer;
}
/* gap растёт плавно mobile→tablet (4px → 16px); padding у mobile/tablet
   совпадает (--space-400 --space-200), поэтому у него плавный участок
   здесь не нужен — начинается только с tablet→regular. */
@media (min-width: 375px) and (max-width: 1023.98px) {
  .gk__footer {
    gap: calc(var(--space-100) + (var(--space-400) - var(--space-100)) * var(--fluid-ratio-mobile-tablet));
  }
}
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__footer {
    gap: var(--space-400);
    padding: calc(
        var(--space-400) + (var(--space-800) - var(--space-400)) * var(--fluid-ratio-tablet-regular)
      )
      calc(var(--space-200) + (var(--space-300) - var(--space-200)) * var(--fluid-ratio-tablet-regular));
  }
}
@media (min-width: 1440px) and (max-width: 1919.98px) {
  .gk__footer {
    gap: var(--space-400);
    padding: var(--space-800)
      calc(var(--space-300) + (var(--space-400) - var(--space-300)) * var(--fluid-ratio-regular-desktop));
  }
}
@media (min-width: 1920px) {
  .gk__footer {
    gap: var(--space-400);
    padding: var(--space-800) var(--space-400);
  }
}

.gk__footer__item {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex: 1 1 220px;
  gap: var(--space-0);
  min-height: var(--space-1200);
  color: var(--color-text-default);
  font-family: var(--font-body-family);
  font-weight: var(--font-body-weight);
  font-size: var(--font-body-size-small);
  line-height: var(--line-height-body-small);
}
/* Тот же плавный переход и диапазон, что у .gk__text-heading/.gk__text-body
   (--fluid-ratio-tablet-regular) — min-height тоже интерполируется вместе со шрифтом
   (48px → 64px), иначе увеличивающийся текст начал бы обрезаться в
   переходной зоне до срабатывания плоского значения на 1440px. */
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .gk__footer__item {
    min-height: calc(
      var(--space-1200) + (var(--space-1600) - var(--space-1200)) * var(--fluid-ratio-tablet-regular)
    );
    font-size: calc(
      var(--font-body-size-small) +
        (var(--font-body-size-base) - var(--font-body-size-small)) * var(--fluid-ratio-tablet-regular)
    );
    line-height: calc(
      var(--line-height-body-small) +
        (var(--line-height-body-base) - var(--line-height-body-small)) * var(--fluid-ratio-tablet-regular)
    );
  }
}
@media (min-width: 1440px) {
  .gk__footer__item {
    min-height: var(--space-1600);
    font-size: var(--font-body-size-base);
    line-height: var(--line-height-body-base);
  }
}
.gk__footer__item p {
  margin: 0;
}
/* Оба <p> в about — конкретные строки из Figma (как и в .est), не единый
   текстовый поток. min-width: max-content не даёт браузеру сжимать первую
   строку («Исследование культуры в свободном жанре») внутри флекс-итема
   ниже её собственной ширины — иначе при промежуточной ширине контейнера
   она бы сама переносилась на 2 строки, и получалось бы 3 визуальные
   строки вместо 2 (см. историю бага в DESIGN-SYSTEM.md). Если места в
   строке футера не хватает даже на эту ширину, весь about-блок целиком
   уходит на новую строку через flex-wrap на .gk__footer, а не ломает
   разметку внутри себя. */
.gk__footer__item.about {
  min-width: max-content;
}
/* Порог — --breakpoint-tablet (1024px): в отличие от отступов/текста/
   иллюстрации выше, это не непрерывная величина, а бинарное включение
   техники (либо есть отрицательный margin, либо нет) — подтверждено в
   Figma на фрейме tablet (est-слот там уже содержит mb-[-8px]), поэтому
   интерполировать нечего, порог соответствует настоящей ширине фрейма. */
@media (min-width: 1024px) {
  /* `gap` не может быть отрицательным — невалидные значения отбрасываются
     и вычисляются в 0px, поэтому им нельзя воспроизвести плотный
     интерлиньяж дизайна между двумя строками. Вместо этого вторая строка
     подтягивается отрицательным margin; -8px (--space-negative-200)
     совпадает со скриншотом дизайна попиксельно (10px между чернилами
     строк в обоих случаях). Работает для обоих слотов (est и about) — у
     обоих теперь ровно два фиксированных <p>, которые никогда не
     переносятся (about защищён min-width: max-content выше), поэтому
     компенсация всегда одинаковая и не сбивает baseline последней строки
     относительно других слотов футера (в отличие от варианта с уменьшенным
     line-height на весь блок — тот менял отступ от базовой линии до низа
     строки и визуально "просаживал" about ниже est/email). */
  .gk__footer__item p + p {
    margin-top: var(--space-negative-200);
  }
}
.gk__footer__item.est {
  text-transform: uppercase;
}
.gk__footer__brand {
  font-style: italic;
}
/* Figma: слот email — items-start (слева) на мобильном, items-end (справа)
   на десктопе — фреймы не масштабированные копии друг друга. Но "десктоп"
   здесь — не про ширину экрана (`@media`), а про то, влезают ли все три
   блока футера физически в одну строку: при промежуточной ширине (между
   ~915 и ~1920px) .about уже не переносится сам в себя (см.
   min-width: max-content выше), но целиком уходит на новую строку через
   flex-wrap на .gk__footer — и если email в этот момент всё ещё
   выровнен вправо через text-align, он повисает одиноко в правом углу.
   @container вместо @media реагирует на реальную ширину футера, а не
   вьюпорта, поэтому выравнивание переключается ровно в тот момент, когда
   строка физически вмещает все три блока. Порог пересчитан
   playwright-скриптом в сессии 2026-08-16 (второй раз — после перехода
   отступов футера на плавную интерполяцию: физическая точка переноса
   сдвинулась с 816px до 808px, т.к. до --breakpoint-tablet padding везде
   плоский 8px+8px). ВАЖНО: `container-type: inline-size` оценивает
   min-width по content-box контейнера (без padding), а не по видимой
   ширине (border-box/getBoundingClientRect) — при horizontal padding
   8px+8px=16px видимая ширина 808px даёт content-box 792px. 796px — 792px
   точного порога с небольшим запасом на субпиксельные отличия между
   браузерами. Если поменяется текст about, email-адрес или отступы/gap
   футера (а после --breakpoint-tablet padding уже не плоский, а плавно
   растёт — при пересчёте порога для более широких контейнеров это надо
   учитывать), порог сдвинется — пересчитать через DevTools/скрипт
   (сравнивая getBoundingClientRect, а не сразу после resize — нужен кадр
   на reflow) и вычесть текущий (не константный!) горизонтальный padding
   футера при переводе видимой ширины в content-box. */
@container gk-footer (min-width: 796px) {
  .gk__footer__item.email {
    align-items: flex-end;
    text-align: right;
  }
}
