/* ВЗЛЁТ — tech-art v2: единая система состояний и эффектов.
 * Движет --charge (0..1) из js/planet-art.js. Планета настраивает ТОЛЬКО:
 *   --dim (видимость во сне), --ta-accent/--ta-accent-rgb (свой оттенок),
 *   --fx-strength (сила эффектов, дефолт .55, максимум .75), --ta-scan-period.
 * Эффекты собираются из примитивов fx-* внутри <div class="tech-art-fx"> (добавляет модуль планеты).
 * Motion — opt-in: @media (prefers-reduced-motion: no-preference); без motion слои статичны и видимы.
 */

/* 1. Контейнер арта, круглая обрезка и фазы сборки */
.tech-art {
  --charge: 0;
  --dim: .16;
  --scale-from: .97;
  --fx-strength: .55;
  --ta-accent: #7eebff;
  --ta-accent-rgb: 126 235 255;
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  /* Во сне тускло и выключено по насыщенности; при зарядке арт догоняет дизайн. */
  opacity: calc(var(--dim) + (1 - var(--dim)) * var(--charge));
  filter: saturate(calc(.3 + .7 * var(--charge))) brightness(calc(.7 + .5 * var(--charge)));
  scale: calc(var(--scale-from) + (1 - var(--scale-from)) * var(--charge));
  /* Жёсткая круговая обрезка: модель, фон и эффекты не выходят за диск планеты. */
  border-radius: 50%;
  overflow: hidden;
}

/* До первого «выдвижения» планеты слоя нет вовсе. */
.tech-art.is-unrevealed {
  opacity: 0;
  visibility: hidden;
}

/* Reveal — короткая одноразовая подсветка появления; только при согласии на motion. */
@media (prefers-reduced-motion: no-preference) {
  .tech-art.is-revealed { animation: ta-reveal .8s ease-out both; }
}

@keyframes ta-reveal {
  from { opacity: 0; }
}

/* 2. Слои: фон (под артом, тоже внутри диска), модель, виньетка */
.tech-art-bg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Фон живёт только внутри диска планеты — никаких углов и выходов за кромку. */
  border-radius: 50%;
  overflow: hidden;
}

.tech-art-bg > svg,
.tech-art-bg > img {
  height: 100%;
  width: auto;
  display: block;
  mix-blend-mode: screen;
  opacity: calc(.22 + .4 * var(--charge));
}

/* Модель: гибкая сцена 800×600, сама картинка не деформируется. */
.tech-art-stage {
  position: relative;
  height: 100%;
  aspect-ratio: 800 / 600;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tech-art-model {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%; /* гарантия: svg/img внутри получает определённую высоту на любой планете */
  /* Асимметрия: арт сдвинут внутри диска; transform живёт только здесь. */
  transform: translate(var(--art-dx, 0%), var(--art-dy, 0%)) scale(var(--art-s, 1));
}

.tech-art-model > svg,
.tech-art-model > img {
  height: 100%;
  width: auto;
  display: block;
  mix-blend-mode: screen;
}

.tech-art--aurora  { --art-dx: 5%;   --art-dy: -8%;   --art-s: .88; }
.tech-art--terra   { --art-dx: -4%;  --art-dy: -6%;   --art-s: .90; }
.tech-art--rust    { --art-dx: 7%;   --art-dy: -5%;   --art-s: .84; }
.tech-art--jovia   { --art-dx: -6%;  --art-dy: -10%;  --art-s: .86; }
.tech-art--glacius { --art-dx: 4.5%; --art-dy: -8.5%; --art-s: .92; }
.tech-art--vulcan  { --art-dx: -3%;  --art-dy: -4.5%; --art-s: .94; }
.tech-art--selena  { --art-dx: 5.5%; --art-dy: -9%;   --art-s: .89; }

/* Компактные режимы: SVG остаётся выразительным и прижат к верхнему краю,
   текст — ниже и к противоположному краю (переменные в styles.css).
   Масштаб и вертикальный сдвиг подобраны по модели: верх сцены остаётся около
   кромки диска, а пёстрая материнская плата Aurora скромнее остального арта. */
@media (max-width: 1100px) {
  .tech-art--aurora  { --art-dx: -10%; --art-dy: -20%; --art-s: .60; --fx-strength: .22; --dim: .12; }
  .tech-art--terra   { --art-dx: 10%;  --art-dy: -19%; --art-s: .68; --fx-strength: .38; }
  .tech-art--rust    { --art-dx: 9%;   --art-dy: -15%; --art-s: .80; --fx-strength: .36; }
  .tech-art--jovia   { --art-dx: -10%; --art-dy: -22%; --art-s: .66; --fx-strength: .34; }
  .tech-art--glacius { --art-dx: 9%;   --art-dy: -12%; --art-s: .86; --fx-strength: .36; }
  .tech-art--vulcan  { --art-dx: -8%;  --art-dy: -18%; --art-s: .74; --fx-strength: .40; }
  .tech-art--selena  { --art-dx: 10%;  --art-dy: -23%; --art-s: .64; --fx-strength: .36; }
}

/* 3. Виньетка во сне: мягко гасит края до зарядки */
.tech-art::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  clip-path: circle(50% at 50% 50%);
  background: radial-gradient(circle at 50% 50%, transparent 40%, rgba(4, 7, 14, .92) 72%);
  opacity: calc(.85 * (1 - var(--charge)));
  pointer-events: none;
}

/* 4. Голограммная «рябь»: копия модели, открытая узкой бегущей полосой.
   Полоса — polygon с постоянной толщиной var(--holo-th), на краях цикла уходит
   за картинку и гаснет по opacity, поэтому стык анимации не виден. */
.tech-art-model > .tech-art-holo {
  --holo-th: .42%; /* ~3.8-4.5px при планете 900-1060px */
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: calc(.035 + .03 * var(--charge));
  filter: brightness(1.07) saturate(1.05);
  /* Ворсинки: 1px штрих / 1.5px промежуток — на полосе 3-5px читается 2-3 штриха. */
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 1px, transparent 1px 2.5px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 1px, transparent 1px 2.5px);
  clip-path: polygon(0 calc(-1 * var(--holo-th)), 100% calc(-1 * var(--holo-th)), 100% 0%, 0 0%);
}

.tech-art-model > .holo-b {
  opacity: calc(.025 + .02 * var(--charge));
  filter: brightness(1.03) saturate(1.02);
  /* Ворсинки реже: 1px штрих / 2px промежуток. */
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 1px, transparent 1px 3px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 1px, transparent 1px 3px);
}

/* Бегущие полосы — только при согласии на motion; без motion копия скрыта полностью. */
@media (prefers-reduced-motion: no-preference) {
  .tech-art-model > .tech-art-holo { animation: holo-sweep-down 10.5s linear -2.3s infinite; }
  .tech-art-model > .holo-b { animation: holo-sweep-up 16.5s linear -7.8s infinite; }
}

@media (prefers-reduced-motion: reduce) {
  /* Без анимаций рябь не показываем вовсе. */
  .tech-art-holo { display: none; }
}

@keyframes holo-sweep-down {
  0% { clip-path: polygon(0 calc(-1 * var(--holo-th)), 100% calc(-1 * var(--holo-th)), 100% 0%, 0 0%); opacity: 0; }
  16%, 84% { opacity: 1; }
  100% { clip-path: polygon(0 100%, 100% 100%, 100% calc(100% + var(--holo-th)), 0 calc(100% + var(--holo-th))); opacity: 0; }
}

@keyframes holo-sweep-up {
  0% { clip-path: polygon(0 100%, 100% 100%, 100% calc(100% + var(--holo-th)), 0 calc(100% + var(--holo-th))); opacity: 0; }
  18%, 82% { opacity: 1; }
  100% { clip-path: polygon(0 calc(-1 * var(--holo-th)), 100% calc(-1 * var(--holo-th)), 100% 0%, 0 0%); opacity: 0; }
}

/* Мобайл: планета 132vw — полоса ряби тоньше, а арт получает собственные
   индивидуальные значения, без срезающей формулы: так проще держать верх/край. */
@media (max-width: 760px) {
  .tech-art-model > .tech-art-holo { --holo-th: .6%; }

  .tech-art--aurora  { --art-dx: -7%; --art-dy: -27%; --art-s: .48; --fx-strength: .16; --dim: .10; }
  .tech-art--terra   { --art-dx: 7%;  --art-dy: -26%; --art-s: .56; --fx-strength: .30; }
  .tech-art--rust    { --art-dx: 7%;  --art-dy: -23%; --art-s: .66; --fx-strength: .28; }
  .tech-art--jovia   { --art-dx: -7%; --art-dy: -27%; --art-s: .52; --fx-strength: .26; }
  .tech-art--glacius { --art-dx: 7%;  --art-dy: -21%; --art-s: .72; --fx-strength: .28; }
  .tech-art--vulcan  { --art-dx: -7%; --art-dy: -24%; --art-s: .62; --fx-strength: .32; }
  .tech-art--selena  { --art-dx: 7%;  --art-dy: -26%; --art-s: .54; --fx-strength: .28; }
}

/* 5. Контейнер эффектов — строго внутри диска планеты */
.tech-art-fx {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
}

.tech-art-fx > * { position: absolute; }

/* ── Примитивы (включаются на .is-charged, яркость = доля от --fx-strength) ── */
/* Скан: вертикальная полоса (уникален для Aurora). */
.fx-scan {
  inset: 0;
  background: linear-gradient(to bottom, transparent 0%, rgba(var(--ta-accent-rgb), .5) 50%, transparent 100%);
  background-size: 100% 16%;
  background-repeat: no-repeat;
  opacity: 0;
}

/* Bloom: мягкая засветка из центра. */
.fx-bloom {
  inset: 10%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--ta-accent-rgb), .5) 0%, transparent 62%);
  opacity: 0;
  scale: .72;
}

/* Radar: вращающийся луч. */
.fx-radar {
  inset: 5%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0deg, transparent 295deg, rgba(var(--ta-accent-rgb), .38) 352deg, transparent 360deg);
  opacity: 0;
  rotate: 0deg;
}

/* Surge: ток по дорожкам — тонкие горизонтали + бегущая яркая полоса. */
.fx-surge {
  inset: 0;
  background:
    linear-gradient(to bottom, transparent 0%, rgba(var(--ta-accent-rgb), .22) 50%, transparent 100%) 0 0 / 100% 30% no-repeat,
    repeating-linear-gradient(0deg, rgba(var(--ta-accent-rgb), .14) 0 1px, transparent 1px 24px);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 30%, transparent 72%);
  mask-image: radial-gradient(circle at 50% 50%, #000 30%, transparent 72%);
  opacity: 0;
}

/* Shimmer: ледяной диагональный блик. */
.fx-shimmer {
  inset: 0;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, .3) 50%, transparent 60%);
  background-size: 240% 240%;
  opacity: 0;
}

/* Heat: магма снизу. */
.fx-heat {
  left: 6%;
  right: 6%;
  bottom: -6%;
  height: 52%;
  background: radial-gradient(62% 100% at 50% 100%, rgba(var(--ta-accent-rgb), .55), transparent 72%);
  opacity: 0;
}

/* Ember: редкие искры (span'ы, позиция/задержка — инлайн-стилями: --ex, --ed). */
.fx-ember {
  bottom: 12%;
  left: var(--ex, 50%);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ta-accent);
  box-shadow: 0 0 6px rgba(var(--ta-accent-rgb), .8);
  opacity: 0;
}

/* Ripple: дуги-сигнал от верхней точки (внутри три <i>). */
.fx-ripple { inset: 0; }

.fx-ripple i {
  left: 50%;
  top: 10%;
  width: 150px;
  height: 150px;
  margin: -75px 0 0 -75px;
  border: 1.5px solid rgba(var(--ta-accent-rgb), .55);
  border-radius: 50%;
  clip-path: inset(0 0 52% 0);
  opacity: 0;
  scale: .25;
}

.fx-ripple i:nth-child(2) { animation-delay: 1s; }
.fx-ripple i:nth-child(3) { animation-delay: 2s; }

/* Ring: кольцо по кромке (вторичный штрих). */
.fx-ring {
  inset: 7%;
  border-radius: 50%;
  border: 1px solid rgba(var(--ta-accent-rgb), .42);
  opacity: 0;
}

/* Wake: разовое кольцо-пробуждение при каждом входе в charged. */
.fx-wake {
  inset: 6%;
  border-radius: 50%;
  border: 1.5px solid rgba(var(--ta-accent-rgb), .7);
  opacity: 0;
  scale: .85;
}

/* Единое «дыхание» сцены вместо самописных пульсов. */
.ta-breathe { scale: 1; }

/* 6. Заряженное состояние и анимации примитивов — opt-in motion */
@media (prefers-reduced-motion: no-preference) {
  .is-charged .fx-scan {
    opacity: calc(.32 * var(--fx-strength));
    animation: ta-scan-move var(--ta-scan-period, 5.2s) linear infinite;
  }

  .is-charged .fx-bloom {
    opacity: calc(.5 * var(--fx-strength));
    animation: ta-bloom-in 1.1s ease-out both, ta-bloom-breathe 3.8s ease-in-out 1.1s infinite;
  }

  .is-charged .fx-radar {
    opacity: calc(.55 * var(--fx-strength));
    animation: ta-radar-spin 5.6s linear infinite;
  }

  .is-charged .fx-surge {
    opacity: calc(.55 * var(--fx-strength));
    animation: ta-surge-run 3.4s linear infinite;
  }

  .is-charged .fx-shimmer {
    opacity: calc(.4 * var(--fx-strength));
    animation: ta-shimmer-sweep 6s ease-in-out infinite;
  }

  .is-charged .fx-heat {
    opacity: calc(.5 * var(--fx-strength));
    animation: ta-heat-breathe 3.2s ease-in-out infinite;
  }

  .is-charged .fx-ember { animation: ta-ember-rise var(--ed, 3s) ease-out infinite; }

  .is-charged .fx-ripple i { animation: ta-ripple-out 3s ease-out infinite; }

  .is-charged .fx-ring {
    opacity: calc(.5 * var(--fx-strength));
    animation: ta-ring-pulse 3.6s ease-in-out infinite;
  }

  .is-charged .fx-wake { animation: ta-wake-once .9s ease-out 1; }

  .ta-breathe { animation: ta-breathe 4.2s ease-in-out infinite; }
}

/* 7. Ключевые кадры; префиксы ta-* и holo-* — контракт JS */
@keyframes ta-scan-move { from { background-position: 0 -20%; } to { background-position: 0 120%; } }

@keyframes ta-bloom-in { from { opacity: 0; scale: .72; } 60% { opacity: calc(.62 * var(--fx-strength)); } to { opacity: calc(.5 * var(--fx-strength)); scale: 1.04; } }

@keyframes ta-bloom-breathe { 0%, 100% { scale: 1.02; } 50% { scale: 1.07; } }

@keyframes ta-radar-spin { to { rotate: 360deg; } }

@keyframes ta-surge-run { from { background-position: 0 120%, 0 0; } to { background-position: 0 -40%, 0 0; } }

@keyframes ta-shimmer-sweep { 0% { background-position: 130% 130%; } 55% { background-position: -30% -30%; } 100% { background-position: -30% -30%; } }

@keyframes ta-heat-breathe { 0%, 100% { translate: 0 0; } 50% { translate: 0 -3%; } }

@keyframes ta-ember-rise {
  0% { opacity: 0; translate: 0 0; scale: 1; }
  12% { opacity: calc(.8 * var(--fx-strength)); }
  100% { opacity: 0; translate: 0 -140px; scale: .4; }
}

@keyframes ta-ripple-out { 0% { opacity: 0; scale: .25; } 14% { opacity: calc(.6 * var(--fx-strength)); } 100% { opacity: 0; scale: 1.9; } }

@keyframes ta-ring-pulse { 0%, 100% { scale: 1; } 50% { scale: 1.025; } }

@keyframes ta-wake-once { from { opacity: calc(.8 * var(--fx-strength)); scale: .85; } to { opacity: 0; scale: 1.22; } }

@keyframes ta-breathe { 0%, 100% { scale: 1; } 50% { scale: 1.012; } }

/* 8. Reduced motion: примитивы остаются видимыми в заряженном состоянии, анимации выключены. */
@media (prefers-reduced-motion: reduce) {
  .is-charged .fx-scan,
  .is-charged .fx-bloom,
  .is-charged .fx-radar,
  .is-charged .fx-surge,
  .is-charged .fx-shimmer,
  .is-charged .fx-heat,
  .is-charged .fx-ember,
  .is-charged .fx-ripple i,
  .is-charged .fx-ring { animation: none; }

  .ta-breathe { scale: 1; }
}
