/* ===========================================================================
   Edumaps UI rebuild — prototype stylesheet (M0, XL focus)
   Zero Bootstrap. Pure CSS custom properties + CSS grid.
   Theming via [data-theme]; respects prefers-color-scheme as the default.
   =========================================================================== */

/* ---- Design tokens -------------------------------------------------------- */
:root {
	/* spacing scale (rem-based so it scales with user/browser zoom) */
	--sp-1: 0.25rem;  --sp-2: 0.5rem;  --sp-3: 0.75rem;
	--sp-4: 1rem;     --sp-5: 1.5rem;  --sp-6: 2rem;

	--radius: 0.5rem;
	--radius-sm: 0.3rem;
	--font: "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;

	/* shell sizing */
	--topbar-h: 3.25rem;
	--bottom-h: 2rem;
	--rail-w: 3.5rem;          /* icons-only */
	--rail-w-expanded: 15rem;  /* icons + labels — fits the longest category name
	                              ("Infraestructura e Industria") on one line; at
	                              13rem it was silently clipped by .rail-items */
	--right-w: clamp(20rem, 26vw, 26rem);

	--transition: 160ms ease;

	/* light theme (default) */
	--bg:        #f4f6f9;
	--surface:   #ffffff;
	--surface-2: #eef1f5;
	--border:    #d7dde6;
	--fg:        #1d2734;
	--fg-muted:  #5b6776;
	--brand:     #1d6fe0;
	--brand-fg:  #ffffff;
	--accent:    #e2a300;
	--shadow:    0 1px 3px rgba(16, 24, 40, .12), 0 1px 2px rgba(16, 24, 40, .08);
	--shadow-lg: 0 8px 24px rgba(16, 24, 40, .16);
	--map-filter: none;
}

[data-theme="dark"] {
	--bg:        #11151c;
	--surface:   #1a2029;
	--surface-2: #232b36;
	--border:    #313b48;
	--fg:        #e7ecf2;
	--fg-muted:  #9aa7b6;
	--brand:     #4f9bff;
	--brand-fg:  #07101d;
	--accent:    #ffc94d;
	--shadow:    0 1px 3px rgba(0, 0, 0, .5);
	--shadow-lg: 0 10px 30px rgba(0, 0, 0, .55);
	/* gently darken the OSM raster tiles so they sit in a dark UI */
	--map-filter: brightness(.78) contrast(1.05) saturate(.85) hue-rotate(180deg) invert(.92);
}

/* Playful "kids" mode — vivid, rounder, friendlier (3rd colour mode). */
[data-theme="kids"] {
	--bg:        #eaf3ff;
	--surface:   #ffffff;
	--surface-2: #fff2d4;
	--border:    #ffd277;
	--fg:        #2a2350;
	--fg-muted:  #6b6a8a;
	--brand:     #7b3ff2;   /* purple */
	--brand-fg:  #ffffff;
	--accent:    #ff7a59;   /* coral */
	--radius:    0.9rem;
	--radius-sm: 0.6rem;
	--shadow:    0 2px 6px rgba(123, 63, 242, .18);
	--shadow-lg: 0 10px 28px rgba(123, 63, 242, .28);
	--map-filter: saturate(1.18);   /* a touch more vivid */
}

/* OS preference only applies before JS sets an explicit data-theme (avoids a
   dark-OS overriding the chosen light/kids theme via specificity). */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme]) {
		--bg: #11151c; --surface: #1a2029; --surface-2: #232b36; --border: #313b48;
		--fg: #e7ecf2; --fg-muted: #9aa7b6; --brand: #4f9bff; --brand-fg: #07101d;
		--accent: #ffc94d; --shadow: 0 1px 3px rgba(0,0,0,.5); --shadow-lg: 0 10px 30px rgba(0,0,0,.55);
		--map-filter: brightness(.78) contrast(1.05) saturate(.85) hue-rotate(180deg) invert(.92);
	}
}

/* ---- Reset ---------------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
	font-family: var(--font);
	color: var(--fg);
	background: var(--bg);
	overflow: hidden;
	-webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; cursor: pointer; }
a { color: var(--brand); }
[hidden] { display: none !important; }
[v-cloak] { display: none; }

/* visible focus for keyboard users */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
	* { transition: none !important; animation: none !important; }
}

/* ---- App shell (CSS grid) ------------------------------------------------- */
#app {
	display: grid;
	position: relative;            /* anchors the overlay rail at XL */
	height: 100vh;                 /* fallback */
	height: 100dvh;                /* tracks mobile browser toolbars */
	/* default = XL layout. The rail is an OVERLAY, not a grid column: the map
	   spans full width underneath it, so toggling the rail reveals/hides map on
	   the left instead of resizing & shifting the whole map. */
	grid-template-columns: 1fr var(--right-w);
	grid-template-rows: var(--topbar-h) 1fr var(--bottom-h);
	grid-template-areas:
		"topbar topbar"
		"map    right"
		"bottom bottom";
}
/* Rail/map/pane layout per orientation lives in the RESPONSIVE section below. */
/* grid items default to min-width/min-height:auto, letting a wide/tall child (the
   bottom legend, or a long fact list) blow the track past the viewport — pin them
   so tracks honour the grid and inner content (e.g. .pane-body) scrolls instead. */
.topbar, .rail, .map-wrap, .right, .bottombar { min-width: 0; min-height: 0; }

/* ---- Brand webfont (Fira Sans, SIL OFL 1.1) ------------------------------- */
/* Unifies the wordmark with the marketing pages (index.html / cover_en.html),
   which already self-host Fira Sans. Only the logo uses it, so this is the
   Latin subset at the two weights the wordmark needs: EDU = 300, MAPS = 400. */
@font-face {
	font-family: "Fira Sans";
	font-style: normal;
	font-weight: 300;
	font-display: swap;
	src: url("../fonts/fira-sans-300-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Fira Sans";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/fira-sans-400-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- Top bar -------------------------------------------------------------- */
.topbar {
	grid-area: topbar;
	display: flex; align-items: center; gap: var(--sp-3);
	padding: 0 var(--sp-3);
	background: var(--surface);
	border-bottom: 1px solid var(--border);
	z-index: 1200;
}
.brand {
	display: flex; align-items: center; gap: var(--sp-2);
	font-weight: 300; font-size: 1.15rem; letter-spacing: .02em;
	color: var(--fg); text-decoration: none; white-space: nowrap;
}
/* Wordmark in Fira Sans to match the marketing pages: EDU 300, MAPS 400. */
.brand .name { font-family: "Fira Sans", var(--font); }
.brand b { font-weight: 400; }
.brand img { width: 28px; height: 28px; }

.topbar-center { flex: 1 1 auto; min-width: 0; display: flex; justify-content: center; }
.topbar-right { display: flex; align-items: center; gap: var(--sp-2); }

/* top-bar dropdowns (language, share) via <details> — no JS */
.topbar-menu { position: relative; }
.topbar-menu > summary { list-style: none; cursor: pointer; }
.topbar-menu > summary::-webkit-details-marker { display: none; }
.topbar-menu-pop {
	position: absolute; right: 0; top: calc(100% + 4px); z-index: 1300;
	display: flex; flex-direction: column; min-width: 10rem; padding: var(--sp-1);
	background: var(--surface); border: 1px solid var(--border);
	border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
}
.topbar-menu-pop a {
	display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2);
	border-radius: var(--radius-sm); color: var(--fg); text-decoration: none; font-size: .85rem; white-space: nowrap;
}
.topbar-menu-pop a:hover { background: var(--surface-2); }
.topbar-menu-pop a.active { color: var(--brand); }

/* time control */
.timectl { display: flex; align-items: center; gap: var(--sp-2); }
.timectl .year {
	width: 6.5rem; text-align: center;   /* definite width — type=number's intrinsic width is too wide */
	font-variant-numeric: tabular-nums; font-size: 1.4rem; font-weight: 700;
	background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
	color: var(--fg); padding: var(--sp-1) var(--sp-2);
}
.timectl .year:hover { border-color: var(--border); }
.timectl .era { color: var(--fg-muted); font-size: .8rem; }

/* search */
.search { position: relative; }
.search input {
	width: clamp(10rem, 18vw, 18rem);
	padding: var(--sp-2) var(--sp-2) var(--sp-2) 2rem;
	background: var(--surface-2); color: var(--fg);
	border: 1px solid var(--border); border-radius: 999px; outline: none;
}
.search i { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--fg-muted); }

/* generic icon button */
.iconbtn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 2.25rem; height: 2.25rem; border-radius: var(--radius-sm);
	background: transparent; border: 1px solid transparent; color: var(--fg-muted);
	transition: background var(--transition), color var(--transition);
}
.iconbtn:hover { background: var(--surface-2); color: var(--fg); }
.iconbtn.primary { background: var(--brand); color: var(--brand-fg); }
.iconbtn.primary:hover { filter: brightness(1.08); }

/* generic toggle switch — a real checkbox drives a CSS track + knob, so keyboard and
   assistive-tech behaviour stays native (role="switch" names it correctly).
   The input is transparent but stretched over the whole label rather than shrunk to 1px:
   it stays the click target, so `#someId.click()` keeps working for tooling and tests.
   Set --switch-on to re-colour a single switch (the rail categories use their own colour). */
.switch { position: relative; display: flex; align-items: center; gap: var(--sp-2); font-size: .8rem; color: var(--fg); cursor: pointer; }
.switch input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.switch-track {
	flex: 0 0 auto; position: relative; width: 2rem; height: 1.1rem; border-radius: 999px;
	background: var(--surface-2); border: 1px solid var(--border);
	transition: background var(--transition), border-color var(--transition);
}
.switch-track::after {
	content: ""; position: absolute; top: 1px; left: 1px; width: .85rem; height: .85rem;
	border-radius: 50%; background: var(--fg-muted);
	transition: transform var(--transition), background var(--transition);
}
.switch input:checked + .switch-track { background: color-mix(in srgb, var(--switch-on, var(--brand)) 30%, var(--surface-2)); border-color: var(--switch-on, var(--brand)); }
.switch input:checked + .switch-track::after { transform: translateX(.9rem); background: var(--switch-on, var(--brand)); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--switch-on, var(--brand)); outline-offset: 2px; }
.switch input:disabled { cursor: not-allowed; }
.switch input:disabled + .switch-track { opacity: .5; }

/* ---- Left rail ------------------------------------------------------------ */
.rail {
	/* no grid-area: the rail is always an absolute (landscape) / fixed (portrait)
	   overlay — a dangling grid-area:rail mis-anchored its containing block. */
	display: flex; flex-direction: column;
	background: var(--surface); border-right: 1px solid var(--border);
	overflow: hidden; z-index: 1100;
}
/* overflow-x must be explicit: with only overflow-y set, the x axis computes to `auto` and the
   collapsed rail (labels hidden with opacity, so they keep their width) grows a scrollbar. */
.rail-items { display: flex; flex-direction: column; gap: 2px; padding: var(--sp-2) var(--sp-1); flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; min-height: 0; }
.rail-item {
	display: flex; align-items: center; gap: var(--sp-3);
	padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm);
	background: transparent; border: none; color: var(--fg-muted); width: 100%;
	white-space: nowrap; text-decoration: none; text-align: left;
	transition: background var(--transition), color var(--transition);
}
.rail-item:hover { background: var(--surface-2); color: var(--fg); }
.rail-item.active { background: color-mix(in srgb, var(--brand) 16%, transparent); color: var(--brand); }
.rail-item i { width: 1.5rem; text-align: center; font-size: 1.05rem; flex: 0 0 auto; }
.rail-item .label { opacity: 0; transition: opacity var(--transition); }
#app.rail-expanded .rail-item .label { opacity: 1; }
.rail-toggle { border-top: 1px solid var(--border); color: var(--fg-muted); flex-shrink: 0; }

/* (P4.5/b) overflow popout — only shown in short landscape (see the media query);
   holds the items that the inline rail hides when vertical space is tight. */
.rail-more { display: none; }                 /* hidden by default; revealed in short landscape */
.rail-more > summary { list-style: none; cursor: pointer; }
.rail-more > summary::-webkit-details-marker { display: none; }
.rail-more-pop {
	/* fixed so it escapes the rail's overflow:hidden + the rail-items scroll clip
	   (which would otherwise hide an absolutely-positioned popout). */
	position: fixed; left: calc(var(--rail-w) + var(--sp-1)); bottom: var(--sp-3);
	min-width: 11rem; background: var(--surface); border: 1px solid var(--border);
	border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: var(--sp-1);
	display: flex; flex-direction: column; gap: 2px; z-index: 1200;
}
/* if the rail happens to be expanded, anchor the popout to its wider right edge */
#app.rail-expanded .rail-more-pop {   /* sit right of the wide landscape rail; cap width so it never runs off-screen */
	left: calc(var(--rail-w-expanded) + var(--sp-1));
	min-width: 0;
	max-width: calc(100vw - var(--rail-w-expanded) - var(--sp-3));
}
/* in the portrait drawer the summary is mid-list — expand inline beneath it (no off-canvas popout) */
#app.drawer-open .rail-more-pop {
	position: static; inset: auto; min-width: 0; max-width: none;
	margin: 2px 0 2px var(--sp-4); padding: 0;
	background: transparent; border: none; box-shadow: none;
}
.rail-more[open] > summary { background: var(--surface-2); color: var(--fg); }
.rail-more-pop .rail-item .label { opacity: 1; display: inline; }   /* always labelled in the popout */
/* popout groups: `more-secondary` = colour-mode + borders (their home on narrow screens);
   `more-optional` = add-fact + tour (overflow, only when the rail is too short for them inline) */
.rail-more-pop .more-optional { display: none; }
@media (min-width: 768px) { .rail-more-pop .more-secondary { display: none; } }

/* categories filter panel inside the rail */
.rail-cats { padding: var(--sp-1) var(--sp-2) var(--sp-2); display: flex; flex-direction: column; gap: 2px; }
/* a .switch whose track carries the category colour, so it replaces the old checkbox + .dot pair.
   The tinted ring keeps that colour readable while the category is switched off, which is what
   the always-visible .dot used to do. */
.rail-cat { padding: var(--sp-1); white-space: nowrap; }
.rail-cat .switch-track { border-color: color-mix(in srgb, var(--switch-on) 55%, var(--border)); }
.rail-cat-actions { display: flex; flex-direction: column; gap: 2px; margin-top: var(--sp-1); }
.rail-cat-actions button { background: transparent; border: none; color: var(--fg-muted); text-align: left; padding: var(--sp-1); font-size: .76rem; }
.rail-cat-actions button:hover { color: var(--brand); }

/* category dot */
.dot { display: inline-block; width: .7rem; height: .7rem; border-radius: 50%; flex: 0 0 auto; }

/* ---- Map ------------------------------------------------------------------ */
.map-wrap { grid-area: map; position: relative; display: flex; flex-direction: column; }
#map { flex: 1 1 auto; min-height: 0; background: var(--surface-2); }
.leaflet-tile-pane { filter: var(--map-filter); }   /* dark-mode map tint */
.leaflet-container { background: var(--surface-2); font-family: var(--font); }

/* the historical-borders toggle is now a Leaflet control (engine addControlBorders),
   so it inherits the .leaflet-bar look below; only its active state is custom. */

/* (a) make Leaflet's own layers control match the map-control buttons + not touch them */
.leaflet-control-layers { border: 1px solid var(--border) !important; border-radius: var(--radius-sm) !important; box-shadow: var(--shadow) !important; background: var(--surface) !important; }
.leaflet-control-layers-toggle { width: 2.4rem !important; height: 2.4rem !important; background-size: 20px 20px !important; }
.leaflet-control-layers-expanded { padding: var(--sp-2) var(--sp-3) !important; color: var(--fg) !important; }

/* (c) unify ALL on-map controls on the layers-control look: zoom (#1) + the custom
   center/locate button share `.leaflet-bar`; theme them + the borders btn (#3) as one family. */
/* selectors are doubled with `.leaflet-touch` to outrank Leaflet's own
   `.leaflet-touch .leaflet-bar …` sizing/radius rules on touch devices. */
.leaflet-bar, .leaflet-touch .leaflet-bar { border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.leaflet-bar a, .leaflet-touch .leaflet-bar a {
	width: 2.4rem; height: 2.4rem; line-height: 2.4rem;
	background: var(--surface); color: var(--fg-muted);
	border-bottom: 1px solid var(--border);
}
.leaflet-bar a:hover, .leaflet-touch .leaflet-bar a:hover { color: var(--fg); background: var(--surface-2); }
.leaflet-bar a:first-child, .leaflet-touch .leaflet-bar a:first-child { border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); }
.leaflet-bar a:last-child, .leaflet-touch .leaflet-bar a:last-child { border-bottom: none; border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
.leaflet-bar a.leaflet-disabled { background: var(--surface); color: var(--border); }
/* toggled-on state for the borders control (mirrors the old .map-ctrl-btn.active) */
.leaflet-bar a.leaflet-active, .leaflet-bar a.leaflet-active:hover { background: var(--brand); color: var(--brand-fg); }
/* (g) rail expand/collapse reads as the menu, capitalised */
.rail-toggle .label { letter-spacing: .03em; }
/* (i) links inside an empty-pane message */
.pane-empty a { color: var(--brand); }

/* (e) date control re-skinned to style.css tokens (theme-aware; overrides dwh-date-control.css) */
.dwh-dc-trigger { color: var(--fg) !important; background: transparent !important; border-color: transparent !important; font-family: var(--font); border-radius: var(--radius-sm) !important; font-weight: 700; }
.dwh-dc-trigger:hover { border-color: var(--border) !important; }
.dwh-dc-panel { background: var(--surface) !important; border-color: var(--border) !important; color: var(--fg) !important; font-family: var(--font); }
.dwh-dc-tile, .dwh-dc-tile-group, .dwh-dc-tile-main, .dwh-dc-tile-confirm, .dwh-dc-breadcrumb, .dwh-dc-panel input {
	background-color: var(--surface-2) !important; color: var(--fg) !important; border-color: var(--border) !important;
}
.dwh-dc-tile:hover:not(:disabled), .dwh-dc-tile-main:hover { background-color: color-mix(in srgb, var(--brand) 14%, var(--surface-2)) !important; }
.dwh-dc-tile.dc-active, .dwh-dc-tile-group.dc-active { background-color: var(--brand) !important; color: var(--brand-fg) !important; border-color: var(--brand) !important; }
.dwh-dc-tile.dc-in-range, .dwh-dc-tile-group.dc-in-range { background-color: color-mix(in srgb, var(--brand) 22%, var(--surface-2)) !important; border-color: var(--brand) !important; }
.dwh-dc-tile.dc-current { border-color: var(--brand) !important; }
.dwh-dc-backdrop { background: rgba(0, 0, 0, .45) !important; }

/* (P4.5/a) date panel: Bootstrap-free, theme-aware, compact restyle. The shared
   template uses Bootstrap utility/component classes that are unstyled on the map
   app — replace them with token-based rules, all scoped to .dwh-dc-panel. */
/* layout-utility shim (only the classes the template actually uses) */
.dwh-dc-panel .d-flex { display: flex; }
.dwh-dc-panel .flex-wrap { flex-wrap: wrap; }
.dwh-dc-panel .align-items-center { align-items: center; }
.dwh-dc-panel .gap-1 { gap: var(--sp-1); }
.dwh-dc-panel .gap-2 { gap: var(--sp-2); }
.dwh-dc-panel .mb-0 { margin-bottom: 0; }
.dwh-dc-panel .mb-1 { margin-bottom: var(--sp-1); }
.dwh-dc-panel .ms-auto { margin-left: auto; }
.dwh-dc-panel .w-100 { width: 100%; }
.dwh-dc-panel .small { font-size: .8rem; }
.dwh-dc-panel .text-muted { color: var(--fg-muted); font-size: .8rem; }
.dwh-dc-panel .row { display: flex; }
.dwh-dc-panel .row.g-1 { gap: var(--sp-1); }
.dwh-dc-panel .col-6 { flex: 1 1 0; min-width: 0; }
/* tighten the header/body so the top rows aren't cramped-then-loose */
.dwh-dc-panel-header { padding: var(--sp-2) var(--sp-3); gap: var(--sp-2); }
.dwh-dc-panel-body { padding: var(--sp-2) var(--sp-3) var(--sp-3); }

/* a.1 close button — BS .btn-close has no glyph/position without Bootstrap */
.dwh-dc-panel-header .btn-close {
	margin-left: auto; flex: 0 0 auto; width: 1.6rem; height: 1.6rem; padding: 0;
	display: inline-flex; align-items: center; justify-content: center;
	border: none; border-radius: 999px; background: var(--surface-2); color: var(--fg-muted);
	cursor: pointer; opacity: 1;
}
.dwh-dc-panel-header .btn-close::before { content: "\00d7"; font-size: 1.1rem; line-height: 1; }
.dwh-dc-panel-header .btn-close:hover { background: var(--brand); color: var(--brand-fg); }

/* a.2 text input fills available width */
.dwh-dc-panel input[type="text"], .dwh-dc-panel .form-control {
	width: 100%; box-sizing: border-box;
	padding: var(--sp-1) var(--sp-2); font-size: .9rem; font-family: var(--font);
	border-radius: var(--radius-sm);
}
.dwh-dc-panel input[type="text"]:focus { outline: 2px solid var(--brand); outline-offset: -1px; }

/* a.3 button variants (preset / era / suggestion) — token colours so text shows in every theme */
.dwh-dc-panel .btn {
	padding: var(--sp-1) var(--sp-3); font-size: .82rem; line-height: 1.2; font-family: var(--font);
	border: 1px solid var(--border); border-radius: var(--radius-sm);
	background: var(--surface-2); color: var(--fg); cursor: pointer;
}
.dwh-dc-panel .btn:hover { border-color: var(--brand); }
.dwh-dc-panel .btn-primary { background: var(--brand); color: var(--brand-fg); border-color: var(--brand); }
.dwh-dc-panel .btn-outline-primary, .dwh-dc-panel .btn-outline-info,
.dwh-dc-panel .btn-outline-secondary, .dwh-dc-panel .btn-outline-success {
	background: transparent; color: var(--fg);
}
.dwh-dc-panel .btn-outline-primary:hover, .dwh-dc-panel .btn-outline-info:hover,
.dwh-dc-panel .btn-outline-secondary:hover, .dwh-dc-panel .btn-outline-success:hover {
	background: color-mix(in srgb, var(--brand) 14%, var(--surface-2)); border-color: var(--brand);
}
.dwh-dc-panel .btn-link { background: none; border: none; color: var(--fg-muted); padding: 0 var(--sp-1); text-decoration: none; }
.dwh-dc-panel .btn-link:hover { color: var(--brand); }

/* a.4 the range-mode and day-precision opt-ins are shared .switch toggles; only the
   font size differs from the default, to match the rest of the panel */
.dwh-dc-panel .switch { font-size: .82rem; }

/* theme the remaining hardcoded-colour bits (badge / breadcrumb) for dark/kids */
.dwh-dc-selected-badge { background: var(--surface-2) !important; color: var(--fg) !important; }
.dwh-dc-breadcrumb-btn { color: var(--brand) !important; }
.dwh-dc-breadcrumb-btn.dc-current { color: var(--fg) !important; }

/* blurry borders for imprecise geometry (mirrors styles.css hcg-bp*) */
.hcg-bp1 { filter: blur(3px); }
.hcg-bp2 { filter: blur(1.5px); }

/* ---- Lesson dock ---------------------------------------------------------- */
/* Soft brand highlight signals the dock is live and interactive. */
.lesson-dock { background: var(--surface); display: flex; flex-direction: column; z-index: 600; animation: dock-pulse 1.5s ease 1; }
/* The dock's own height is auto — head + measured body + controls, all stable for the lesson
   (the body's height is set from JS, see measureDockHeight). max-height is only a backstop so a
   long lesson can never eat the map. */
.lesson-dock.docked {
	flex: 0 0 auto; max-height: 60%;
	border-top: 2px solid var(--brand);
	box-shadow: 0 -3px 16px color-mix(in srgb, var(--brand) 26%, transparent);
}
.lesson-dock.float {
	position: absolute; left: var(--sp-4); bottom: calc(var(--sp-4) + 1.25rem);
	width: min(26rem, 60%); max-height: 60%;
	border: 1px solid var(--brand); border-radius: var(--radius);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent), var(--shadow-lg);
}
@keyframes dock-pulse {
	0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 55%, transparent); }
	100% { box-shadow: 0 -3px 16px color-mix(in srgb, var(--brand) 26%, transparent); }
}
.dock-head {
	display: flex; align-items: center; gap: var(--sp-2);
	padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border);
	background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}
.dock-head > i { color: var(--brand); }
.lesson-dock.float .dock-head { cursor: grab; }
.lesson-dock.float .dock-head:active { cursor: grabbing; }
.dock-title { flex: 1 1 auto; min-width: 0; font-weight: 700; font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dock-head .iconbtn { width: 1.9rem; height: 1.9rem; }
/* collapsed = head only */
.lesson-dock.collapsed { height: auto; }
/* min/max bound whatever measureDockHeight computes; overflow only bites past the max */
.dock-body { flex: 1 1 auto; min-height: 4.5rem; max-height: 22rem; padding: var(--sp-3); overflow-y: auto; }
.dock-step-name { font-weight: 600; font-size: .95rem; margin-bottom: var(--sp-1); }
.dock-text { font-size: .88rem; line-height: 1.5; margin: 0; }
/* One wrapping row instead of media queries: the dock's width depends on `dockPos`
   (float is min(26rem, 60%)) as much as on the viewport, so it must adapt to its own box.
   Wide  → [<] 3/8 [>]  [audio]  1519  on one line, audio capped so it can't stretch.
   Narrow → the 14rem basis can't be met and the audio wraps to its own full-width line. */
.dock-controls { flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
	padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--border); }
.dock-nav { display: flex; align-items: center; gap: var(--sp-2); }
.dock-nav .readout { font-variant-numeric: tabular-nums; }
.dock-audio { flex: 1 1 12rem; min-width: 0; max-width: 22rem; }
.dock-audio audio { display: block; width: 100%; height: 2rem; }
.dock-controls .era { margin-left: auto; }

/* ---- Right-click "add fact" menu ------------------------------------------ */
/* Position and visibility come from Vue (contextMenu state); these were inline styles. */
.dropdown-context {
	position: absolute; z-index: 2500; list-style: none; margin: 0; padding: .35rem;
	background: var(--surface); border: 1px solid var(--border);
	border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
}
.dropdown-context a { text-decoration: none; color: var(--fg); }

/* ---- Right pane ----------------------------------------------------------- */
.right {
	grid-area: right;
	display: flex; flex-direction: column;
	background: var(--surface); border-left: 1px solid var(--border);
	overflow: hidden;
}
.pane-tabs { display: flex; border-bottom: 1px solid var(--border); }
.pane-tab {
	flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
	padding: var(--sp-2) var(--sp-1); background: transparent; border: none;
	border-bottom: 2px solid transparent; color: var(--fg-muted); font-size: .7rem;
}
.pane-tab i { font-size: 1rem; }
.pane-tab:hover { color: var(--fg); }
.pane-tab.active { color: var(--brand); border-bottom-color: var(--brand); }
.pane-tab .count {
	font-size: .6rem; background: var(--surface-2); color: var(--fg-muted);
	border-radius: 999px; padding: 0 .35rem; min-width: 1.1rem;
}
.pane-body { flex: 1 1 auto; overflow-y: auto; padding: var(--sp-3); }
.pane-empty { color: var(--fg-muted); text-align: center; padding: var(--sp-6) var(--sp-3); font-size: .9rem; }
.pane-cap { padding: var(--sp-2) var(--sp-3); font-size: .72rem; color: var(--fg-muted); text-align: center; border-top: 1px solid var(--border); font-variant-numeric: tabular-nums; }

/* fact card */
.card {
	display: flex; gap: var(--sp-3); padding: var(--sp-3);
	background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
	margin-bottom: var(--sp-3); cursor: pointer; box-shadow: var(--shadow);
	transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.card:hover { border-color: var(--brand); transform: translateY(-1px); box-shadow: var(--shadow-lg); }
.card.active { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand) inset; }
.card-thumb { width: 64px; height: 64px; border-radius: var(--radius-sm); object-fit: cover; flex: 0 0 auto; background: var(--surface-2); }
.card-body { min-width: 0; flex: 1 1 auto; }
.card-title { margin: 0 0 var(--sp-1); font-size: .95rem; display: flex; align-items: center; gap: var(--sp-2); }
.card-title .cat-ico {
	display: inline-flex; align-items: center; justify-content: center;
	width: 1.4rem; height: 1.4rem; border-radius: 50%; color: #fff; font-size: .7rem; flex: 0 0 auto;
}
.card-desc { margin: 0; font-size: .82rem; color: var(--fg-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card-meta { margin-top: var(--sp-2); font-size: .72rem; color: var(--fg-muted); text-align: right; font-variant-numeric: tabular-nums; }

/* image carousel (detail hero + list/search cards) */
.fact-carousel { position: relative; }
.fact-carousel-thumb { flex: 0 0 auto; }
.fact-carousel .card-thumb, .fact-carousel .detail-hero { touch-action: pan-y; }
.fact-dots { display: flex; justify-content: center; gap: var(--sp-2); flex-wrap: wrap; }
.fact-carousel-hero .fact-dots { margin-top: calc(-1 * var(--sp-2)); margin-bottom: var(--sp-3); }
.fact-carousel-thumb .fact-dots { gap: 4px; margin-top: 4px; }
.fact-dot {
	width: 8px; height: 8px; padding: 0; border-radius: 50%; cursor: pointer;
	background: transparent; border: 1px solid var(--fg-muted);
	transition: background var(--transition), border-color var(--transition);
}
.fact-carousel-thumb .fact-dot { width: 6px; height: 6px; }
.fact-dot:hover { border-color: var(--brand); }
.fact-dot.active { background: var(--brand); border-color: var(--brand); }

/* hero: tap/click opens the full uncropped image in a lightbox */
.fact-carousel-hero .detail-hero { cursor: zoom-in; }
.fact-zoom {
	position: absolute; top: var(--sp-2); right: var(--sp-2);
	display: inline-flex; align-items: center; justify-content: center;
	width: 1.9rem; height: 1.9rem; border: none; border-radius: var(--radius-sm);
	background: color-mix(in srgb, var(--surface) 70%, transparent); color: var(--fg);
	cursor: zoom-in; opacity: 0; transition: opacity var(--transition);
}
.fact-carousel-hero:hover .fact-zoom, .fact-zoom:focus-visible { opacity: 1; }
@media (hover: none) { .fact-zoom { opacity: 1; } }   /* always visible on touch */

.fact-lightbox {
	position: fixed; inset: 0; z-index: 2400;
	display: flex; align-items: center; justify-content: center;
	background: rgba(0, 0, 0, .85); padding: var(--sp-4);
}
.fact-lightbox-img { max-width: 92vw; max-height: 88vh; object-fit: contain; border-radius: var(--radius-sm); }
.fact-lightbox-close {
	position: absolute; top: var(--sp-3); right: var(--sp-3);
	display: inline-flex; align-items: center; justify-content: center;
	width: 2.4rem; height: 2.4rem; border: none; border-radius: var(--radius-sm);
	background: rgba(255, 255, 255, .15); color: #fff; font-size: 1.1rem; cursor: pointer;
}
.fact-lightbox-close:hover { background: rgba(255, 255, 255, .28); }
.fact-lightbox-nav {
	position: absolute; top: 50%; transform: translateY(-50%);
	display: inline-flex; align-items: center; justify-content: center;
	width: 2.6rem; height: 2.6rem; border: none; border-radius: 50%;
	background: rgba(255, 255, 255, .15); color: #fff; font-size: 1.1rem; cursor: pointer;
}
.fact-lightbox-nav.prev { left: var(--sp-3); }
.fact-lightbox-nav.next { right: var(--sp-3); }
.fact-lightbox-nav:hover:not(:disabled) { background: rgba(255, 255, 255, .28); }
.fact-lightbox-nav:disabled { opacity: .35; cursor: default; }
.fact-lightbox .fact-dots { position: absolute; bottom: var(--sp-4); left: 0; right: 0; }
.fact-lightbox .fact-dot { border-color: rgba(255, 255, 255, .6); }
.fact-lightbox .fact-dot.active { background: #fff; border-color: #fff; }

/* selected fact detail */
.detail-hero { width: 100%; height: 9rem; object-fit: cover; object-position: 50% 20%; border-radius: var(--radius); background: var(--surface-2); margin-bottom: var(--sp-3); display: block; }
.detail-title { margin: 0 0 var(--sp-2); font-size: 1.2rem; }
.detail-section h4 { margin: var(--sp-4) 0 var(--sp-1); font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-muted); }
.detail-text { font-size: .9rem; line-height: 1.5; text-align: justify; }
.detail-list { list-style: none; padding: 0; margin: 0; font-size: .88rem; line-height: 1.5; }
.detail-list li { margin-bottom: var(--sp-1); }
.chip {
	display: inline-block; padding: .15rem .55rem; margin: 0 .25rem .25rem 0;
	background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px;
	font-size: .78rem; color: var(--fg); text-decoration: none;
}
.chip:hover { border-color: var(--brand); color: var(--brand); }
/* back bar shown above a selected fact — signals the list is still behind it */
.detail-back {
	display: flex; align-items: center; gap: var(--sp-2); width: 100%;
	margin: 0 0 var(--sp-3); padding: var(--sp-2) var(--sp-3);
	background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
	color: var(--brand); font-size: .85rem; text-align: left;
}
.detail-back:hover { border-color: var(--brand); }
.detail-back .detail-back-hint { margin-left: auto; color: var(--fg-muted); font-size: .72rem; font-style: italic; }

/* ---- Bottom bar ----------------------------------------------------------- */
.bottombar {
	grid-area: bottom;
	display: flex; align-items: center; gap: var(--sp-4);
	padding: 0 var(--sp-3); font-size: .78rem; color: var(--fg-muted);
	background: var(--surface); border-top: 1px solid var(--border);
	overflow: hidden; white-space: nowrap;
}
.legend { display: flex; align-items: center; gap: var(--sp-3); flex: 1 1 auto; overflow-x: auto; }
.legend-item {
	display: inline-flex; align-items: center; gap: var(--sp-1);
	/* themed chip so it reads as clickable and contrasts in every mode
	   (the default <button> face was light-grey on light-grey text in dark mode) */
	background: var(--surface-2); border: 1px solid var(--border); color: var(--fg);
	padding: 1px var(--sp-2); border-radius: 999px;
}
.legend-item:hover { border-color: var(--brand); color: var(--brand); }
.legend-item.off { opacity: .45; }
.bottombar .readout { font-variant-numeric: tabular-nums; }
/* The population readout is the first thing to go when the bar gets tight: it is context,
   not state. Hidden below the full-XL tier; see the breakpoint block further down. */
.pop-readout { flex: 0 0 auto; }

/* ---- Leaflet marker (custom div icon, no awesome-markers dependency) ------ */
.em-pin {
	display: flex; align-items: center; justify-content: center;
	width: 30px; height: 30px; border-radius: 50% 50% 50% 0;
	transform: rotate(-45deg); border: 2px solid rgba(255,255,255,.9);
	box-shadow: var(--shadow); color: #fff;
}
.em-pin i { transform: rotate(45deg); font-size: .8rem; }
.em-pin.sel { outline: 3px solid var(--accent); outline-offset: 1px; z-index: 1000; }

/* ---- Responsive helpers (revealed only in the relevant mode) -------------- */
.hamburger, .search-btn, .counts-row, .rail-extra { display: none; }
.drawer-backdrop { position: fixed; inset: 0; z-index: 1900; background: rgba(0, 0, 0, .4); }
.counts-row {
	align-items: center; gap: var(--sp-2);
	padding: var(--sp-1) var(--sp-3); font-size: .72rem; color: var(--fg-muted);
	border-bottom: 1px solid var(--border); white-space: nowrap; overflow-x: auto;
	font-variant-numeric: tabular-nums;
}
.counts-row b { color: var(--fg); }
.pane-search {
	display: none;   /* shown when the top-bar search is unavailable (narrow / portrait) */
	width: 100%; margin-bottom: var(--sp-3); padding: var(--sp-2) var(--sp-3);
	background: var(--surface-2); color: var(--fg);
	border: 1px solid var(--border); border-radius: 999px; outline: none;
}

/* search pane (forked dwh-search-pane-next) */
.search-pane .pane-search { display: block; margin-bottom: var(--sp-2); }
.search-bar { display: flex; align-items: center; gap: var(--sp-1); }
.search-advanced { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-2) 0; font-size: .8rem; color: var(--fg-muted); }
.search-advanced input { width: 5rem; padding: var(--sp-1) var(--sp-2); background: var(--surface-2); color: var(--fg); border: 1px solid var(--border); border-radius: var(--radius-sm); }
/* each switch takes a full row under the year pair; its transparent input must keep
   covering the label, not inherit the 5rem year-input width above */
.search-advanced .switch { flex: 1 1 100%; }
.search-advanced .switch input { width: 100%; padding: 0; border: none; background: none; }
.search-advanced label.is-disabled { opacity: .5; }
.search-advanced input:disabled { cursor: not-allowed; }
.search-order { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; margin: var(--sp-2) 0; }
.search-order .iconbtn { width: 2rem; height: 1.9rem; font-size: .8rem; }
.search-count { flex: 1 1 100%; font-size: .72rem; color: var(--fg-muted); margin-bottom: var(--sp-1); }
.search-special { padding: var(--sp-2) 0; }
.search-special h4 { margin: 0 0 var(--sp-2); font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-muted); }
.search-special .chip { cursor: pointer; }
.rail-extra { flex-direction: column; gap: 2px; padding: 0 var(--sp-1) var(--sp-2); border-top: 1px solid var(--border); }
.too-small {
	display: none; position: fixed; inset: 0; z-index: 9999;
	flex-direction: column; align-items: center; justify-content: center;
	gap: var(--sp-3); padding: var(--sp-5); text-align: center;
	background: var(--bg); color: var(--fg);
}
.too-small i { font-size: 2.5rem; color: var(--brand); }

/* ============================================================================
   RESPONSIVE — arrangement by ORIENTATION, feature richness by WIDTH.
     Landscape → side-by-side (rail | map | right pane), at every width.
     Portrait  → stacked (map over the info pane); rail = hamburger drawer.
   ============================================================================ */

/* --- SIDE-BY-SIDE (landscape): rail overlays the map's left --- */
@media (orientation: landscape) {
	.rail {
		position: absolute; left: 0; top: var(--topbar-h); bottom: var(--bottom-h);
		width: var(--rail-w); z-index: 1100; transition: width var(--transition);
	}
	#app .leaflet-left { transition: margin-left var(--transition); margin-left: var(--rail-w); }
	.lesson-dock.docked { margin-left: var(--rail-w); transition: margin-left var(--transition); }
	.lesson-dock.float { left: calc(var(--rail-w) + var(--sp-4)); }
}
/* full (>=1024 landscape): rail can expand, right pane can collapse */
@media (min-width: 1024px) and (orientation: landscape) {
	#app.rail-expanded .rail { width: var(--rail-w-expanded); }
	#app.rail-expanded .leaflet-left { margin-left: var(--rail-w-expanded); }
	#app.rail-expanded .lesson-dock.docked { margin-left: var(--rail-w-expanded); }
	#app.rail-expanded .lesson-dock.float { left: calc(var(--rail-w-expanded) + var(--sp-4)); }
	#app.right-collapsed { grid-template-columns: 1fr 0; }
}
/* compact (<1024 landscape): icon rail, no expand, narrower pane */
@media (max-width: 1023px) and (orientation: landscape) {
	:root { --right-w: clamp(16rem, 30vw, 20rem); }
	.pop-readout { display: none; }                            /* world population: full XL only */
	.rail-item .label { display: none; }                       /* icon-only by default */
	#app.rail-expanded .rail { width: var(--rail-w-expanded); }/* expand toggle DOES widen it */
	#app.rail-expanded .rail-item .label { display: inline; }
}

/* --- STACKED (portrait) --- */
@media (orientation: portrait) {
	#app {
		grid-template-columns: 1fr;
		grid-template-rows: var(--topbar-h) 60dvh 1fr;
		grid-template-areas: "topbar" "map" "right";
	}
	.right { grid-area: right; border-left: none; border-top: 1px solid var(--border); }
	.rail {
		position: fixed; left: 0; top: var(--topbar-h); bottom: 0; width: var(--rail-w-expanded);
		transform: translateX(-100%); transition: transform var(--transition);
		z-index: 2000; border-right: 1px solid var(--border);
	}
	#app.drawer-open .rail { transform: translateX(0); }
	.rail-item .label { opacity: 1; }                    /* labelled drawer */
	.rail-toggle { display: none; }
	.hamburger { display: inline-flex; }
	.bottombar { display: none; }
	.counts-row { display: flex; }
	.topbar .search { display: none; }
	.pane-search { display: block; }
	/* lesson dock: stays at the bottom of the 60dvh map; float disabled (cramped) */
	.lesson-dock.docked { margin-left: 0; }
	.lesson-dock.float {
		position: static; left: auto; bottom: auto; width: auto;
		border: none; border-top: 2px solid var(--brand); border-radius: 0; box-shadow: none;
	}
	/* the map row is only 60dvh here, so cap both modes harder */
	.lesson-dock.docked, .lesson-dock.float { max-height: 42%; }
	.dock-body { max-height: 11rem; }
	.lesson-dock.float .dock-head { cursor: default; }
}
/* comfortable portrait (>=768): keep a search button in the top bar */
@media (orientation: portrait) and (min-width: 768px) {
	.search-btn { display: inline-flex; }
}

/* --- NARROW (<768, either orientation): move top-bar chrome into the menu --- */
@media (max-width: 767px) {
	.bottombar { display: none; }                  /* too cramped — counts move to the pane */
	.counts-row { display: flex; }
	.topbar .search, .search-btn, .theme-btn { display: none; }   /* search via the Search tab */
	.dwh-borders-control { display: none; }         /* borders → rail */
	.lang-menu { display: none; }                  /* language → rail (n) */
	.leaflet-control-layers { display: none; }     /* base-map layers → rail (m) */
	.pane-tab-nolocation { display: none; }        /* hide 'unknown location' tab to save space (o) */
	.rail-extra { display: flex; }                 /* language as a direct rail item */
	.rail-more { display: block; }                 /* >> popout home for colour-mode + borders */
	.pane-search { display: block; }
	.topbar { gap: var(--sp-2); padding: 0 var(--sp-2); }
	.timectl .year { font-size: 1.1rem; width: 4.5rem; }
	.timectl .era { display: none; }
	.brand .name { display: none; }
	/* compact pane tabs only on small screens (column design is fine on larger ones) */
	.pane-tab { flex-direction: row; justify-content: center; gap: var(--sp-1); font-size: .76rem; white-space: nowrap; overflow: hidden; }
	.pane-tab i { font-size: .92rem; }
}

@media ((orientation: landscape) and (max-width: 768px)) or ((orientation: portrait) and (max-width: 480px)) {
	.pane-tab-label { display: none; }
}

/* (c) Tiny screens (largest side < 768 ⇒ both axes < 768): the pane tabs already
   carry per-pane counts, so drop the redundant counts-row. */
@media (max-width: 767px) and (max-height: 767px) {
	.counts-row { display: none; }
}

/* (d) Short landscape (no hamburger ⇒ icon rail): not enough height for every
   item AND the MENU toggle — drop the optional items so the toggle stays visible. */
@media (orientation: landscape) and (max-height: 480px) {
	.rail-item.rail-item-optional { display: none; }   /* moved into the >> popout */
	.rail-more { display: block; }                     /* reveal the overflow popout */
	.rail-more-pop .more-optional { display: flex; }   /* add-fact + tour join the popout here */
}

/* --- Progressive degradation --- */
@media (max-width: 400px) {
	.topbar [aria-label="Share"], .leaflet-control-zoom, .leaflet-control-scale { display: none; }
}
@media (max-width: 330px) {
	.leaflet-popup-content { font-size: .8rem; max-width: 180px; }
}

/* --- Device too small: show a notice, hide the (unusable) app chrome --- */
@media (max-width: 319px), (max-height: 319px) {
	.too-small { display: flex; }
}

/* ===================================================================
   Guided tour (em-tour.js) — Bootstrap-free, theme-aware.
   ==================================================================== */
/* Sits above all app chrome (shell uses z-index up to ~2000). Geometry is set
   inline by em-tour.js; `.full` dims everything (intro), `.spotlight` cuts a
   transparent hole over the target via a huge box-shadow. */
.tour-overlay {
	position: fixed; z-index: 3000; pointer-events: none;
	border-radius: var(--radius-sm);
	transition: top .2s ease, left .2s ease, width .2s ease, height .2s ease;
}
.tour-overlay.full { background: rgba(8, 12, 18, .55); border-radius: 0; }
.tour-overlay.spotlight {
	background: transparent;
	box-shadow: 0 0 0 9999px rgba(8, 12, 18, .55);
	outline: 2px solid var(--brand); outline-offset: 0;
}

.popover-tour {
	position: fixed; z-index: 3001;
	width: min(420px, calc(100vw - 16px));
	background: var(--surface); color: var(--fg);
	border: 1px solid var(--border); border-radius: var(--radius);
	box-shadow: var(--shadow-lg);
	font-size: .9rem;
}
.popover-tour.popover-tour-center {
	top: 50%; left: 50%; transform: translate(-50%, -50%);
}
.popover-tour .hidden { display: none !important; }

.popover-tour .tour-exit {
	position: absolute; top: var(--sp-2); right: var(--sp-2);
	width: 1.6rem; height: 1.6rem; padding: 0; line-height: 1;
	border: none; border-radius: 999px;
	background: var(--surface-2); color: var(--fg-muted); cursor: pointer;
}
.popover-tour .tour-exit::before { content: "\00d7"; font-size: 1.1rem; }
.popover-tour .tour-exit:hover { background: var(--brand); color: var(--brand-fg); }

.popover-tour .popover-header {
	margin: 0; padding: var(--sp-3) var(--sp-5) var(--sp-3) var(--sp-3);
	font-size: 1rem; font-weight: 700;
	background: var(--brand); color: var(--brand-fg);
	border-radius: var(--radius) var(--radius) 0 0;
}
.popover-tour .popover-body { padding: var(--sp-3); line-height: 1.45; }

.popover-tour .tour-tab-links {
	display: flex; justify-content: center; gap: var(--sp-1);
	list-style: none; margin: var(--sp-3) 0 0; padding: 0;
}
.popover-tour .tour-tab-links li { display: inline-block; }
.popover-tour .tour-tab-links a {
	display: block; width: 8px; height: 8px; border-radius: 999px;
	background: var(--border); cursor: pointer; transition: width .15s, background .15s;
}
.popover-tour .tour-tab-links a.active { width: 20px; background: var(--brand); }

.popover-tour .popover-footer {
	display: flex; align-items: center; gap: var(--sp-2);
	padding: var(--sp-3); border-top: 1px solid var(--border);
}
.popover-tour .popover-footer .btn {
	padding: var(--sp-1) var(--sp-4); border-radius: var(--radius-sm);
	border: 1px solid var(--border); background: var(--surface-2); color: var(--fg);
	font-size: .85rem; cursor: pointer;
}
.popover-tour .popover-footer .btn:hover { border-color: var(--brand); }
.popover-tour .popover-footer .tour-next,
.popover-tour .popover-footer .tour-finish {
	margin-left: auto; background: var(--brand); color: var(--brand-fg); border-color: var(--brand);
}

/* ===================================================================
   Toasts (dwh-messages) — Bootstrap-free re-skin, scoped to #messages.
   The shared template emits Bootstrap classes (alert/btn-close/float-*);
   the map app has no Bootstrap, so theme them with tokens here. Pages that do
   load Bootstrap don't load style.css, so they keep the stock look.
   ==================================================================== */
#messages .row { display: block; margin: 0 0 var(--sp-2); }
#messages .alert {
	position: relative; margin: 0;
	padding: var(--sp-3) 2.2rem var(--sp-3) var(--sp-3);
	background: var(--surface); color: var(--fg);
	border: 1px solid var(--border); border-left: 4px solid var(--fg-muted);
	border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
	font-size: .9rem; line-height: 1.4;
}
#messages .alert a { color: var(--brand); }
#messages .alert-info    { border-left-color: var(--brand); }
#messages .alert-success { border-left-color: #2e9e5b; }
#messages .alert-warning { border-left-color: #d99a00; }
#messages .alert-danger  { border-left-color: #d65745; }
/* close X (top-right) + full-width message — neutralise the BS float layout */
#messages .float-start { float: none; display: block; }
#messages .float-end { position: absolute; top: var(--sp-1); right: var(--sp-1); float: none; }
#messages .btn-close {
	width: 1.6rem; height: 1.6rem; padding: 0; opacity: 1; cursor: pointer;
	display: inline-flex; align-items: center; justify-content: center;
	border: none; border-radius: 999px; background: transparent; color: var(--fg-muted);
}
#messages .btn-close::before { content: "\00d7"; font-size: 1.1rem; line-height: 1; }
#messages .btn-close:hover { background: var(--surface-2); color: var(--fg); }

/* ===================================================================
   Trace panel (#traceWindow) — troubleshooting overlay, opt-in via
   ?traceEnabled=1. Rendered only when config.traceEnabled is true, so
   it costs nothing in normal use. Theme-aware via tokens.
   ==================================================================== */
#traceWindow {
	position: fixed; right: var(--sp-3); bottom: var(--sp-3);
	width: min(320px, calc(100vw - var(--sp-3) * 2));
	z-index: 2400;                       /* above the panes, below toasts (2200) + context menu (2500) */
	background: var(--surface); color: var(--fg);
	border: 1px solid var(--border); border-radius: var(--radius-sm);
	box-shadow: var(--shadow-lg);
	transition: top .3s, bottom .3s;
}
#traceWindow .trace-header {
	padding: var(--sp-2) var(--sp-3);
	background: var(--brand); color: #fff;
	border-radius: var(--radius-sm) var(--radius-sm) 0 0;
	font-size: .85rem; font-weight: 600; cursor: pointer;
	user-select: none;
}
#trace-body {
	max-height: 40vh; min-height: 6rem;
	padding: var(--sp-2);
	overflow-y: auto; overflow-x: hidden; overflow-wrap: anywhere;
	font-family: ui-monospace, monospace; font-size: .7rem; line-height: 1.5;
	color: var(--fg-muted);
}
