/* Asian Strike Map public styles. Everything scoped under .asm-root.
Look: "De Sarann Villa" palette (warm ivory, maroon text, crimson
primary) with self-hosted Poppins/Playfair Display.

Light only, on purpose (user request 2026-10-13, DECISIONS 49): there
is no dark palette and no prefers-color-scheme branch, so the component
paints the same warm ivory on a dark page as on a light one. It owns its
own background and ink, so the palette is legible wherever it is
embedded. */

/* Self-hosted webfonts (SIL OFL, see assets/vendor/fonts/). Paths are
relative to assets/dist/map.css, the only copy ever enqueued; the src
copy is never served directly. */
@font-face {
	font-family: Poppins;
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../vendor/fonts/poppins/poppins-latin-400-normal.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

@font-face {
	font-family: Poppins;
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../vendor/fonts/poppins/poppins-latin-500-normal.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

@font-face {
	font-family: Poppins;
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../vendor/fonts/poppins/poppins-latin-600-normal.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

@font-face {
	font-family: Poppins;
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../vendor/fonts/poppins/poppins-latin-700-normal.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

@font-face {
	font-family: "Playfair Display";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../vendor/fonts/playfair-display/playfair-display-latin-700-normal.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2026;
}

.asm-root {
	isolation: isolate;
	position: relative;
	container-type: inline-size;
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;

	/* Phones get a 12px inset, wide viewports the roomy 24px. A
	clamp() (not a container query) because a container query cannot
	style its own container element. */
	padding: clamp(12px, 1.5vw + 6px, 24px);
	font-family: var(--asm-font);
	line-height: 1.5;
	letter-spacing: 0.015em;

	--asm-font: "Poppins", -apple-system, "Segoe UI", roboto, "Helvetica Neue", arial, sans-serif;
	--asm-font-serif: "Playfair Display", georgia, "Times New Roman", serif;

	/* Theme-exact surface and ink: the WP preset colors measured live
	(#f9f9f9 base, #111 contrast) are close but not the theme's warm
	ivory/maroon, so the theme tokens win here by request. */
	--asm-color-text: #4d0013;
	--asm-color-bg: #fafafa;
	--asm-color-accent: #b3002d;
	--asm-color-border: #e8e7e3;
	--asm-color-muted: #8a5c67;
	--asm-radius: 4px;
	--asm-radius-sm: 2px;
	--asm-gap: 12px;
	--asm-status-ongoing: #c2410c;
	--asm-status-resolved: #0f766e;
	--asm-status-unknown: #8a5c67;

	/* Component chrome as tokens, so the pieces that are not plain text
	(the select popup, its option hover, the popup card, the focus ring)
	stay in step with the palette above instead of repeating literals. */
	--asm-badge-unknown-ink: #fff;
	--asm-icon-dot: 28px;
	--asm-field-bg: transparent;
	--asm-ring: rgb(179 0 45 / 50%);
	--asm-pop-bg: #fff;
	--asm-pop-shadow: 0 2px 10px 0 hsl(345deg 100% 15% / 5%), 0 2px 4px -1px hsl(345deg 100% 15% / 5%);
	--asm-opt-hover-bg: #ede9de;
	--asm-opt-hover-ink: #990026;
	--asm-popup-bg: #fff;
	--asm-action-hover-bg: rgb(179 0 45 / 8%);

	/* Insight charts. One radius for every bar in every chart (trend
	columns and ranking meters alike) so no figure rounds differently
	from its neighbour. 4px, not a pill: an 8px-tall meter clamps 4px to
	half its height and still renders as the same capsule it always did,
	while an 18-month column keeps a soft corner instead of turning into
	a lozenge — so the computed and the painted radius match everywhere.
	The axis ink is the muted token, the only gray that clears 3:1 on the
	card in both schemes. */
	--asm-chart-bar-radius: 4px;
	--asm-chart-axis: var(--asm-color-muted);
	--asm-chart-gutter: 26px;

	color: var(--asm-color-text);
	background: var(--asm-color-bg);
}

.asm-root :where(a, button, select, label, table, h1, h2, h3, p) {
	line-height: inherit;
	font-size: inherit;
}

/* Neutralize theme img rules that break Leaflet tiles. */
.asm-root .leaflet-container img,
.asm-root .leaflet-pane img,
.asm-root .leaflet-tile {
	max-width: none !important;
	max-height: none !important;
	width: auto;
	padding: 0;
}

.asm-root .leaflet-container {
	font: inherit;
}

.asm-skip {
	position: absolute;
	left: -9999px;
	top: 0;
	background: var(--asm-color-accent);
	color: #fff;
	padding: 8px 12px;
	z-index: 1001;
}

.asm-skip:focus { left: 0; }

.asm-filters {
	display: flex;
	flex-wrap: wrap;
	gap: var(--asm-gap);
	margin-block: 20px var(--asm-gap);
}

.asm-filters label {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 0.875rem;
	font-weight: 500;
}

/* Text field, pixel-matched to the theme's Input: 36px tall, 2px
radius, hairline warm border. No shadow at all (user request
2026-10-13): the field sits flat and focus is the crimson border. */
.asm-filters input[type="search"] {
	height: 36px;
	padding: 4px 12px;
	font-size: 0.875rem;
	font-weight: 400;
	color: var(--asm-color-text);
	background: var(--asm-field-bg);
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius-sm);
	max-width: 100%;
	box-sizing: border-box;
	transition: border-color 0.15s;
}

.asm-filters input[type="search"]::placeholder {
	color: var(--asm-color-muted);
	opacity: 1;
}

.asm-filters input[type="search"]:focus-visible {
	outline: none;
	border-color: var(--asm-color-accent);
}

/* Themed listbox replacing the OS-rendered <select> dropdown. Trigger
matches the theme's Select: 36px, muted chevron, no shadow. */
.asm-select {
	position: relative;
	display: inline-flex;
	min-width: 0;
}

.asm-select__trigger {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	height: 36px;
	padding: 8px 12px;
	font-size: 0.875rem;
	font-weight: 400;
	color: var(--asm-color-text);
	background: var(--asm-field-bg);
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius-sm);
	cursor: pointer;
	box-sizing: border-box;
	transition: border-color 0.15s;
}

/* Focus/open state is the crimson border alone: the 3px ring was the
last shadow on these fields (user request 2026-10-13). No height or
border-width change here, so focus cannot nudge the text. */
.asm-root .asm-select__trigger:focus-visible,
.asm-root .asm-select__trigger[aria-expanded="true"] {
	outline: none;
	border-color: var(--asm-color-accent);
}

/* The open state paints the same frame as the click: easing it over
0.15s read as a pale blink before the red settled. */
.asm-root .asm-select__trigger[aria-expanded="true"] { transition: none; }

/* Pressed-but-not-yet-open (real mousedown precedes the click
handler): tint the border red immediately so no pale frame shows. */
.asm-root .asm-select__trigger:active { border-color: var(--asm-color-accent); }

.asm-select__value {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	text-align: start;
}

.asm-select__chev {
	flex: none;
	display: inline-flex;
	opacity: 0.5;
}

.asm-select__chev svg { display: block; }

.asm-select__pop {
	position: absolute;
	top: calc(100% + 4px);
	left: 0;
	z-index: 1200;
	min-width: 100%;
	width: max-content;
	max-width: 16rem;
	background: var(--asm-pop-bg);
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius-sm);
	box-shadow: var(--asm-pop-shadow);

	/* Stays mounted and toggles via .is-open (fade like the theme's
	select content) instead of display flips: inserting/removing the
	layer painted a one-frame white flash on click. Visibility keeps
	it out of the a11y tree while closed, like display:none. */
	visibility: hidden;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.12s ease-out, visibility 0.12s;
}

.asm-select__pop.is-open {
	visibility: visible;
	opacity: 1;
	pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
	.asm-select__pop { transition: none; }
	.asm-map__hint { transition: none; }
}

.asm-select__list {
	list-style: none;
	margin: 0;
	padding: 4px;
	max-height: 240px;
	overflow-y: auto;
}

.asm-select__opt {
	position: relative;
	display: flex;
	align-items: center;
	gap: 8px;
	min-height: 32px;
	padding: 6px 32px 6px 8px;
	font-size: 0.875rem;
	border-radius: 0;
	cursor: default;
	user-select: none;
}

.asm-select__opt-label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.asm-select__opt:hover,
.asm-select__opt.is-active {
	background: var(--asm-opt-hover-bg);
	color: var(--asm-opt-hover-ink);
}

.asm-select__check {
	position: absolute;
	right: 8px;
	display: none;
	width: 16px;
	height: 16px;
}

.asm-select__check svg { display: block; }

.asm-select__opt[aria-selected="true"] .asm-select__check { display: inline-flex; }

/* Scrollbars, matching the theme's thin ScrollArea: 10px track,
border-colored pill thumb. Covers the option list and the table
scroller on narrow screens. */
.asm-root .asm-select__list,
.asm-root .asm-table-scroll {
	scrollbar-width: thin;
	scrollbar-color: var(--asm-color-border) transparent;
}

.asm-root .asm-select__list::-webkit-scrollbar,
.asm-root .asm-table-scroll::-webkit-scrollbar {
	width: 10px;
	height: 10px;
}

.asm-root .asm-select__list::-webkit-scrollbar-thumb,
.asm-root .asm-table-scroll::-webkit-scrollbar-thumb {
	background: var(--asm-color-border);
	border-radius: 999px;
	border: 3px solid transparent;
	background-clip: padding-box;
}

.asm-root .asm-select__list::-webkit-scrollbar-track,
.asm-root .asm-table-scroll::-webkit-scrollbar-track,
.asm-root .asm-select__list::-webkit-scrollbar-corner,
.asm-root .asm-table-scroll::-webkit-scrollbar-corner { background: transparent; }

.asm-root .asm-table-scroll {
	overflow-x: auto;
	max-width: 100%;
}

.asm-pager {
	display: flex;
	align-items: center;
	gap: var(--asm-gap);
	margin-block-start: var(--asm-gap);
}

/* Same reason as the rail items and source rows: flex beats [hidden]. */
.asm-pager[hidden] { display: none; }

/* "‹ Previous" (96.6px) and "Next ›" (71px) are different label
lengths, so the pair used to render lopsided. One shared min-width
makes them equal at every breakpoint; em keeps it scaling with the
label when the base font size changes. Centering is the button
default, so both labels sit in the middle of the same box. */
.asm-pager button { min-width: 7.5em; }

.asm-pager button,
.asm-load-btn {
	height: 36px;
	padding: 4px 16px;
	font-size: 0.875rem;
	font-weight: 500;
	color: #fff;
	background: var(--asm-color-accent);
	border: 1px solid var(--asm-color-accent);
	border-radius: var(--asm-radius-sm);
	box-shadow: 0 2px 10px 0 hsl(345deg 100% 15% / 3%);
	cursor: pointer;
	box-sizing: border-box;
	transition: border-color 0.15s, box-shadow 0.15s, filter 0.15s;
}

.asm-pager button:not([disabled]):hover,
.asm-load-btn:hover { filter: brightness(0.94); }

.asm-pager button[disabled] {
	opacity: 0.5;
	cursor: default;
}

.asm-pager__info {
	font-size: 0.875rem;
	color: var(--asm-color-muted);
}

.asm-status {
	font-size: 0.875rem;
	color: var(--asm-color-muted);
}

.asm-map {
	width: 100%;
	max-width: 100%;
	min-height: 240px;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
}

/* ---- Insights: hand-rolled charts (no chart library) --------------
Two columns on a roomy canvas, one on a phone: a 420px minimum keeps
the four cards in a 2x2 block instead of a 3-across row that leaves
the last card stranded and squeezes every 18-month bar to ~14px. Cards
reuse the surface/border/radius language of the rest of the component
so the figures read as part of the same theme, and the accent (already
contrast-checked against both schemes) is the only fill color. */
.asm-insights[hidden] { display: none; }

.asm-insights {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
	gap: var(--asm-gap);
	margin-block-start: var(--asm-gap);
}

.asm-chart {
	padding: 12px;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
	background: var(--asm-field-bg);
}

.asm-chart__title {
	margin: 0 0 2px;
	font-family: var(--asm-font);
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--asm-color-text);
}

.asm-chart__note {
	margin: 0 0 10px;
	font-size: 0.75rem;
	line-height: 1.45;
	color: var(--asm-color-muted);
}

/* Monthly trend: columns share the width, each bar is a percentage of
the peak month so the card scales with the container. The plot reserves
a gutter on the left for the y scale and is the positioning context for
the axes, the guidelines and the tooltip. */
.asm-chart__plot {
	position: relative;
	display: flex;
	align-items: flex-end;
	gap: 2px;
	height: 120px;
	padding-inline-start: var(--asm-chart-gutter);
	margin-block-end: 6px;
}

/* Both axes and the value guidelines. The grid box starts where the
bars start, so its left border is the y axis and its full-width lines
sit exactly under the value they label. */
.asm-chart__grid {
	position: absolute;
	inset-block: 0;
	left: var(--asm-chart-gutter);
	right: 0;
	border-inline-start: 1px solid var(--asm-chart-axis);
	pointer-events: none;
}

.asm-chart__gridline {
	position: absolute;
	left: 0;
	right: 0;
	height: 0;
	border-block-start: 1px dashed var(--asm-chart-axis);
}

/* The baseline is the x axis: solid, and the only line a bar stands on. */
.asm-chart__gridline--zero {
	top: auto;
	bottom: 0;
	border-block-start-style: solid;
}

/* Values print in the gutter, flush against the y axis. */
.asm-chart__gridline i {
	position: absolute;
	right: 100%;
	padding-inline-end: 5px;
	transform: translateY(-50%);
	font-style: normal;
	font-size: 0.625rem;
	line-height: 1;
	color: var(--asm-color-muted);
}

.asm-chart__col {
	position: relative;
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	height: 100%;
}

/* Every bar is the full accent: dimming the non-peak months with opacity
dropped their contrast against the dark surface to ~2.3:1, under the 3:1
graphics threshold. Height alone marks the peak, and the note states it.
The radius is the shared chart token, not a per-chart choice, so a column
and a meter corner round by the same amount. */
.asm-chart__bar {
	width: 100%;
	min-height: 0;
	border-radius: var(--asm-chart-bar-radius);
	background: var(--asm-color-accent);
}

/* Hover/tap readout. Pointer-only decoration: the plot is aria-hidden
and the table below holds the same figures. */
.asm-chart__tip {
	position: absolute;
	z-index: 3;
	max-width: min(220px, 100%);
	padding: 6px 8px;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
	background: var(--asm-color-bg);
	color: var(--asm-color-text);
	font-size: 0.6875rem;
	line-height: 1.4;
	box-shadow: 0 2px 8px rgb(0 0 0 / 14%);
	pointer-events: none;
	visibility: hidden;
}

.asm-chart__tip--on { visibility: visible; }

.asm-chart__tip-month {
	display: block;
	font-weight: 600;
}

.asm-chart__tip-line {
	display: block;
	color: var(--asm-color-muted);
}

/* Status split in the status hues, the one place a month shows which
kinds of incidents it holds. */
.asm-chart__tip-stat--ongoing { color: var(--asm-status-ongoing); }
.asm-chart__tip-stat--resolved { color: var(--asm-status-resolved); }
.asm-chart__tip-stat--unknown { color: var(--asm-status-unknown); }

/* Three labels (start / middle / end) spread across the same width as
the plot, so the month range reads without crowding the ~15px columns. */
.asm-chart__axis {
	display: flex;
	justify-content: space-between;
	gap: 8px;
	padding-inline-start: var(--asm-chart-gutter);
	font-size: 0.625rem;
	color: var(--asm-color-muted);
}

.asm-chart__axis span { white-space: nowrap; }

/* Rankings: label, meter, figure. The meter is decorative length; the
number stays readable text so nothing depends on a pixel width. */
.asm-chart__rank {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 6px;
}

.asm-chart__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	align-items: center;
	gap: 8px;
	font-size: 0.8125rem;
}

.asm-chart__cell {
	display: flex;
	align-items: center;
	min-width: 0;
}

.asm-chart__label {
	min-width: 0;
	overflow-wrap: anywhere;
}

.asm-chart__meter {
	justify-self: end;
	width: 84px;
	height: 8px;
	border-radius: var(--asm-chart-bar-radius);
	background: var(--asm-color-border);
	overflow: hidden;
}

.asm-chart__fill {
	display: block;
	height: 100%;
	border-radius: var(--asm-chart-bar-radius);
	background: var(--asm-color-accent);
}

.asm-chart__count {
	min-width: 2ch;
	text-align: end;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.asm-chart__icon {
	display: inline-flex;
	vertical-align: -3px;
	margin-inline-end: 6px;
	color: var(--asm-color-accent);
}

.asm-chart__icon svg {
	display: block;
	width: 14px;
	height: 14px;
}

/* The equivalent table is collapsed by default; when open it scrolls
instead of widening the card. */
.asm-chart__data {
	margin-block-start: 10px;
	font-size: 0.75rem;
}

.asm-chart__data summary {
	cursor: pointer;
	color: var(--asm-color-muted);
}

.asm-chart__table {
	width: 100%;
	margin-block-start: 6px;
	border-collapse: collapse;
}

.asm-chart__table th,
.asm-chart__table td {
	text-align: start;
	padding: 2px 4px;
	border-block-end: 1px solid var(--asm-color-border);
}

.asm-chart__table td {
	text-align: end;
	font-variant-numeric: tabular-nums;
}

/* Transient hint chip over the map (touch-first devices: one finger
scrolls the page, two fingers move the map). Painted after the
Leaflet panes so it never hides a control; pointer-events stay off
so it cannot swallow a tap. */
.asm-map__hint {
	position: absolute;
	left: 50%;
	bottom: 10px;
	z-index: 500;
	max-width: calc(100% - 20px);
	padding: 4px 10px;
	border-radius: 999px;
	background: rgb(0 0 0 / 62%);
	color: #fff;
	font-size: 0.75rem;
	line-height: 1.4;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	transform: translateX(-50%);
	pointer-events: none;
	transition: opacity 0.4s ease-out;
}

.asm-map__hint--hidden { opacity: 0; }

/* MarkerCluster ships no CSS of its own here: without these rules a
cluster renders as bare white text on the tiles (unreadable). Badge
circles grow with the count tier and heat up through the theme's own
reds — rose pink for few, crimson for several, dark maroon-red for
many — each dark enough that white numerals pass WCAG AA (4.7/7.1/
13.3 by script). */
.asm-root .marker-cluster-small,
.asm-root .marker-cluster-medium,
.asm-root .marker-cluster-large { background: transparent; }

.asm-root .marker-cluster div {
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	color: #fff;
	font-weight: 700;
}

.asm-root .marker-cluster-small div {
	background: rgb(225 29 72 / 90%);
	border: 3px solid rgb(225 29 72 / 40%);
}

.asm-root .marker-cluster-medium div {
	background: rgb(179 0 45 / 90%);
	border: 3px solid rgb(179 0 45 / 40%);
}

.asm-root .marker-cluster-large div {
	background: rgb(102 0 25 / 92%);
	border: 3px solid rgb(102 0 25 / 45%);
}

.asm-root .marker-cluster-small,
.asm-root .marker-cluster-small div { width: 40px; height: 40px; }

.asm-root .marker-cluster-medium,
.asm-root .marker-cluster-medium div { width: 48px; height: 48px; }

.asm-root .marker-cluster-large,
.asm-root .marker-cluster-large div { width: 56px; height: 56px; }

.asm-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 16px;
	list-style: none;
	margin: 0 0 var(--asm-gap);
	padding: 0;
	font-size: 0.875rem;
}

.asm-legend li {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.asm-legend__dot {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	flex: none;
}

.asm-legend__note {
	font-size: 0.75rem;
	color: var(--asm-color-muted);
	margin: 0 0 var(--asm-gap);
}

.asm-marker__pin {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	border: 2px solid #fff;
	color: #fff;
	font-size: 14px;
}

/* Action-type icon: inline Lucide SVG from the server icon map,
sized into the 28px pin (white stroke on the status color). */
.asm-marker__glyph { display: inline-flex; line-height: 0; }
.asm-marker__glyph svg { width: 15px; height: 15px; display: block; }

/* Touch accuracy (spec §7.5): the 28px pin carries an invisible
44×44 hit area. The pseudo-element paints nothing and does not move
the pin — it only widens what the finger can land on. */
.asm-marker::after {
	content: "";
	position: absolute;
	inset: -8px;
}

.asm-marker--approx .asm-marker__pin { outline: 2px dashed currentcolor; }

/* The theme draws a currentColor outline on every :focus — white in
dark mode — including mouse focus. Our controls speak border+ring
instead, so opt the whole component out. Keyboard focus still gets
a visible marker from the red fallback directly below (same
specificity, later order wins) or the ring rules above it. */
.asm-root :focus {
	outline: none;
}

/* Keyboard-focus fallback for links, pager buttons and anything
else without its own ring design. */
.asm-root :focus-visible {
	outline: 2px solid var(--asm-color-accent);
	outline-offset: 2px;
}

.asm-table {
	width: 100%;
	border-collapse: collapse;
	margin-block-start: var(--asm-gap);
	font-size: 0.875rem;
}

.asm-table th,
.asm-table td {
	text-align: start;
	padding: 8px;
	border-block-end: 1px solid var(--asm-color-border);
	vertical-align: middle;
}

.asm-table th {
	font-weight: 500;
	color: var(--asm-color-muted);
}

.asm-table th[data-asm-sort] {
	cursor: pointer;
	user-select: none;
	white-space: nowrap;
}

.asm-table th[data-asm-sort]:hover { color: var(--asm-color-text); }

.asm-sort-ic {
	display: inline-block;
	min-width: 1em;
	margin-inline-start: 4px;
	font-size: 0.75em;
	color: var(--asm-color-accent);
}

/* Title links inherit the surface ink (white in dark mode) instead
of the accent: plain text look, underline keeps the affordance. */
.asm-table td a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Date · location echo printed under the title on narrow layouts,
where those columns are dropped (see the container query below). */
.asm-table__meta { display: none; }

.asm-badge {
	display: inline-block;
	padding: 2px 10px;
	border-radius: 999px;
	color: #fff;
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.5;
}

.asm-badge--ongoing { background: var(--asm-status-ongoing); }
.asm-badge--resolved { background: var(--asm-status-resolved); }
.asm-badge--unknown { background: var(--asm-status-unknown); color: var(--asm-badge-unknown-ink); }

/* Conflict timeline as a visual rail: one dot per incident on a
vertical spine, the dot ringed in that incident's status color and
carrying its action-type icon. The list semantics stay (<ol>), so the
order is still announced; the spine and dots are decoration.

One token drives the disc size and the spine offset. The spine used to
sit at a hand-computed `left: 17px` — written as if the pseudo-element
inherited the rail's 4px padding, which it never did — so the line ran
4px right of the dot centres. The offset is now derived from the same
number that sizes the grid column, so the two cannot drift apart. */
.asm-rail {
	--asm-rail-spine: 2px;

	list-style: none;
	margin: 0;
	padding: 0;
}

.asm-rail__item {
	position: relative;
	display: grid;
	grid-template-columns: var(--asm-icon-dot) minmax(0, 1fr);
	gap: 12px;
	padding-block-end: 20px;
}

/* The connecting spine: drawn from each dot down to the next one, and
stopped after the last one a reader can see. Painted with the muted ink,
not the border color: #e8e7e3 on the #f9f9f9 page measures 1.06:1 and
the rail read as a stack of loose dots. */
.asm-rail__item::before {
	content: "";
	position: absolute;
	left: calc((var(--asm-icon-dot) - var(--asm-rail-spine)) / 2);
	top: calc(var(--asm-icon-dot) + 2px);
	bottom: 0;
	width: var(--asm-rail-spine);
	background: var(--asm-color-muted);
}

.asm-rail__item:last-child { padding-block-end: 0; }
.asm-rail__item:last-child::before { display: none; }

/* Same stop, but for the last *visible* dot: a collapsed timeline hides
the items below the fold, and the line used to hang past the final dot
it is supposed to end at. */
.asm-rail__item:not(:has(~ .asm-rail__item:not([hidden])))::before { display: none; }

/* The status-ringed icon disc. Shared by the rail dots and the detail
header, so a record carries the same mark on both pages. The background
is opaque: it has to mask the spine running behind a rail dot. */
.asm-icon-dot {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--asm-icon-dot);
	height: var(--asm-icon-dot);
	box-sizing: border-box;
	border-radius: 50%;
	border: 2px solid var(--asm-color-border);
	background: var(--asm-color-bg);
	color: var(--asm-color-accent);
}

.asm-icon-dot svg {
	width: 15px;
	height: 15px;
	display: block;
}

.asm-icon-dot--ongoing { border-color: var(--asm-status-ongoing); }
.asm-icon-dot--resolved { border-color: var(--asm-status-resolved); }
.asm-icon-dot--unknown { border-color: var(--asm-status-unknown); }

.asm-rail__dot { grid-area: 1 / 1; }

.asm-rail__body {
	grid-area: 1 / 2;
	min-width: 0;
}

.asm-rail__meta {
	margin: 0;
	font-size: 0.75rem;
	color: var(--asm-color-muted);
}

.asm-rail__meta time { font-variant-numeric: tabular-nums; }

.asm-rail__sep { margin-inline: 6px; }

.asm-rail__action { color: var(--asm-color-text); }

.asm-rail__title {
	margin: 2px 0 0;
	font-size: 0.9375rem;
	font-weight: 500;
}

.asm-rail .asm-rail__title a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.asm-rail__tags {
	margin: 6px 0 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}

.asm-rail__workers {
	font-size: 0.75rem;
	color: var(--asm-color-muted);
}

/* Outcome badges: only rendered when the outcome is no longer
"unknown", so the three states that carry meaning get real colors. */
.asm-badge--outcome-won { background: var(--asm-status-resolved); }
.asm-badge--outcome-partial { background: var(--asm-status-ongoing); }
.asm-badge--outcome-lost { background: var(--asm-status-unknown); color: var(--asm-badge-unknown-ink); }

/* Popup as a theme Card: the Leaflet chrome (wrapper, tip, content
margins, close glyph) is re-skinned to card surface, border, radius
and shadow; the inner content follows Card header/content/footer
rhythm with the serif title, muted meta and an outline action. */
.asm-root .leaflet-popup-content-wrapper {
	background: var(--asm-popup-bg);
	color: var(--asm-color-text);
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
	box-shadow: 0 2px 10px 0 hsl(345deg 100% 15% / 8%), 0 8px 24px -8px hsl(345deg 100% 15% / 25%);
}

.asm-root .leaflet-popup-content {
	margin: 0;
	line-height: 1.5;
	font-family: var(--asm-font);
	font-size: 0.875rem;
}

.asm-root .leaflet-popup-tip {
	background: var(--asm-popup-bg);
	border: 1px solid var(--asm-color-border);
	box-shadow: 0 2px 10px 0 hsl(345deg 100% 15% / 8%);
}

.asm-root .leaflet-container a.leaflet-popup-close-button {
	color: var(--asm-color-muted);
	font-size: 16px;
	padding-top: 6px;
}

.asm-root .leaflet-container a.leaflet-popup-close-button:hover,
.asm-root .leaflet-container a.leaflet-popup-close-button:focus-visible {
	color: var(--asm-color-text);
}

/* Popup titles use the same Poppins voice as every other text, set
semibold like a theme CardTitle. */
.asm-popup {
	font-size: 0.875rem;
	padding: 16px;
	display: grid;
	gap: 8px;
	align-content: start;
	justify-items: start;
}

.asm-popup strong {
	font-family: var(--asm-font);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.3;
	display: block;
}

.asm-popup p { margin: 0; color: var(--asm-color-muted); }

.asm-popup__photo {
	max-width: 100%;
	height: auto;
	display: block;
	border-radius: var(--asm-radius-sm);
}

/* Doubled under .asm-root (0,2,0): Leaflet's own
.leaflet-container a (0,1,1) paints popup links its brand blue. */
.asm-root .asm-popup__action {
	display: inline-flex;
	align-items: center;
	height: 32px;
	padding: 4px 12px;
	font-size: 0.75rem;
	font-weight: 500;
	color: var(--asm-color-text);
	background: transparent;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius-sm);
	box-shadow: 0 2px 10px 0 hsl(345deg 100% 15% / 3%);
	text-decoration: none;
	box-sizing: border-box;
	transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}

.asm-root .asm-popup__action:hover {
	background: var(--asm-action-hover-bg);
	border-color: var(--asm-color-accent);
}

.asm-root .asm-popup__action:focus-visible {
	outline: none;
	border-color: var(--asm-color-accent);
	box-shadow: 0 0 0 3px var(--asm-ring);
}

@container (max-width: 480px) {
	/* One full-width field per row, label above it: inline labels made
	each control fill "whatever is left after this label", so the
	search box (shortest label) came out a few px wider and further
	left than the three selects. Stacking gives every field the same
	left edge and the same width, in any language. (The root's own
	mobile inset lives in the clamp() above — a container query cannot
	style its container.) */
	.asm-filters { flex-direction: column; }

	.asm-filters > label {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 4px;
		width: 100%;
	}

	.asm-filters input[type="search"],
	.asm-filters .asm-select {
		width: 100%;
		min-width: 0;
	}

	.asm-filters input[type="search"],
	.asm-select__trigger,
	.asm-load-btn,
	.asm-pager button { height: 44px; }

	/* The renderer sets an inline pixel height for CLS; on narrow
	containers it would tower over the content, so reclaim it here. */
	.asm-map { height: 320px !important; }

	/* The 5-column table is 411px wide and needed sideways scrolling in
	a ~265px column, so phones keep Title and Status; the Date and
	Location cells move into the Title cell as a muted meta line (the
	markup prints both) and No is just the row order. Anything long
	wraps instead of pushing the table out of the box, and Status hugs
	its badge on one line. */
	.asm-table { font-size: 0.8125rem; }

	.asm-table th,
	.asm-table td { padding: 6px 4px; }

	.asm-table th:nth-child(1),
	.asm-table td:nth-child(1),
	.asm-table th:nth-child(3),
	.asm-table td:nth-child(3),
	.asm-table th:nth-child(4),
	.asm-table td:nth-child(4) { display: none; }

	.asm-table td:nth-child(2),
	.asm-table th:nth-child(2) { overflow-wrap: anywhere; }

	.asm-table th:nth-child(5),
	.asm-table td:nth-child(5) { width: 1%; white-space: nowrap; }

	.asm-table__meta {
		display: block;
		margin-block-start: 2px;
		font-size: 0.75rem;
		color: var(--asm-color-muted);
	}

	/* Below this width the counter no longer fits between the two
	105px buttons, and flex used to push Next onto a line of its own
	with the counter stranded above it. The pair now stays together on
	one row and the counter gets the next line at every phone width,
	so the pager reads the same on all of them. */
	.asm-pager { flex-wrap: wrap; row-gap: 8px; }

	.asm-pager__info { order: 3; flex-basis: 100%; }

	/* Leaflet ships 30px zoom buttons: a miss-prone target next to our
	44px controls, so the mobile bar grows to match. */
	.asm-root .leaflet-control-zoom a {
		width: 44px;
		height: 44px;
		line-height: 44px;
		font-size: 22px;
	}

	/* The chart data tables are the accessible equivalent, so they get a
	real touch target too: a bare 18px "Data table" row is easy to miss
	with a thumb. */
	.asm-chart__data summary {
		display: flex;
		align-items: center;
		min-height: 44px;
	}

	.asm-chart__data .asm-chart__table th,
	.asm-chart__data .asm-chart__table td { padding: 6px 4px; }
}

/* Wide viewports: break out of narrow theme columns and claim a roomy
1024px centered canvas. The doubled class selector (0,2,0) outranks the
theme's content-size rule (0,1,0, e.g. max-width:620px on post children)
regardless of stylesheet order; the theme's own margin-inline:auto then
centers the wider box. Below 1060px the base 100% rules above apply, so
small screens keep the theme's behavior untouched. */
@media (width >= 1060px) {
	.asm-root.asm-root {
		width: 1024px;
		max-width: calc(100vw - 48px);
		margin-inline: auto;
	}
}

@media print {
	.asm-map, .asm-filters, .asm-pager, .asm-detail__more { display: none; }
}

/* ---- Detail pages (virtual conflict/incident posts) ----------------
A record page is the map panel in document form: one hairline card per
block on the same 12px rhythm, muted 12px meta, the status badge and
icon disc the rail uses, and the panel's own two button styles. Two
things are page-specific:

1. Type is pinned. A theme's theme.json sets font-family on h1..h6,
   which is what turned this page's record title into a 16.8px serif
   (the theme's post title, 52px, printed above it as a second h1 — the
   Router drops that block, and .asm-detail-view is the fallback for
   classic themes that print the title from their own template). The
   component owns its type: Poppins, semibold titles, as on the map.
2. The measure is narrower. The panel is a dashboard and claims a
   1024px canvas; a page of prose and fact rows stays readable at 760px.
   This rule sits below the wide-canvas rule and repeats its class so
   order cannot flip it back. */
.asm-root.asm-detail {
	display: grid;
	gap: var(--asm-gap);
	width: 100%;
	max-width: 760px;
	margin-inline: auto;
}

.asm-detail__card {
	padding: 12px;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
	background: var(--asm-field-bg);
}

.asm-detail__head {
	display: grid;
	gap: 8px;
}

.asm-detail__eyebrow {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0;
}

.asm-detail__kind {
	font-size: 0.75rem;
	font-weight: 500;
	color: var(--asm-color-muted);
}

.asm-detail__title {
	margin: 0;
	font-family: var(--asm-font);
	font-size: 1.375rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--asm-color-text);
	overflow-wrap: anywhere;
}

.asm-detail__meta {
	margin: 0;
	font-size: 0.75rem;
	line-height: 1.6;
	color: var(--asm-color-muted);
}

.asm-detail__meta time { font-variant-numeric: tabular-nums; }

.asm-detail__sep { margin-inline: 6px; }

.asm-detail__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 4px 0 0;
}

/* The panel's two actions: the filled accent button for the primary
step (36px, 2px radius, 14px/500 — the pager button), the outlined one
for everything else (the popup's "View details" action). */
.asm-detail__action {
	display: inline-flex;
	align-items: center;
	min-height: 36px;
	padding: 4px 16px;
	font-size: 0.875rem;
	font-weight: 500;
	line-height: 1.4;
	color: var(--asm-color-text);
	background: transparent;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius-sm);
	text-decoration: none;
	box-sizing: border-box;
	transition: border-color 0.15s, background-color 0.15s, filter 0.15s;
}

.asm-detail__action:hover {
	background: var(--asm-action-hover-bg);
	border-color: var(--asm-color-accent);
}

.asm-detail__action:focus-visible {
	outline: none;
	border-color: var(--asm-color-accent);
	box-shadow: 0 0 0 3px var(--asm-ring);
}

.asm-detail__action--primary,
.asm-detail__action--primary:hover {
	color: #fff;
	background: var(--asm-color-accent);
	border-color: var(--asm-color-accent);
}

.asm-detail__action--primary:hover { filter: brightness(0.94); }

/* Photos and the no-photo placeholder share the card frame. */
.asm-root .asm-photo {
	margin: 0;
	padding: 0;
	overflow: hidden;
	border: 1px solid var(--asm-color-border);
	border-radius: var(--asm-radius);
	background: var(--asm-field-bg);
}

.asm-root .asm-photo img {
	display: block;
	max-width: 100%;
	height: auto;
}

.asm-root .asm-photo figcaption {
	padding: 8px 12px;
	font-size: 0.75rem;
	color: var(--asm-color-muted);
	border-block-start: 1px solid var(--asm-color-border);
}

/* No photo: the record's own icon disc, so the frame reads as a
placeholder rather than a broken image. */
.asm-root .asm-photo--placeholder {
	display: grid;
	justify-items: center;
	gap: 8px;
	padding: 24px 12px;
	text-align: center;
}

.asm-photo__note {
	font-size: 0.75rem;
	color: var(--asm-color-muted);
}

/* Prose: one rhythm, no theme paragraph margins. */
.asm-detail .asm-body p { margin: 0 0 var(--asm-gap); }

.asm-detail .asm-body > :last-child { margin-block-end: 0; }

/* Facts as the map table: muted 500 labels, ink values, hairline rows.
Each pair is wrapped so the rule runs the full card width. */
.asm-facts { margin: 0; }

.asm-facts__row {
	display: grid;
	grid-template-columns: minmax(9rem, max-content) minmax(0, 1fr);
	column-gap: 16px;
	padding-block: 8px;
}

.asm-facts__row + .asm-facts__row { border-block-start: 1px solid var(--asm-color-border); }

.asm-facts__row:first-child { padding-block-start: 0; }

.asm-facts__row:last-child { padding-block-end: 0; }

.asm-facts dt {
	font-size: 0.875rem;
	font-weight: 500;
	color: var(--asm-color-muted);
}

.asm-facts dd {
	margin: 0;
	font-size: 0.875rem;
	overflow-wrap: anywhere;
}

.asm-sources {
	list-style: none;
	margin: 0;
	padding: 0;
}

.asm-sources li {
	display: grid;
	gap: 2px;
	padding-block: 8px;
}

.asm-sources li + li { border-block-start: 1px solid var(--asm-color-border); }

.asm-sources li:first-child { padding-block-start: 0; }

.asm-sources li:last-child { padding-block-end: 0; }

/* `hidden` needs saying out loud: the author rules above set display on
both of these, and any author display beats the UA rule for [hidden].
Without these two lines a collapsed timeline or paged source list would
stay fully visible. */
.asm-rail__item[hidden],
.asm-sources li[hidden] { display: none; }

/* A printed record is the whole record: undo the paging the script
applied for the screen. This block has to sit *after* the two rules
above, not in the print block further up the file: they carry the same
specificity, so the last one with a display wins and a printed page
would otherwise still drop everything past the fifth entry. */
@media print {
	.asm-rail__item[hidden] { display: grid; }
	.asm-sources li[hidden] { display: grid; }
}

/* Timeline "load more" row: the panel's filled action, mounted by the
template but kept hidden until the script knows there is more to show,
so a reader without JavaScript sees the whole timeline and no button. */
.asm-detail__more {
	margin: var(--asm-gap) 0 0;
}

.asm-detail__more[hidden] { display: none; }

.asm-detail .asm-sources a {
	font-size: 0.875rem;
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
	overflow-wrap: anywhere;
}

.asm-sources span {
	font-size: 0.75rem;
	color: var(--asm-color-muted);
}

/* Section headings carry the panel's card-title voice (the map's chart
cards), with the section's own count beside them. */
.asm-detail h2 {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
	margin: 0 0 8px;
	font-family: var(--asm-font);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.4;
	color: var(--asm-color-text);
}

.asm-detail__count {
	font-size: 0.75rem;
	font-weight: 400;
	color: var(--asm-color-muted);
}

.asm-empty {
	margin: 0;
	font-size: 0.875rem;
	color: var(--asm-color-muted);
}

.asm-correction {
	margin: 0;
	font-size: 0.75rem;
	color: var(--asm-color-muted);
}

.asm-detail .asm-correction a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Classic themes print the post title from their own template, where no
block filter can reach it; the body class covers those. */
.asm-detail-view .wp-block-post-title,
.asm-detail-view .entry-title { display: none; }

@container (max-width: 480px) {
	/* A phone stacks the record: one action per row at the panel's 44px
	touch height, fact labels above their values, and a smaller title. */
	.asm-detail__title { font-size: 1.25rem; }

	.asm-detail__actions { flex-direction: column; }

	.asm-detail__action {
		justify-content: center;
		min-height: 44px;
	}

	.asm-facts__row {
		grid-template-columns: minmax(0, 1fr);
		row-gap: 2px;
	}
}
