/* ═══ ПЕРВЫЙ ЭКРАН ════════════════════════════════════════════════════════
   Секция закрепляется (pin) на 100vh скролла, всё движение — scrub.
   Слои разведены так, чтобы у каждого был свой трансформ и они не дрались:
     .plaque          — скролл (x, scale)
     .plaque__breathe — дыхание в покое (scale), бесконечный yoyo
     .plaque__bloom   — скролл (opacity)
     .plaque__bloom-in — пульс свечения (opacity), множится на предыдущий
   Свечение — самостоятельные слои: тёплый ореол вокруг знака и мягкий
   налив по его лицу. Ни filter, ни blur на картинку не накладывается. */

.hero {
  position: relative;
  height: 100vh; height: 100svh;
  overflow: hidden;
  isolation: isolate;
}

/* ─── фон: три слоя, анимируется opacity верхних двух ─────────────────────
   Вариант «один слой, которому меняют background-color» проверен замером
   и оказался заметно хуже: 33 кадра против 46 на 1920 при CPU x4.
   Перекрашивать два миллиона пикселей каждый кадр дороже, чем композитить
   готовые слои. ───────────────────────────────────────────────────────── */
.hero__bg,
.hero__bg-warm,
.hero__bg-light { position: absolute; inset: 0; z-index: 0; }
.hero__bg { background: var(--prune); }
/* промежуточный слой бордо. Без него середина перехода — серая муть:
   прямое перекрытие чернослива слоновой костью даёт мёртвый серый. */
/* не плоская заливка, а та же радиальная подсветка, что на концах перехода:
   без неё середина выглядит куском однотонной краски */
.hero__bg-warm  {
  background:
    radial-gradient(ellipse 60% 55% at 50% 48%,
      rgba(201, 162, 77, 0.10) 0%, rgba(201, 162, 77, 0) 70%),
    var(--bordeaux);
  opacity: 0;
}
.hero__bg-light {
  background:
    radial-gradient(ellipse 62% 58% at 50% 48%,
      rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 72%),
    var(--ivory);
  opacity: 0;
}

/* ─── слои под композитор: только пока первый экран на экране ────────────
   Постоянный will-change держал девять полноэкранных слоёв живыми всю
   прокрутку — а страница со сценами стала вдвое длиннее, и на 1920
   это стоило кадров в закреплённых секциях, за тысячи пикселей от героя.
   Класс is-live ставит и снимает сам таймлайн первого экрана (js/app.js),
   вместе с ним встаёт и дыхание знака: анимировать то, чего не видно,
   незачем. При «меньше движения» класс не ставится вовсе. */
.hero.is-live .hero__bg-warm,
.hero.is-live .hero__bg-light,
.hero.is-live .plaque__bloom-in { will-change: opacity; }
.hero.is-live .plaque,
.hero.is-live .plaque__breathe { will-change: transform; }
.hero.is-live .plaque__bloom,
.hero.is-live .plaque__shadow,
.hero.is-live .plaque__reflect,
.hero.is-live .hero__copy > * { will-change: transform, opacity; }

/* ─── сцена ───────────────────────────────────────────────────────────── */
.hero__stage { position: absolute; inset: 0; z-index: 1; }

.hero__plaque-slot {
  position: absolute;
  left: 50%; top: 50%;
  width: min(50vw, 78vh);
  transform: translate(-50%, -50%);
}
.plaque { position: relative; }
.plaque__breathe { position: relative; display: block; }
.plaque__img { width: 100%; height: auto; }

/* тёплое свечение вокруг знака — под ним, отдельным слоем */
.plaque__bloom {
  position: absolute; left: 50%; top: 50%;
  width: 156%; height: 178%;
  transform: translate(-50%, -50%);
  pointer-events: none; z-index: 0;
}
.plaque__bloom-in {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 50% 50% at 50% 47%,
              rgba(201, 162, 77, 0.40) 0%,
              rgba(201, 162, 77, 0.15) 38%,
              rgba(201, 162, 77, 0.04) 58%,
              rgba(201, 162, 77, 0) 76%);
}

/* Опора знака. Плита стоит на поверхности: плотная полоса контакта прямо
   по нижней кромке и мягкий ореол под ней. Проявляется вместе со светлым
   фоном — на тёмном экране тени не видно. */
.plaque__shadow {
  position: absolute; left: 50%; bottom: -9%;
  width: 108%; height: 20%;
  transform: translateX(-50%);
  background:
    radial-gradient(ellipse 40% 13% at 50% 44%,
      rgba(26, 11, 16, 0.52) 0%, rgba(26, 11, 16, 0.12) 62%, rgba(26, 11, 16, 0) 86%),
    radial-gradient(ellipse 50% 44% at 50% 44%,
      rgba(26, 11, 16, 0.22) 0%, rgba(26, 11, 16, 0) 80%);
  opacity: 0; z-index: 3; pointer-events: none;
}
/* На тёмном экране тень не читается. Под кромкой лежит тёплый отсвет:
   поверхность ловит свет, которым залита плита. Гаснет вместе со свечением. */
.plaque__reflect {
  position: absolute; left: 50%; bottom: -5%;
  width: 104%; height: 12%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse 42% 48% at 50% 40%,
              rgba(201, 162, 77, 0.38) 0%,
              rgba(201, 162, 77, 0.10) 50%,
              rgba(201, 162, 77, 0) 82%);
  z-index: 1; pointer-events: none;
}

/* ─── текстовая колонка (приезжает слева на светлом) ──────────────────── */
.hero__copy {
  position: absolute;
  left: var(--gutter); top: 50%;
  transform: translateY(-50%);
  width: min(44vw, 820px);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--gap-m);
  color: var(--bordeaux);
}


.hero__badge {
  display: inline-flex; align-items: center; gap: 10px;
  font: 500 var(--fs-small)/1 var(--text);
  letter-spacing: 0.02em;
  color: var(--bordeaux);
}
.hero__badge::before {
  content: ''; width: 34px; height: 2px; background: var(--gold);
}

.hero__title { font-size: var(--fs-h1); }
.hero__lead { color: var(--bordeaux-soft); max-width: 56ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--gap-xs); }

/* ─── углы ────────────────────────────────────────────────────────────── */
.hero__corners {
  position: absolute; inset: 0; z-index: 3;
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: 0 var(--gutter) clamp(22px, 3.4vh, 44px);
  pointer-events: none;
  color: var(--ivory);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
}
.hero__corners a { pointer-events: auto; }

.hero__status { max-width: 30ch; line-height: 1.5; }
.hero__status .sep { color: var(--gold); margin: 0 0.5em; }

.hero__scroll {
  display: flex; align-items: center; gap: 12px;
  letter-spacing: 0.06em;
}
.hero__scroll-rail {
  position: relative; width: 64px; height: 1px;
  background: var(--ivory-faint); overflow: hidden;
}
.hero__scroll-rail::after {
  content: ''; position: absolute; inset: 0;
  background: var(--gold);
  transform: translateX(-100%);
  animation: rail 2.6s var(--ease) infinite;
}
@keyframes rail {
  0%   { transform: translateX(-100%); }
  55%  { transform: translateX(0); }
  100% { transform: translateX(100%); }
}

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

   Гарантия геометрическая, а не подобранная числами. Знак живёт в первой
   строке сетки, текст — во второй, и по скроллу знак только УМЕНЬШАЕТСЯ
   и УЕЗЖАЕТ ВВЕРХ, за шапку. Трансформ, который только сжимает и двигает
   вверх, не может занести прямоугольник знака в чужую строку — значит,
   пересечься им нечем. Раньше оба слоя стояли absolute от середины
   экрана, и на 390 заголовок ложился прямо на плиту. */
@media (max-width: 900px) {
  .hero__stage {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    align-content: start;
    gap: clamp(14px, 2.6vh, 30px);
    padding: calc(var(--topbar-h) + clamp(6px, 1.6vh, 18px))
             var(--gutter)
             clamp(64px, 10.5vh, 104px);
  }

  .hero__plaque-slot {
    position: static; transform: none;
    /* по ширине колонки, но не выше трети экрана: ниже начинается текст */
    width: min(100%, 46vh);
    margin-inline: auto;
  }
  /* На высоком экране (планшет в портрете, крупный телефон) под знаком
     остаётся полторы сотни пикселей пустоты: текстовой строке столько
     не нужно. Отдаём их знаку. Строку сетки это не меняет — знак
     по-прежнему живёт в первой, текст во второй. */
  @media (min-height: 900px) {
    .hero__plaque-slot { width: min(100%, 58vh); }
  }
  /* Точка отсчёта трансформа — верх знака. Тогда «уменьшается» читается
     как «втягивается под шапку», а не как «сжимается к своей середине». */
  .plaque { transform-origin: 50% 0%; }

  .hero__copy {
    position: static; transform: none;
    left: auto; bottom: auto; top: auto;
    width: 100%; padding: 0;
    align-self: center;
    gap: clamp(10px, 1.8vh, 18px);
  }
  /* Значок наследует цвет колонки. Свой color: var(--bordeaux) он держал
     на самом элементе, и перекраска родителя его не доставала — на тёмном
     выходило бордо по черносливу, 1.28:1. На телефоне это единственное
     место, где сказано «скоро открытие»: угловую строку оттуда убрали. */
  html.hero-motion .hero__badge { color: inherit; }
  .hero__title { font-size: calc(clamp(2.3rem, 9.6vw, 3.4rem) * var(--display-scale)); }
  .hero__lead { font-size: var(--fs-body); max-width: 40ch; }

  /* Углы. Строка про лицензию с телефона убрана совсем: теперь текстовая
     колонка стоит на первом экране с самого начала и доходит до низа,
     и угловая строка легла бы прямо на кнопку WhatsApp. Дубля при этом
     не теряется — «Скоро открытие» есть в самой колонке, значком над
     заголовком, а лицензия набрана в подвале. */
  .hero__status { display: none; }
  .hero__corners {
    flex-direction: column; align-items: stretch;
    justify-content: flex-end; gap: 10px;
  }
  /* подсказка скролла по ТЗ живёт в правом нижнем углу — в колонке это
     выравнивание по правому краю */
  .hero__scroll { align-self: flex-end; }
  /* фон на телефоне светлым не становится, а тень видна только на светлом */
  .plaque__shadow { display: none; }
  .hero__scroll-rail { width: 44px; }
  .btn { min-height: 48px; padding: 0 20px; }
}

/* кнопки во всю ширину колонки: столбиком разной длины правый край рвётся */
@media (max-width: 560px) {
  .hero__actions { width: 100%; }
  .hero__actions .btn { flex: 1 1 100%; justify-content: center; }
}

/* Совсем низкий экран: подпись в углу уступает место тексту. Она и так
   гаснет к середине перехода, а на 640px высоты её строка съедает
   последнюю кнопку. */
@media (max-width: 900px) and (max-height: 700px) {
  .hero__stage { padding-bottom: clamp(48px, 8vh, 70px); }
  .hero__plaque-slot { width: min(100%, 38vh); }
}

/* ─── уважение к reduced-motion: сразу конечное состояние ─────────────── */
/* ─── Статический первый экран ────────────────────────────────────────────
   Применяется в двух случаях: у человека включено «меньше движения» или
   на странице не работает javascript. Класс hero-motion ставит встроенный
   скрипт в <head>; нет класса — нет и анимации, первый экран сразу
   раскладывается в конечное состояние обычной сеткой.
   Так страница остаётся рабочей без js: иначе тёмный текст лежал бы
   на тёмном фоне поверх знака. */
html:not(.hero-motion) .hero {
  height: auto; overflow: visible;
  padding: clamp(120px, 16vh, 190px) 0 0;
}
html:not(.hero-motion) .hero__bg-light { opacity: 1; }
/* relative, а не static. У .hero__stage стоит z-index: 1, и он работает
   только на позиционированном элементе: со static колонка текста уезжала
   ПОД непрозрачный .hero__bg-light (он absolute с z-index: 0, а
   позиционированные элементы рисуются поверх обычного потока). Без
   javascript первый экран показывал знак и пустое поле — ни заголовка,
   ни кнопки «Позвонить». При «меньше движения» то же самое не проявлялось
   случайно: GSAP вешает на строки inline-трансформ, а он сам создаёт
   контекст наложения. Две проверки на деле проверяли один путь. */
html:not(.hero-motion) .hero__stage {
  position: relative; width: var(--wrap); margin-inline: auto;
  grid-template-rows: none; padding: 0;
  /* minmax(0, …) обязателен: без него доли считаются от min-content
     картинки, и колонка текста ужимается до трети экрана. С ним выходит
     ровно 43% — в норму «не шире 0.45» и без перелёта в другую сторону. */
  display: grid; grid-template-columns: minmax(0, 0.98fr) minmax(0, 1fr);
  gap: clamp(30px, 5vw, 80px); align-items: center;
}
html:not(.hero-motion) .hero__plaque-slot {
  position: static; transform: none; width: 100%; order: 2;
}
/* В статической раскладке колонка чуть уже, чем в анимированной: кегль
   поменьше, и перенос обычный, а не balance — balance выравнивает длины
   строк и ради этого ломает заголовок на четыре вместо трёх. */
html:not(.hero-motion) .hero__title {
  font-size: calc(clamp(2.6rem, 6.1vw, 6.4rem) * var(--display-scale));
  text-wrap: pretty;
}
html:not(.hero-motion) .hero__copy {
  position: static; transform: none; left: auto; width: 100%;
  order: 1; padding: 0;
}
html:not(.hero-motion) .hero__corners {
  position: static; color: var(--bordeaux);
  width: var(--wrap); margin: clamp(40px, 6vh, 70px) auto 0; padding: 0;
  flex-direction: row; align-items: flex-end;
}
html:not(.hero-motion) .hero__scroll { display: none; }
html:not(.hero-motion) .plaque__reflect { opacity: 0; }
html:not(.hero-motion) .plaque__shadow { opacity: 1; }
html:not(.hero-motion) .topbar { color: var(--bordeaux); }
html:not(.hero-motion) .topbar__scrim { opacity: 1; }

@media (max-width: 900px) {
  html:not(.hero-motion) .hero__stage {
    grid-template-columns: 1fr; grid-template-rows: auto auto;
    padding: 0; gap: clamp(24px, 5vw, 40px);
  }
  html:not(.hero-motion) .hero__plaque-slot { order: 1; width: 80%; margin-inline: auto; }
  html:not(.hero-motion) .hero__copy { order: 2; }
}
