:root {
  --bg-color: #0f1117;
  --panel-bg: rgba(25, 25, 35, 0.95);
  --text-main: #e4e4e7;
  --text-muted: #a1a1aa;
  --border-color: rgba(255, 255, 255, 0.15);
  --accent: #3b82f6;
  --accent-hover: #60a5fa;
}

* { 
  box-sizing: border-box; 
  margin: 0; 
  padding: 0; 
}

body, html {
  width: 100%;
  height: 100%;
  overflow: hidden;
  font-family: "Segoe UI", system-ui, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-main);
}
@supports (height: 100dvh) {
  body, html { height: 100dvh; }
}

#app {
  position: relative;
  width: 100%; 
  height: 100%;
}

/* OpenSeadragon and Canvas Overlay */
#openseadragon1 {
  position: absolute; 
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 1;
}

#marker-canvas {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  /* Crucial: lets drag/scroll events pass through to OpenSeadragon */
  pointer-events: none;
  z-index: 2;
}
/* OSD navigator must sit above the marker canvas so markers don't bleed into the minimap */
.navigator {
  z-index: 3 !important;
}

/* Top Controls */
/* Zoom / nav controls — top-left */
#zoom-controls {
  position: absolute;
  top: 10px; left: 10px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  pointer-events: auto;
}
#zoom-top-row {
  display: flex;
  gap: 4px;
  align-items: stretch;
}
#nav-btns-row {
  display: flex;
  gap: 3px;
  align-items: flex-start;
}
#nav-square {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3px;
}
#nav-square .ctrl-btn {
  padding: 5px;
  width: 28px;
  height: 28px;
  border-radius: 5px;
}
#control-fullpage {
  width: 40px;
  height: auto;   /* stretches to match #nav-square combined height via align-items: stretch */
  padding: 8px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#top-bar {
  position: absolute;
  top: 10px; left: 120px; right: 10px;
  display: flex;
  justify-content: space-between;
  z-index: 10;
  pointer-events: none;
}

#left-controls, #right-controls {
  pointer-events: auto;
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
#left-controls { flex: 1; min-width: 0; }
#about-btn-col { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
/* Demo and the auto-read toggle below it: only as wide as their content plus a little side
   padding, right-aligned under the About button. On wide screens their text matches the About
   button's (see below). The auto-read toggle shows a speaker with waves when on, with a slash
   when off; gold when active. Its speaker is twice the size of the text-sized icons. */
#replay-demo-btn, #autoread-btn {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 0 4px; font-size: 10px; font-weight: 600; line-height: 1.6;
  min-width: 0; height: auto; align-self: flex-end;
}
#replay-demo-btn svg, #autoread-btn svg { flex-shrink: 0; }
#autoread-btn svg { width: 26px; height: 26px; }
@media (min-width: 700px) {
  #replay-demo-btn, #autoread-btn { font-size: 13px; gap: 6px; }
  #replay-demo-btn svg { width: 13px; height: 13px; }
  #autoread-btn svg { width: 30px; height: 30px; }
}
#autoread-btn .autoread-icon-on { display: none; }
#autoread-btn .autoread-icon-off { display: inline; }
/* On: the About button's gold, opaque, so the state reads at a glance */
#autoread-btn.active { color: #ffd080; border-color: #c8a050; background: #3a2c0e; }
#autoread-btn.active:hover { background: #4a3812; }
#autoread-btn.active .autoread-icon-on { display: inline; }
#autoread-btn.active .autoread-icon-off { display: none; }
#search-container {
  pointer-events: auto;
  display: flex;
  align-items: center;
  position: relative;
  flex: 1;
  min-width: 0;
  max-width: 320px;
}

#bottom-left-controls {
  position: absolute;
  bottom: 10px;
  left: 10px;
  z-index: 36;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
.toggle-row { display: flex; gap: 6px; }

/* Category popup */
#cat-popup-wrapper { position: relative; }
#cat-popup-btn {
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 8px;
  border-color: rgba(200, 160, 80, 0.55);
  color: #c8a050;
}
#cat-popup-btn:hover {
  background: rgba(55, 42, 10, 0.95);
  border-color: #c8a050;
  color: #ffd080;
}
#cat-popup-btn svg { width: 22px; height: 22px; }
/* Country-flag button: the category button's size and gold look, pinned just above the whole
   control group so it sits over the category button on every layout (the group is a column
   on desktop but a row on phones). Filled gold = flags on all places; gold ring = only on
   the markers shown; the caption spells the mode out, since touch has no tooltip. */
#flags-mode-btn {
  position: absolute; left: 0; bottom: calc(100% + 6px);
  width: 44px; height: 44px; padding: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  border-radius: 8px;
  border-color: rgba(200, 160, 80, 0.55);
  color: #c8a050;
}
#flags-mode-btn:hover { background: rgba(55, 42, 10, 0.95); border-color: #c8a050; color: #ffd080; }
#flags-mode-btn[data-mode="all"] { background: rgba(200, 160, 80, 0.9); border-color: #ffd080; color: #1b1408; }
/* Dark with a bright gold ring: a half-transparent gold fill washed out over the parchment. */
#flags-mode-btn[data-mode="markers"] { background: rgba(35, 27, 8, 0.95); border-color: #ffd080; color: #ffd080; box-shadow: inset 0 0 0 1px #ffd080; }
/* While the category menu is open the button lives in its top row (see dockFlagsButton in
   main.js): in the row's flow, as tall as its neighbours. */
#flags-mode-btn.in-menu { position: static; left: auto; bottom: auto; height: auto; align-self: stretch; }
#flags-mode-btn svg { flex-shrink: 0; }
.flags-mode-caption { font-size: 8.5px; font-weight: 700; line-height: 1; letter-spacing: 0.02em; }
.flags-mode-caption:empty { display: none; }
#category-popup {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 10px;
  z-index: 20;
  min-width: 220px;
  box-shadow: 0 -4px 20px rgba(0,0,0,0.5);
  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Auto-hide fade: this is the only panel in the app that closes by itself (idle timeout,
     CAT_POPUP_IDLE_MS in main.js). .hidden is a global `display:none !important`, which
     cannot be transitioned, so the auto-hide fades on .cat-fading first and adds .hidden
     only after CAT_POPUP_FADE_MS. Explicit closes (button toggle, hover-out, outside click)
     stay instant on purpose — the fade is the tell that the app closed it, not the user. */
  transition: opacity 200ms ease, transform 200ms ease;
}
#category-popup.cat-fading { opacity: 0; transform: translateY(4px); }
@media (prefers-reduced-motion: reduce) {
  #category-popup { transition: none; }
}
.cat-popup-top-row {
  display: flex;
  gap: 6px;
  margin-bottom: 10px;
}
.cat-type-sep {
  width: 100%;
  height: 0;
  border-top: 1px solid rgba(255,255,255,0.12);
  margin: 6px 0;
  flex-basis: 100%;
}
.cat-popup-solo-row {
  margin-top: 6px;
}
#category-popup .type-filter-group {
  flex-wrap: wrap;
  max-width: 300px;
  gap: 4px;
}


/* Segment button group */
.segment-btn-group {
  display: flex;
  gap: 2px;
  align-items: center;
  flex-wrap: wrap;
}
.seg-group-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  white-space: nowrap;
  padding: 0 4px 0 0;
  user-select: none;
}
#segment-buttons-wrapper { position: relative; }
.seg-hover-info {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-main);
  white-space: nowrap;
  z-index: 20;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
.seg-btn {
  background: var(--panel-bg);
  color: rgba(215, 220, 230, 0.92);
  border: 1px solid rgba(120, 130, 150, 0.55);
  border-radius: 5px;
  padding: 5px 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  cursor: pointer;
  line-height: 1;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.seg-btn:hover {
  background: rgba(50,50,60,0.95);
  color: var(--text-main);
}
.seg-btn.active {
  background: rgba(59,130,246,0.2);
  color: var(--accent);
  border-color: var(--accent);
}
/* Lost segment I button */
.seg-btn-lost {
  color: rgba(160,160,170,0.55) !important;
  border-style: dashed !important;
  border-color: rgba(120,120,140,0.4) !important;
  font-style: italic;
  letter-spacing: 0;
  cursor: help;
}
.seg-btn-lost:hover {
  background: rgba(80,60,60,0.6) !important;
  color: rgba(200,180,160,0.85) !important;
}

/* Segment I info modal */
#seg1-modal {
  position: fixed; inset: 0; background: rgba(0,0,0,0.6);
  z-index: 200; display: flex; align-items: center; justify-content: center;
}
#seg1-modal.hidden { display: none !important; }
#seg1-modal-inner {
  position: relative;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 28px 28px 22px;
  max-width: min(560px, calc(100vw - 32px));
  max-height: 85vh; overflow-y: auto;
  box-shadow: 0 16px 48px rgba(0,0,0,0.75);
  color: var(--text-main);
}
#seg1-modal-inner h3 { margin: 0 0 14px; font-size: 18px; color: var(--text-main); }
#seg1-modal-inner h4 { margin: 16px 0 6px; font-size: 14px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
#seg1-modal-inner p, #seg1-modal-inner li { font-size: 13px; line-height: 1.65; color: var(--text-main); }
#seg1-modal-inner ul { padding-left: 20px; margin: 8px 0; }
#seg1-modal-close {
  position: absolute; top: 10px; right: 12px;
  background: transparent; border: none; color: var(--text-muted);
  font-size: 24px; cursor: pointer; line-height: 1;
}
#seg1-modal-close:hover { color: #fff; }

/* Country alpha slider in country-select-bar */
#country-alpha-label {
  display: flex; align-items: center; gap: 5px;
  color: var(--text-muted); font-size: 11px; white-space: nowrap;
  margin-left: 4px;
}
#country-alpha-slider {
  width: 72px; height: 4px; accent-color: var(--accent);
  cursor: pointer; vertical-align: middle;
}

/* Buttons */
.ctrl-btn {
  background: var(--panel-bg); 
  color: var(--text-main);
  border: 1px solid var(--border-color);
  border-radius: 6px; 
  padding: 8px;
  cursor: pointer; 
  display: flex; align-items: center; justify-content: center;
  transition: background 0.2s;
}
.ctrl-btn:hover { background: rgba(50, 50, 60, 0.95); }
.toggle-btn { padding: 8px 12px; font-weight: 600; font-size: 13px; }

/* Fullscreen control, highlighted briefly at startup on touch devices. This replaces the
   old "rotate to landscape" banner: whether landscape actually helps depends on the phone's
   aspect ratio and how much chrome the browser keeps on screen, which the page can't judge,
   whereas fullscreen is a win in either orientation. Pointing at the real control also
   teaches where it is, instead of covering the map with a bar that says it. Gold rather than
   --accent blue: gold is this UI's attention colour (see the result pill, feedback button).
   Self-limiting — see the fullscreen-hint block in main.js, which stops it on first use. */
@keyframes fs-hint-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(200,160,80,0); }
  50%      { box-shadow: 0 0 0 6px rgba(200,160,80,0.32); }
}
#control-fullpage.fs-hint {
  border-color: #c8a050;
  color: #ffd080;
  animation: fs-hint-pulse 1.6s ease-in-out infinite;
}
/* Still call it out for anyone who has asked the OS to stop animating things — just hold
   the ring steady instead of pulsing it. */
@media (prefers-reduced-motion: reduce) {
  #control-fullpage.fs-hint {
    animation: none;
    box-shadow: 0 0 0 4px rgba(200,160,80,0.32);
  }
}

/* Feedback email button */
#feedback-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  text-decoration: none;
}
#feedback-btn:hover { color: #ffd080; border-color: #c8a050; background: rgba(55,42,10,0.9); }

/* About button — prominent on large screens */
.about-btn-label { display: none; }
@media (min-width: 700px) {
  #about-btn {
    padding: 0 14px;
    height: 34px;
    gap: 7px;
    font-size: 13px;
    font-weight: 600;
    border-color: rgba(160, 130, 90, 0.5);
    color: #d4b483;
  }
  #about-btn:hover {
    background: rgba(55, 42, 10, 0.95);
    border-color: #c8a050;
    color: #ffd080;
  }
  .about-btn-label { display: inline; }
}

/* Locate popup header — icon-only square buttons */
#locate-gps-btn, #locate-places-btn, #locate-roads-btn, #locate-my-country-btn {
  width: 34px;
  height: 34px;
  padding: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Countries toggle button keeps text label */
#modern-state-solo-btn { gap: 5px; height: 34px; padding: 4px 10px; }

/* Category popup All/Labels buttons — larger to house icon properly */
#toggle-all-types, #toggle-labels {
  gap: 6px;
  padding: 7px 12px;
  font-size: 13px;
}
#control-locate {
  border-color: rgba(200, 160, 80, 0.55);
  color: #c8a050;
  padding: 9px;
  width: 100%; /* stretch to match #zoom-top-row width */
}
#control-locate:hover {
  background: rgba(55, 42, 10, 0.95);
  border-color: #c8a050;
  color: #ffd080;
}
.toggle-btn-sm { padding: 10px 16px; font-size: 15px; min-height: 42px; gap: 8px; }
.toggle-btn.active { border-color: var(--accent); color: var(--accent); }

/* Search */
#search-input {
  background: var(--panel-bg); 
  color: var(--text-main);
  border: 1px solid var(--border-color); 
  border-radius: 6px;
  padding: 8px 12px; width: 100%; font-size: 14px; outline: none; box-sizing: border-box;
}
#search-input:focus { border-color: var(--accent); }

#search-results {
  position: absolute; 
  top: 40px; left: 0; right: 0;
  background: var(--panel-bg); 
  border: 1px solid var(--border-color);
  border-radius: 6px; 
  max-height: 300px; overflow-y: auto;
  display: flex; flex-direction: column; 
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}
.search-item {
  padding: 10px; cursor: pointer; 
  border-bottom: 1px solid var(--border-color);
  display: flex; align-items: center; gap: 8px;
}
.search-item:hover { background: rgba(255,255,255,0.1); }
.si-latin { font-weight: 600; }
.si-modern { font-size: 12px; color: var(--text-muted); }

/* Info Panel */
#info-panel {
  position: absolute;
  /* Sits below the right-hand button column (About / Demo / Auto-read) so those controls stay
     clickable while a place is open, instead of the panel covering them. */
  right: 20px; top: 104px; width: 280px;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 8px; padding: 0; z-index: 30;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  pointer-events: auto;
  /* flex column: #panel-scroll-body fills height, resize handle stays outside scroll */
  display: flex; flex-direction: column;
  overflow: hidden;
}
/* Landscape with mouse or trackpad: about a sixth of the screen width, never narrower than the
   280px default (1920px wide → 320px). Touch devices keep their own rules below. */
@media (orientation: landscape) and (pointer: fine) {
  #info-panel { width: max(280px, calc(100vw / 6)); }
}
/* Inner scroll zone — keeps resize handle anchored to panel bottom, not content bottom */
#panel-scroll-body {
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding: 8px 10px 8px;
  /* the panel's top (104px) plus 20px: a long place ends above the screen's bottom edge, its
     resize handle within reach (with 80px, set when the panel still sat at 60px, they were cut off) */
  max-height: calc(100vh - 124px);
}
#close-panel {
  position: absolute; top: 6px; right: 6px;
  background: transparent; border: none; color: var(--text-muted);
  font-size: 28px; cursor: pointer; line-height: 1;
  width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
}
#close-panel:hover { color: #fff; }
#panel-email-btn {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex-shrink: 0; margin-left: auto;
  background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.15);
  border-radius: 5px; color: #c4c4cc; font-size: 14px; line-height: 1;
  text-decoration: none; cursor: pointer;
}
#panel-email-btn:hover { background: rgba(255,255,255,0.14); color: #fff; border-color: rgba(255,255,255,0.35); }
/* Segment badge row — padding-right leaves room for the absolute close button */
#panel-top-row { display: flex; align-items: center; margin-bottom: 4px; padding-right: 44px; }
#panel-segment-badge { font-size: 11px; color: var(--text-muted); background: rgba(255,255,255,0.06); border: 1px solid var(--border-color); border-radius: 4px; padding: 3px 8px; white-space: nowrap; }
/* Links row: left side of the wiki-bottom row */
#panel-links { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.panel-link { font-size: 16px; color: var(--accent); text-decoration: none; background: rgba(59,130,246,0.1); border: 1px solid rgba(59,130,246,0.25); border-radius: 4px; padding: 4px 10px; }
/* Province shown inline to the right of the type label */
#panel-province:not(:empty) { margin-left: auto; font-size: 0.72rem; color: var(--text-muted); opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%; text-align: right; }
/* Tabula view label: always visible, click to open Ulm, hover to reveal preview image */
#panel-ulm-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .06em; margin-top: 14px; margin-bottom: 4px; cursor: pointer; }
#panel-ulm-label:not(.hidden) { display: block; }
#panel-ulm-section:not(.hidden) { display: none; }
#panel-ulm-label:not(.hidden):hover ~ #panel-ulm-section:not(.hidden),
#panel-ulm-section:not(.hidden):hover { display: block; }
.panel-link:hover { background: rgba(59,130,246,0.2); text-decoration: none; }
/* Language buttons (used in About panel) */
.lang-btn { padding: 4px 10px; border-radius: 4px; border: 1px solid var(--border-color); background: transparent; color: var(--text-muted); font-size: 12px; cursor: pointer; line-height: 1.5; transition: color 0.15s, border-color 0.15s; }
.lang-btn.active { border-color: var(--accent); color: var(--accent); }
.lang-btn:hover { color: var(--text-main); }
#about-lang-row { display: flex; gap: 6px; margin: 10px 0 16px; }
/* Names: Latin and modern same weight/size */
#panel-names { margin-bottom: 8px; }
#panel-latin { font-size: 20px; font-weight: 700; line-height: 1.25; margin-bottom: 2px; }
#panel-latin-transl { font-style: italic; font-size: 14px; color: var(--text-muted); line-height: 1.35; margin-bottom: 4px; }
#panel-latin-transl.hidden { display: none; }
#panel-modern { font-size: 20px; font-weight: 600; color: var(--text-muted); line-height: 1.25; }
/* Wiki section: summary full-width, then links+image row below */
#panel-seg1-note { font-size: 12px; color: var(--text-muted); margin: 6px 0 8px; padding: 5px 9px; background: rgba(136,136,153,0.12); border-left: 2px solid #888899; border-radius: 0 3px 3px 0; line-height: 1.5; }
#panel-seg1-note a { color: #a89f8c; }
#panel-wiki-section { margin-top: 10px; }
/* Podcast-style narration: the headline text for a place, with a speaker (re)play button. */
#panel-podcast { margin: 2px 0 10px; }
#panel-podcast-text { font-size: 14px; color: var(--text-main); line-height: 1.6; margin: 0 0 8px; }
.panel-podcast-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(200,160,80,0.12); border: 1px solid var(--border-color);
  color: var(--text-main); border-radius: 16px; padding: 4px 12px;
  font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.panel-podcast-btn:hover { background: rgba(200,160,80,0.20); border-color: #c8a050; color: #ffd080; }
.panel-podcast-btn:focus-visible { outline: 2px solid #c8a050; outline-offset: 2px; }
.panel-podcast-btn svg { flex-shrink: 0; }
.panel-podcast-btn .panel-podcast-icon-stop { display: none; }
.panel-share-btn { margin-left: 8px; }
.panel-podcast-btn.speaking { background: rgba(200,160,80,0.28); border-color: #c8a050; color: #ffd080; }
.panel-podcast-btn.speaking .panel-podcast-icon-play { display: none; }
.panel-podcast-btn.speaking .panel-podcast-icon-stop { display: inline; }
#panel-wiki-toggle { margin: 2px 0 6px; }
#panel-wiki-summary { font-size: 13px; color: var(--text-muted); line-height: 1.55; margin-bottom: 8px; }
#panel-wiki-bottom { display: flex; gap: 10px; align-items: flex-start; margin-top: 6px; }
#panel-wiki-img {
  flex: 0 0 66%; max-width: 66%; max-height: 200px;
  border-radius: 6px; object-fit: cover;
  border: 1px solid rgba(255,255,255,0.15);
  display: block;
}
/* Drag bar at top of info panel */
#panel-drag-bar {
  position: absolute; top: 0; left: 0; right: 0; height: 22px;
  cursor: move; z-index: 1500; border-radius: 8px 8px 0 0;
  touch-action: none; pointer-events: all;
  background: linear-gradient(to bottom, rgba(255,255,255,0.04), transparent);
}
/* Drag pill indicator — visible on touch devices */
#panel-drag-bar::before {
  content: "";
  position: absolute;
  top: 5px; left: 50%; transform: translateX(-50%);
  width: 36px; height: 4px; border-radius: 2px;
  background: rgba(255,255,255,0.22);
  display: none;
}
@media (pointer: coarse) {
  #panel-drag-bar::before { display: block; }
}
#locate-map-header { cursor: move; touch-action: none; }
#panel-country { font-size: 14px; margin: 6px 0 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
#panel-country img { height: 1em; vertical-align: middle; border-radius: 1px; }
#panel-type { display: flex; align-items: center; gap: 8px; margin: 10px 0; font-weight: 600; font-size: 16px; }
.type-icon  { font-size: 1.1em; line-height: 1; }
#panel-details { margin-bottom: 0; }
#panel-details dt { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; margin-top: 10px; }
#panel-details dd { font-size: 14px; margin-left: 0; margin-top: 2px; }
#panel-map { margin-top: 12px; border-radius: 6px; overflow: hidden; line-height: 0; height: 252px; }
#panel-map iframe { display: block; width: 100%; height: 280px; border: 0; pointer-events: auto; }
#panel-ulm-section { margin-top: 8px; }
#panel-ulm-section a { display: block; }
#panel-ulm-section img { display: block; width: 100%; max-height: 500px; object-fit: contain; border-radius: 6px; border: 1px solid var(--border-color); background: rgba(0,0,0,0.2); cursor: pointer; }
@media (max-width: 768px) { #panel-ulm-section { display: none; } }
#panel-sources { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border-color); font-size: 10px; color: var(--text-muted); line-height: 1.5; }
#panel-sources a { color: var(--accent); text-decoration: none; }
#panel-sources a:hover { text-decoration: underline; }
#mobile-menu-attribution { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border-color); font-size: 11px; color: var(--text-muted); text-align: center; line-height: 1.6; }
#mobile-menu-attribution a { color: var(--accent); text-decoration: none; }

/* Type filter buttons */
.type-filter-group { display: flex; gap: 3px; flex-wrap: wrap; }
.type-filter-btn {
  padding: 5px 10px; border-radius: 5px; border: 1px solid var(--border-color);
  background: var(--panel-bg); color: var(--text-muted);
  font-size: 14px; font-weight: 600; cursor: pointer; white-space: nowrap;
  display: flex; align-items: center; gap: 8px;
  transition: all 0.15s;
  line-height: 1;
  opacity: 0.6;
}
.type-filter-btn .tf-dot { width: 18px; height: 18px; border-radius: 4px; flex-shrink: 0; }
.type-filter-btn.active {
  opacity: 1;
  color: var(--text-main);
  border-color: rgba(255,255,255,0.45);
  background: rgba(40,40,55,0.98);
}
.type-filter-btn:hover { opacity: 0.9; background: rgba(40,40,55,0.95); color: var(--text-main); }

/* Tooltip */
#tooltip {
  position: absolute; background: rgba(0, 0, 0, 0.90); color: #fff;
  padding: 10px 14px; border-radius: 6px; pointer-events: none; z-index: 20;
  font-size: 12px; box-shadow: 0 3px 16px rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.14);
  max-width: 304px;
}
#tooltip.tt-rich { max-width: 304px; padding: 11px 14px; }
.tt-latin { font-weight: 700; font-size: 16px; margin-bottom: 3px; }
.tt-modern { color: #ddd; margin-bottom: 2px; font-size: 12px; font-weight: 500; }
.tt-transl { color: #b0a890; font-style: italic; font-size: 10.4px; margin-bottom: 4px; }
.tt-type { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #bbb; margin-bottom: 3px; margin-top: 5px; }
.tt-type-icon { font-size: 1.5em; line-height: 1; }
.tt-country { display: flex; align-items: center; gap: 5px; font-size: 11.2px; color: #fff; margin-bottom: 2px; }
.tt-country img { height: 1.2em; vertical-align: middle; border-radius: 2px; }
.tt-country-name { font-weight: 500; }
.tt-detail { font-size: 10.4px; color: #aaa; margin-top: 2px; }
.tt-detail span { color: #ddd; }
/* .dot is shared with other UI at 10px; scaled down here only, in step with the tooltip text. */
#tooltip .dot { width: 8px; height: 8px; }

/* Region-solo button — standalone below type filters, dashed border signals "area" */
#region-solo-btn { align-self: flex-start; margin-top: 4px; border-style: dashed !important; color: #a78bfa !important; }
#region-solo-btn:hover { border-style: dashed !important; }
#region-solo-btn.active { border-style: solid !important; border-color: #7c3aed !important; color: #c4b5fd !important; background: rgba(124,58,237,0.22) !important; }

/* Latin-name hover translation tooltip */
#latin-tip {
  position: fixed;
  background: rgba(14,11,6,0.96);
  border: 1px solid rgba(200,160,80,0.45);
  color: #e8dfc8;
  font-size: 13px;
  line-height: 1.4;
  padding: 5px 10px;
  border-radius: 6px;
  pointer-events: none;
  z-index: 9999;
  max-width: 240px;
  white-space: pre-wrap;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#panel-latin[data-translation] { cursor: help; }

/* Rich place-dot hover card — positioned up-and-right of the mouse pointer with a gap by
   placeLocateHoverCard in main.js, which sets left/top on every move; see there for the
   edge-flipping. Hover is a pointer concept, so this only ever appears on mouse screens —
   the binding that fills it is gated on !S.isMobile.
   pointer-events:none is load-bearing, not cosmetic: the card follows the pointer, so if
   it could catch the mouse it would steal it from the dot underneath, fire a mouseout,
   clear itself, and flicker on every move. */
#locate-hover-card {
  position: absolute; left: 0; top: 0;
  z-index: 500;
  background: rgba(18,16,12,0.94);
  border: 1px solid rgba(255,255,255,0.14);
  color: rgba(220,215,200,0.96);
  border-radius: 5.5px;
  padding: 6.6px 8.8px;
  font-size: 10.8px; line-height: 1.45;
  box-shadow: 0 2px 9px rgba(0,0,0,0.55);
  width: max-content;
  /* Never wider than the map itself: on desktop the locate map can be only ~250px wide. */
  max-width: min(231px, calc(100% - 8px));
  pointer-events: none;
}
#locate-hover-card:empty { display: none; }
#locate-hover-card .hc-name   { font-size: 11.55px; font-weight: 700; color: #f2e8cc; }
#locate-hover-card .hc-modern { font-size: 10.4px; color: rgba(205,200,185,0.92); }
#locate-hover-card .hc-type   { font-size: 10.4px; }
#locate-hover-card .hc-seg1   { font-size: 9.6px; opacity: 0.75; }
#locate-hover-card .hc-dot {
  display: inline-block; width: 6.2px; height: 6.2px; border-radius: 50%;
  vertical-align: middle; margin-right: 3.85px;
}
/* Suppress hover tooltips/popups while panning or zooming — a moving map sweeps the
   cursor across many dense markers, opening a flickery burst that can also strand a
   tooltip open with no mouseout to close it. */
#locate-leaflet-map.tp-panning .leaflet-tooltip,
#locate-leaflet-map.tp-panning .leaflet-popup { display: none !important; }
/* Country mode: country layer shows country name tooltip; place dots show their own tooltip.
   No blanket suppression — Leaflet handles tooltip priority by hover proximity. */

/* About modal backdrop */
#about-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 28;
  cursor: default;
}

/* About Panel – centered modal */
#about-panel {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(1100px, calc(100vw - 24px));
  max-height: 88vh;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 12px; padding: 28px 28px 20px;
  z-index: 30;
  box-shadow: 0 16px 48px rgba(0,0,0,0.75);
  pointer-events: auto;
  overflow-y: auto;
}
#close-about {
  position: absolute; top: 12px; right: 12px;
  background: transparent; border: none; color: var(--text-muted);
  font-size: 24px; cursor: pointer; line-height: 1;
}
#close-about:hover { color: #fff; }
.about-title { font-size: 22px; font-weight: 700; margin-bottom: 2px; }
.about-subtitle { font-size: 13px; color: var(--text-muted); margin-bottom: 12px; font-style: italic; }
/* UNESCO status under the subtitle: a quiet gold text link, so it doesn't compete with the
   "Listen to the story" pill right below it. */
.about-unesco {
  display: flex; align-items: center; gap: 6px; width: fit-content;
  margin: -6px 0 12px;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: #d4b36a; text-decoration: none;
}
.about-unesco:hover { color: #ffd080; text-decoration: underline; }
.about-unesco svg { flex-shrink: 0; }

/* "Listen to the story" — gold pill: gold is this UI's attention colour, and this is the one
   primary action in an otherwise read-only panel. Swaps its speaker icon for a stop square
   while speaking (.speaking is toggled by the About narration block in main.js). */
.about-listen-btn {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0 0 2px;
  padding: 6px 14px 6px 11px;
  border-radius: 999px;
  border: 1px solid rgba(200,160,80,0.55);
  background: rgba(200,160,80,0.10);
  color: #e8d8a8;
  font-size: 13px; font-weight: 600; line-height: 1.2;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.about-listen-btn:hover { background: rgba(200,160,80,0.20); border-color: #c8a050; color: #ffd080; }
.about-listen-btn:focus-visible { outline: 2px solid #c8a050; outline-offset: 2px; }
.about-listen-btn svg { flex-shrink: 0; }
.about-listen-btn .about-listen-icon-stop { display: none; }
.about-listen-btn.speaking { background: rgba(200,160,80,0.28); border-color: #c8a050; color: #ffd080; }
.about-listen-btn.speaking .about-listen-icon-play { display: none; }
.about-listen-btn.speaking .about-listen-icon-stop { display: inline; }
.about-tabula-img-wrap {
  margin: 0 0 18px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--border-color);
}
.about-tabula-img-wrap img { width: 100%; height: auto; display: block; }
.about-section { margin-bottom: 18px; }
.about-section h3 { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); margin-bottom: 8px; }
.about-section p { font-size: 14px; line-height: 1.6; color: var(--text-main); margin-bottom: 8px; }
.about-section p:last-child { margin-bottom: 0; }
.about-section p em { color: #c4b5fd; font-style: normal; }
.about-section p strong { color: #fcd34d; }
.about-facts { display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; }
.about-facts div { display: contents; }
.about-facts dt { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); padding: 3px 0; }
.about-facts dd { font-size: 13px; color: var(--text-main); margin: 0; padding: 3px 0; }
/* Live place census — legend and count in one table. The two numeric columns shrink to their
   content (width:1%) and their headers are allowed to wrap, so the long category names keep the
   flexible column even inside the ~278px-wide About panel on a phone. Nothing here sets a
   min-width, so the panel never gains a horizontal scrollbar. */
.about-stats table { width: 100%; border-collapse: collapse; }
.about-stats th {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted); text-align: left; line-height: 1.3;
  padding: 0 0 6px; border-bottom: 1px solid var(--border-color);
}
.about-stats td { font-size: 13px; color: var(--text-main); padding: 3px 0; }
.about-stats .as-num { width: 1%; padding-left: 12px; text-align: right; }
.about-stats th.as-num { white-space: normal; }
.about-stats td.as-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.about-stats .as-name { display: flex; align-items: center; gap: 7px; }
.about-stats .as-dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.about-stats .as-icon { font-size: 13px; line-height: 1; flex-shrink: 0; opacity: .85; }
.about-stats .as-total td { border-top: 1px solid var(--border-color); padding-top: 6px; font-weight: 700; }
.about-stats .as-note { margin-top: 8px; font-size: 11px; color: var(--text-muted); line-height: 1.5; }
/* Collapsible section header (places-by-category table) — same type treatment as a plain
   .about-section h3, just promoted to a real <button> so it's clickable/keyboard-operable. */
.about-collapsible-toggle {
  display: flex; align-items: center; gap: 6px;
  width: 100%; margin-bottom: 8px; padding: 0;
  background: transparent; border: none; font: inherit; text-align: left; cursor: pointer;
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-muted);
}
.about-collapsible-toggle:hover { color: var(--text-main); }
.about-collapsible-chevron { display: inline-block; font-size: 9px; transition: transform 0.15s; }
.about-collapsible-toggle[aria-expanded="true"] .about-collapsible-chevron { transform: rotate(90deg); }
@media (pointer: coarse), (max-width: 600px) {
  .about-stats td { font-size: 12px; }
  .about-stats .as-icon { display: none; }  /* give the width back to the category name */
  .about-stats .as-num { padding-left: 8px; }
}
.about-links { display: flex; flex-direction: column; gap: 8px; }
.about-link {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-radius: 6px;
  border: 1px solid var(--border-color);
  background: rgba(255,255,255,0.03);
  color: var(--accent); text-decoration: none;
  font-size: 13px; transition: background 0.15s;
}
.about-link:hover { background: rgba(59,130,246,0.12); text-decoration: none; }
.about-link-icon { font-size: 16px; flex-shrink: 0; }
/* Videos. The film keeps a 16:9 frame up to 720px wide. Until play is pressed the frame holds a
   poster button (local image, dark gradient for the caption, gold play button in this UI's
   attention colour); the About video block in main.js swaps in the YouTube iframe. */
.about-video { max-width: 720px; margin-bottom: 12px; }
.about-video-frame {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: 8px; overflow: hidden;
  border: 1px solid var(--border-color); background: #1b1810;
}
.about-video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.about-video-poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  padding: 0; border: 0; background: none; font: inherit; text-align: left; cursor: pointer;
}
.about-video-poster img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  filter: brightness(0.8) saturate(0.9); transition: filter 0.2s;
}
.about-video-poster::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(10,8,4,0.9) 0%, rgba(10,8,4,0.5) 30%, rgba(10,8,4,0) 58%);
}
.about-video-play {
  position: absolute; left: 50%; top: 50%; z-index: 1;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: 50%;
  border: 2px solid #c8a050; background: rgba(20,16,8,0.72); color: #ffd080;
  box-shadow: 0 4px 18px rgba(0,0,0,0.5);
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.about-video-play svg { margin-left: 3px; }  /* a play triangle looks off-centre when centred exactly */
.about-video-poster:hover img { filter: brightness(0.92) saturate(1); }
.about-video-poster:hover .about-video-play,
.about-video-poster:focus-visible .about-video-play {
  background: #c8a050; color: #1b1408; transform: translate(-50%, -50%) scale(1.06);
}
.about-video-poster:focus-visible { outline: 2px solid #c8a050; outline-offset: -3px; }
.about-video-caption {
  position: absolute; left: 14px; right: 14px; bottom: 12px; z-index: 1;
  display: flex; flex-direction: column; gap: 2px;
  text-shadow: 0 1px 3px rgba(0,0,0,0.85);
}
.about-video-title { font-size: 15px; font-weight: 600; line-height: 1.3; color: #fff; }
.about-video-meta { font-size: 12px; color: #e8d8a8; }
.about-section .about-video-note {
  display: flex; flex-wrap: wrap; gap: 2px 12px;
  margin: 6px 0 0; font-size: 11px; line-height: 1.5; color: var(--text-muted);
}
.about-video-note a { color: var(--accent); text-decoration: none; white-space: nowrap; }
.about-lecture-link { max-width: 720px; }
.about-lecture-text { display: flex; flex-direction: column; gap: 1px; }
.about-lecture-meta { font-size: 11px; color: var(--text-muted); }
@media (max-width: 600px) {
  .about-video-play { width: 46px; height: 46px; }
  .about-video-play svg { width: 22px; height: 22px; }
  .about-video-caption { left: 10px; right: 10px; bottom: 8px; }
  .about-video-title { font-size: 13px; }
  .about-video-meta { font-size: 11px; }
}
.about-footer { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border-color); font-size: 11px; color: var(--text-muted); line-height: 1.5; }
.about-footer a { color: var(--accent); text-decoration: none; }
#about-settings-row { margin-top: 10px; display: flex; justify-content: flex-end; }
.about-settings-btn { display: flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 4px; border: 1px solid var(--border-color); background: transparent; color: var(--text-muted); font-size: 11px; font-family: inherit; cursor: pointer; transition: color 0.15s, border-color 0.15s; }
.about-settings-btn:hover { color: var(--text-main); border-color: rgba(255,255,255,0.3); }

/* Country mode floating bar */
#country-mode-bar {
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(18, 14, 8, 0.93);
  border: 1px solid rgba(200, 160, 80, 0.35);
  border-radius: 20px;
  padding: 7px 8px 7px 16px;
  color: #e8dfc8;
  font-size: 13px;
  font-weight: 600;
  pointer-events: auto;
  backdrop-filter: blur(6px);
  white-space: nowrap;
  box-shadow: 0 4px 18px rgba(0,0,0,0.5);
}
#country-mode-bar.hidden { display: none; }
#country-mode-bar::before { content: "🗺"; margin-right: 2px; font-size: 13px; }
#country-mode-exit {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.15);
  color: #e8dfc8;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 12px;
  transition: background 0.15s, color 0.15s;
}
#country-mode-exit:hover { background: rgba(255,255,255,0.16); color: #fff; }

/* Developer settings button — fixed bottom-right, very transparent on desktop */
#settings-btn {
  display: flex;
  position: fixed;
  bottom: 10px;
  right: 10px;
  z-index: 25;
  width: 28px;
  height: 28px;
  padding: 5px;
  background: rgba(15,12,6,0.75);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: var(--text-muted);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
  opacity: 0.12;
  transition: opacity 0.2s;
}
#settings-btn:hover { opacity: 0.8; color: var(--text-main); }

/* Footer Elements */
#attribution { position: absolute; bottom: 10px; right: 10px; z-index: 10; font-size: 12px; color: var(--text-muted); background: rgba(15, 17, 23, 0.8); padding: 4px 8px; border-radius: 4px; pointer-events: auto; }
#attribution a { color: var(--accent); text-decoration: none; }
#attribution a:hover { text-decoration: underline; }
/* Legal links kept as discreet as is still legally reachable: small, faint muted grey. */
#attribution a.legal { color: var(--text-muted); opacity: 0.5; font-size: 10px; }
#attribution a.legal:hover { color: var(--text-main); opacity: 1; }

/* Transient status toast (locate/GPS feedback) — hides itself via :empty, no JS class needed */
#status {
  position: fixed; top: 62px; left: 50%; transform: translateX(-50%);
  z-index: 250;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 20px;
  padding: 7px 16px;
  font-size: 13px; color: var(--text-main);
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  pointer-events: none;
  white-space: nowrap;
  max-width: min(90vw, 420px);
  overflow: hidden; text-overflow: ellipsis;
}
#status:empty { display: none; }
@media (pointer: coarse), (max-width: 600px) {
  #status { top: 46px; font-size: 11px; padding: 5px 12px; }
}

/* Utilities */
.hidden { display: none !important; }

/* Onboarding hint pulse (flashOnboardingHints) + panel fly-to-button flourish (demoFlyToButton) */
@keyframes demoBtnPulse {
  0%   { transform: scale(1);    box-shadow: none; }
  45%  { transform: scale(1.45); box-shadow: 0 0 14px 5px rgba(200,160,80,0.75); }
  100% { transform: scale(1);    box-shadow: none; }
}
.demo-btn-pulse { animation: demoBtnPulse 0.55s ease-out forwards; }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.5); }

/* ── Mobile menu overlay ─────────────────────────────────────── */
#bottom-filter-btn { display: none; }
#mobile-menu {
  position: fixed; inset: 0; z-index: 50;
  display: flex; flex-direction: column; justify-content: flex-end;
}
#mobile-menu-backdrop {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.55);
}
#mobile-menu-sheet {
  position: relative;
  background: var(--panel-bg);
  border-radius: 16px 16px 0 0;
  padding: 16px 16px 32px;
  max-height: 80svh;
  overflow-y: auto;
  border-top: 1px solid var(--border-color);
}
#mobile-menu-handle {
  width: 40px; height: 4px;
  background: var(--border-color);
  border-radius: 2px;
  margin: 0 auto 16px;
}
#mobile-menu h3 {
  font-size: 11px; font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .06em;
  margin: 14px 0 6px;
}
#mobile-menu h3:first-of-type { margin-top: 4px; }
#mobile-type-filter-buttons,
#mobile-segment-buttons { display: flex; flex-wrap: wrap; gap: 5px; }
#mobile-display-controls { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Mobile responsive overrides ────────────────────────────── */
@media (pointer: coarse), (max-width: 600px) {
  /* On mobile: hide segment popup jump button (use mobile menu instead) */
  #segment-buttons-wrapper { display: none; }
  /* Category popup still accessible via cat-popup-btn on mobile */
  #bottom-left-controls { bottom: 10px; flex-direction: row; gap: 6px; align-items: center; }
  #attribution { display: none; }
  #settings-btn { display: none !important; }

  /* Search: wider, compact, small font on mobile */
  #search-container { flex: 0 0 auto; width: min(30vw, 140px); min-width: 0; margin: 0 4px; }
  #search-input { width: 100%; min-width: 0; font-size: 9px; height: 24px; padding: 2px 6px; }
  #search-results .search-item { font-size: 9px; padding: 5px 6px; }
  #search-results .si-modern { font-size: 7px; }

  /* Info panel → left-side panel, width reduced by 1/4 */
  #info-panel {
    position: fixed !important;
    left: 0 !important; right: auto !important;
    top: 56px !important; bottom: 0 !important;
    width: min(210px, 41vw) !important;
    max-height: none !important;
    border-radius: 0 12px 12px 0 !important;
    /* Left/right stay 0 here -- #panel-scroll-body's own 10px matches the desktop gap;
       adding padding here too was nearly 2.5x the desktop side margin. */
    padding: 12px 0 24px;
    box-shadow: 4px 0 24px rgba(0,0,0,0.6);
    overflow-y: auto;
  }
  #info-panel::before { display: none; }

  #panel-latin, #panel-modern { font-size: 14px; }
  /* On touch: scroll is in #panel-scroll-body; panel itself is overflow:hidden */
  #panel-scroll-body { max-height: none !important; overflow-y: auto; }
  #panel-map:not(.hidden) {
    display: block !important;
    margin: 10px 0 0;
    border-radius: 6px;
    overflow: hidden;
    position: relative;
    /* Aspect-ratio drives height from panel width, so map shrinks as panel is resized smaller */
    height: auto !important;
    aspect-ratio: 16 / 9;
    max-height: 130px !important;
    min-height: 36px !important;
    flex-shrink: 1;
  }
  #panel-map:not(.hidden) iframe {
    position: absolute; top: 0; left: 0;
    /* Scale iframe to 70% so the +/- Leaflet buttons inside are 30% smaller.
       Compensate size so the scaled result still fills the container exactly. */
    width: calc(100% / 0.7) !important; height: calc(100% / 0.7) !important;
    transform: scale(0.7); transform-origin: top left;
    display: block;
  }
  /* Larger map on tablets (wider touch screens) */
  @media (min-width: 601px) {
    #panel-map:not(.hidden) { max-height: 180px !important; }
  }
  /* Slightly smaller fonts for narrow panel */
  #info-panel #panel-latin  { font-size: 14px; margin-bottom: 2px; }
  #info-panel #panel-latin-transl { font-size: 11px; }
  #info-panel #panel-modern { font-size: 12px; margin-bottom: 8px; }
  #info-panel #panel-wiki-summary { font-size: 12px; margin-top: 5px; }
  #info-panel #panel-type   { font-size: 16px; }

  /* Larger tap targets for controls */
  .ctrl-btn { min-width: 38px; min-height: 38px; }

  /* Zoom +/- buttons smaller on mobile */
  #nav-square .ctrl-btn { width: 22px !important; height: 22px !important; min-width: 22px !important; min-height: 22px !important; padding: 3px !important; }

  /* Drag/resize are enabled on touch via JS detach — show controls */
  .resize-handle { display: block; }
  #panel-drag-bar { display: block; }
  /* Larger tap target on touch — 32px keeps it unobtrusive while still tappable */
  .resize-handle { width: 32px !important; height: 32px !important; }
  /* Leaflet zoom +/- in locate map: reduce by ~30% (default 26px → 18px) */
  #locate-leaflet-map .leaflet-control-zoom a {
    width: 18px !important; height: 18px !important;
    line-height: 18px !important; font-size: 14px !important;
  }
}

/* Mobile: "Tabula Peutingeriana" label appears on load then slides away */
@keyframes slideOutLabel {
  0%   { max-width: 240px; opacity: 1; margin-left: 6px; padding-right: 4px; }
  80%  { max-width: 240px; opacity: 1; margin-left: 6px; padding-right: 4px; }
  100% { max-width: 0; opacity: 0; margin-left: 0; padding-right: 0; }
}
@media (pointer: coarse), (max-width: 699px) {
  .about-btn-label {
    display: inline-block !important;
    overflow: hidden; white-space: nowrap;
    animation: slideOutLabel 1.2s ease 2s forwards;
  }
}

/* Portrait mode overrides */
@media (pointer: coarse) and (orientation: portrait) {
  /* Info panel: bottom sheet, right-aligned — 6px inset on right+bottom for visible rounding */
  #info-panel {
    /* 15% (was 20%, user: 5% wider), but never over the category buttons (54px) */
    left: max(15%, 58px) !important; right: 6px !important; width: auto !important;
    bottom: 6px !important; top: auto !important;
    height: 33vh !important;
    border-radius: 10px !important;
    box-shadow: 0 -4px 24px rgba(0,0,0,0.6) !important;
  }
  /* Panel map in portrait: tighter cap for narrow bottom sheet */
  #panel-map { max-height: 110px !important; height: 110px !important; }
  /* Category popup: max 70% screen height, scrollable */
  #category-popup {
    max-height: 70svh;
    overflow-y: auto;
  }
}

/* Landscape/fullscreen tip banner */
#landscape-tip {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 200;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  background: rgba(20, 18, 14, 0.92);
  color: #e8dfc8; font-size: 14px;
  border-top: 1px solid rgba(255,255,255,0.12);
  backdrop-filter: blur(6px);
}
#landscape-tip.hidden { display: none; }
#landscape-tip-text { flex: 1; }
#landscape-tip-fs {
  padding: 5px 14px; border-radius: 5px;
  background: rgba(59,130,246,0.2); border: 1px solid rgba(59,130,246,0.4);
  color: #93c5fd; font-size: 13px; cursor: pointer; white-space: nowrap;
}
#landscape-tip-fs:hover { background: rgba(59,130,246,0.35); }
#landscape-tip-close {
  background: transparent; border: none; color: rgba(255,255,255,0.45);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px;
}
#landscape-tip-close:hover { color: #fff; }
/* Only show tip on coarse-pointer (touch) devices in portrait */
@media not ((pointer: coarse) and (orientation: portrait)) {
  #landscape-tip { display: none !important; }
}

/* ── Country filter ─────────────────────────────────────────── */
#country-select-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 8px;
  background: rgba(0,0,0,0.2);
  border-bottom: 1px solid var(--border-color);
  flex-shrink: 0;
}
#country-filter-select {
  flex: 1; min-width: 0;
  background: var(--panel-bg); color: var(--text);
  border: 1px solid var(--border-color); border-radius: 5px;
  padding: 3px 6px; font-size: 12px; cursor: pointer;
}
.filter-chip {
  display: inline-flex; align-items: center;
  background: rgba(59,130,246,0.18);
  border: 1px solid rgba(59,130,246,0.45);
  color: #93c5fd; border-radius: 5px;
  padding: 3px 10px; font-size: 12px;
  cursor: pointer; white-space: nowrap;
}
.filter-chip:hover { background: rgba(59,130,246,0.32); }
.country-tooltip {
  background: rgba(20,18,14,0.92) !important;
  border: none !important; color: #e8dfc8 !important;
  font-size: 12px; font-weight: 500;
  padding: 3px 7px !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 8px rgba(0,0,0,0.5) !important;
}

/* ── Location map popup ─────────────────────────────────────── */
#locate-map-popup {
  position: absolute;
  /* aligns with top of the locate button: zoom-controls top(10) + nav-btns-row(59) + gap(4) */
  top: 73px; left: 10px;
  bottom: 10px;
  height: auto;
  width: 25vw;
  min-height: 200px;
  min-width: 160px;
  display: flex; flex-direction: column;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  z-index: 35;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  pointer-events: auto;
  overflow: hidden;
  transition: border-color 0.4s, box-shadow 0.4s;
}
#country-isolate-btn {
  flex-shrink: 0;
  font-size: 12px;
  padding: 4px 8px;
  gap: 4px;
  white-space: nowrap;
}
#country-isolate-btn.hidden { display: none !important; }
/* Deactivate country mode button */
#country-deactivate-btn {
  font-size: 11px; padding: 5px 8px; gap: 4px; margin-top: 2px;
  white-space: nowrap; flex-shrink: 0;
  border-color: rgba(220,100,80,0.45); color: rgba(230,140,120,0.9);
}
#country-deactivate-btn:hover { background: rgba(80,30,20,0.55); border-color: rgba(230,140,120,0.8); }
#country-deactivate-btn.hidden { display: none !important; }
/* locate-map label toggle buttons */
#locate-toggle-names, #locate-toggle-modern, #locate-toggle-all-labels {
  font-size: 11px; padding: 3px 7px; gap: 3px; flex-shrink: 0;
}
#locate-toggle-names svg, #locate-toggle-modern svg, #locate-toggle-all-labels svg { width: 14px !important; height: 14px !important; }
/* Individual label buttons hidden; combined always visible */
#locate-toggle-names, #locate-toggle-modern { display: none !important; }
/* cat-popup-btn disabled state in country mode */
#cat-popup-btn:disabled, #cat-popup-btn.disabled {
  opacity: 0.35; pointer-events: none; cursor: not-allowed;
}
/* On mobile: hide country-mode-exit button (redundant, deactivate is via locate map button) */
@media (pointer: coarse) {
  #country-mode-exit { display: none !important; }
  /* Locate header buttons: compact — keep icon size, reduce container */
  #locate-gps-btn, #locate-places-btn, #locate-roads-btn, #locate-my-country-btn {
    width: 24px !important; height: 24px !important;
    min-width: auto !important; min-height: auto !important;
    padding: 2px !important;
  }
  #locate-gps-btn svg, #locate-places-btn svg, #locate-roads-btn svg, #locate-my-country-btn svg {
    width: 18px !important; height: 18px !important;
  }
  /* Close button: compact but still clearly tappable */
  #locate-map-close { width: 28px !important; height: 28px !important; min-width: auto !important; min-height: auto !important; font-size: 22px !important; }
  /* Hide hint + attr text on phone (takes up map space) */
  #locate-map-hint { display: none !important; }
  #locate-map-attr { display: none !important; }
  /* The caveat is the one footer line that stays: it changes how every marker on this map
     should be read, so hiding it is worse than the space it costs. Shrunk so that even the
     longer German string wraps to at most two lines (~24px) in the 34vh portrait popup —
     still well under the ~39px the hidden hint + attr used to take on desktop. It clears
     #locate-legend-btn (bottom:38px) and the 32px touch resize handle below it. */
  #locate-map-caveat { font-size: 8.5px; line-height: 1.25; margin: 0 8px 3px; opacity: 0.7; }
  /* Locate header: ultra-compact to maximise map area */
  #locate-map-header { padding: 1px 5px 1px 6px !important; }
  #locate-header-btns { gap: 2px !important; }
  /* Country bar: reduce padding so more map is visible (keep font/icon size) */
  #country-select-bar { padding: 2px 6px !important; gap: 4px !important; }
  /* These buttons already declare small padding, but the generic .ctrl-btn 38px
     touch-target floor (below) was overriding it, forcing dead space in the bar. */
  #country-select-bar .ctrl-btn {
    min-width: auto !important; min-height: auto !important;
  }
  #country-isolate-btn { padding: 3px 7px !important; }
  /* The generic .ctrl-btn touch-target floor (38px min-height) was forcing dead
     space above/below this button's small icon+text despite the tight padding. */
  #country-deactivate-btn {
    padding: 2px 4px !important; margin-top: 1px !important;
    min-width: auto !important; min-height: auto !important;
  }
  #locate-toggle-all-labels { padding: 2px 6px !important; }
  #country-filter-select { padding: 2px 5px !important; }
  /* Category popup: smaller fonts + icons on mobile */
  #category-popup { font-size: 11px; }
  #category-popup .toggle-btn-sm { font-size: 11px !important; padding: 5px 9px !important; min-height: 32px !important; gap: 4px !important; }
  #category-popup .toggle-btn-sm svg { width: 15px !important; height: 15px !important; }
  #category-popup .type-filter-btn { font-size: 11px !important; padding: 4px 7px !important; gap: 5px !important; }
  #category-popup .tf-dot { width: 13px !important; height: 13px !important; border-radius: 3px !important; }
}
/* Mobile portrait: locate map full width, 34vh height at top (15% shorter than the
   original 40vh) — 6px inset on all edges for visible rounding */
@media (pointer: coarse) and (orientation: portrait) {
  #locate-map-popup {
    position: fixed !important;
    top: 6px !important; left: 6px !important; right: 6px !important; bottom: auto !important;
    width: calc(100vw - 12px) !important; height: 34vh !important;
    border-radius: 10px !important;
    z-index: 200;
  }
}
/* Mobile landscape: full height, info panel right, hide title, shrink header, fix category popup */
@media (pointer: coarse) and (orientation: landscape) {
  #locate-map-popup {
    top: 6px !important;
    bottom: 6px !important;
    width: 29vw !important;
    height: calc(100dvh - 12px) !important;
  }
  #locate-my-country-btn { display: none !important; }
  #locate-header-title { display: none; }
  #locate-gps-btn, #locate-places-btn, #locate-roads-btn, #locate-my-country-btn {
    width: 28px !important;
    height: 28px !important;
    min-width: auto !important; min-height: auto !important;
    padding: 4px !important;
  }
  #locate-gps-btn svg, #locate-places-btn svg, #locate-roads-btn svg,
  #locate-my-country-btn svg, #modern-state-solo-btn svg {
    width: 18px !important;
    height: 18px !important;
  }
  #modern-state-solo-btn { font-size: 11px; padding: 2px 3px; gap: 2px !important; }
  #locate-map-close { width: 36px !important; height: 36px !important; min-width: auto !important; min-height: auto !important; font-size: 28px !important; }
  /* Info panel: right side — 6px inset on right+top+bottom for visible rounding on all corners */
  #info-panel {
    left: auto !important; right: 6px !important;
    top: 6px !important; bottom: 6px !important;
    width: 25.5vw !important; height: auto !important;
    max-height: none !important;
    border-radius: 10px !important;
    box-shadow: -4px 0 24px rgba(0,0,0,0.6) !important;
  }
  /* Panel map in landscape right panel: proportional height */
  #panel-map { height: 140px !important; max-height: 140px !important; }
  /* Category popup: constrain to 80% screen height to prevent overflow off-screen */
  #category-popup {
    max-height: 80svh !important;
    overflow-y: auto !important;
  }
}
/* Custom resize handles */
.resize-handle {
  position: absolute; bottom: 0; width: 20px; height: 20px;
  z-index: 1500;         /* above Leaflet's highest pane (700) */
  touch-action: none;    /* prevents scroll/pan gestures from stealing the touch */
  pointer-events: all;
}
.resize-handle.resize-br {
  right: 0; cursor: se-resize;
  background: linear-gradient(135deg, transparent 52%, rgba(200,160,80,0.7) 52%);
  border-bottom-right-radius: 7px;
}
.resize-handle.resize-bl {
  /* Info panel: width + height resize (bottom-left corner) */
  left: 0; cursor: sw-resize;
  background: linear-gradient(225deg, transparent 52%, rgba(200,160,80,0.7) 52%);
  border-bottom-left-radius: 7px;
}
#locate-map-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px 8px 14px;
  border-bottom: 1px solid var(--border-color);
  font-size: 12px; font-weight: 600;
  flex-shrink: 0;
}
#locate-map-close {
  background: transparent; border: none; color: var(--text-muted);
  font-size: 28px; cursor: pointer; line-height: 1;
  width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
#locate-map-close:hover { color: #fff; }
#locate-leaflet-map { width: 100%; flex: 1; min-height: 0; position: relative; isolation: isolate; }

/* Follow toggle — top-right overlay on the map itself, translucent until active.
   Text is always dark: the map underneath (OSM land tiles) is light-colored, so light
   text on a transparent background was unreadable. */
#locate-follow-btn {
  position: absolute; top: 8px; right: 8px; z-index: 1000;
  display: flex; align-items: center; gap: 3px;
  padding: 2px 5px; font-size: 10px; font-weight: 600;
  background: rgba(255,255,255,0.55); border: 1px solid rgba(0,0,0,0.25);
  border-radius: 5px; color: #14120e;
  cursor: pointer;
}
#locate-follow-btn:hover { background: rgba(255,255,255,0.75); }
#locate-follow-btn.active {
  background: rgba(200,160,80,0.9); border-color: var(--accent);
  color: #14120e;
}

/* Country mode: the selected country's flag, top-right below Follow and Match, with a tiny ×
   on its top-right corner that deselects the country. */
#locate-country-flag-wrap { position: absolute; top: 58px; right: 8px; z-index: 1000; }
#locate-country-flag {
  display: block; width: 44px; height: auto;
  border: 1px solid rgba(0,0,0,0.35); border-radius: 3px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.45);
  pointer-events: none;
}
#locate-country-flag-x {
  position: absolute; top: -6px; right: -6px;
  display: flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0;
  border: 1px solid rgba(255,255,255,0.85); border-radius: 50%;
  background: rgba(20,18,14,0.9); color: #fff;
  font-size: 13px; line-height: 1; cursor: pointer;
}
#locate-country-flag-x:hover { background: #b91c1c; }
/* Tiny to look at, but a finger-sized target: the hit area reaches 8px beyond the circle. */
#locate-country-flag-x::after { content: ""; position: absolute; inset: -8px; }
@media (pointer: coarse), (max-width: 600px) {
  #locate-country-flag { width: 34px; }
}

/* Match toggle — same style as Follow, stacked directly below it. */
#locate-match-btn {
  position: absolute; top: 32px; right: 8px; z-index: 1000;
  display: flex; align-items: center; gap: 3px;
  padding: 2px 5px; font-size: 10px; font-weight: 600;
  background: rgba(255,255,255,0.55); border: 1px solid rgba(0,0,0,0.25);
  border-radius: 5px; color: #14120e;
  cursor: pointer;
}
#locate-match-btn:hover { background: rgba(255,255,255,0.75); }
#locate-match-btn.active {
  background: rgba(57,255,20,0.85); border-color: #22c55e;
  color: #0a1f0a;
}

/* Dot-color legend — bottom-right of popup; z-index 2000 so it sits above resize handle (1500) */
#locate-legend {
  /* bottom was 26px, tuned to sit just above the two-line footer (attr + hint). The caveat
     line added below the attribution makes that footer one line taller, so without this bump
     the opaque legend box would cover #locate-map-hint — which carries live status text such
     as "Location unknown for this place". The mobile override further down (64px) is unchanged. */
  /* Shown only while .legend-open: the toggle button below it works on every screen size.
     Large screens start with it open (see the legend button's setup in main.js), phones
     closed. On large screens it sits above that button, which took its old spot. */
  position: absolute; bottom: 76px; right: 8px; left: auto; top: auto; z-index: 2000;
  background: rgba(18,16,12,0.88);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 6px;
  padding: 5px 8px;
  display: none; flex-direction: column; gap: 3px;
  pointer-events: none;
}
#locate-legend.legend-open { display: flex; }
/* Legend toggle button — bottom-right, above resize handle and Leaflet marker pane */
#locate-legend-btn {
  display: flex;
  position: absolute; bottom: 44px; right: 8px; left: auto; z-index: 2001;
  opacity: 0.5;
  background: rgba(18,16,12,0.88);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 5px;
  padding: 5px 7px;
  cursor: pointer;
  color: rgba(220,215,200,0.95);
  align-items: center; justify-content: center;
  pointer-events: auto;
}
/* Mobile country label — bottom-left of the Leaflet map (was bottom-centre, which read as
   floating in the middle of the map rather than anchored to an edge). */
#locate-country-bar {
  display: none;
  position: absolute; bottom: 66px; left: 8px;
  z-index: 501;
  background: rgba(18,14,8,0.88);
  border: 1px solid rgba(200,160,80,0.45);
  border-radius: 14px;
  padding: 4px 14px;
  color: #e8dfc8; font-size: 12px; font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
}
/* Nearest-place result — docked flush with the map's bottom edge (not centered mid-map, and
   not anchored to the marker) so it never sits on top of the place-dot cluster, which is
   densest toward the middle of the view. Portrait: bottom-left, hard against the edge;
   landscape: bottom-centre, see the media query below. */
#locate-result-bar {
  position: absolute; bottom: 3px; left: 6px;
  max-width: calc(100% - 20px);
  z-index: 500;
  background: rgba(18,16,12,0.93);
  border: 1px solid rgba(200,160,80,0.45);
  border-radius: 10px;
  padding: 4px 11px;
  color: #e8d8a8; font-size: 11px; font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  overflow: hidden; text-overflow: ellipsis;
}
#locate-result-bar:empty { display: none; }
/* Landscape: centred along the bottom instead of left-aligned, and flush with the edge —
   same 3px as portrait. The bottom row is free for it because the duplicate in-map
   attribution overlay is removed in openLocatePopup (the credit lives in #locate-map-attr
   just below the map instead), so nothing else competes for that strip. */
@media (orientation: landscape) {
  #locate-result-bar {
    left: 50%; right: auto;
    transform: translateX(-50%);
    bottom: 3px;
    max-width: calc(100% - 20px);
  }
}
/* Locate map: transient ring confirming that a near-miss tap was snapped to a place dot.
   Shrinking onto the dot makes the direction of the snap legible — it reads as "your tap
   was pulled to here" rather than as yet another marker sitting on the map. Removed from
   the map by a timer in flashLeafletSnap, so `forwards` only has to hold the last frame
   for the few ms before that fires. transform-box/transform-origin are required to scale
   an SVG path about its own centre rather than about the SVG root's origin. */
@keyframes tp-snap-pulse-anim {
  from { transform: scale(1.9); opacity: 0.95; }
  to   { transform: scale(0.55); opacity: 0; }
}
.tp-snap-pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: tp-snap-pulse-anim 0.45s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
  .tp-snap-pulse { animation: none; opacity: 0.7; }
}
@media (pointer: coarse), (max-width: 600px) {
  /* Push both elements up to clear the 32px touch resize handle at bottom-right */
  #locate-legend { display: none; bottom: 64px; right: 8px; left: auto; }
  /* When legend is open its panel should block taps reaching the map behind it */
  #locate-legend.legend-open { display: flex !important; pointer-events: auto; }
  #locate-legend-btn { display: flex !important; bottom: 38px; right: 8px; left: auto; }
  #locate-country-bar:not(.hidden) { display: flex !important; }
}
.ll-row { display: flex; align-items: center; gap: 5px; }
.ll-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
}
.ll-label { font-size: 10px; color: rgba(220,215,200,0.88); white-space: nowrap; line-height: 1.3; }
#locate-map-hint {
  font-size: 10px; color: var(--text-muted);
  margin: 4px 12px 2px; text-align: center;
  flex-shrink: 0;
}
#locate-map-attr {
  font-size: 9px; color: var(--text-muted);
  margin: 0 12px 4px; text-align: center;
  flex-shrink: 0;
}
#locate-map-attr a { color: var(--accent); text-decoration: none; }
#locate-map-attr a:hover { text-decoration: underline; }
/* Scholarly-uncertainty caveat — the last in-flow line of the popup, below the attribution.
   Deliberately the quietest text in the panel (same 9px as the attribution but dimmed): it has
   to be permanently legible without competing with the map, the result bar or the legend. */
#locate-map-caveat {
  font-size: 9px; color: var(--text-muted); opacity: 0.72;
  line-height: 1.3;
  margin: 0 12px 5px; text-align: center;
  flex-shrink: 0;
}
/* ── Developer settings panel ───────────────────────────────── */
#settings-panel {
  position: fixed;
  right: 10px; bottom: 48px;
  width: 290px;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  z-index: 30;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  pointer-events: auto;
  overflow-y: auto;
  max-height: calc(100vh - 80px);
}
#settings-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--border-color);
  font-weight: 600; font-size: 13px;
}
#close-settings {
  background: transparent; border: none; color: var(--text-muted);
  font-size: 22px; cursor: pointer; line-height: 1; padding: 0;
}
#close-settings:hover { color: #fff; }
#settings-body { padding: 6px 14px 4px; }
.sp-section {
  font-size: 10px; font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .07em;
  margin: 10px 0 5px;
}
.sp-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 5px;
}
.sp-label { font-size: 11px; color: var(--text-main); flex: 1; min-width: 0; }
.sp-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.sp-slider-wrap { display: flex; align-items: center; gap: 3px; }
.sp-slider { width: 72px; accent-color: var(--accent); cursor: pointer; }
.sp-step-btn {
  width: 20px; height: 20px; min-width: 20px; padding: 0;
  font-size: 15px; line-height: 1;
  background: var(--panel-bg); color: var(--text-main);
  border: 1px solid var(--border-color); border-radius: 4px;
  cursor: pointer; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.sp-step-btn:hover { background: rgba(50,50,60,0.95); }
.sp-step-btn:active { opacity: 0.6; }
.sp-val {
  font-size: 11px; color: var(--accent);
  min-width: 32px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.sp-desc {
  font-size: 10px; color: var(--text-muted);
  line-height: 1.4; margin: -2px 0 6px;
  padding-left: 1px;
}
.sp-coord-input {
  width: 90px; padding: 3px 5px;
  background: rgba(0,0,0,0.3); color: var(--text-main);
  border: 1px solid var(--border-color); border-radius: 4px;
  font-size: 11px; font-family: monospace;
  text-align: right;
}
.sp-coord-input:focus { outline: none; border-color: var(--accent); }
.sp-section-row {
  display: flex; align-items: center; justify-content: space-between;
  margin: 10px 0 5px;
}
.sp-section-row .sp-section { margin: 0; }
.sp-zoom-badge {
  font-size: 10px; font-weight: 700;
  color: var(--accent);
  background: rgba(59,130,246,0.12);
  border: 1px solid rgba(59,130,246,0.3);
  border-radius: 4px;
  padding: 1px 6px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}
.sp-curve-pt-label {
  font-size: 11px; font-weight: 600; color: var(--text-main);
  margin: 8px 0 2px;
}
.sp-subrow { padding-left: 10px; margin-bottom: 3px; }
#settings-footer {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 8px 14px 12px;
  border-top: 1px solid var(--border-color);
}
#settings-footer .ctrl-btn { padding: 6px 12px; font-size: 12px; font-weight: 600; }
#settings-save { border-color: var(--accent); color: var(--accent); }

@media (pointer: coarse), (max-width: 600px) {
  #settings-panel {
    position: fixed !important;
    left: 0 !important; right: 0 !important;
    bottom: 0 !important; top: auto !important;
    width: 100% !important;
    max-height: 75svh;
    border-radius: 16px 16px 0 0;
  }
  .sp-desc { display: none; }
}

/* Mobile layout toggle button — visible on touch screens only */
#mobile-layout-toggle {
  display: none;
  position: fixed;
  bottom: 14px; right: 14px;
  z-index: 300;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(30,27,22,0.9);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  font-size: 17px; line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.5);
}
@media (pointer: coarse), (max-width: 600px) {
  #mobile-layout-toggle { display: none !important; }
}

/* Compact panel mode — overrides portrait full-width to keep map visible */
@media (pointer: coarse) and (orientation: portrait) {
  body.mobile-compact #info-panel {
    left: 0 !important; right: auto !important;
    width: min(300px, 72vw) !important;
    border-radius: 0 12px 12px 0 !important;
    box-shadow: 4px 0 24px rgba(0,0,0,0.6) !important;
  }
}

/* GPS location pin — the exact same icon graphic as the default (blue) draggable
   marker, recolored red via filter, so the two are identical in size/shape and
   differ only by color. Distinct from the blue pin the user can drag to adjust
   their position. */
.gps-red-icon {
  filter: hue-rotate(150deg) saturate(2.6) brightness(0.95);
}

/* "Snapped to this place" pin — see placeSnapMarker. Same default marker graphic as the
   red GPS pin and the blue draggable one (just smaller, via iconSize), recolored via
   filter so all three read as one consistent icon family instead of three different pin
   designs. Shown only when a click/tap didn't land exactly on a place and the app snapped
   to the nearest one instead — the blue draggable pin stays at the raw click point. */
.snap-purple-icon {
  filter: hue-rotate(85deg) saturate(1.8) brightness(1.05);
}

/* ── Tile loading spinner for locate map ─────────────────── */
#locate-map-loading {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 600;
  width: 32px; height: 32px;
  border: 3px solid rgba(255,255,255,0.15);
  border-top-color: #c8a050;
  border-radius: 50%;
  animation: locateSpin 0.7s linear infinite;
  pointer-events: none;
}
#locate-map-loading.hidden { display: none !important; }
@keyframes locateSpin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

/* ── Tablet overrides (touch + ≥768px) ───────────────────── */
@media (pointer: coarse) and (min-width: 768px) {
  /* Wider info panel on tablet */
  #info-panel {
    width: min(280px, 38vw) !important;
  }
  /* Locate map icons slightly larger on tablet */
  #locate-gps-btn, #locate-places-btn, #locate-roads-btn, #locate-my-country-btn {
    width: 35px !important; height: 35px !important;
  }
  #locate-gps-btn svg, #locate-places-btn svg, #locate-roads-btn svg, #locate-my-country-btn svg {
    width: 22px !important; height: 22px !important;
  }
  /* Tablet search field 50% bigger than base mobile (7px → 11px) */
  #search-input { font-size: 11px !important; height: 28px !important; }
  #search-results .search-item { font-size: 11px !important; }
  #search-results .si-modern { font-size: 9px !important; }

  /* Touch screens this large aren't as space-constrained as a phone -- the base
     mobile sizing below reads too small. Bump general buttons/icons ~10%. */
  .ctrl-btn { min-width: 42px !important; min-height: 42px !important; }
  #nav-square .ctrl-btn { width: 24px !important; height: 24px !important; min-width: 24px !important; min-height: 24px !important; }
  #locate-leaflet-map .leaflet-control-zoom a {
    width: 22px !important; height: 22px !important; line-height: 22px !important; font-size: 15px !important;
  }
  #category-popup { font-size: 12px; }
  #category-popup .toggle-btn-sm { font-size: 12px !important; padding: 6px 10px !important; min-height: 35px !important; }
  #category-popup .toggle-btn-sm svg { width: 17px !important; height: 17px !important; }
  #category-popup .type-filter-btn { font-size: 12px !important; padding: 4px 8px !important; }
  #category-popup .tf-dot { width: 14px !important; height: 14px !important; }
}

/* Tablet portrait: info panel starts at 25% of screen width, goes full right */
@media (pointer: coarse) and (orientation: portrait) and (min-width: 768px) {
  #info-panel {
    left: 25% !important;
    right: 0 !important;
    width: 75% !important;
    border-radius: 10px 10px 0 0 !important;
  }
}

/* Tablet landscape: info panel fits content, not full height */
@media (pointer: coarse) and (orientation: landscape) and (min-width: 768px) {
  #info-panel {
    top: 0 !important;
    bottom: auto !important;
    height: auto !important;
    max-height: 100dvh !important;
    overflow-y: auto !important;
  }
}

/* Guided tour caption (runFullTour in main.js): the narration as subtitles when there is no
   sound, otherwise a slim bar with progress, "Next" and close. It never moves: bottom centre on
   wide screens (anchored at the bottom, so "Next" stays under the finger whatever the text's
   length), flat against the bottom edge on phones and touch screens (below). Above every panel. */
#demo-caption {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(46px + env(safe-area-inset-bottom, 0px));
  z-index: 2000; width: min(620px, calc(100vw - 24px));
  background: rgba(20, 17, 12, 0.94); color: #f3ead6;
  border: 1px solid #c8a050; border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  padding: 12px 14px 10px; pointer-events: auto;
  animation: demo-cap-in 0.25s ease-out;
  display: flex; flex-direction: column;
}
#demo-caption .demo-cap-bar { order: 2; }
@keyframes demo-cap-in { from { opacity: 0; } to { opacity: 1; } }
#demo-caption .demo-cap-text { margin: 0; font: 17px/1.5 Georgia, 'Times New Roman', serif; min-height: 1.5em; }
#demo-caption.sound .demo-cap-text { display: none; }
#demo-caption .demo-cap-bar { display: flex; align-items: center; gap: 8px; margin-top: 8px;
  font: 12.5px system-ui, -apple-system, sans-serif; color: #b9ad92; }
#demo-caption.sound .demo-cap-bar { margin-top: 0; }
#demo-caption .demo-cap-label:empty { display: none; }
#demo-caption .demo-cap-dots { display: flex; gap: 5px; flex: 1; flex-wrap: wrap; }
/* each dot jumps to its step; the ::after widens the target to a finger's width */
#demo-caption .demo-cap-dots i { position: relative; width: 7px; height: 7px; border-radius: 50%; background: #4a3f2c;
  cursor: pointer; outline: none; }
#demo-caption .demo-cap-dots i::after { content: ""; position: absolute; inset: -7px -3px; }
#demo-caption .demo-cap-dots i.on { background: #c8a050; }
#demo-caption .demo-cap-dots i:hover, #demo-caption .demo-cap-dots i:focus-visible { background: #ffd080; }
#demo-caption .demo-cap-dots i.cur { box-shadow: 0 0 0 2px rgba(255, 208, 128, 0.45); }
#demo-caption .demo-cap-btns { display: flex; gap: 8px; flex-shrink: 0; }
#demo-caption button { background: transparent; border: 1px solid #5a4a2c; color: #f3ead6; border-radius: 8px;
  padding: 3px 11px; cursor: pointer; font: 600 13px system-ui, -apple-system, sans-serif; }
#demo-caption button:hover { border-color: #c8a050; color: #ffd080; }
#demo-caption .demo-cap-end { padding: 1px 9px; font-size: 16px; line-height: 1.2; }
/* Phones and touch screens, portrait and landscape: the caption lies flat against the bottom edge,
   compact, so it hides as little as possible of what the tour shows. While the tour runs, what is
   anchored to the bottom edge moves up by the caption's height (--demo-cap-h, kept by
   demoCaption in main.js; body.demo-on), so the caption covers none of the controls it taps. */
@media (max-width: 699px), (pointer: coarse) {
  #demo-caption {
    top: auto; bottom: 0;
    width: min(640px, 100vw);
    border-radius: 12px 12px 0 0; border-bottom-width: 0;
    padding: 6px 10px calc(6px + env(safe-area-inset-bottom, 0px)) 12px;
    box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.4);
  }
  #demo-caption .demo-cap-text { font-size: 13.5px; line-height: 1.35; min-height: 0; }
  #demo-caption .demo-cap-bar { margin-top: 4px; gap: 6px; font-size: 11px; }
  #demo-caption .demo-cap-dots { gap: 5px; }
  #demo-caption .demo-cap-dots i { width: 6px; height: 6px; }
  #demo-caption .demo-cap-btns { gap: 6px; }
  #demo-caption button { padding: 2px 10px; font-size: 12px; border-radius: 7px; }
  #demo-caption .demo-cap-end { padding: 0 8px; font-size: 15px; }
}
/* Touch landscape: the caption starts right of the location map's column (29vw wide, 10px from
   the left), and the bar floats beside the sentence's first line, so two lines usually hold it. */
@media (pointer: coarse) and (orientation: landscape) {
  #demo-caption {
    left: auto; right: 0; transform: none;
    width: calc(71vw - 18px); max-width: 760px;
    border-top-right-radius: 0;
  }
  #demo-caption:not(.sound) { display: flow-root; }
  #demo-caption:not(.sound) .demo-cap-bar { float: right; margin: 0 0 2px 12px; }
  #demo-caption:not(.sound) .demo-cap-dots { flex-wrap: nowrap; }
  body.demo-on #info-panel { bottom: calc(6px + var(--demo-cap-h, 0px)) !important; }
  body.demo-on #country-mode-bar { transform: translateY(calc(-1 * var(--demo-cap-h, 0px))); }
}
@media (max-width: 699px) and (pointer: fine), (pointer: coarse) and (orientation: portrait) {
  body.demo-on #bottom-left-controls { bottom: calc(10px + var(--demo-cap-h, 0px)); }
}
/* the info panel's bottom sheet keeps its top edge and ends above the caption */
@media (pointer: coarse) and (orientation: portrait) {
  body.demo-on #info-panel {
    bottom: calc(6px + var(--demo-cap-h, 0px)) !important;
    height: calc(33vh - var(--demo-cap-h, 0px)) !important;
  }
}
/* narrow mouse-driven window: the info panel is a column down the left side */
@media (max-width: 600px) and (pointer: fine) {
  body.demo-on #info-panel { bottom: var(--demo-cap-h, 0px) !important; }
}

/* The tour's hand (demoTap / demoDrag in main.js): a touch marker that travels to each control
   and presses it, so a viewer sees what opens what. Never takes a click itself. */
#demo-hand { position: fixed; left: 0; top: 0; z-index: 2100; pointer-events: none; opacity: 0; width: 0; height: 0; }
#demo-hand.on { opacity: 1; }
#demo-hand .dh-dot { position: absolute; left: -17px; top: -17px; width: 34px; height: 34px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.28); border: 2.5px solid #fff;
  box-shadow: 0 0 0 3px rgba(200, 160, 80, 0.95), 0 6px 18px rgba(0, 0, 0, 0.55);
  transition: transform 0.15s ease, background 0.15s ease; }
#demo-hand.down .dh-dot { transform: scale(0.78); background: rgba(255, 208, 128, 0.6); }
#demo-hand .dh-ripple { position: absolute; left: -17px; top: -17px; width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid #ffd080; opacity: 0; }
#demo-hand.tap .dh-ripple { animation: dh-ripple 0.7s ease-out; }
@keyframes dh-ripple { from { transform: scale(0.6); opacity: 1; } to { transform: scale(2.8); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #demo-hand { transition: none !important; } }

/* While the tour runs, the page takes no clicks: only the caption's buttons end it (main.js). */
#demo-shield { position: fixed; inset: 0; z-index: 1990; background: transparent; cursor: default; touch-action: none; }

/* Phone portrait: tighter header buttons (user: less padding around Info, Demo and the email icon,
   a smaller "Vorlesen"), and a country-mode button in the location map's header no taller than
   its icon needs. Touch targets stay at least 24px. */
@media (pointer: coarse) and (orientation: portrait) {
  #feedback-btn { min-width: 30px; min-height: 30px; width: 30px; height: 30px; padding: 4px; }
  #about-btn { min-height: 30px; height: 30px; padding: 4px 6px; }
  #about-btn-col { gap: 3px; }
  #replay-demo-btn { min-height: 24px; }
  #autoread-btn { min-height: 28px; }
  #autoread-btn .autoread-label { font-size: 8.5px; }
  #modern-state-solo-btn { min-height: 0; height: 28px; padding-top: 1px; padding-bottom: 1px; }
}

/* ── Phone layout (touch screens) ─────────────────────────────────────────────────────────
   Bigger close buttons, the info panel's phone arrangement, the location map's dock row and
   the panels' default sizes. Touch screens only ((pointer: coarse), the test main.js's phone
   layout block uses too); mouse screens are untouched by everything below. */

/* The category popup's × exists for touch only (a mouse closes it by leaving it); the dock row
   only ever fills on touch screens. */
#cat-popup-close { display: none; }
#locate-dock-row:not(.docked) { display: none; }

@media (pointer: coarse) {
  /* Close buttons: a 44px rounded-square target with a × big enough to see and hit at a glance.
     The × is drawn (centred SVG), not the &times; glyph: the glyph sits differently in every
     phone font and looked lopsided in its outline (user). The glyph stays as the button text
     for screen readers and the aria-label, just invisible. */
  #close-panel, #locate-map-close, #close-about, #close-settings, #seg1-modal-close,
  #cat-popup-close, #landscape-tip-close {
    width: 44px !important; height: 44px !important;
    min-width: 44px !important; min-height: 44px !important;
    padding: 0 !important;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    font-size: 0 !important; line-height: 0 !important; color: transparent !important;
    background: rgba(255,255,255,0.08) center / 20px 20px no-repeat
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 4L16 16M16 4L4 16' stroke='%23e4e4e7' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E") !important;
    border: 1px solid rgba(255,255,255,0.18);
    border-radius: 10px;
    cursor: pointer;
  }
  #close-panel:active, #locate-map-close:active, #close-about:active, #close-settings:active,
  #seg1-modal-close:active, #cat-popup-close:active, #landscape-tip-close:active {
    background-color: rgba(255,255,255,0.18) !important;
  }
  /* Above the info panel's drag bar (z-index 1500), which otherwise eats the top of the button */
  #close-panel { top: 4px; right: 4px; z-index: 1600; }
  /* The mail button sits beside the × instead of on a row of its own, so the name starts at the
     top of the panel (user: no empty band above the name). The first lines keep clear of both. */
  #panel-top-row {
    position: absolute; top: 4px; right: 54px; height: 44px; z-index: 1600;
    margin: 0 !important; padding: 0 !important; align-items: center;
  }
  #panel-top-row #panel-email-btn { margin: 0 !important; }
  #panel-latin { padding-right: 78px; }
  #panel-latin-transl, #panel-modern-row { padding-right: 46px; }
  #close-about { top: 8px; right: 8px; }
  #seg1-modal-close { top: 6px; right: 6px; }
  #cat-popup-close { order: 99; margin-left: auto; align-self: center; }

  /* Info panel (rows moved by applyPhoneInfoLayout in main.js): the segment below the
     narration, the country on the modern name's line, a smaller category line. */
  #panel-segment-badge { width: fit-content; max-width: 100%; white-space: normal; margin: 2px 0 10px; }
  #panel-modern-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
  #panel-modern-row #panel-modern { flex: 1 1 auto; min-width: 0; margin-bottom: 0 !important; }
  #panel-modern-row #panel-country {
    flex: 0 0 auto; max-width: 55%; margin: 0; flex-wrap: nowrap;
    justify-content: flex-end; text-align: right; font-size: 12px; line-height: 1.25; gap: 4px;
  }
  #info-panel #panel-type { font-size: 12.5px; gap: 5px; margin: 6px 0 8px; }
  #info-panel #panel-type .type-icon { font-size: 1.05em; }

  /* Location map in front of / behind the info panel — whichever was touched last (main.js) */
  #locate-map-popup.phone-behind { z-index: 29 !important; }
  /* The open category menu reaches up into the (now taller) location map: keep it on top */
  #bottom-left-controls:has(#category-popup:not(.hidden)) { z-index: 201; }

  /* The row at the top of the location map that takes in the search field and the
     About / Demo / Auto-read column while the map covers their own spots (main.js). Above the
     map's legend and resize handle so the search results can drop down over the map. */
  #locate-dock-row.docked {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    padding: 4px 6px; flex-shrink: 0;
    border-bottom: 1px solid var(--border-color); background: rgba(0,0,0,0.18);
    position: relative; z-index: 2100;
  }
  #locate-dock-row #search-container { flex: 1 1 110px; width: auto; max-width: none; min-width: 110px; margin: 0; }
  /* 16px: iOS zooms the page into any smaller input when it is focused */
  #locate-dock-row #search-input { font-size: 16px !important; height: 34px !important; padding: 4px 10px !important; }
  #locate-dock-row #search-results { top: 38px; max-height: min(300px, 50vh); z-index: 1; }
  #locate-dock-row #search-results .search-item { font-size: 14px !important; padding: 8px 10px !important; }
  #locate-dock-row #search-results .si-modern { font-size: 12px !important; }
  #locate-dock-row #about-btn-col { flex-direction: row; align-items: center; gap: 4px; margin-left: auto; }
  #locate-dock-row #about-btn-col .ctrl-btn { align-self: auto; height: 34px; min-height: 34px; min-width: 34px; }
  /* Compact, so the column fits on the search field's line even in a landscape phone's panel */
  #locate-dock-row #about-btn { padding: 0 8px; gap: 0; }
  #locate-dock-row #replay-demo-btn, #locate-dock-row #autoread-btn { font-size: 11px; gap: 4px; padding: 0 7px; }
  #locate-dock-row #replay-demo-btn svg { width: 11px; height: 11px; }
  #locate-dock-row #autoread-btn svg { width: 22px; height: 22px; }
  #locate-dock-row .about-btn-label { display: none !important; }
  /* The column slid beside the info panel (main.js sets the transform) */
  #about-btn-col { transition: transform 0.2s ease; }
  /* Once its intro animation has run (main.js) — moving the column would otherwise replay it */
  .about-btn-label.label-gone { display: none !important; }

  /* The header has to hold the larger × as well: let the title give way first */
  #locate-header-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Phone portrait: the info panel and the location map both default to 3/4 of the screen height
   (was 33vh / 34vh). A size the user dragged or resized is kept: those are inline styles, which
   win over these. */
@media (pointer: coarse) and (orientation: portrait) and (max-width: 767px) {
  #info-panel       { height: 75vh !important; height: 75dvh !important; }
  #locate-map-popup { height: 75vh !important; height: 75dvh !important; }
  /* A narrower Modern Countries button, so the header still fits the larger × */
  #modern-state-solo-btn { font-size: 12px; padding-left: 6px; padding-right: 6px; gap: 3px; }
  #modern-state-solo-btn svg { width: 20px; height: 20px; }
}
/* Phone landscape: both panels already run the full height, so here the extra room goes into
   their width — the location map from 29vw to half the screen, the info panel from 280px (or
   25.5vw) to 40vw — and the info panel always runs the full height. Together they still leave
   a strip of the Tabula between them. */
@media (pointer: coarse) and (orientation: landscape) and (max-height: 599px) {
  #locate-map-popup { width: 50vw !important; }
  #info-panel {
    top: 6px !important; bottom: 6px !important; height: auto !important; max-height: none !important;
    width: max(280px, 40vw) !important;
  }
}
/* While the guided tour runs (#demo-shield, see startDemoTour in main.js) phones keep the earlier,
   smaller panels: the tour frames the Tabula and drags it around the middle of the screen, which
   the 3/4-size panels above would cover. */
@media (pointer: coarse) and (orientation: portrait) and (max-width: 767px) {
  body:has(> #demo-shield) #info-panel       { height: 33vh !important; }
  body:has(> #demo-shield) #locate-map-popup { height: 34vh !important; }
}
@media (pointer: coarse) and (orientation: landscape) and (max-height: 599px) {
  body:has(> #demo-shield) #locate-map-popup { width: 29vw !important; }
}
