/* Map background (injected by js/map-bg.js).
 *
 * The same class is used whether the injected background is an inline
 * `<svg>` (SVG sources) or an `<img>` (raster sources). `object-fit` is
 * a no-op on SVG — the SVG's own `preserveAspectRatio` (set by the
 * helper to `xMidYMid meet` or `xMidYMid slice`) provides the
 * equivalent behaviour.
 *
 * Default fit is `contain` (letterbox so the whole map is visible);
 * the `--cover` modifier switches to `cover` (fill the container,
 * cropping edges).
 */
.map-canvas__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center;
	pointer-events: none;
	user-select: none;
	display: block;
}
.map-canvas__bg--cover {
	object-fit: cover;
}

/* Oversampled SVG background — the fix for Safari "map stays fuzzy at
 * max zoom" that was flagged in the 0.5.6 changelog as a deferred
 * known issue. See js/map-bg.js for the rationale in more depth, but
 * the short version is this:
 *
 *   Inline SVG inside a transformed/composited parent is rasterised
 *   into a bitmap sized to the parent's *natural* (unzoomed) layout.
 *   When the parent's `transform: scale(N)` zooms in, the GPU simply
 *   upscales that bitmap by N — no re-render from vector geometry —
 *   so the map gets visibly blurrier at every step. This is a
 *   long-standing WebKit behaviour and is not addressed by any
 *   combination of `will-change`, inline-SVG, or image-rendering
 *   hints.
 *
 *   The fix here is "oversample + counter-scale":
 *     • `width: 400%; height: 400%` makes the SVG element itself
 *       4× the canvas in both dimensions — so its rasterised bitmap
 *       is at 4× the resolution of the canvas.
 *     • `transform: translate(-50%, -50%) scale(0.25)` counter-scales
 *       it back to 1× the canvas *visually*, so everything else on
 *       the canvas (pins, people markers, etc.) still lines up and
 *       no JS math has to change.
 *     • `will-change: transform` gives the SVG its own GPU layer,
 *       which Safari will composite using the layer's natural
 *       rasterised resolution rather than flattening it into the
 *       parent's backing store.
 *
 *   When the parent canvas then zooms up to `scale(4)` (the max),
 *   the composed effective scale of the SVG layer is
 *   `4 × 0.25 = 1.0` — i.e. 1:1 of the pre-rasterised 4× bitmap to
 *   screen pixels, which is pixel-perfect crisp. When the canvas is
 *   zoomed out to `scale(1)` (the min), effective scale is 0.25 and
 *   the GPU downsamples the 4× bitmap (which is always sharp, just
 *   potentially losing detail).
 *
 * The 4× factor matches the hard-coded `maxScale = 4` in
 * `js/map-template-3.js`. If that cap ever changes, bump the numbers
 * here in lockstep (width/height + scale value) so the bitmap
 * resolution stays matched to the max zoom.
 *
 * Memory cost: on a ~800×800 framed viewport the SVG's GPU backing
 * store is ~3200×3200 × 4 bytes ≈ 40 MB. Double that on Retina. Not
 * free, but well within budget for a single layer on modern hardware,
 * and it's the only layer doing this.
 */
.map-canvas__bg--oversample {
	inset: auto;
	top: 50%;
	left: 50%;
	right: auto;
	bottom: auto;
	width: 400%;
	height: 400%;
	/* `translate3d` (instead of 2D `translate`) and `backface-visibility:
	 * hidden` are redundant-but-belt-and-braces GPU-promotion hints
	 * alongside `will-change`. WebKit has historically been willing to
	 * flatten child layers back into a composited parent if the only
	 * promotion hint is `will-change`; the 3D transform + backface
	 * combination tips the compositor into always keeping this one on
	 * its own layer with its own native-resolution backing store. */
	transform: translate3d(-50%, -50%, 0) scale(0.25);
	transform-origin: center center;
	backface-visibility: hidden;
	will-change: transform;
}
