/* =========================================================
   CLICKRONIX GLOBE COLOR CONTROLS

   Change these variables to recolor the entire globe.
   ========================================================= */

:root {
  /* Globe inner surface */
  --globe-inner-highlight: 255, 255, 255;
  --globe-inner-light: 242, 242, 244;
  --globe-inner-middle: 211, 212, 216;
  --globe-inner-shadow: 164, 166, 172;
  --globe-inner-edge: 108, 111, 119;

  /* Map and geographic dots */
  --globe-map-dot: 8, 9, 12;
  --globe-map-dot-opacity: 0.92;

  /* Highlighted map dots */
  --globe-accent-dot: 255, 102, 0;
  --globe-accent-dot-opacity: 0.95;

  /* Live IP location dots */
  --globe-ip-dot: 10, 10, 12;
  --globe-ip-ring: 255, 102, 0;
  --globe-ip-glow: 255, 102, 0;

  /* Network connection lines */
  --globe-line: 255, 102, 0;
  --globe-line-opacity: 0.92;
  --globe-line-glow: 255, 102, 0;

  /* Animated moving dots on connections */
  --globe-moving-dot: 255, 255, 255;
  --globe-moving-dot-secondary: 255, 102, 0;

  /* Outside orbit rings */
  --globe-orbit: 255, 145, 80;
  --globe-orbit-opacity: 0.22;
  --globe-orbit-dashed-opacity: 0.14;

  /* Globe outline */
  --globe-border: 255, 145, 70;
  --globe-border-opacity: 0.68;

  /* Globe exterior glow */
  --globe-glow: 255, 102, 0;
  --globe-glow-opacity: 0.20;

  /* Background particles */
  --globe-particle: 255, 153, 74;

  /* Live label */
  --globe-label-bg: 18, 18, 21;
  --globe-label-border: 255, 140, 70;
  --globe-label-text: 240, 240, 242;
  --globe-label-accent: 255, 102, 0;
}

/* =========================================================
   GLOBE CONTAINER
   ========================================================= */

.globe-stage {
  position: relative;

  width: min(100%, 670px);
  aspect-ratio: 1;

  display: grid;
  place-items: center;

  border-radius: 50%;

  user-select: none;
  touch-action: none;

  /*
   * Allows the canvas and labels to remain visible
   * without creating a solid background circle.
   */
  isolation: isolate;
}

/* Remove old background circles */
.globe-stage::before,
.globe-stage::after {
  content: none;
}

/* =========================================================
   CANVAS
   ========================================================= */

.globe {
  position: relative;
  z-index: 2;

  display: block;
  width: 100%;
  height: 100%;

  cursor: grab;
  opacity: 0;

  border-radius: 50%;

  transition:
    opacity 0.8s ease,
    filter 0.35s ease;

  filter:
    drop-shadow(
      0 0 24px
      rgba(
        var(--globe-glow),
        var(--globe-glow-opacity)
      )
    );
}

.globe.ready {
  opacity: 1;
}

.globe:active {
  cursor: grabbing;
}

/* Slightly increase glow while hovering */
.globe-stage:hover .globe {
  filter:
    drop-shadow(
      0 0 30px
      rgba(
        var(--globe-glow),
        calc(var(--globe-glow-opacity) + 0.06)
      )
    );
}

/* =========================================================
   OUTSIDE ORBIT RINGS
   ========================================================= */

.globe-ring {
  position: absolute;
  inset: 10%;
  z-index: 1;

  border:
    1px solid
    rgba(
      var(--globe-orbit),
      var(--globe-orbit-opacity)
    );

  border-radius: 50%;

  pointer-events: none;

  animation:
    globe-orbit-spin 24s linear infinite;
}

.globe-ring::before,
.globe-ring::after {
  content: "";
  position: absolute;

  border:
    1px dashed
    rgba(
      var(--globe-orbit),
      var(--globe-orbit-dashed-opacity)
    );

  border-radius: 50%;
}

.globe-ring::before {
  inset: -10%;
  transform: rotate(62deg);
}

.globe-ring::after {
  inset: 9%;
  transform: rotate(-34deg);
}

/* Optional extra orbit */
.globe-ring-extra {
  position: absolute;
  inset: 3%;
  z-index: 1;

  border:
    1px solid
    rgba(
      var(--globe-orbit),
      0.09
    );

  border-radius: 50%;

  pointer-events: none;

  animation:
    globe-orbit-spin-reverse
    34s linear infinite;
}

/* =========================================================
   LIVE IP LABELS
   ========================================================= */

.globe-label {
  position: absolute;
  z-index: 5;

  display: flex;
  align-items: center;
  gap: 7px;

  padding: 7px 11px;

  color:
    rgb(var(--globe-label-text));

  background:
    rgba(
      var(--globe-label-bg),
      0.88
    );

  border:
    1px solid
    rgba(
      var(--globe-label-border),
      0.36
    );

  border-radius: 8px;

  box-shadow:
    0 10px 28px rgba(0, 0, 0, 0.30),
    0 0 18px
      rgba(
        var(--globe-label-accent),
        0.10
      );

  font:
    600 0.66rem
    ui-monospace,
    SFMono-Regular,
    Menlo,
    Monaco,
    Consolas,
    monospace;

  white-space: nowrap;
  pointer-events: none;

  transform:
    translate(-50%, -120%)
    scale(0.96);

  opacity: 0;

  transition:
    opacity 0.25s ease,
    filter 0.25s ease,
    transform 0.25s ease;
}

.globe-label.visible {
  opacity: 1;

  transform:
    translate(-50%, -120%)
    scale(1);
}

/* Pulsing live indicator */
.globe-label i {
  width: 7px;
  height: 7px;
  flex: 0 0 7px;

  border-radius: 50%;

  background:
    rgb(var(--globe-label-accent));

  box-shadow:
    0 0 11px
    rgb(var(--globe-label-accent));

  animation:
    globe-live-pulse
    1.5s ease-in-out infinite;
}

.globe-label b {
  color:
    rgb(var(--globe-label-accent));

  font-size: 0.61rem;
  letter-spacing: 0.08em;
}

.globe-label span {
  padding-left: 7px;

  color:
    rgb(var(--globe-label-text));

  font-weight: 500;

  border-left:
    1px solid
    rgba(255, 255, 255, 0.16);
}

.globe-status {
  display: none;
}

/* =========================================================
   ANIMATIONS
   ========================================================= */

@keyframes globe-live-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }

  50% {
    opacity: 0.48;
    transform: scale(0.82);
  }
}

@keyframes globe-orbit-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes globe-orbit-spin-reverse {
  to {
    transform: rotate(-360deg);
  }
}

/* =========================================================
   RESPONSIVE GLOBE
   ========================================================= */

@media (max-width: 1160px) {
  .globe-stage {
    max-width: 600px;
  }
}

@media (max-width: 1020px) {
  .globe-stage {
    max-width: 570px;
  }
}

@media (max-width: 600px) {
  .globe-stage {
    width: 430px;
    max-width: 118vw;
    margin-left: -9vw;
  }

  .globe-label {
    padding: 6px 8px;
    font-size: 0.54rem;
  }

  .globe-label:nth-of-type(n + 5) {
    display: none;
  }
}

/* =========================================================
   REDUCED MOTION
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
  .globe-ring,
  .globe-ring-extra,
  .globe-label i {
    animation: none !important;
  }

  .globe-label,
  .globe {
    transition: none !important;
  }
}
