/* components/map.css
   Interactive world map.

   Part of assets/css/. The load order lives in
   inc/setup.php - add new files there, not with @import. */

.globe {
	position: relative;
	width: 100%;
	background:
		radial-gradient(120% 90% at 78% 18%, rgba(46, 85, 200, 0.07), transparent 60%),
		linear-gradient(180deg, #FCFDFE 0%, #F1F4FA 100%);
	border: 1px solid var(--line);
	overflow: hidden;
}

/* The panel and its land are painted immediately - fading the whole .globe in on
   scroll left the section looking empty until you reached it. Only the blue office
   fills, pins, arcs and labels wait for .is-live. */
/* Faint graticule so the panel does not read as flat paper. */
.globe::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(to right, rgba(25, 29, 126, 0.05) 1px, transparent 1px),
		linear-gradient(to bottom, rgba(25, 29, 126, 0.05) 1px, transparent 1px);
	background-size: 58px 58px;
	pointer-events: none;
	z-index: 0;
}

/* Brand bars in the corner, echoing the hero. */
.globe::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 132px;
	height: 4px;
	background: linear-gradient(90deg, var(--red) 0 33.33%, var(--blue) 33.33% 66.66%, var(--green) 66.66% 100%);
	z-index: 3;
}

.globe-canvas { position: relative; z-index: 1; width: 100%; aspect-ratio: 16 / 10; min-height: 340px; }

.globe-fallback { width: 100%; height: auto; display: block; }

.globe .jvm-container { background: transparent !important; }

.globe-layer { pointer-events: none; }

/* Country name on hover. The library's own tooltip, restyled off its default purple.
   The library appends it to <body> with no z-index, and .globe-canvas sits at z-index 1,
   so without this the label is painted underneath the countries it is naming. 40 clears
   the map and still passes under the sticky header at 50. */
.jvm-tooltip {
	z-index: 40;
	border-radius: 0;
	background: var(--night);
	border: 1px solid rgba(255, 255, 255, 0.16);
	font-family: Poppins, Helvetica, Arial, sans-serif;
	font-size: 11.5px;
	font-weight: 500;
	letter-spacing: 0.04em;
	padding: 7px 11px;
	box-shadow: 0 10px 26px rgba(14, 16, 48, 0.22);
	transform: translateY(-4px);
	pointer-events: none;
}

/* Office countries fill one after another. */
.globe .jvm-region { transition: fill 0.55s ease; }

.globe .jvm-region.is-office { fill: #D7DCE8; }

.globe.is-live .jvm-region.is-office {
	fill: #2E55C8;
	transition-delay: calc(0.25s + var(--i, 0) * 0.13s);
}

/* Office countries and pins are hoverable, so say so. The library's own grey hover
   loses to the blue above, which left these with no feedback at all. */
.globe.is-live .jvm-region.is-office,
.globe circle.jvm-marker { cursor: pointer; }

.globe.is-live .jvm-region.is-office:hover {
	fill: #1F07B5;
	transition-delay: 0s;
}

/* --- routes --- */
.globe-arc-glow {
	fill: none;
	stroke: var(--red);
	stroke-width: 8;
	stroke-linecap: round;
	opacity: 0;
	transition: opacity 0.5s ease;
}

.globe.is-live .globe-arc-glow {
	opacity: 0.1;
	transition-delay: calc(0.95s + var(--i, 0) * 0.16s);
}

.globe-arc {
	fill: none;
	stroke: var(--red);
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-dasharray: 6 7;
	stroke-dashoffset: var(--arc-len);
	opacity: 0;
	transition: stroke-width 0.2s ease, stroke 0.2s ease, opacity 0.3s ease;
}

.globe.is-live .globe-arc {
	animation:
		globe-draw 1.15s cubic-bezier(0.4, 0, 0.2, 1) calc(0.85s + var(--i, 0) * 0.16s) forwards,
		globe-flow 1.1s linear calc(2.1s + var(--i, 0) * 0.16s) infinite;
}

.globe-arc.is-active { stroke-width: 3.2; stroke: #9E0000; }

@keyframes globe-draw {
	from { stroke-dashoffset: var(--arc-len); opacity: 0; }
	30%  { opacity: 0.92; }
	to   { stroke-dashoffset: 0; opacity: 0.92; }
}

@keyframes globe-flow {
	from { stroke-dashoffset: 0; }
	to   { stroke-dashoffset: -26; }
}

/* A light running the route, positioned from JS. */
.globe-spark {
	fill: #fff;
	stroke: var(--red);
	stroke-width: 2.4;
	opacity: 0;
	filter: drop-shadow(0 0 5px rgba(199, 0, 0, 0.75));
}

/* --- pins --- */
.globe circle.jvm-marker {
	opacity: 0;
	transform-box: fill-box;
	transform-origin: 50% 100%;
	cursor: pointer;
	transition: r 0.22s cubic-bezier(0.34, 1.56, 0.64, 1), stroke-width 0.2s ease, opacity 0.25s ease;
}

.globe.is-live circle.jvm-marker {
	animation: globe-pin 0.68s cubic-bezier(0.22, 1.4, 0.36, 1) calc(1.35s + var(--i, 0) * 0.11s) forwards;
}

.globe circle.jvm-marker.is-hub { r: 9; }

.globe circle.jvm-marker.is-active { r: 10.5; stroke-width: 3; }

@keyframes globe-pin {
	0%   { opacity: 0; transform: translateY(-20px) scale(0.35); }
	65%  { opacity: 1; transform: translateY(0) scale(1.22); }
	100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* Radar rings on the hub. */
.globe-radar {
	fill: none;
	stroke: var(--red);
	stroke-width: 1.6;
	opacity: 0;
}

.globe.is-live .globe-radar {
	animation: globe-radar 3.2s ease-out calc(2.4s + var(--i, 0) * 1.05s) infinite;
}

@keyframes globe-radar {
	0%   { r: 7; opacity: 0.5; stroke-width: 1.8; }
	70%  { opacity: 0; }
	100% { r: 42; opacity: 0; stroke-width: 0.4; }
}

/* --- labels: country, city and role printed on the map, no hover needed --- */
.globe-label-text {
	font-family: Poppins, sans-serif;
	paint-order: stroke;
	stroke: #fff;
	stroke-width: 3.6px;
	stroke-linejoin: round;
}

.globe-label { opacity: 0; }

.globe.is-live .globe-label {
	animation: globe-label 0.55s ease calc(1.75s + var(--i, 0) * 0.11s) forwards;
}

.lbl-country { font-size: 12.5px; font-weight: 700; fill: var(--red); letter-spacing: 0.01em; }

.lbl-city    { font-size: 12px; font-weight: 600; fill: var(--navy); }

.lbl-role    { font-size: 11px; font-weight: 400; fill: #5A6070; }

@keyframes globe-label {
	from { opacity: 0; transform: translateY(6px); }
	to   { opacity: 1; transform: translateY(0); }
}

/* Hovering or selecting lifts one label clear of the rest. */
.globe-label { transition: opacity 0.2s ease; }

/* !important is needed: the reveal animation uses fill-mode forwards, and an
   animated value beats a normal declaration. Only !important outranks it. */
.globe.is-focused .globe-label:not(.is-active) { opacity: 0.22 !important; }

.globe-label.is-active .lbl-country { fill: #9E0000; }

.globe-label.is-active .globe-label-text { stroke-width: 4.2px; }

/* Dim everything but the highlighted route. */
.globe.is-focused circle.jvm-marker:not(.is-active) { opacity: 0.3; }

.globe.is-focused .globe-arc:not(.is-active) { opacity: 0.15; }

.globe.is-focused .globe-arc-glow { opacity: 0.04; }

@media (prefers-reduced-motion: reduce) {
	.globe circle.jvm-marker { opacity: 1; animation: none !important; }

	.globe-label { opacity: 1; animation: none !important; }

	.globe-arc { opacity: 0.9; stroke-dashoffset: 0; animation: none !important; }

	.globe-arc-glow { opacity: 0.1; }

	.globe-radar,
		.globe-spark { display: none; }

	.globe .jvm-region { transition: none; }
}

@media (max-width: 680px) {
	.globe-canvas { aspect-ratio: 4 / 3; }

	.lbl-country { font-size: 10.5px; }

	.lbl-city { font-size: 10px; }

	.lbl-role { display: none; }

	/* the cards below carry the role on small screens */
	.globe::after { width: 96px; }
}

/* Give touch gestures back to the page.
   jsvectormap.min.css declares touch-action: none, which tells the browser the element
   handles every gesture itself. That was true while the library's own touch handlers
   were bound; globe.js now passes bindTouchEvents: false, so nothing handles them and a
   finger that landed on the map simply did nothing - the page would not scroll under it.
   The vendor stylesheet loads before this one, so these win.
   The library sets it on a bare `svg`, not just its own container, so on the contact
   page it was silencing every other icon on the page as well. */
.jvm-container,
.jvm-container svg,
svg {
	touch-action: auto;
}
