/* Map Template 3
 * - Same base as Template 2: pinch-zoom + pan
 * - Adds .map-person animated markers
 */

.map-template-3,
.map-template-svg { position: fixed; inset: 0; overflow: hidden; touch-action: none; }
.map-template-3 { background-color: #E3D1B9; }
.map-template-svg { background-color: #fff; }
.map-template-svg { background-image: var(--map-texture, none); background-size: cover; background-position: center; background-repeat: repeat; }
/* `will-change: transform` is applied to the canvas dynamically by the JS only
 * during active pan/zoom gestures (see map-template-3.js). At rest, the canvas
 * is *not* a composited GPU layer, so paints draw everything at the canvas's
 * current transform scale. The SVG background (inline <svg>) redraws from
 * vector geometry at that scale, and markers render at their own final scale,
 * so the whole thing stays crisp at any zoom level. */
.map-template-3 .map-canvas,
.map-template-svg .map-canvas { position: absolute; inset: 0; transform-origin: center center; }

/* `.map-canvas__bg` styling now lives in css/map-bg.css and is shared
 * across all map templates. See js/map-bg.js for the injection logic
 * and the WebKit-specific reasoning for using inline SVG. */

.map-template-3 .map-canvas.is-panning,
.map-template-svg .map-canvas.is-panning { cursor: grabbing; }

/* NOTE: `will-change: transform` is intentionally *not* set on map-pins or
 * map-people. With ~100 people + dozens of pins it would promote each marker
 * into its own GPU compositing layer, blowing past WebKit's layer budget and
 * causing markers to silently vanish after prolonged use. The parent
 * `.map-canvas` opts into `will-change` dynamically only during active
 * gestures (see map-template-3.js), which is enough to keep the transform
 * smooth without hoarding GPU memory. */
.map-template-3 .map-pin,
.map-template-svg .map-pin { position: absolute; transform: translate3d(-50%, -100%, 0) scale(var(--pm-inv-scale, 1)); transform-origin: 50% 100%; width: 24px; height: auto; pointer-events: auto; z-index: 2; cursor: pointer; transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1), opacity 160ms ease; contain: layout paint; }
.map-template-3 .map-pin:hover,
.map-template-svg .map-pin:hover { transform: translate3d(-50%, -100%, 0) scale(calc(var(--pm-inv-scale, 1) * 1.08)); }

/* Atelier fallback pin (no featured image) */
.map-template-3 .map-pin--atelier,
.map-template-svg .map-pin--atelier {
	--pm-atelier-d: 22px;
	--pm-atelier-tail-w: 5px;
	--pm-atelier-tail-h: 4px;
	width: var(--pm-atelier-d) !important;
	height: calc(var(--pm-atelier-d) + var(--pm-atelier-tail-h)) !important;
	display: block;
	background: transparent;
	position: absolute; /* ensure pseudo-elements position correctly */
}
.map-template-3 .map-pin--atelier::before,
.map-template-svg .map-pin--atelier::before {
	content: "";
	position: absolute;
	left: 50%;
	top: 0;
	transform: translateX(-50%);
	width: var(--pm-atelier-d);
	height: var(--pm-atelier-d);
	border-radius: 999px;
	background-color: #f4f4f4;
	border: 1px solid rgba(0,0,0,0.16);
	background-image: var(--pm-pin-icon);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 78% 78%;
	z-index: 2; /* circle sits above the tail */
}
.map-template-3 .map-pin--atelier::after,
.map-template-svg .map-pin--atelier::after {
	content: "";
	position: absolute;
	left: 50%;
	/* tuck behind the circle slightly */
	top: calc(var(--pm-atelier-d) - (var(--pm-atelier-tail-h) * 0.55));
	transform: translateX(-50%);
	width: 0;
	height: 0;
	border-left: calc(var(--pm-atelier-tail-w) / 2) solid transparent;
	border-right: calc(var(--pm-atelier-tail-w) / 2) solid transparent;
	border-top: var(--pm-atelier-tail-h) solid #f4f4f4; /* points down */
	z-index: 1; /* tail behind the circle */
}

/* Person markers.
 *
 * Several deliberate performance choices here, learnt the hard way on Safari:
 *
 *   - **No permanent `will-change`** (see note above map-pin).
 *
 *   - **`transform: translate3d(...)` is kept as-is**, so Safari
 *     treats each marker as a GPU-promotion candidate in its own
 *     right. Removing that hint (e.g. switching to the individual
 *     `translate:` property) caused Safari to stop layer-promoting
 *     the markers, which in turn forced the whole `.map-canvas` to be
 *     auto-layerised on invalidation — rasterising the canvas at its
 *     unzoomed resolution and GPU-upscaling for zoom, so everything
 *     (SVG background and markers) went blurry.
 *
 *   - **`transform` is NOT in the transition list.** The animation
 *     loop rewrites `--pm-x` / `--pm-y` at 60 Hz; the transform's
 *     computed value therefore changes every frame. With a transition
 *     on `transform`, Safari would spin up and cancel thousands of
 *     transform transitions per second, occasionally losing track of
 *     the in-flight buffer and dropping the marker as empty. Hover
 *     scale is a subtle 1.08× pop, which looks fine instantaneous.
 *
 *   - **`drop-shadow` only on `.is-selected-person`.** The shadow
 *     routes every paint through an offscreen GPU buffer; at zoom=4
 *     interpolating it on hover (via a `filter` transition) had to
 *     allocate/deallocate a buffer ~4× bigger in every dimension on
 *     each hover-in and hover-out, which was visibly flashing the
 *     marker to empty. Hover now uses the scale pop only. The
 *     selected state — only ever one marker at a time — keeps the
 *     shadow.
 */
.map-template-3 .map-person,
.map-template-svg .map-person {
	position: absolute;
	transform-origin: 50% 100%;
	width: 30px;
	height: auto;
	pointer-events: auto;
	z-index: 2;
	cursor: grab;
	transition: opacity 160ms ease;
	--pm-x: 0px;
	--pm-y: 0px;
	--pm-scale: 1;
	transform: translate3d(var(--pm-x), var(--pm-y), 0) translate3d(-50%, -100%, 0) scale(calc(var(--pm-inv-scale, 1) * var(--pm-scale)));
	/* Give each marker its own compositor layer so its position is moved by
	   the GPU with sub-pixel precision. Without this the markers are painted
	   inside the canvas's (intentionally un-composited) paint and their
	   position snaps to whole device pixels — at the slow ambient speeds this
	   shows up as visible "stepping", especially when zoomed out where each
	   frame moves only a fraction of a pixel. Markers are small raster
	   headshots kept at a constant on-screen size, so promoting them does NOT
	   affect the SVG map's crispness (the canvas layer is untouched). Cost is
	   one tiny ~30px layer per marker — negligible for the usual marker count. */
	will-change: transform;
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
	/* Normalise every headshot to greyscale. See css/generic.css for the
	   full rationale and the `--pm-person-filter` token definition — this
	   is the map-marker half of the same rule. */
	filter: var(--pm-person-filter);
	-webkit-filter: var(--pm-person-filter);
}
.map-template-3 .map-person:hover,
.map-template-3 .map-person:focus,
.map-template-svg .map-person:hover,
.map-template-svg .map-person:focus {
	--pm-scale: 1.08;
}

/* Selected person highlight: enlarge + shadow. Only one selected at a time.
   `filter` is not composable across rules — the more-specific selector wins
   outright — so we restate the person filter alongside the drop-shadow via
   the shared `--pm-person-filter` token (see css/generic.css) to keep the
   selected marker both highlighted and in the canonical headshot treatment. */
.map-template-3 .map-person.is-selected-person,
.map-template-svg .map-person.is-selected-person {
	--pm-scale: 1.65;
	z-index: 10;
	filter: var(--pm-person-filter) drop-shadow(0 3px 10px rgba(0,0,0,0.6));
	-webkit-filter: var(--pm-person-filter) drop-shadow(0 3px 10px rgba(0,0,0,0.6));
}

/* Filtering */
.map-template-3 .is-filtered-out,
.map-template-svg .is-filtered-out { opacity: 0; pointer-events: none; }

/* Filters UI */
.map-template-3 .map-filters,
.map-template-svg .map-filters {
	position: fixed;
	top: 58px;
	left: 12px;
	z-index: 30;
	display: flex;
	gap: 10px;
	align-items: center;
	padding: 8px 10px;
	border-radius: 14px;
	background: rgba(0,0,0,0.6);
	border: 1px solid rgba(255,255,255,0.2);
	color: #fff;
	pointer-events: auto;
	touch-action: auto;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}
.map-template-3 .map-filter,
.map-template-svg .map-filter { display: flex; gap: 8px; align-items: center; }
.map-template-3 .map-filter__label,
.map-template-svg .map-filter__label { font-weight: 800; font-size: 0.9rem; }
.map-template-3 .map-filter__select,
.map-template-svg .map-filter__select {
	appearance: none;
	background: rgba(255,255,255,0.15);
	color: #fff;
	border: 1px solid rgba(255,255,255,0.2);
	border-radius: 10px;
	padding: 6px 10px;
	font-weight: 800;
}
.map-template-3 .map-filter__select option,
.map-template-svg .map-filter__select option { color: #111; }
.map-template-3 .map-filter__clear,
.map-template-svg .map-filter__clear {
	border: 1px solid rgba(255,255,255,0.2);
	background: rgba(255,255,255,0.08);
	color: #fff;
	border-radius: 10px;
	padding: 6px 10px;
	font-weight: 800;
}
.map-template-3 .map-filter__clear:hover,
.map-template-svg .map-filter__clear:hover { background: rgba(255,255,255,0.14); }

/* Hover tooltip (name + plus) */
.map-hover {
	position: fixed;
	left: 0;
	top: 0;
	transform: translate(-50%, 0);
	background: rgba(0,0,0,0.78);
	color: #fff;
	border: 1px solid rgba(255,255,255,0.18);
	border-radius: 999px;
	padding: 6px 10px;
	display: inline-flex;
	align-items: center;
	gap: 0;
	font-size: 13px;
	line-height: 1;
	white-space: nowrap;
	z-index: 20; /* above pins (2-10) and selected person (10), but below People panel (25), modal (40), and backdrop (45) */
	pointer-events: none;
	opacity: 0;
	transition: opacity 120ms ease;
}
.map-hover.is-open { opacity: 1; }
.map-hover__title { font-weight: 700; }

/* Modal styles inline mirror (ensure visible even if other CSS not present) */
.map-template-3 .map-modal,
.map-template-svg .map-modal { position: fixed; inset: 0; display: grid; place-items: center; pointer-events: none; z-index: 40; }
.map-template-3 .map-modal[aria-hidden="true"],
.map-template-svg .map-modal[aria-hidden="true"] { opacity: 0; }
.map-template-3 .map-modal[aria-hidden="false"],
.map-template-svg .map-modal[aria-hidden="false"] { pointer-events: auto; }
.map-template-3 .map-modal__backdrop,
.map-template-svg .map-modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); opacity: 0; transition: opacity 220ms cubic-bezier(0.22, 1, 0.36, 1); }
.map-template-3 .map-modal__panel,
.map-template-svg .map-modal__panel { position: relative; width: min(92vw, 720px); max-height: 80vh; overflow: auto; background: #f4f4f4; color: #111; border-radius: 18px; padding: 1.25rem 1.25rem 1.1rem; box-shadow: 0 18px 60px rgba(0,0,0,0.35); transform: translateY(16px) scale(0.98); opacity: 0; transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1), opacity 320ms cubic-bezier(0.22, 1, 0.36, 1); -webkit-overflow-scrolling: touch; border: 1px solid rgba(0,0,0,0.08); }
.map-template-3 .map-modal__close,
.map-template-svg .map-modal__close { position: absolute; top: 10px; right: 10px; width: 38px; height: 38px; border-radius: 12px; border: 1px solid rgba(0,0,0,0.12); background: rgba(255,255,255,0.75); color: #111; font-size: 24px; line-height: 1; }
.map-template-3 .map-modal__title,
.map-template-svg .map-modal__title { margin: 0 0 4px; font-size: clamp(1.25rem, 2.8vw, 1.75rem); }
.map-template-3 .map-modal__street,
.map-template-svg .map-modal__street { margin: 0 0 12px; font-size: 0.95rem; opacity: 0.8; }
.map-template-3 .map-modal__content,
.map-template-svg .map-modal__content { font-size: 1rem; line-height: 1.6; margin: 0; }
.map-template-3 .map-modal__actions,
.map-template-svg .map-modal__actions { margin-top: 16px; }
.map-template-3 .map-modal__button,
.map-template-svg .map-modal__button { display: inline-block; padding: 0.625rem 1rem; background: #111; color: #fff; border-radius: 999px; text-decoration: none; font-weight: 800; border: 1px solid rgba(0,0,0,0.12); }
.map-template-3 .map-modal__thumb,
.map-template-svg .map-modal__thumb { position: static; width: 112px; height: 112px; padding: 10px 14px; border-radius: 999px; overflow: hidden; border: 1px solid rgba(0,0,0,0.12); background: #ccc; margin: 10px auto 12px; }
.map-template-3 .map-modal__thumb img,
.map-template-svg .map-modal__thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Apply the canonical Person filter to the modal thumbnail, but only when
   the modal was opened for a person (the same modal element is reused for
   Location pins and Person markers — JS toggles `.map-modal--person` on
   open so we can discriminate here). See css/generic.css for the
   `--pm-person-filter` token. */
.map-template-3 .map-modal.map-modal--person .map-modal__thumb img,
.map-template-svg .map-modal.map-modal--person .map-modal__thumb img {
	filter: var(--pm-person-filter);
	-webkit-filter: var(--pm-person-filter);
}
.map-template-3 .map-modal[data-state="opening"] .map-modal__backdrop,
.map-template-3 .map-modal[data-state="open"] .map-modal__backdrop,
.map-template-svg .map-modal[data-state="opening"] .map-modal__backdrop,
.map-template-svg .map-modal[data-state="open"] .map-modal__backdrop { opacity: 1; }
.map-template-3 .map-modal[data-state="opening"] .map-modal__panel,
.map-template-3 .map-modal[data-state="open"] .map-modal__panel,
.map-template-svg .map-modal[data-state="opening"] .map-modal__panel,
.map-template-svg .map-modal[data-state="open"] .map-modal__panel { transform: translateY(0) scale(1); opacity: 1; }
.map-template-3 .map-modal[data-state="closing"] .map-modal__backdrop,
.map-template-svg .map-modal[data-state="closing"] .map-modal__backdrop { opacity: 0; }
.map-template-3 .map-modal[data-state="closing"] .map-modal__panel,
.map-template-svg .map-modal[data-state="closing"] .map-modal__panel { transform: translateY(16px) scale(0.98); opacity: 0; }

/* Map controls (reuse v1 look) */
.map-template-3 .map-controls,
.map-template-svg .map-controls { position: absolute; right: 1rem; bottom: 1rem; display: flex; gap: 0.5rem; z-index: 15; pointer-events: auto; touch-action: auto; }
.map-template-3 .map-controls button,
.map-template-svg .map-controls button { width: 2.5rem; height: 2.5rem; border: 1px solid rgba(255,255,255,0.25); background: rgba(0,0,0,0.5); color: #fff; border-radius: 0.375rem; font-size: 1.25rem; line-height: 1; display: grid; place-items: center; }
.map-template-3 .map-controls button:hover,
.map-template-svg .map-controls button:hover { background: rgba(0,0,0,0.65); }

/* People search panel */
.map-people-panel {
	position: fixed;
	left: 12px;
	top: 108px;
	bottom: 12px;
	width: 240px;
	z-index: 25;
	display: grid;
	grid-template-rows: auto 1fr auto;
	gap: 6px;
	padding: 10px;
	border-radius: 14px;
	background: rgba(0,0,0,0.6);
	border: 1px solid rgba(255,255,255,0.2);
	color: #fff;
	pointer-events: auto;
	touch-action: auto;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	font-size: 0.85rem;
}
.map-people-panel__search {
	width: 100%;
	padding: 8px 10px;
	border-radius: 10px;
	border: 1px solid rgba(255,255,255,0.2);
	background: rgba(255,255,255,0.12);
	color: #fff;
	font-size: 0.85rem;
	font-weight: 600;
	box-sizing: border-box;
}
.map-people-panel__search::placeholder { color: rgba(255,255,255,0.55); }
.map-people-panel__list {
	list-style: none;
	margin: 0;
	padding: 0;
	overflow-y: auto;
	overflow-x: hidden;
	-webkit-overflow-scrolling: touch;
	overscroll-behavior: contain;
}
.map-people-panel__item { margin: 0; }
.map-people-panel__btn {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	width: 100%;
	padding: 5px 6px;
	border: none;
	border-radius: 8px;
	background: transparent;
	color: #fff;
	text-align: left;
	cursor: pointer;
	transition: background 120ms ease;
}
.map-people-panel__btn:hover { background: rgba(255,255,255,0.12); }
.map-people-panel__item.is-active .map-people-panel__btn { background: rgba(255,255,255,0.22); }
.map-people-panel__thumb {
	width: 28px;
	height: 28px;
	border-radius: 999px;
	object-fit: cover;
	flex: 0 0 28px;
	border: 1px solid rgba(255,255,255,0.15);
	background: rgba(255,255,255,0.08);
}
.map-people-panel__name { font-weight: 600; line-height: 1.25; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 0; }
.map-people-panel__clear {
	display: none;
	width: 100%;
	padding: 8px 10px;
	border-radius: 10px;
	border: 1px solid rgba(255,255,255,0.2);
	background: rgba(255,255,255,0.08);
	color: #fff;
	font-weight: 800;
	font-size: 0.85rem;
	cursor: pointer;
}
.map-people-panel.has-active-person .map-people-panel__clear { display: block; }
.map-people-panel__clear:hover { background: rgba(255,255,255,0.14); }

/* Year-hidden items in the people panel (greyed out when visible via search) */
.map-people-panel__item.is-year-hidden .map-people-panel__btn {
	opacity: 0.4;
	pointer-events: none;
}
.map-people-panel__item.is-year-hidden .map-people-panel__inactive-badge { display: block; }

/* Inactive badge (hidden by default, shown for year-filtered items during search) */
.map-people-panel__inactive-badge {
	display: none;
	width: 100%;
	font-size: 0.65rem;
	font-weight: 500;
	color: rgba(255,255,255,0.45);
	font-style: italic;
	line-height: 1.2;
	padding-left: 36px;
	box-sizing: border-box;
}

/* Mobile toggle for the people panel */
.map-people-panel__toggle {
	display: none;
	position: fixed;
	left: 12px;
	bottom: 12px;
	z-index: 25;
	padding: 8px 14px;
	border-radius: 14px;
	border: 1px solid rgba(255,255,255,0.2);
	background: rgba(0,0,0,0.6);
	color: #fff;
	font-weight: 800;
	font-size: 0.85rem;
	cursor: pointer;
	pointer-events: auto;
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
}
.map-people-panel__toggle:hover { background: rgba(0,0,0,0.75); }

@media (max-width: 600px) {
	.map-people-panel {
		transform: translateX(calc(-100% - 24px));
		transition: transform 260ms cubic-bezier(0.22,1,0.36,1);
	}
	.map-people-panel.is-open { transform: translateX(0); }
	.map-people-panel__toggle { display: block; }
	.map-people-panel__toggle.is-open { left: 264px; }
}

/* Fixed home button */
.map-template-3 .map-home,
.map-template-svg .map-home { position: fixed; top: 12px; left: 12px; z-index: 30; padding: 0.4rem 0.6rem; border-radius: 999px; background: rgba(0,0,0,0.6); color: #fff; text-decoration: none; font-weight: 700; font-size: 0.9rem; border: 1px solid rgba(255,255,255,0.2); }
.map-template-3 .map-home:hover,
.map-template-svg .map-home:hover { background: rgba(0,0,0,0.75); }


