/* Interactive Map — layout, transitions, pan/zoom, a11y polish. */

.interactive-map {
	position: relative;
	width: 100%;
	aspect-ratio: 2560 / 1770;
	margin: 0 auto;
	background: #1a1a1a;
	overflow: hidden;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* Host embed: the Webflow `.map-container > .w-embed` slot. On mobile that
   slot flips to a tall portrait box (aspect-ratio ~1000/2000) while the map
   keeps its native 2560:1770 landscape ratio, so by default it only fills a
   short strip at the top and leaves the slot half empty. Fill the slot's
   full height instead and let the overflowing width be clipped and panned
   sideways — the same cover-in-a-slot trick the single-property map uses,
   reachable at scale 1 via PanZoom's cropped-slot pan slack (see
   interactive-map.js `_getVisibleBounds` / `_hasPanSlack`). On desktop the
   slot already matches 2560:1770, so these rules resolve to a no-op.

   Note: `.map-container` / `.w-embed` are host (Webflow) classes, so this is
   the one place the portable component knows about its host. Harmless if the
   directory is ever copied elsewhere — the selectors simply won't match. */
.map-container .w-embed:has(> .interactive-map) {
	position: relative;
	height: 100%;
	overflow: hidden;
}

.map-container .w-embed > .interactive-map {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	min-width: 100%;
	min-height: 100%;
	width: auto;
	height: auto;
	max-width: none;
	max-height: none;
	aspect-ratio: 2560 / 1770;
	margin: 0;
}

/* Viewport: clipping container. Stage transforms inside it. */
.interactive-map-viewport {
	position: absolute;
	inset: 0;
	overflow: hidden;
	touch-action: none;
}

/* Stage: this is what pan/zoom transforms. Everything geographic lives here. */
.interactive-map-stage {
	position: absolute;
	inset: 0;
	transform: translate(0, 0) scale(1);
	transform-origin: 0 0;
	transition: transform 0.18s ease-out;
	will-change: transform;
}

/* Drop the transition while a pan is in progress so the drag tracks the pointer. */
.interactive-map.is-panning .interactive-map-stage {
	transition: none;
}

/* Reduced-motion users get instant transforms on the stage too. */
.interactive-map.is-reduced-motion .interactive-map-stage {
	transition: none;
}

.interactive-map-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.interactive-map-regions {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	cursor: pointer;
}

.interactive-map-regions polygon {
	fill: rgba(255, 255, 255, 0.05);
	stroke: rgba(255, 255, 255, 0.3);
	stroke-width: 4;
	transition: fill 0.15s ease, stroke 0.15s ease;
	outline: none;
}

.interactive-map-regions polygon:hover {
	fill: rgba(255, 255, 255, 0.15);
	stroke: rgba(255, 255, 255, 0.6);
}

.interactive-map-regions polygon:focus-visible {
	fill: rgba(255, 255, 255, 0.2);
	stroke: #fff;
	stroke-width: 6;
}

.interactive-map-markers {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.interactive-map-marker {
	position: absolute;
	width: 20px;
	height: 20px;
	margin-left: -10px;
	margin-top: -10px;
	background: #ea5549;
	border: 3px solid white;
	border-radius: 50%;
	cursor: pointer;
	pointer-events: auto;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
	transition: transform 0.15s ease;
	outline: none;
	/* Counter the stage's zoom so the marker keeps a constant on-screen
	   size. --im-mscale is 1/scale, published by the pan/zoom helper;
	   defaults to 1 before the first transform. Origin stays centred on
	   the marker's geo anchor so the pin doesn't drift when it rescales. */
	transform: scale(var(--im-mscale, 1));
	transform-origin: 50% 50%;
}

/* Keep the counter-scale glued to the pointer while panning/pinching, the
   same way the stage drops its transition (see .is-panning above). */
.interactive-map.is-panning .interactive-map-marker,
.interactive-map.is-reduced-motion .interactive-map-marker {
	transition: none;
}

/* Generous touch hit area without changing the visual size. 44x44 is the
   Apple HIG / WCAG minimum for tap targets. */
.interactive-map-marker::before {
	content: "";
	position: absolute;
	inset: 50% 50%;
	width: 44px;
	height: 44px;
	margin-left: -22px;
	margin-top: -22px;
	background: transparent;
}

.interactive-map-marker:hover {
	transform: scale(calc(1.3 * var(--im-mscale, 1)));
}

.interactive-map-marker:focus-visible {
	box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.95), 0 0 0 6px #2563eb, 0 2px 8px rgba(0, 0, 0, 0.4);
}

/* Inert markers (placeholder, no URL): visually distinct from authored pins
 * so a viewer reads them as "coming soon" rather than broken/unclickable.
 * Squarer chrome, dashed accent ring, no pointer cursor, no hover lift. */
.interactive-map-marker--inert {
	background: rgba(255, 255, 255, 0.92);
	border: 2px dashed rgba(60, 60, 60, 0.85);
	border-radius: 4px;
	width: 18px;
	height: 18px;
	margin-left: -9px;
	margin-top: -9px;
	cursor: default;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.interactive-map-marker--inert::after {
	content: "";
	position: absolute;
	inset: 3px;
	background: rgba(80, 80, 80, 0.55);
	border-radius: 2px;
}

.interactive-map-marker--inert:hover {
	transform: scale(var(--im-mscale, 1));
}

/* Inert label is always faintly visible — explicit placeholder semantics
 * so stakeholders know these are intentional pre-content, not broken UI. */
.interactive-map-marker--inert .interactive-map-marker__label {
	opacity: 0.85;
	transform: translateX(-50%) translateY(-12px);
	font-size: 11px;
	background: rgba(40, 40, 40, 0.78);
	font-style: italic;
}

.interactive-map-marker--inert .interactive-map-marker__label::after {
	content: " · placeholder";
	opacity: 0.7;
	font-style: normal;
	font-weight: 400;
}

.interactive-map-marker--inert:hover .interactive-map-marker__label {
	opacity: 1;
}

.interactive-map-marker__label {
	position: absolute;
	bottom: 100%;
	left: 50%;
	transform: translateX(-50%) translateY(-8px);
	background: #2E3364;
	background-color: #2E3364;
	color: white;
	padding: 4px 10px;
	font-size: 12px;
	font-weight: 600;
	border-radius: 0 !important;
	white-space: nowrap;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.15s ease;
}

/* Defensive — ensure the always variant inherits the navy fill +
 * 600 weight even if a future rule scopes only to `--always`. */
.interactive-map-marker__label--always.interactive-map-marker__label {
	background-color: #2E3364;
	font-weight: 600;
	border-radius: 0 !important;
}

.interactive-map-marker:hover .interactive-map-marker__label,
.interactive-map-marker:focus-visible .interactive-map-marker__label {
	opacity: 1;
}

/* Lift the hovered/focused marker above its neighbours so the label
   doesn't end up tucked behind an adjacent marker's icon. Siblings
   keep z-index: auto, so unhovered markers stack in DOM order. */
.interactive-map-marker:hover,
.interactive-map-marker:focus-visible {
	z-index: 3;
}

/* Always-visible label variant for residential/commercial markers.
 * Project markers should be recognisable at a glance — no hover required.
 * On hover the label grows + brightens (instead of the pin scaling),
 * and the underlying pin shifts colour as a feedback cue. */
.interactive-map-marker__label--always {
	opacity: 1;
	transform-origin: bottom center;
	transition: transform 0.15s ease, background 0.15s ease, padding 0.15s ease;
}

.interactive-map-marker:has(.interactive-map-marker__label--always):hover {
	transform: scale(var(--im-mscale, 1));
}

.interactive-map-marker:has(.interactive-map-marker__label--always):hover .interactive-map-marker__label--always,
.interactive-map-marker:has(.interactive-map-marker__label--always):focus-visible .interactive-map-marker__label--always,
.interactive-map-marker--polygon-label.is-poly-hover .interactive-map-marker__label--always {
	transform: translateX(-50%) translateY(-12px) scale(1.15);
	background: #2E3364;
	padding: 5px 12px;
}

/* Polygon (shape) markers — suppress the default browser focus
 * rectangle that lingers after the user clicks a polygon and a modal
 * (re)takes / returns focus to it. Keyboard users keep an indicator
 * via the :focus-visible rule below. */
.interactive-map-marker-polygons polygon:focus {
	outline: none;
}

.interactive-map-marker-polygons polygon:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

/* Polygon (shape) markers for residential/commercial — always-on
 * red-tinted highlight (Karoline's spec). Same tint for both kinds
 * so a building's footprint reads as "this is the building" rather
 * than as a per-type colour cue (the floating label already carries
 * type colour). Drill-shape polygons share the look on hover/focus
 * (rules below) — same tint, but only when the user reaches them. */
.interactive-map-marker-polygons polygon[data-link-type="building"],
.interactive-map-marker-polygons polygon[data-link-type="commercial_building"] {
	fill: rgba(234, 85, 73, 0.25) !important;
	stroke: #fff !important;
	transition: fill 0.15s ease, stroke 0.15s ease;
}

/* Cluster pin: bigger circle with a count number at its centre. Distinct
   from regular markers so a viewer reads it as "tap to expand" rather than
   "tap to navigate to one property". */
.interactive-map-marker--cluster {
	width: 36px;
	height: 36px;
	margin-left: -18px;
	margin-top: -18px;
	background: #1d4ed8;
	border: 3px solid #fff;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	font-size: 14px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}

.interactive-map-marker--cluster:hover {
	background: #1e40af;
	transform: scale(calc(1.15 * var(--im-mscale, 1)));
}

.interactive-map-marker__cluster-count {
	pointer-events: none;
}

/* Aggregate pin: same DOM as a pin marker, but bigger and visibly distinct
   from a same-state cluster (which uses --cluster). Aggregate pins represent
   the count of CONTENT markers in a child state's subtree, surfaced via a
   drill polygon authored at the parent. Click → drills into the child. */
.interactive-map-marker--aggregate {
	width: 40px;
	height: 40px;
	margin-left: -20px;
	margin-top: -20px;
	background: #2563eb;
	border: 3px solid #fff;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	font-size: 15px;
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
	transition: filter 120ms ease, transform 120ms ease;
	cursor: pointer;
}

/* Mixed-subtree = blue (the base background above). Single-type
   variants use Webflow's theme vars with a hardcoded fallback in case
   the variable isn't in scope (e.g. shortcode rendered outside the
   Webflow theme cascade). */
.interactive-map-marker--aggregate-mixed {
	background: #2563eb;
}

.interactive-map-marker--aggregate-residential {
	background: var(--_main---orange-primær, #ea5549);
}

.interactive-map-marker--aggregate-commercial {
	background: var(--_main---grøn-sekundær, #62b773);
}

.interactive-map-marker--aggregate:hover {
	filter: brightness(0.92);
	transform: scale(calc(1.1 * var(--im-mscale, 1)));
}

.interactive-map-marker--aggregate .interactive-map-marker__cluster-count {
	pointer-events: none;
}

/* Custom marker with an inline-SVG icon: solid black circle, white icon
   centred. Matches the reference visual on the public map (Apple-style
   landmark pins). No border, soft shadow for separation against the
   aerial backdrop. */
.interactive-map-marker--icon {
	width: 44px;
	height: 44px;
	margin-left: -22px;
	margin-top: -22px;
	background: #EEF0F7;
	border: 0;
	color: #2E3364;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}

.interactive-map-marker--icon:hover {
	transform: scale(calc(1.1 * var(--im-mscale, 1)));
}

/* Residential / Commercial pins — same icon-bearing chrome as Hotspots
   but with the type-specific Webflow colour as the fill and a white
   icon stroke (via `color: #fff` cascading into the inline SVG's
   `stroke="currentColor"`). Mirrors the admin map-editor pin look.
   Borderless per Karoline's spec — the colour-and-shadow combo is
   enough to lift the pin off the aerial backdrop. */
.interactive-map-marker--residential,
.interactive-map-marker--commercial {
	width: 44px;
	height: 44px;
	margin-left: -22px;
	margin-top: -22px;
	border: none !important;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.interactive-map-marker--residential {
	background: var(--_main---orange-primær, #ea5549);
}

.interactive-map-marker--commercial {
	background: var(--_main---grøn-sekundær, #62b773);
}

.interactive-map-marker--residential:hover,
.interactive-map-marker--commercial:hover {
	transform: scale(calc(1.1 * var(--im-mscale, 1)));
	filter: brightness(1.05);
}

.interactive-map-marker__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	color: inherit;
	pointer-events: none;
}

.interactive-map-marker__icon svg {
	width: 100%;
	height: 100%;
}

/* Badge layer: row of pill buttons anchored to the bottom of the viewport.
   Outside the transformed stage so badges don't pan/zoom with the image. */
.interactive-map-badges {
	position: absolute;
	left: 16px;
	right: 16px;
	bottom: 16px;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	pointer-events: none;
	z-index: 5;
}

.interactive-map-badge {
	pointer-events: auto;
	min-height: 44px;
	padding: 10px 18px;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 999px;
	font-family: inherit;
	font-size: 14px;
	font-weight: 500;
	cursor: pointer;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.interactive-map-badge:hover {
	background: rgba(0, 0, 0, 0.75);
	border-color: rgba(255, 255, 255, 0.6);
	transform: translateY(-1px);
}

.interactive-map-badge:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}

.interactive-map-badge__label {
	pointer-events: none;
}

/* Controls (back, reset-zoom): stacked top-left, anchored to the wrapper so
   they don't move with pan/zoom. */
.interactive-map-controls {
	position: absolute;
	top: 16px;
	left: 16px;
	z-index: 10;
	display: flex;
	flex-direction: row;
	gap: 8px;
	align-items: center;
}

/* Bottom-left control stack (reset-zoom on top, rotate at the corner). Anchored
 * to the bottom of the visible image region by _positionControls(); rotate is
 * the last child so it stays pinned to the corner as reset-zoom shows/hides
 * above it. */
.interactive-map-controls--bottom {
	top: auto;
	bottom: 16px;
}

/* Reset-zoom lives on its own at bottom-left. JS may override top/left
   via inline styles to inset into the visible region when the map is
   embedded in a smaller `overflow: hidden` slot. */
.interactive-map button.interactive-map-reset-zoom {
	position: absolute;
	bottom: 16px;
	left: 16px;
	z-index: 10;
}

/* Drill-shape polygons (link_type=state) are invisible until the
 * user hovers or focuses them. We keep pointer-events:auto on the
 * shape itself so it still catches the hover, just transparent
 * fill + stroke until then. */
.interactive-map-marker-polygons polygon.is-drill-shape {
	fill: transparent;
	stroke: transparent;
	transition: fill 0.15s ease, stroke 0.15s ease;
}

.interactive-map-marker-polygons polygon.is-drill-shape:hover,
.interactive-map-marker-polygons polygon.is-drill-shape:focus {
	fill: rgba(234, 85, 73, 0.25) !important;
	stroke: #fff !important;
	outline: none;
}

/* Custom-marker info modal. Centered over the viewport with a soft
 * dim-but-not-black backdrop; backdrop click and Esc close it. */
.interactive-map-modal {
	position: absolute;
	inset: 0;
	z-index: 50;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	box-sizing: border-box;
}

.interactive-map-modal[hidden] {
	display: none;
}

.interactive-map-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(15, 23, 42, 0.45);
	animation: im-modal-fade 0.18s ease-out;
}

.interactive-map-modal__card {
	position: relative;
	z-index: 1;
	width: min(560px, 100%);
	max-height: calc(100% - 16px);
	overflow-y: auto;
	background: #fff;
	color: #111827;
	border-radius: 0;
	padding: 24px;
	box-shadow: 0 10px 32px rgba(15, 23, 42, 0.28);
	animation: im-modal-pop 0.18s ease-out;
}

.interactive-map-modal__card:focus {
	outline: none;
}

.interactive-map-modal__close {
	position: absolute;
	top: 14px;
	right: 14px;
	width: 32px;
	height: 32px;
	padding: 0;
	margin: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: transparent;
	color: #6b7280;
	border: 0;
	box-shadow: none;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease;
	-webkit-appearance: none;
	appearance: none;
	font: inherit;
	line-height: 1;
}

.interactive-map-modal__close:hover,
.interactive-map-modal__close:focus-visible {
	background: #f3f4f6;
	color: #111827;
	outline: none;
	box-shadow: none;
}

.interactive-map-modal__close svg {
	display: block;
	width: 16px;
	height: 16px;
}

.interactive-map-modal__title {
	font-size: 22px;
	font-weight: 700;
	margin: 0 0 8px;
	letter-spacing: -0.01em;
	color: #2E3364;
}

.interactive-map-modal__body {
	font-size: 15px;
	line-height: 1.55;
	color: #374151;
	margin-bottom: 16px;
}

.interactive-map-modal__body p {
	margin: 0 0 12px;
}

.interactive-map-modal__body p:last-child {
	margin-bottom: 0;
}

.interactive-map-modal__photo {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 0;
	margin-top: 8px;
}

/* Project popover (residential/commercial) reuses the modal shell with
 * extra typography for the address line + CTA button. */
.interactive-map-modal__address {
	font-size: 13px;
	font-weight: 700;
	color: #9799B0;
	margin: -4px 0 12px;
	letter-spacing: 0.01em;
}

/* Specificity bump: the generic `.interactive-map-modal__body p` and
   `.interactive-map-modal__body p:last-child` rules above set the
   margin (12px / 0 respectively); without an element selector here
   our class-only rule (0,1,0) loses to (0,1,1) and (0,2,1). Including
   `p.interactive-map-modal__summary` lifts us to (0,2,1), and since
   we come later in the file we win against `p:last-child` too. */
.interactive-map-modal__body p.interactive-map-modal__summary {
	font-size: 15px;
	line-height: 1.55;
	color: #2E3364;
	margin: 0 0 18px !important;
}

.interactive-map-modal__cta {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 10px 18px;
	background: #EA5549;
	color: #fff;
	border-radius: 999px;
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	transition: background 0.15s ease, transform 0.12s ease;
	margin-bottom: 8px;
}

.interactive-map-modal__cta:hover,
.interactive-map-modal__cta:focus-visible {
	background: #a4332a;
	color: #fff;
	transform: translateY(-1px);
	outline: none;
}

.interactive-map-modal__photo[hidden] {
	display: none;
}

/* Property-type picker — small popover anchored above (or below) the
   clicked aggregate cluster. Two stacked buttons; colours mirror the
   marker pin fills (residential = warm red, commercial = brand green). */
.interactive-map-type-picker {
	position: absolute;
	z-index: 50;
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 180px;
	padding: 8px;
	background: #fff;
	border-radius: 12px;
	box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18), 0 2px 4px rgba(0, 0, 0, 0.08);
	animation: im-popover-pop 120ms ease-out;
}

/* Small arrow pointing at the marker. Default = arrow on bottom edge
   (popover sits above the marker). When .is-below is added by JS the
   arrow flips to the top edge. */
.interactive-map-type-picker::after {
	content: '';
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: 0;
	height: 0;
	border: 6px solid transparent;
}

.interactive-map-type-picker:not(.is-below)::after {
	bottom: -12px;
	border-top-color: #fff;
}

.interactive-map-type-picker.is-below::after {
	top: -12px;
	border-bottom-color: #fff;
}

.interactive-map-type-picker__option {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 10px 14px;
	border: 0;
	border-radius: 8px;
	color: #fff;
	font: inherit;
	text-align: left;
	cursor: pointer;
	transition: transform 100ms ease, filter 100ms ease;
}

.interactive-map-type-picker__option:hover,
.interactive-map-type-picker__option:focus-visible {
	transform: translateY(-1px);
	filter: brightness(1.05);
	outline: none;
}

.interactive-map-type-picker__option--residential {
	background: var(--_main---orange-primær, #ea5549);
}

.interactive-map-type-picker__option--commercial {
	background: var(--_main---grøn-sekundær, #62b773);
}

.interactive-map-type-picker__label {
	font-size: 15px;
	font-weight: 600;
	line-height: 1.2;
}

.interactive-map-type-picker__count {
	font-size: 13px;
	opacity: 0.88;
}

@keyframes im-popover-pop {
	from { transform: translateY(4px); opacity: 0; }
	to   { transform: translateY(0);   opacity: 1; }
}

/* Single-property unit marker — the marker that matches `unit_building`
   is rendered inert (no click, no focus styling) because its data
   lives in the always-visible bottom bar rendered as a sibling of
   the map (see akf-plugin.css `.akf-unit-bottom-bar`). */
.interactive-map-marker--unit {
	cursor: default;
}

@keyframes im-modal-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes im-modal-pop {
	from { transform: translateY(6px) scale(0.98); opacity: 0; }
	to   { transform: translateY(0)   scale(1);    opacity: 1; }
}

/* Instant-hover tooltip used by drill-shape polygon markers. Replaces
 * the SVG <title> tooltip which has a 500-1500ms browser delay.
 * Position is set via inline `left`/`top` in JS, in wrapper-relative
 * pixel space. */
.interactive-map-hover-tooltip {
	position: absolute;
	z-index: 30;
	background: rgba(20, 20, 20, 0.92);
	color: #fff;
	font-size: 12px;
	font-weight: 500;
	padding: 5px 9px;
	border-radius: 4px;
	pointer-events: none;
	white-space: nowrap;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
	transition: opacity 0.08s ease;
}

.interactive-map-hover-tooltip[hidden] {
	display: none;
}

/* Theme buttons in GeneratePress (and most themes) win the cascade by
 * default — `button.X` beats `.X`. Match their specificity (or higher)
 * on every state so the pill colour stays consistent across hover, focus,
 * active. Brand palette per Karoline: pale-blue fill, brand-blue text. */
.interactive-map button.interactive-map-back,
.interactive-map button.interactive-map-reset-zoom {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
	padding: 10px 22px 10px 18px;
	background: #EEF0F7;
	background-color: #EEF0F7;
	background-image: none;
	color: #2E3364;
	border: 0;
	border-radius: 999px;
	cursor: pointer;
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	letter-spacing: -0.01em;
	box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18), 0 1px 2px rgba(15, 23, 42, 0.08);
	transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
	-webkit-appearance: none;
	appearance: none;
	text-shadow: none;
}

.interactive-map-back__icon,
.interactive-map-rotate__icon,
.interactive-map-reset-zoom__icon {
	display: block;
	flex: 0 0 auto;
	color: #2E3364;
}

.interactive-map button.interactive-map-back:hover,
.interactive-map button.interactive-map-back:focus,
.interactive-map button.interactive-map-back:active,
.interactive-map button.interactive-map-reset-zoom:hover,
.interactive-map button.interactive-map-reset-zoom:focus,
.interactive-map button.interactive-map-reset-zoom:active {
	background: #EEF0F7;
	background-color: #EEF0F7;
	background-image: none;
	color: #2E3364;
	box-shadow: 0 3px 12px rgba(15, 23, 42, 0.22), 0 1px 2px rgba(15, 23, 42, 0.08);
	transform: translateY(-1px);
}

.interactive-map button.interactive-map-back:focus-visible,
.interactive-map button.interactive-map-reset-zoom:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: 2px;
}

.interactive-map button.interactive-map-back[hidden],
.interactive-map button.interactive-map-reset-zoom[hidden] {
	display: none;
}

/* Rotate control: centered along the bottom edge, icon stacked over a small
 * "Rotate" label. _positionControls() sets left/bottom inline to the centre of
 * the visible image region; translateX(-50%) keeps it centred on that point. */
.interactive-map button.interactive-map-rotate {
	position: absolute;
	left: 50%;
	bottom: 16px;
	transform: translateX(-50%);
	z-index: 10;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 3px;
	min-height: 0;
	padding: 8px 14px;
	background: #EEF0F7;
	background-color: #EEF0F7;
	background-image: none;
	color: #2E3364;
	border: 0;
	border-radius: 14px;
	cursor: pointer;
	font-family: inherit;
	font-size: 11px;
	font-weight: 600;
	line-height: 1;
	letter-spacing: 0.01em;
	box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18), 0 1px 2px rgba(15, 23, 42, 0.08);
	transition: box-shadow 0.15s ease, background 0.15s ease;
	-webkit-appearance: none;
	appearance: none;
	text-shadow: none;
}

.interactive-map button.interactive-map-rotate:hover,
.interactive-map button.interactive-map-rotate:focus,
.interactive-map button.interactive-map-rotate:active {
	background: #EEF0F7;
	background-color: #EEF0F7;
	color: #2E3364;
	box-shadow: 0 3px 12px rgba(15, 23, 42, 0.22), 0 1px 2px rgba(15, 23, 42, 0.08);
}

.interactive-map button.interactive-map-rotate:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: 2px;
}

.interactive-map button.interactive-map-rotate[hidden] {
	display: none;
}

/* Compass: north indicator. Lives inside the top-left controls row, after the
 * Back button, and flows with it. updateCompass() rotates the needle to point
 * at the scene's true north for the current state; the coral tip is north. */
.interactive-map-compass {
	position: relative;
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #EEF0F7;
	border-radius: 999px;
	box-shadow: 0 2px 8px rgba(15, 23, 42, 0.18), 0 1px 2px rgba(15, 23, 42, 0.08);
	pointer-events: none;
}

.interactive-map-compass[hidden] {
	display: none;
}

.interactive-map-compass__needle {
	display: block;
	transform: rotate(0deg);
	transform-origin: 50% 50%;
	transition: transform 0.4s ease;
}

.interactive-map-compass__north {
	fill: #EA5549;
}

.interactive-map-compass__south {
	fill: #C2C7DA;
}

/* Toast: sits above badges, hidden by default. */
.interactive-map-toast {
	position: absolute;
	left: 50%;
	bottom: 80px;
	transform: translateX(-50%);
	max-width: calc(100% - 32px);
	padding: 12px 18px;
	background: rgba(20, 20, 20, 0.92);
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.2);
	border-radius: 8px;
	font-size: 14px;
	z-index: 20;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
}

.interactive-map-toast[hidden] {
	display: none;
}

/*
 * Transition playback state.
 * - .is-transitioning is toggled on the wrapper while frames load and play.
 * - The regions SVG and markers stop responding to clicks; the wrapper hints
 *   "wait" so the user knows the click landed but is being processed.
 * - The previous state's regions stay rendered behind the curtain so a
 *   transition cancellation/error keeps a usable UI; pointer-events: none
 *   is enough to guarantee no further drilling mid-flight.
 */
.interactive-map.is-transitioning {
	cursor: wait;
}

.interactive-map.is-transitioning .interactive-map-regions,
.interactive-map.is-transitioning .interactive-map-markers,
.interactive-map.is-transitioning .interactive-map-badges {
	pointer-events: none;
}

/* Fully hide the previous state's markers + polygon layer once a
 * transition starts — otherwise polygons / pins / aggregate badges
 * stay painted on top of the animating image, which reads as the
 * old UI lingering. They reappear in the new state once `renderState`
 * rebuilds them and is-transitioning is removed. */
.interactive-map.is-transitioning .interactive-map-markers,
.interactive-map.is-transitioning .interactive-map-marker-polygons {
	visibility: hidden;
}

.interactive-map.is-transitioning .interactive-map-regions polygon {
	/* Hide hover treatment to make the curtain feel calm during playback. */
	fill: transparent;
	stroke: transparent;
}
