/* ─────────────────────────────────────────────────────────────
   Карта России на первом экране.

   Базовое состояние — статичная видимая карта. Всё остальное
   (волна, сеть, импульсы) навешивается скриптом поверх. Если JS
   не отработал, на экране остаётся корректная карта, а не пустота.
   ───────────────────────────────────────────────────────────── */

.ru-map {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  overflow: hidden;
}

.ru-map svg {
  width: min(1180px, 82%);
  height: auto;
  overflow: visible;
}

/* Пока идёт сборка — режем по рамке самой карты. Без этого фрагменты
   летят через весь первый экран поверх заголовка: обрезает их только
   .ru-map, а он растянут на всю секцию. «Из-за кадра» должно значить
   из-за края карты, а не из-за края страницы. */
.ru-map[data-wave] svg { overflow: hidden; }

/* Регион по умолчанию: светлая заливка, читается как силуэт страны */
.ru-region {
  fill: var(--line);
  transition: fill var(--t-hover) ease;
}

/* Регион, где есть проекты. Цвет не единственный носитель смысла:
   рядом в тексте стоит число регионов, а сама карта aria-hidden. */
.ru-region[data-has-projects] {
  fill: var(--cyan);
}

/* Под курсором — красный.
   Регион ищет скрипт геометрией и вешает data-hover: поверх карты
   лежит текст героя, и :hover до неё просто не доходит. Карта остаётся
   pointer-events:none, чтобы заголовок можно было выделить мышью. */
.ru-region[data-hover] { fill: var(--red); }

/* ── Сборка карты ──
   Регионы влетают из-за кадра и сходятся на свои места. Вектор
   разлёта, поворот и задержку считает скрипт: направление у каждого
   своё, от центра карты к самому фрагменту.

   Скрытое состояние включается только после того, как скрипт
   всё разметил. Не отработал — карта осталась статичной и целой.

   Переход объявлен в состоянии 'run', а не в 'ready': браузер берёт
   описание перехода из стиля, который действует ПОСЛЕ смены значения.
   Пока оно стояло в 'ready', на opacity не оставалось ни одной строки
   перехода — побеждало базовое `transition: fill` у .ru-region,
   и фрагменты появлялись разом. */
.ru-map[data-wave='ready'] .ru-region {
  opacity: 0;
  transform: translate(var(--fly-x, 0), var(--fly-y, 0)) rotate(var(--fly-r, 0deg));
}

.ru-map[data-wave='run'] .ru-region {
  opacity: 1;
  transform: none;
  /* Длинной записью, а не сокращением: у свойств разные задержки
     и длительности, в сокращении это читается неверно. Порядок
     значений совпадает с порядком в transition-property. */
  transition-property: opacity, transform, fill;
  transition-duration: 0.34s, 0.7s, var(--t-hover);
  /* Прозрачность набирается быстрее перелёта: фрагмент виден почти
     сразу и весь путь читается как движение, а не как проявление
     в конечной точке. Для перелёта — торможение к месту. */
  transition-timing-function: ease, var(--ease), ease;
  transition-delay: var(--wave-delay, 0ms), var(--wave-delay, 0ms), 0ms;
}

/* Поворот вокруг центра самого фрагмента, а не начала координат SVG:
   без fill-box остров у края улетал бы по дуге через весь кадр. */
.ru-region {
  transform-box: fill-box;
  transform-origin: center;
}

/* ── Сеть узлов ── */
.ru-net { pointer-events: none; }
.ru-net__link {
  stroke: var(--ink-3);
  stroke-width: 1;
  opacity: 0.22;
}
.ru-net__node {
  fill: var(--ink-3);
  opacity: 0.45;
  transition: r var(--t-hover) var(--ease), fill var(--t-hover) ease, opacity var(--t-hover) ease;
}
.ru-net__node[data-near='1'] {
  fill: var(--red);
  opacity: 1;
}
.ru-net__pulse { fill: var(--red); }

/* ── Движение выключено: карта статична и полностью отрисована ──
   Не «ускоренная анимация», а её отсутствие. */
@media (prefers-reduced-motion: reduce) {
  .ru-map[data-wave='ready'] .ru-region,
  .ru-map[data-wave='run'] .ru-region {
    opacity: 1;
    transition: none;
  }
  .ru-net { display: none; }
}

/* ── Режим для слабовидящих: сеть убирается, карта остаётся ── */
html[data-mono='on'] .ru-net { display: none; }

@media (max-width: 900px) {
  .ru-map { align-items: flex-start; justify-content: center; opacity: 0.55; }
  .ru-map svg { width: 150%; margin-top: -4%; }
  .ru-net { display: none; }
}
