/* =========================================================================
   UGLY BABY — заглушка
   Фон собран градиентами и CSS-паттернами (никаких растровых текстур),
   вся анимация — на transform/opacity, чтобы не грузить CPU.
   ========================================================================= */

@font-face {
  font-family: "Usually";
  src: url("../fonts/usually-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* палитра снята с example.jpg */
  --c-deep:  #010b18;
  --c-navy:  #041e3d;
  --c-blue:  #0b3a67;
  --c-mid:   #0e4475;
  --c-glow:  #2d8cc6;
  --c-line:  180, 220, 255;

  /* курсор: -1..1 по осям, --pd — удаление от центра 0..1 */
  --px: 0;
  --py: 0;
  --pd: 0;

  /* сила RGB-расслоения заголовка (растёт от скорости курсора) */
  --split: 1;

  /* переменные глитч-всплеска, значения подставляет js */
  --gx1: 0px;  --gx2: 0px;
  --tt1: 30%;  --th1: 8px;
  --tt2: 66%;  --th2: 3px;

  --cell: clamp(74px, 9.4vw, 150px);
  --head-h: min(46vh, 62vw, 420px);

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--c-deep);
  color: #eaf3ff;
  font-family: "Usually", "Arial Narrow", system-ui, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}

/* =========================================================================
   ФОН
   ========================================================================= */

.bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  contain: strict;
}

.bg > * {
  position: absolute;
  inset: 0;
}

/* Базовый градиент: небольшое светлое пятно чуть выше центра -> глубокая синева по краям. */
.bg__base {
  background:
    radial-gradient(90% 72% at 50% 40%,
      var(--c-glow) 0%,
      #17608f 9%,
      var(--c-mid) 20%,
      var(--c-blue) 32%,
      #072b51 48%,
      var(--c-navy) 66%,
      #021126 84%,
      var(--c-deep) 100%);
  animation: breathe 26s ease-in-out infinite;
  will-change: transform;
}

/* Разводы и потёртости — как пятна краски на референсе. */
.bg__blobs {
  background:
    radial-gradient(38% 46% at 22% 30%, rgba(2, 13, 28, .62), transparent 70%),
    radial-gradient(46% 38% at 82% 22%, rgba(1, 10, 24, .58), transparent 72%),
    radial-gradient(52% 44% at 74% 84%, rgba(2, 16, 34, .62), transparent 70%),
    radial-gradient(40% 52% at 12% 82%, rgba(1, 11, 26, .58), transparent 74%),
    radial-gradient(30% 26% at 60% 58%, rgba(90, 175, 235, .10), transparent 76%);
  animation: drift 34s ease-in-out infinite alternate;
  will-change: transform;
}

/* Крупная «грязь»: тот же feTurbulence, но растянутый — даёт разводы краски
   как на example.jpg. Растр считается один раз, дальше только сдвигается. */
.bg__dirt {
  inset: -14%;
  width: 128%;
  height: 128%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.012' numOctaves='4' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='512' height='512' filter='url(%23d)'/%3E%3C/svg%3E");
  background-size: 1100px 1100px;
  opacity: .5;
  mix-blend-mode: overlay;
  animation: drift 48s ease-in-out infinite alternate-reverse;
  will-change: transform;
}

/* ---------- сетка ----------
   Живёт в canvas: линии гнутся под курсором, а в покое на них лежит лёгкая
   постоянная кривизна, чтобы не выглядело чертёжной калькой. Деформацию
   самих линий на css не изобразить — только рисованием. */
.bg__grid {
  -webkit-mask-image: radial-gradient(ellipse 82% 78% at 50% 46%, #000 34%, transparent 86%);
          mask-image: radial-gradient(ellipse 82% 78% at 50% 46%, #000 34%, transparent 86%);
}

.bg__grid-c {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Зерно за персонажем: SVG-шум тайлом, дёргается 8 раз в секунду сдвигом
   слоя (без перерисовки). */
.bg__grain {
  inset: -30%;
  width: 160%;
  height: 160%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.4' intercept='-.7'/%3E%3CfeFuncG type='linear' slope='2.4' intercept='-.7'/%3E%3CfeFuncB type='linear' slope='2.4' intercept='-.7'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .34;
  mix-blend-mode: overlay;
  animation: grain 1s steps(1, end) infinite;
  will-change: transform;
}

/* =========================================================================
   ПЛЁНОЧНЫЕ ЭФФЕКТЫ ПОВЕРХ ВСЕГО (включая персонажа)
   z-index намеренно не задан: он бы создал контекст наложения и mix-blend-mode
   перестал бы видеть фон под собой. Порядок держится порядком в разметке.
   ========================================================================= */

.fx {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.fx > * {
  position: absolute;
  inset: 0;
}

/* Медленная светлая полоса — «прокрутка кадра» старого телевизора. */
.fx__roll {
  inset: -30% 0 auto 0;
  height: 30%;
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(150, 205, 255, .05) 42%,
    rgba(190, 230, 255, .085) 50%,
    rgba(150, 205, 255, .05) 58%,
    transparent 100%);
  animation: roll 9s linear infinite;
  will-change: transform;
}

.fx__scan {
  background: repeating-linear-gradient(to bottom,
    rgba(0, 10, 25, .26) 0 1px,
    transparent 1px 3px);
  opacity: .5;
  animation: scan 1.6s linear infinite;
  will-change: transform;
}

.fx__grain {
  inset: -30%;
  width: 160%;
  height: 160%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.72' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.8' intercept='-.9'/%3E%3CfeFuncG type='linear' slope='2.8' intercept='-.9'/%3E%3CfeFuncB type='linear' slope='2.8' intercept='-.9'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23m)'/%3E%3C/svg%3E");
  opacity: .32;
  mix-blend-mode: overlay;
  animation: grain 1.1s steps(1, end) infinite reverse;
  will-change: transform;
}

/* Полосы срыва кадра — видны только во время глитч-всплеска. */
.fx__tear::before,
.fx__tear::after {
  content: "";
  position: absolute;
  left: -12%;
  width: 124%;
  opacity: 0;
  mix-blend-mode: screen;
  background: linear-gradient(to right,
    transparent, rgba(120, 200, 255, .18) 12%, rgba(255, 255, 255, .28) 50%,
    rgba(120, 200, 255, .18) 88%, transparent);
}
.fx__tear::before { top: var(--tt1); height: var(--th1); }
.fx__tear::after  { top: var(--tt2); height: var(--th2); }

.fx__vignette {
  background:
    radial-gradient(120% 96% at 50% 46%, transparent 38%, rgba(0, 6, 16, .6) 78%, rgba(0, 4, 12, .88) 100%);
}

/* =========================================================================
   СЦЕНА
   ========================================================================= */

.stage {
  position: relative;
  height: 100%;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 3.4vh, 42px);
  padding: max(16px, env(safe-area-inset-top)) 20px max(16px, env(safe-area-inset-bottom));
  /* блок чуть выше геометрического центра */
  padding-bottom: calc(max(16px, env(safe-area-inset-bottom)) + clamp(24px, 8vh, 90px));
  perspective: 900px;
}

/* ---------- голова ---------- */

.head {
  position: relative;
  height: var(--head-h);
  aspect-ratio: 396 / 528;
  flex: none;
  cursor: pointer;
  transform-style: preserve-3d;
  transform:
    translate3d(calc(var(--px) * 16px), calc(var(--py) * 11px), 0)
    rotateY(calc(var(--px) * 7deg))
    rotateX(calc(var(--py) * -5deg));
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
  will-change: transform;
}

/* Свечение под головой вместо drop-shadow — фильтр на движущемся слое дорогой. */
.head__glow {
  position: absolute;
  left: 50%;
  top: 52%;
  width: 165%;
  height: 130%;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side,
    rgba(120, 200, 255, .30), rgba(60, 140, 220, .13) 52%, transparent 72%);
  animation: pulse 7s ease-in-out infinite;
  will-change: transform, opacity;
}

.head__sway {
  position: absolute;
  inset: 0;
  animation: sway 6.4s ease-in-out infinite;
  transition: filter 1s ease-in-out;
  will-change: transform;
}

/* Поза покоя: полное разрешение кропа (528x704), видна почти всё время.
   Двойная цветная тень повторяет то же RGB-расслоение, что js рисует
   в canvas, — чтобы переход «покой -> анимация» был незаметен. */
.head__still {
  position: absolute;
  inset: 0;
  background: url("../img/head-rest.webp") no-repeat center / contain;
  filter:
    drop-shadow(-1.5px 0 0 rgba(255, 43, 69, .5))
    drop-shadow(1.5px 0 0 rgba(37, 226, 255, .45));
}

/* Кадры рисуются в canvas, а не масштабированным background-ом:
   в софтверном растре (без GPU) слой с 3D-трансформом и растянутым фоном
   местами вообще не отрисовывается, а персонаж пропасть не должен.
   Canvas включается только на время движения — в покое остаётся чёткий still. */
.head__canvas {
  position: absolute;
  inset: 0;
  display: none;
  width: 100%;
  height: 100%;
}
.head.is-live .head__still  { display: none; }
.head.is-live .head__canvas { display: block; }

/* ---------- заголовок ---------- */

.title {
  position: relative;
  flex: none;
  transform: translate3d(calc(var(--px) * -9px), calc(var(--py) * -6px), 0);
  transition: transform .6s cubic-bezier(.22, .61, .36, 1), filter 1s ease-in-out;
  will-change: transform;
}

.title__text {
  display: block;
  margin: 0;
  /* «РАЗРАБОТКЕ» в этом шрифте занимает ~9.5em, вся фраза одной строкой ~15.9em,
     отсюда потолки по vw: иначе строка вылезает за экран. */
  font-size: clamp(1.45rem, 7.4vw, 4.1rem);
  font-weight: 700;
  line-height: 1;
  /* шрифт нарисован с очень плотными боковыми пробелами, буквы слипаются —
     разводим руками */
  letter-spacing: .1em;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
  color: #fff;
}

.title__line { display: block; }

.title__ghost {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: .75;
}
.title__ghost--r {
  color: #ff2b45;
  transform: translate3d(calc(var(--split) * -1px), calc(var(--split) * .18px), 0);
}
.title__ghost--c {
  color: #25e2ff;
  transform: translate3d(calc(var(--split) * 1px), calc(var(--split) * -.18px), 0);
}

/* ---------- контакты (сейчас закомментированы в index.html) ---------- */

.contacts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 26px;
  margin-top: clamp(2px, 1.2vh, 14px);
  font-family: system-ui, "Segoe UI", sans-serif;
  font-size: clamp(.82rem, 2.9vw, 1rem);
  font-style: normal;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: rgba(210, 232, 255, .62);
}
.contacts__item {
  color: inherit;
  text-decoration: none;
  transition: color .25s ease;
}
a.contacts__item:hover { color: #fff; }

/* =========================================================================
   ГЛИТЧ-ВСПЛЕСК (класс вешает js на <html> на ~200 мс)
   ========================================================================= */

:root.is-glitch .fx__tear::before { animation: tear .2s steps(2, end) both; }
:root.is-glitch .fx__tear::after  { animation: tear .2s steps(3, end) both .04s; }

:root.is-glitch .bg__grid {
  transform: translate3d(var(--gx1), 0, 0) skewX(1.4deg);
}

:root.is-glitch .title { transition: none; transform: translate3d(var(--gx2), 0, 0); }
:root.is-glitch .title__ghost--r { transform: translate3d(calc(var(--split) * -1px - 7px), -1px, 0); }
:root.is-glitch .title__ghost--c { transform: translate3d(calc(var(--split) * 1px + 7px), 1px, 0); }

/* сам разрыв и RGB-расслоение персонажа рисует js прямо в canvas */
:root.is-glitch .head {
  transition: none;
  transform:
    translate3d(calc(var(--px) * 16px + var(--gx2)), calc(var(--py) * 11px), 0)
    rotateY(calc(var(--px) * 7deg))
    rotateX(calc(var(--py) * -5deg));
}

/* =========================================================================
   ВОЛНА РАССТРОЙКИ ФОКУСА (js вешает класс раз в 15-26 с)
   ========================================================================= */

:root.is-defocus .head__sway { filter: blur(1.5px); }
:root.is-defocus .title      { filter: blur(1.2px); }

/* =========================================================================
   АНИМАЦИИ
   ========================================================================= */

@keyframes breathe {
  0%, 100% { transform: scale(1)     translate3d(0, 0, 0); }
  50%      { transform: scale(1.045) translate3d(0, -.8%, 0); }
}

@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(1.6%, -1.2%, 0) scale(1.06); }
}

@keyframes roll {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(0, calc(100vh + 60%), 0); }
}

@keyframes scan {
  0%   { transform: translate3d(0, 0, 0); }
  100% { transform: translate3d(0, 3px, 0); }
}

@keyframes grain {
  0%    { transform: translate3d(0, 0, 0); }
  12.5% { transform: translate3d(-2%, 1.5%, 0); }
  25%   { transform: translate3d(1.5%, -2%, 0); }
  37.5% { transform: translate3d(-1%, -1.5%, 0); }
  50%   { transform: translate3d(2%, 1%, 0); }
  62.5% { transform: translate3d(-1.5%, 2%, 0); }
  75%   { transform: translate3d(1%, -1%, 0); }
  87.5% { transform: translate3d(-2%, -1%, 0); }
  100%  { transform: translate3d(0, 0, 0); }
}

@keyframes sway {
  0%   { transform: translate3d(0, 0, 0) rotate(-1.5deg); }
  50%  { transform: translate3d(0, -1.6%, 0) rotate(1.4deg); }
  100% { transform: translate3d(0, 0, 0) rotate(-1.5deg); }
}

@keyframes pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: .85; }
  50%      { transform: translate(-50%, -50%) scale(1.09); opacity: 1; }
}

@keyframes tear {
  0%   { opacity: 0;   transform: translate3d(0, 0, 0); }
  35%  { opacity: .95; transform: translate3d(-3%, 0, 0); }
  70%  { opacity: .7;  transform: translate3d(4%, 0, 0); }
  100% { opacity: 0;   transform: translate3d(0, 0, 0); }
}

/* =========================================================================
   АДАПТИВ И ДОСТУПНОСТЬ
   ========================================================================= */

/* Десктоп: голова компактнее, фраза — одной строкой. */
@media (min-width: 700px) {
  :root { --head-h: min(32vh, 44vw, 294px); }

  .title__text { font-size: min(3rem, 5.5vw); }
  .title__line { display: inline; }
}

/* Узкие/низкие экраны: голова компактнее, чтобы надпись не липла к краям. */
@media (max-height: 560px) and (max-width: 699.98px) {
  :root { --head-h: min(46vh, 46vw, 300px); }
  .title__text { font-size: clamp(1.4rem, 6vw, 2.6rem); }
}

@media (prefers-reduced-motion: reduce) {
  .bg__base, .bg__blobs, .bg__dirt, .bg__grain,
  .fx__roll, .fx__scan, .fx__grain, .head__sway, .head__glow {
    animation: none !important;
  }
  .head, .title, .bg__grid { transition-duration: .8s; }
}
