/* ═══ ВРАЩАЮЩИЙСЯ ГЛОБУС ═══════════════════════════════════════════════
   Перенесён с главной страницы Reactr (reactr.tech), собран заново
   и отвязан от чужих ссылок 12 сентября 2026.

   Как устроен. Никакой трёхмерной графики нет, всё держится на двух
   приёмах. Первый: круглая маска, внутри которой лежит картинка карты
   Земли шириной в два круга. Второй: эта картинка непрерывно едет вбок
   и, дойдя до повтора, начинает круг заново. Глаз читает это как
   вращение шара. Картинка своя, лежит рядом файлом earth-nightmap.jpg
   (ночная сторона Земли, огни городов), исходник взят у бесплатного
   астрономического архива Solar System Scope.

   Настройки вынесены наверх, в переменные. Шар чёрно-белый по решению
   владельца 13 сентября 2026: свечение белое, карта обесцвечена. Раньше
   свечение брало акцентный оранжевый из палитры макета, в исходнике на
   Reactr было салатовым. Меняется одной строкой.

   Все классы начинаются с globe- и живут только здесь.
   ══════════════════════════════════════════════════════════════════════ */

.globe-visual {
  /* ── Настройки ────────────────────────────────────────────────────── */
  --globe-glow: #ffffff;              /* цвет свечения и ободка */
  --globe-turn: 80s;                  /* полный оборот, по умолчанию 80 секунд */
  --globe-size: 60vw;                 /* размер шара относительно ширины экрана */
  --globe-max: 750px;                 /* но не больше этого */
  --globe-map: url("earth-nightmap.jpg");
  --globe-opacity: .35;               /* насколько ярко видна сама карта */
  /* ─────────────────────────────────────────────────────────────────── */

  position: relative;
  width: var(--globe-size);
  height: var(--globe-size);
  max-width: var(--globe-max);
  max-height: var(--globe-max);
  pointer-events: none; /* шар декоративный, мышь его не замечает */
  overflow: visible;
}

/* Мягкое сияние вокруг шара. Вынесено отдельным слоем под ним,
   чтобы не резалось круглой маской. */
.globe-visual::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow:
    0 0 25px color-mix(in srgb, var(--globe-glow) 12%, transparent),
    0 0 15px color-mix(in srgb, var(--globe-glow) 15%, transparent);
  z-index: -1;
  pointer-events: none;
}

/* Круглая маска. Всё, что выходит за круг, обрезается. */
.globe-container {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: inset 0 0 40px color-mix(in srgb, var(--globe-glow) 5%, transparent);
  -webkit-mask-image: -webkit-radial-gradient(white, black); /* лечит рваный край круга в Safari */
}

/* Сам шар. Наклонён на 23,5 градуса, как настоящая земная ось. */
.globe-sphere {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: #000;
  overflow: hidden;
  transform: rotate(23.5deg);
  box-shadow: inset 0 0 40px color-mix(in srgb, var(--globe-glow) 30%, transparent);
}

/* Карта Земли. Ширина двойная, поэтому при сдвиге на один круг
   рисунок стыкуется сам с собой и шов не виден. */
.globe-map {
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 100%;
  background-image: var(--globe-map);
  background-size: 50% 100%;
  background-repeat: repeat-x;
  background-position: 35% 0;
  opacity: var(--globe-opacity);
  filter: grayscale(1) brightness(1.15) contrast(1.15);
  animation: globeTurn var(--globe-turn) linear infinite;
  will-change: transform;
  backface-visibility: hidden;
  transform: translateZ(0); /* просит видеокарту крутить это плавно */
}

/* Затемнение по краю и блик сверху слева. Из-за них плоский круг
   начинает читаться как объёмный шар. */
.globe-overlay {
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 30%,
      color-mix(in srgb, var(--globe-glow) 12%, transparent) 0%,
      transparent 45%,
      rgba(0, 0, 0, .9) 85%),
    radial-gradient(circle at center,
      transparent 60%,
      color-mix(in srgb, var(--globe-glow) 10%, transparent) 100%);
  z-index: 2;
}

@keyframes globeTurn {
  0%   { background-position: 35% 0; }
  100% { background-position: 135% 0; }
}

/* На телефоне шар вырастает и уходит вниз за край экрана,
   работая фоном под текстом, а не картинкой рядом с ним. */
@media (max-width: 768px) {
  .globe-visual {
    --globe-size: 120vw;
  }
}

/* Если человек в системе отключил анимацию, шар замирает.
   Картинка остаётся, движение уходит. */
@media (prefers-reduced-motion: reduce) {
  .globe-map { animation: none; }
}

/* ═══ ЛЕТАЮЩИЕ ПЛАТЕЖИ ПО ШАРУ ═════════════════════════════════════════
   Вторая половина картины, добавлена 13 сентября 2026.

   Как читается. В случайном месте шара вспыхивает сумма, тут же
   схлопывается в яркую точку, и точка улетает по прямой, вытягивая за
   собой светящийся хвост. Через пару секунд всё гаснет, а на её месте
   рождается следующая. Платежей одновременно несколько, поэтому шар
   выглядит живым.

   Сами платежи рождает скрипт globe.js, разметки у них нет. Всё, что
   ниже, описывает как они выглядят и как двигаются.

   Платежи живут внутри круглой маски шара, поэтому за его край не
   вылетают и обрезаются по кругу.
   ══════════════════════════════════════════════════════════════════════ */

/* Держатель одного платежа. Стоит там, где платёж родился, и повёрнут
   в ту сторону, куда полетит. */
.globe-tx {
  position: absolute;
  opacity: 0;
  transform-origin: center center;
  z-index: 10;
}

/* Сумма. Поворот держателя ей компенсируют обратным поворотом, иначе
   цифры стояли бы боком. Шрифт берётся тот же, что у макета. */
.globe-tx-amount {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--globe-glow, #ffffff);
}

/* Летящая часть. Хвост выложен справа налево, поэтому точка всегда
   идёт впереди, а хвост тянется позади неё. */
.globe-tx-move {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -2px;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
}

/* Сама точка платежа. Белая сердцевина с цветным ореолом. */
.globe-tx-point {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 12px var(--globe-glow, #ffffff), 0 0 4px #fff;
  flex-shrink: 0;
  z-index: 2;
}

/* Хвост. Начинается нулевой длины и вытягивается по ходу полёта. */
.globe-tx-trail {
  width: 0;
  height: 1.5px;
  transform-origin: right center;
  background: linear-gradient(to right,
    transparent,
    color-mix(in srgb, var(--globe-glow, #ffffff) 90%, transparent));
}

/* Общее появление и угасание платежа. */
@keyframes globeTxLife {
  0%   { opacity: 0; }
  5%   { opacity: 1; }
  95%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Полёт. Первую четверть времени платёж стоит на месте, пока читается
   сумма, и только потом срывается. */
@keyframes globeTxSlide {
  0%, 25% { transform: translate(0); }
  100%    { transform: translate(var(--globe-tx-dist)); }
}

/* Вытягивание хвоста, ровно в такт полёту. */
@keyframes globeTxTrail {
  0%, 25% { width: 0; opacity: 0; }
  30%     { opacity: 1; }
  100%    { width: var(--globe-tx-dist); opacity: .9; }
}

/* Жизнь суммы. Проявляется из размытия, держится, схлопывается в ноль
   ровно к моменту, когда точка срывается в полёт. */
@keyframes globeTxAmount {
  0%   { opacity: 0; transform: var(--globe-tx-base) scale(1.2); filter: blur(2px); }
  5%   { opacity: 1; transform: var(--globe-tx-base) scale(1);   filter: blur(0); }
  20%  { opacity: 1; transform: var(--globe-tx-base) scale(1); }
  30%  { opacity: 0; transform: var(--globe-tx-base) scale(0); }
  100% { opacity: 0; transform: var(--globe-tx-base) scale(0); }
}
