/**
 * The front-end map.
 *
 * Deliberately small. The map itself is Leaflet's own stylesheet, and the theme
 * owns the page around it; what is here is the container, the status line and
 * the handful of places where Leaflet's defaults would fight the site.
 *
 * Two class names in a selector wherever a theme could plausibly have its own
 * rule for the element — the same rule the Divi work arrived at
 * (`AI/architecture/divi-fallstricke.md`).
 *
 * @package WildislandMap
 */

.wildisland-map {
	position: relative;
	margin: 0 0 1.5em;
}

.wildisland-map .wildisland-map__canvas {
	width: 100%;
	/* The height comes inline from the layout or the attribute; this is what a
	   template override that forgets one still gets. */
	min-height: 240px;
	background: #e8ebe6;
}

/* Full bleed: the map is the page, not a picture on it.
 *
 * Measured on the legacy page rather than guessed — `#map2` renders at the full
 * viewport, out of `width: 100%; height: 100vh`, with no content frame between
 * it and the body (`scripts/measure-bestand.sh 1920 karte`). A theme that puts
 * its content in a centred column would shrink that to the column, so the
 * container steps out of it: as wide as the viewport, pulled back by half the
 * difference.
 *
 * `margin-left`/`margin-right` rather than a transform, because the element has
 * to keep taking part in the page flow — the filter panel of T15 sits directly
 * underneath it, as it does in the legacy page.
 *
 * The width is *not* `100vw`: that unit counts the vertical scrollbar in, so on
 * a page long enough to scroll the map would be some 15px wider than the room
 * the document has and would earn a horizontal scrollbar of its own — measured
 * 2026-09-04 at a 1280px window: 1280px of map in a 1265px document. The real
 * figure is `documentElement.clientWidth`, and only a script can read it; the
 * renderer writes it here (`publishViewportWidth()` in `map.js`). */
:root {
	/* The value before the renderer has run — and the value a visitor without
	   JavaScript keeps, who sees no map either way. */
	--wildisland-viewport: 100vw;
}

.wildisland-map.wildisland-map--full {
	width: var(--wildisland-viewport);
	max-width: var(--wildisland-viewport);
	margin-left: calc(50% - var(--wildisland-viewport) / 2);
	margin-right: calc(50% - var(--wildisland-viewport) / 2);
	margin-bottom: 0;
}

/* The WordPress admin bar, for everyone who is logged in.
 *
 * It pushes the document down with `html { margin-top: 32px !important }` while
 * leaving the viewport the size it was, so a map of `100vh` ends 32px below the
 * fold and an editor has to scroll to see its bottom edge. Measured 2026-09-08
 * in a 1995px-high window: map 1995px tall, starting at y = 32.
 *
 * `!important` and no way around it: the height is an inline style on the
 * CANVAS (`templates/map.php` writes what the shortcode resolved), and an
 * inline declaration beats any selector. The alternative — resolving the height
 * in PHP — would put a WordPress detail into a value a theme is meant to be
 * able to override.
 *
 * On the canvas, not on the container. Up to 0.25.1 this rule shortened the
 * container while the inline height sat on the canvas, as it always has: the
 * canvas stayed 100vh tall and ended 32px below the fold, and the legend,
 * which stands on the canvas's bottom edge, went down with it — behind the
 * fixed funding badge of the theme, measured 2026-10-08 on prod with the bar
 * at every width from 375 to 1920px (NA19 in AI/plans/done/nacharbeiten.md).
 *
 * 32px, and 46px below 782px where the bar grows a row: WordPress's own two
 * heights. Below 600px the bar stops being fixed, but it still pushes the
 * document down, so the subtraction stays. Visitors see none of this. */
body.admin-bar .wildisland-map.wildisland-map--full .wildisland-map__canvas {
	height: calc(100vh - 32px) !important;
}

@media only screen and (max-width: 782px) {
	body.admin-bar .wildisland-map.wildisland-map--full .wildisland-map__canvas {
		height: calc(100vh - 46px) !important;
	}
}

/* The scrim of the legacy page: it darkens the top of the map so that a fixed,
 * transparent site header stays readable over it (`.map-container::before`).
 * Off unless asked for — see the `scrim` attribute in `Frontend\Map`.
 *
 * ITS HEIGHT IS A LADDER, and the first version of this file took the second
 * rung for the whole thing. Measured in the legacy stylesheet and confirmed on
 * the rendered legacy page (`scripts/measure-bestand.sh … karte`):
 *
 *     above 1600px   150px      · measured 150 at 1920
 *     from 1600px    105px
 *     from 1366px     95px      · measured 95 at 1280, 768 and 375
 *     from 1300px    none       · the legacy header turns opaque black there,
 *                                 and an opaque bar needs nothing behind it
 *
 * A flat 105px is therefore 45px too short on a wide screen — which is what it
 * looks like: the header is 120px tall, the band ends inside it, and the fade
 * has nothing left to fade into. Found 2026-09-08 on a 2545px-wide window.
 *
 * The height is a custom property so a theme with a header of its own height
 * can set it without restating the gradient. */
.wildisland-map.wildisland-map--scrim {
	--wildisland-map-scrim-height: 150px;
}

@media only screen and (max-width: 1600px) {
	.wildisland-map.wildisland-map--scrim {
		--wildisland-map-scrim-height: 105px;
	}
}

@media only screen and (max-width: 1366px) {
	.wildisland-map.wildisland-map--scrim {
		--wildisland-map-scrim-height: 95px;
	}
}

.wildisland-map.wildisland-map--scrim::before {
	position: absolute;
	z-index: 500; /* Above Leaflet's tile pane (200), below its controls (1000). */
	top: 0;
	left: 0;
	width: 100%;
	height: var(--wildisland-map-scrim-height);
	content: "";
	display: block;
	pointer-events: none;
	/* The first three stops are the legacy site's, and they are the ones that
	 * carry the header. The LAST one is not: the legacy gradient holds 0.07 to
	 * its bottom edge and then stops dead, and 7% of black ending on a line is
	 * a line you can see on a bright map. It fades out instead — a deliberate
	 * difference, and the only one in this band. */
	background: linear-gradient(
		to bottom,
		rgba(0, 0, 0, 0.65) 0%,
		rgba(0, 0, 0, 0.28) 39%,
		rgba(0, 0, 0, 0.07) 79%,
		rgba(0, 0, 0, 0) 100%
	);
}

@media only screen and (max-width: 1300px) {
	.wildisland-map.wildisland-map--scrim::before {
		display: none;
	}
}

/* Where the site header lies over the map, Leaflet's own controls have to step
 * out from under it — otherwise the zoom buttons sit in the dark band, half
 * covered by the logo. The offset is the scrim's height plus Leaflet's usual
 * 10px margin, and it follows the ladder above instead of repeating one rung
 * of it. */
.wildisland-map.wildisland-map--scrim .leaflet-top .leaflet-control {
	margin-top: calc(var(--wildisland-map-scrim-height) + 10px);
}

/* Below 1300px the band is gone but the site header is not — it turns opaque
 * there, which is why the legacy page drops the band. The controls therefore
 * keep their offset: the variable stays defined at its last rung (95px), and
 * the rule above goes on reading it. No separate number here, because a number
 * for the height of somebody else's header would be a guess. */

.wildisland-map .wildisland-map__status,
.wildisland-map .wildisland-map__noscript {
	margin: 0.5em 0 0;
	font-size: 0.9em;
	/* Not `color: inherit`: the line sits under the map, on the page's own
	   background, and has to stay readable on a light and a dark section
	   alike. A muted grey does that in both. */
	color: #6b6b6b;
}

/* Under a full-bleed map the line would sit at the very edge of the window. */
.wildisland-map.wildisland-map--full .wildisland-map__status,
.wildisland-map.wildisland-map--full .wildisland-map__noscript {
	padding: 0 1em;
}

/* Leaflet draws its own popup, control and attribution chrome. Two corrections
   are needed against a theme like Divi, which sets global rules for links and
   list items that reach inside the map. */
.wildisland-map .leaflet-container a {
	text-decoration: none;
}

.wildisland-map .leaflet-control-layers-list label {
	display: flex;
	gap: 0.4em;
	align-items: center;
	margin: 0;
	font-weight: 400;
}

/* ------------------------------------------------------------- the popup */

/* The legacy `.map-info`: the island's name, its country and area on the left,
 * the photograph on the right with the "Learn more" button under it. Measured
 * off `merged.css` rather than reinvented — 500 px wide, a 60/40 split — with
 * the one part of the legacy markup left out that the legacy stylesheet itself
 * hides (`.map-info .tools { display: none !important }`). */
/* Only the padding. The width is Leaflet's to write — it measures the content
 * with `white-space: nowrap`, clamps the result between the popup's `minWidth`
 * and `maxWidth` and writes it inline. Overriding it with `auto` looks harmless
 * and takes the minimum with it, which is what left the popup 96 px wide at a
 * 390 px viewport. */
.wildisland-map .wildisland-popup__frame .leaflet-popup-content {
	margin: 14px;
}

/* Leaflet's own close button is a 24x24 target carrying a 16px cross in
 * #757575, and the photograph reaches underneath it: the media cell pulls back
 * over the content margin to the top right corner, so on the 270 islands that
 * have a picture the grey cross lies on top of one — hard to see and barely
 * worth aiming at.
 *
 * The legacy had the same overlap and answered it: the picture is
 * `position: absolute; z-index: 10` and `merged.css` lifts the close button
 * over it with `.gm-style-iw button { z-index: 15 !important }`. What it lifted
 * was Google's own 30px button, which brings a light backing of its own.
 * Leaflet's brings none, so it is written here — the same 30px target, the
 * popup's near-black instead of grey, and a white patch so the mark stays
 * readable over any photograph. Square rather than Google's circle, because
 * the rest of this popup is square.
 *
 * The 30px is READ FROM Google's chrome, not measured on the legacy page: the
 * legacy map does not render in the automation browser, so no rendered popup
 * was available to measure. Same caveat as `.wildisland-popup__subtitle` below.
 *
 * Leaflet stacking needs no help — the button is the last child of
 * `.leaflet-popup` and paints above the wrapper on its own. */
.wildisland-map .wildisland-popup__frame a.leaflet-popup-close-button {
	top: 6px;
	right: 6px;
	width: 30px;
	height: 30px;
	background: rgba(255, 255, 255, 0.85);
	color: #333;
	font: 24px/30px Tahoma, Verdana, sans-serif;
}

.wildisland-map .wildisland-popup__frame a.leaflet-popup-close-button:hover,
.wildisland-map .wildisland-popup__frame a.leaflet-popup-close-button:focus {
	background: #fff;
	color: #000;
}

.wildisland-map .wildisland-popup__frame a.leaflet-popup-close-button:focus-visible {
	outline: 2px solid #333;
	outline-offset: 1px;
}

/* **The base size is absolute, and it has to be.** Leaflet gives its popup
 * `font: 12px/1.5` and a theme scales that further — the panel measured 10.5px
 * on the dev instance, which pulled every `em` below with it: a 22px title
 * came out at 14.8px. The legacy popup sits in the page's own 14px/20px, so
 * that is what the box declares, and the sizes below are the ratios of
 * `merged.css` against it. */
.wildisland-map .wildisland-popup {
	display: grid;
	gap: 1em;
	color: #000;
	font-size: 14px;
	font-weight: 400;
	line-height: 20px;
	grid-template-columns: 1fr;
}

@media (min-width: 30em) {
	/* 186 and not 200: the cell reaches 14px further right than the track,
	   over Leaflet's content margin, so the picture is the legacy's 200. */
	.wildisland-map .wildisland-popup {
		gap: 0;
		grid-template-columns: 1fr 186px;
	}

	/* Flush with the top, right and bottom of the white box, as the legacy
	   picture is: it is `position: absolute; right: 0; top: 0` inside the info
	   window and overlaps its padding. Leaflet's padding is the 14px margin on
	   `.leaflet-popup-content`, so the cell reaches back over it. */
	.wildisland-map .wildisland-popup__media {
		margin: -14px -14px -14px 0;
		overflow: hidden;
	}
}

/* 22px on a 16px line and 10px/20px of air, as `merged.css` writes it. The
 * tight leading is the legacy's own `line-height: 16px !important`. */
.wildisland-map .wildisland-popup__title {
	margin: 10px 0 20px;
	color: #000;
	font-size: 22px;
	font-weight: 400;
	line-height: 16px;
	text-transform: uppercase;
}

.wildisland-map .wildisland-popup__place {
	display: flex;
	align-items: flex-start;
	gap: 5px;
}

/* 19% of the left column, which on the legacy's 470px box is 49px. */
/*
 * The second line of a name, on the six islands that have one.
 *
 * These values are READ FROM the legacy stylesheet, not measured on the
 * rendered page — `.std-content .tx-wild .map-info .left h2 span` gives
 * 15px, 5px of lead and no upper case, against the 22px upper-case title
 * above it. The usual rule of this repo is to measure the rendered document
 * (CLAUDE.md, "Beim Messen"), and it is not followed here for one reason:
 * the legacy popup is built by script from the AJAX answer, so rendering one
 * of those six means driving the legacy map itself. If the popup is ever
 * measured for another reason, this is the block to check.
 */
.wildisland-map .wildisland-popup__subtitle {
	display: block;
	padding-top: 5px;
	font-size: 15px;
	text-transform: none;
}

.wildisland-map .wildisland-popup__flag {
	width: auto;
	max-width: 49px;
	height: auto;
	margin-top: 4px;
}

.wildisland-map .wildisland-popup__country {
	font-size: 20px;
	line-height: 1.43;
	color: #333;
}

.wildisland-map .wildisland-popup__area {
	font-size: 14px;
	line-height: 20px;
	color: #333;
}

/* The legacy right-hand column is 200x145 and absolutely placed at the top
 * right of the white box, with the button lying over the foot of the picture.
 * Here it is a grid cell of the same width that stacks the two — the overlay
 * is `position: relative` around an absolutely placed button, so an island
 * without a photograph keeps a button of the same size in the same place
 * rather than a 200px-wide one where the picture should be. */
.wildisland-map .wildisland-popup__media {
	position: relative;
	min-height: 145px;
}

.wildisland-map .wildisland-popup__thumbnail {
	display: block;
	width: 100%;
	height: auto;
}

/* The legacy button, quoted: white, a three-pixel dark frame, uppercase, 140px
 * wide and centred over the foot of the picture. */
.wildisland-map .wildisland-popup__more {
	position: absolute;
	right: 0;
	bottom: 10px;
	left: 0;
	display: block;
	width: 100%;
	max-width: 140px;
	box-sizing: border-box;
	margin: 0 auto;
	padding: 5px 0;
	border: 3px solid #333;
	background: #fff;
	color: #000;
	font-size: 16px;
	line-height: 1.43;
	text-align: center;
	text-transform: uppercase;
}

/* ------------------------------------------------------------ the legend */

/* The stage is the canvas's box and nothing more: the legend is positioned
 * against it. Against the container it would be positioned against the
 * status line and, below 641px, the filter panel in the flow as well — and
 * would hang over the panel instead of over the map (templates/map.php). */
.wildisland-map .wildisland-map__stage {
	position: relative;
}

/* Over the lower left corner of the map: bottom right belongs to Leaflet's
 * attribution — which with Google carries a required data line — and the right
 * edge to the filter panel. Above Leaflet's own chrome (its controls sit at
 * 1000) so that a legend is never half covered by a zoom button.
 *
 * The distance from the bottom is a custom property with the plugin's value as
 * its default: the theme keeps the funding emblems fixed in the window's bottom
 * left corner (NA8 in AI/plans/done/nacharbeiten.md), exactly where the legend
 * of a full-window map stands, and lifts the legend above them by setting
 * `--wildisland-legend-bottom` on the map. The plugin does not know the badge,
 * only that something may claim the corner. */
.wildisland-map .wildisland-legend {
	position: absolute;
	z-index: 1001;
	bottom: var(--wildisland-legend-bottom, 1.5em);
	left: 1em;
	max-width: min(22em, calc(100% - 2em));
	padding: 0.6em 0.9em;
	border-radius: 3px;
	background: rgba(255, 255, 255, 0.92);
	box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
	color: #333;
	font-size: 0.85em;
	line-height: 1.35;
}

.wildisland-map .wildisland-legend__summary {
	font-weight: 700;
	text-transform: uppercase;
	cursor: pointer;
}

.wildisland-map .wildisland-legend__list {
	margin: 0.6em 0 0;
	padding: 0;
	list-style: none;
}

.wildisland-map .wildisland-legend__item {
	display: flex;
	align-items: center;
	margin: 0 0 0.5em;
	padding: 0;
	gap: 0.6em;
	list-style: none;
}

.wildisland-map .wildisland-legend__item:last-child {
	margin-bottom: 0;
}

/* The pin at a third of its own height: the graphics are 35 × 60, and a legend
 * whose rows are 60px tall is a legend that covers the map it explains. */
.wildisland-map .wildisland-legend__pin {
	width: auto;
	height: 20px;
	flex: 0 0 auto;
}

.wildisland-map .wildisland-legend__swatch {
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--wildisland-legend-color, #9b9b9b);
	flex: 0 0 auto;
}

.wildisland-map .wildisland-legend__text {
	display: flex;
	flex-direction: column;
}

.wildisland-map .wildisland-legend__description {
	color: #6b6b6b;
	font-size: 0.9em;
}

/* Under a scrim the legend keeps its place — the band darkens the top edge, not
 * the bottom — but on a short inline map the two would meet. */
.wildisland-map.wildisland-map--inline .wildisland-legend {
	bottom: var(--wildisland-legend-bottom, 1em);
}
