/* ─────────────────────────────────────────────────────────
   Component Styles — Grünflächen Inventar
───────────────────────────────────────────────────────── */

/* ── Reset & base ──────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  height: 100%;
  font-family: system-ui, -apple-system, sans-serif;
  font-size: var(--text-base);
  color: var(--grey-900);
}

/* ── App shell ─────────────────────────────────────────── */
#app { display: flex; flex-direction: column; height: 100vh; }

/* ── Shared: uppercase section label ──────────────────── */
.section-label,
.dd-menu-label,
.filter-group-label,
.search-section-header,
#sidebar-header {
  font-size: var(--text-label); font-weight: var(--fw-bold);
  color: var(--grey-400); text-transform: uppercase; letter-spacing: .06em;
}

/* ── Shared: checkbox list item ───────────────────────── */
.check-item {
  display: flex; align-items: center; gap: var(--sp2);
  padding: var(--sp2) 10px; font-size: var(--text-sm); color: var(--grey-700);
  cursor: pointer; border-radius: var(--radius-sm); transition: background var(--t-fast);
}
.check-item:hover { background: var(--grey-100); }
.check-item input[type=checkbox] { cursor: pointer; accent-color: var(--primary); }

/* ── Shared: outlined interactive button base ──────────── */
.edit-btn,
.dd-btn,
.pg-btn,
.filter-clear-btn {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--white); border: 1px solid var(--grey-300);
  border-radius: var(--radius); cursor: pointer;
  font-size: var(--text-sm); color: var(--grey-700); line-height: 1;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
  user-select: none; white-space: nowrap;
}

/* ── Shared: clear-X button for inputs ────────────────── */
.input-clear-x {
  position: absolute; right: var(--sp2); top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: none; background: none;
  cursor: pointer; font-size: 16px; line-height: 1; color: var(--grey-400);
  border-radius: var(--radius-sm); transition: color var(--t-fast), background var(--t-fast);
}
.input-clear-x:hover { color: var(--grey-700); background: var(--grey-100); }

/* ── Header ────────────────────────────────────────────── */
#header {
  height: var(--header-height);
  background: var(--white);
  border-bottom: 1px solid var(--grey-300);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--sp5);
  flex-shrink: 0; z-index: var(--z-overlay); gap: var(--sp5);
}
.header-title { display: flex; flex-direction: column; gap: 1px; }
.header-agency {
  font-size: var(--text-xs); color: var(--grey-500);
  font-weight: var(--fw-medium); letter-spacing: .02em;
}
.header-app { font-size: var(--text-md); font-weight: var(--fw-bold); color: var(--grey-900); }
.header-right { display: flex; align-items: center; gap: var(--sp3); }

/* Header buttons (Filter / Share / Print / Edit) all reuse .edit-btn */
.edit-btn { padding: var(--sp-btn-y) var(--sp4); border-width: 1.5px; }
.edit-btn svg { flex-shrink: 0; }
.edit-btn:hover { border-color: var(--primary); color: var(--primary); }
.edit-btn.active { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn-text); }

/* Icon-only variant — square footprint, matches text-button height so the
   header row stays consistent.  Used for Share and Print where the icon
   alone is universally recognised. */
.edit-btn.icon-btn {
  padding: 0; width: var(--ctrl-h); height: var(--ctrl-h);
  display: inline-flex; align-items: center; justify-content: center;
}
.edit-btn.icon-btn svg { display: block; }

/* ── Header search ────────────────────────────────────── */
#search-area { flex: 1; display: flex; justify-content: center; padding: 0 var(--sp5); }
#search-wrapper { position: relative; width: 100%; max-width: 480px; z-index: var(--z-dropdown); }
#search-container {
  display: flex; align-items: center; height: var(--ctrl-h);
  border: 1px solid var(--grey-300); border-radius: var(--radius);
  background: var(--white); overflow: hidden;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
#search-container:focus-within { border-color: var(--primary); box-shadow: var(--shadow-focus); }
#search-icon {
  flex-shrink: 0; margin-left: var(--sp3); color: var(--grey-400); pointer-events: none;
}
#search-input {
  flex: 1; border: none; background: transparent;
  padding: 0 var(--sp3); font-size: var(--text-sm); color: var(--grey-900); outline: none;
  min-width: 0;
}
#search-input::placeholder { color: var(--grey-400); }
#search-input::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
#search-spinner {
  width: 16px; height: 16px; flex-shrink: 0; margin-right: var(--sp2);
  border: 2px solid var(--grey-200); border-top-color: var(--grey-600);
  border-radius: 50%; display: none;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
#search-container .input-clear-x {
  position: static; flex-shrink: 0; margin-right: var(--sp1);
  transform: none; align-self: center;
}

/* ── Search results dropdown ──────────────────────────── */
#search-results {
  position: absolute; top: calc(100% + var(--sp2)); left: 0; right: 0;
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  max-height: 380px; overflow-y: auto; display: none;
}
#search-results.active { display: block; }
.search-section-header {
  padding: 5px var(--sp4);
  background: var(--grey-50); border-bottom: 1px solid var(--grey-100);
}
.search-item {
  padding: 7px var(--sp4); cursor: pointer;
  border-bottom: 1px solid var(--grey-100);
  transition: background var(--t-fast);
}
.search-item:last-child { border-bottom: none; }
.search-item:hover { background: var(--grey-50); }
.search-item-title { font-size: var(--text-sm); color: var(--grey-900); }
.search-item-subtitle { font-size: var(--text-xs); color: var(--grey-500); margin-top: 1px; }

.badge {
  background: var(--grey-100); border: 1px solid var(--grey-300);
  border-radius: var(--radius-full); padding: var(--sp1) 10px;
  font-size: var(--text-xs); color: var(--grey-600); white-space: nowrap;
}

/* ── Body / layout ─────────────────────────────────────── */
#body { flex: 1; display: flex; overflow: hidden; }

/* ── Sidebar ───────────────────────────────────────────── */
#sidebar {
  width: var(--panel-width); background: var(--white);
  border-right: 1px solid var(--grey-300);
  display: flex; flex-direction: column; overflow: hidden; flex-shrink: 0;
  transition: width var(--t-slow), opacity var(--t-slow);
}
#sidebar.collapsed { width: 0; border-right: none; opacity: 0; pointer-events: none; }
#sidebar-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp3) var(--sp5); border-bottom: 1px solid var(--grey-200);
  flex-shrink: 0;
}
.sidebar-close-btn {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; border: none; background: none;
  cursor: pointer; font-size: 18px; line-height: 1; color: var(--grey-400);
  border-radius: var(--radius-sm); transition: color var(--t-fast), background var(--t-fast);
}
.sidebar-close-btn:hover { color: var(--grey-700); background: var(--grey-100); }
#legend-scroll { flex: 1; overflow-y: auto; padding: var(--sp2) 0 var(--sp4); }

/* ── Legend groups ─────────────────────────────────────── */
.lg-group { margin-bottom: var(--sp1); }
.lg-group-head {
  display: flex; align-items: center; gap: var(--sp2);
  padding: 5px var(--sp4) var(--sp1) var(--sp3);
}
/* Generic eye-btn — used by both group headers and external-layer rows so
   they share visual style (size, hover, hidden state). */
.eye-btn {
  flex-shrink: 0; width: 20px; height: 20px;
  background: none; border: none; cursor: pointer;
  color: var(--grey-400); padding: 1px;
  border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center;
  transition: color var(--t-fast);
}
.eye-btn:hover { color: var(--grey-700); }
.eye-btn.hidden-eye { color: var(--grey-300); }
.lg-group-title {
  font-size: var(--text-xs); font-weight: var(--fw-bold); color: var(--grey-700);
  text-transform: uppercase; letter-spacing: .05em;
}
.lg-items { padding: 0 var(--sp4) var(--sp1) 34px; }
.lg-item { display: flex; align-items: center; gap: 7px; padding: var(--sp1) 0; transition: opacity var(--t-base); }
.lg-item.empty { opacity: 0.38; }
.lg-swatch { width: 22px; height: 13px; border-radius: var(--radius-sm); flex-shrink: 0; border: 1px solid rgba(0,0,0,.12); }
.lg-label { font-size: var(--text-sm); color: var(--grey-800); line-height: 1.3; }
.group-hidden .lg-items { opacity: 0.3; pointer-events: none; }

/* Pattern swatches */
.sw-dots    { background-image: radial-gradient(circle, #333 30%, transparent 30%); background-size: 5px 5px; }
.sw-vdots   { background-image: radial-gradient(circle, #856a00 40%, transparent 40%); background-size: 5px 5px; }
.sw-odots   { background-image: radial-gradient(circle, #804000 35%, transparent 35%); background-size: var(--sp2) var(--sp2); }
.sw-pstripe { background-image: repeating-linear-gradient(45deg,#9040c0 0,#9040c0 1.5px,transparent 0,transparent 50%); background-size: 5px 5px; }
.sw-ostripe { background-image: repeating-linear-gradient(45deg,#c05000 0,#c05000 1.5px,transparent 0,transparent 50%); background-size: 5px 5px; }
.sw-hstripe { background-image: repeating-linear-gradient(45deg,#5a3800 0,#5a3800 1.5px,transparent 0,transparent 50%); background-size: 5px 5px; }
.sw-xhatch  { background-image: repeating-linear-gradient(45deg,#333 0,#333 1px,transparent 0,transparent 50%), repeating-linear-gradient(-45deg,#333 0,#333 1px,transparent 0,transparent 50%); background-size: 5px 5px; }
.sw-gdots   { background-image: radial-gradient(circle, #555 30%, transparent 30%); background-size: 5px 5px; }
.sw-outline { background: transparent !important; border: 2px solid var(--red) !important; }
.sw-circ    { border-radius: 50% !important; width: 13px !important; height: 13px !important; border: 2px solid rgba(0,0,0,.25) !important; }
.sw-circ-cross {
  border-radius: 50% !important; width: 13px !important; height: 13px !important;
  border: 2px solid rgba(0,0,0,.4) !important; position: relative;
}
.sw-circ-cross::before, .sw-circ-cross::after {
  content: ''; position: absolute; background: rgba(0,0,0,.5);
  top: 50%; left: 50%; transform: translate(-50%,-50%);
}
.sw-circ-cross::before { width: 7px; height: 1.5px; }
.sw-circ-cross::after  { width: 1.5px; height: 7px; }
.sw-triangle {
  width: 0 !important; height: 0 !important; background: transparent !important;
  border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-bottom: 12px solid var(--red); border-top: none !important; border-radius: 0 !important;
}

/* ── Main content column ───────────────────────────────── */
#main-content { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0; }

/* ── Map ───────────────────────────────────────────────── */
#map { flex: 1; position: relative; min-height: 0; overflow: visible; }
#map.edit-active::after {
  content: ''; position: absolute; inset: 0;
  border: 3px solid var(--red); border-radius: 0;
  pointer-events: none; z-index: var(--z-overlay);
  animation: editPulse 2s ease-in-out infinite;
}
@keyframes editPulse {
  0%, 100% { border-color: var(--red); }
  50%      { border-color: rgba(204, 0, 0, .4); }
}
/* Legend toggle button (visible when sidebar is collapsed) */
.legend-toggle-btn {
  position: absolute; top: var(--sp3); left: var(--sp3);
  z-index: var(--z-map-ctrl);
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  background: var(--white); border: 1.5px solid var(--grey-300);
  border-radius: var(--radius); cursor: pointer;
  color: var(--grey-600); box-shadow: var(--shadow-map-ctrl);
  transition: border-color var(--t-fast), color var(--t-fast);
}
.legend-toggle-btn:hover { border-color: var(--primary); color: var(--primary); }

.maplibregl-ctrl-top-right { top: var(--sp3); right: var(--sp3); }

/* Custom IconCtrl buttons (Home, 2D/3D toggle) — match the look of the
   built-in MapLibre nav buttons.  SVG icons centered; text-only buttons
   (the 3D toggle) get a tighter font. */
.maplibregl-ctrl-group button > svg {
  display: block; margin: auto; color: var(--grey-700);
}
.maplibregl-ctrl-group button:hover > svg { color: var(--primary); }

/* Text-content buttons - target buttons whose direct text is "2D" or "3D"
   via :not([class*=zoom]) is too broad; instead key on a single rule that
   styles letter-content reliably regardless of which IconCtrl uses text. */
.maplibregl-ctrl-group button {
  font-family: inherit;
  font-weight: var(--fw-bold);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  color: var(--grey-700);
}
.maplibregl-ctrl-group button:hover { color: var(--primary); }

/* Pressed/active state for the 3D toggle.  MapLibre's default
   `.maplibregl-ctrl button:hover` rule sets `background-color` to a near-
   white overlay; without an explicit hover background here, our white
   text lands on near-white and becomes unreadable.  Pin the background to
   primary-dark so hover stays high-contrast AND provides a clear
   interaction cue. */
.maplibregl-ctrl-group button.ctrl-active {
  background: var(--primary);
  color: var(--white);
}
.maplibregl-ctrl-group button.ctrl-active > svg { color: var(--white); }
.maplibregl-ctrl-group button.ctrl-active:hover {
  background: var(--primary-dark);
  color: var(--white);
}
.maplibregl-ctrl-group button.ctrl-active:hover > svg { color: var(--white); }

/* ── Map popup ─────────────────────────────────────────── */
.maplibregl-popup-content {
  padding: 0; border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 4px 20px rgba(0,0,0,.16); font-size: var(--text-sm); min-width: 220px;
}
.maplibregl-popup-close-button {
  font-size: var(--text-lg); padding: var(--sp2) var(--sp3); color: var(--grey-400);
  transition: color var(--t-fast);
}
.maplibregl-popup-close-button:hover { color: var(--grey-700); }
.pu-header {
  display: flex; align-items: center; gap: var(--sp3);
  padding: var(--sp3) var(--sp4); border-bottom: 1px solid var(--grey-100);
}
.pu-swatch {
  width: 14px; height: 14px; border-radius: var(--radius-sm); flex-shrink: 0;
  border: 1px solid var(--border-subtle);
}
.pu-titles { min-width: 0; }
.pu-type { font-weight: var(--fw-semibold); color: var(--grey-900); line-height: 1.3; }
.pu-sub  { color: var(--grey-500); font-size: var(--text-xs); line-height: 1.3; }
.pu-body { padding: var(--sp3) var(--sp4); }
.pu-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: var(--sp1) 0; font-size: var(--text-sm); color: var(--grey-500);
}
.pu-row + .pu-row { border-top: 1px solid var(--grey-50); }
.pu-row strong {
  color: var(--grey-800); font-weight: var(--fw-medium);
  text-align: right; margin-left: var(--sp4);
  word-break: break-word; max-width: 60%;
}
.pu-section {
  font-size: var(--text-label); font-weight: var(--fw-bold);
  color: var(--grey-400); text-transform: uppercase; letter-spacing: .06em;
  margin: var(--sp3) 0 var(--sp1) 0;
  padding-top: var(--sp2); border-top: 1px solid var(--grey-100);
}
.pu-section:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.pu-body { max-height: 380px; overflow-y: auto; padding: var(--sp3) var(--sp4); }

/* ── Map overlay banners (shared base) ─────────────────── */
#edit-banner,
#save-banner {
  display: none; position: absolute; left: 50%; transform: translateX(-50%);
  z-index: var(--z-overlay); border-radius: var(--radius);
  font-size: var(--text-sm); box-shadow: var(--shadow-md);
}

/* Permanent "Prototyp" pill at the top-center of the map.  Same colour
   family as the footer pill so the demo flag reads consistently in both
   places.  Pointer-events disabled so it never intercepts map clicks. */
#map-prototype-banner {
  position: absolute;
  top: max(var(--sp3), env(safe-area-inset-top, 0));
  left: 50%; transform: translateX(-50%);
  z-index: var(--z-overlay);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-pill);
  padding: 2px var(--sp4);
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.03em;
  color: var(--warn-text);
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
  pointer-events: none;
  /* If the placeholder edit mode is ever turned on, hide this pill so it
     doesn't stack under the edit banner (same position). */
}
#map.edit-active #map-prototype-banner { display: none; }
#edit-banner {
  top: var(--sp3);
  background: var(--warn-bg); border: 1.5px solid var(--warn-border);
  padding: var(--sp2) var(--sp5); color: var(--warn-text); pointer-events: none;
}
#edit-banner.visible { display: block; }
#save-banner {
  bottom: var(--sp5);
  background: var(--white); border: 1.5px solid var(--grey-300);
  padding: var(--sp3) var(--sp6); color: var(--grey-800);
  box-shadow: var(--shadow-pop);
  align-items: center; gap: var(--sp4);
}
#save-banner.visible { display: flex; }
#save-banner button {
  background: var(--primary); color: var(--white); border: none;
  border-radius: var(--radius); padding: var(--sp-btn-y) 14px; cursor: pointer;
  font-size: var(--text-sm); font-weight: var(--fw-semibold);
  transition: background var(--t-fast);
}
#save-banner button:hover { background: var(--primary-dark); }
#save-banner .cancel-btn { background: none; color: var(--grey-600); border: 1px solid var(--grey-300); }
#save-banner .cancel-btn:hover { background: var(--grey-100); }

/* ── Footer ────────────────────────────────────────────── */
/* 3-column grid: coords (left), prototype-banner (centred), links (right).
   Centred element stays geometrically centred regardless of left/right
   content width — `justify-content: space-between` on flex would shift it
   off-axis as coords expand/contract. */
#footer {
  height: var(--footer-height); background: var(--grey-100);
  border-top: 1px solid var(--grey-300);
  padding: 0 var(--sp5); font-size: var(--text-xs); color: var(--grey-600);
  display: flex; justify-content: space-between; align-items: center;
  flex-shrink: 0; z-index: var(--z-overlay);
}
#coordinates { font-family: monospace; }
#footer-links a { color: var(--primary); text-decoration: none; margin-left: var(--sp4); }
#footer-links a:hover { text-decoration: underline; }

/* ── Basemap switcher ──────────────────────────────────── */
#basemap-switcher { position: absolute; bottom: 50px; right: var(--map-ctrl-right); z-index: var(--z-map-ctrl); }
.bm-btn {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp2);
  background: var(--white); border: 1.5px solid var(--grey-300);
  border-radius: var(--radius); padding: var(--sp-btn-y);
  font-size: var(--text-xs); color: var(--grey-700);
  cursor: pointer; box-shadow: var(--shadow-map-ctrl);
  transition: border-color var(--t-fast);
}
.bm-btn:hover { border-color: var(--primary); color: var(--primary); }
.bm-btn img {
  width: 80px; height: 60px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle); display: block; object-fit: cover;
}
.bm-btn span { font-size: var(--text-xs); color: var(--grey-700); line-height: 1; }
.bm-panel {
  position: absolute; bottom: 0; right: calc(100% + var(--sp4));
  background: var(--white); border: 1.5px solid var(--grey-300);
  border-radius: var(--radius); padding: var(--sp3);
  box-shadow: var(--shadow-panel);
  display: flex; gap: var(--sp3);
  opacity: 0; visibility: hidden; transform: translateX(4px);
  transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
  white-space: nowrap;
}
.bm-panel.open { opacity: 1; visibility: visible; transform: translateX(0); }
.bm-option {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp2);
  background: none; border: 2px solid var(--grey-200);
  border-radius: var(--radius); padding: var(--radius-sm);
  cursor: pointer; transition: border-color var(--t-fast);
}
.bm-option:hover { border-color: var(--grey-400); }
.bm-option.active { border-color: var(--primary); }
.bm-option img {
  width: 70px; height: 50px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle); display: block; object-fit: cover;
}
.bm-opt-label { font-size: var(--text-xs); color: var(--grey-700); }
.bm-option.active .bm-opt-label { color: var(--primary); font-weight: var(--fw-semibold); }

/* ── Table panel ───────────────────────────────────────── */
#table-panel {
  height: var(--table-height); flex-shrink: 0;
  display: flex; flex-direction: column;
  overflow: hidden; background: var(--white);
  transition: height var(--t-slow);
  position: relative; z-index: var(--z-table);
}
#table-panel.collapsed { height: 0; }
#table-panel.resizing { transition: none; }

/* Drag handle between map and table panel */
#tbl-resize-handle {
  flex-shrink: 0; height: 6px;
  cursor: ns-resize; user-select: none;
  position: relative; z-index: var(--z-table);
  background: var(--grey-200);
  transition: background var(--t-fast);
}
#tbl-resize-handle::after {
  content: ''; position: absolute;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 36px; height: var(--sp2); border-radius: var(--sp1);
  background: var(--grey-400); opacity: 0;
  transition: opacity var(--t-fast);
}
#tbl-resize-handle:hover { background: var(--grey-300); }
#tbl-resize-handle:hover::after,
#tbl-resize-handle.dragging::after { opacity: 1; }
#tbl-resize-handle.dragging { background: var(--primary); }
#tbl-resize-handle.dragging::after { background: var(--white); opacity: 1; }

/* ── Table toggle pill ─────────────────────────────────── */
#tbl-toggle {
  position: absolute; bottom: var(--map-ctrl-bottom); left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-toggle);
  display: inline-flex; align-items: center; gap: var(--sp2);
  padding: 11px var(--sp5) 11px var(--sp4);
  background: var(--white); border: 1px solid var(--grey-300);
  border-radius: var(--radius-full);
  font-size: var(--text-xs); font-weight: var(--fw-semibold); color: var(--grey-500);
  cursor: pointer; letter-spacing: .02em; white-space: nowrap;
  box-shadow: var(--shadow-pill);
  transition: border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
  user-select: none;
}
#tbl-toggle:hover {
  border-color: var(--primary); color: var(--primary);
  box-shadow: var(--shadow-pill-hover);
}
#tbl-toggle svg { transition: transform var(--t-base); flex-shrink: 0; }
#tbl-toggle.collapsed svg { transform: rotate(180deg); }

/* ── Table action bar ──────────────────────────────────── */
#tbl-action-bar {
  display: flex; align-items: center; gap: var(--sp3); padding: var(--sp2) var(--sp5);
  border-bottom: 1px solid var(--grey-200); flex-shrink: 0; background: var(--white);
  position: relative; z-index: var(--z-table-bar);
}
/* ── Tab strip (Standorte / Grünflächen) ──────────────────────────── */
/* Segmented-control style: inactive tabs blend with the surrounding action
   bar; the active tab gets a white pill with a subtle shadow so it reads
   as "currently selected" without competing with primary buttons.  Counts
   are dimmed so the label stays the focal point. */
#tbl-tabs {
  display: inline-flex; align-items: center; gap: 0;
  background: var(--grey-100);
  border-radius: var(--radius); padding: 2px;
  flex-shrink: 0;
}
.tbl-tab {
  display: inline-flex; align-items: center; gap: var(--sp2);
  height: var(--ctrl-h); padding: 0 var(--sp4);
  background: transparent; border: none;
  cursor: pointer; border-radius: var(--radius-sm);
  font-size: var(--text-sm); font-weight: var(--fw-medium);
  color: var(--grey-600);
  white-space: nowrap;
  transition: color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.tbl-tab:hover { color: var(--grey-900); }
.tbl-tab.active {
  background: var(--white);
  color: var(--primary);
  font-weight: var(--fw-semibold);
  box-shadow: var(--shadow-sm);
}
.tbl-tab-count {
  font-size: var(--text-xs); color: inherit; opacity: 0.65;
  font-weight: var(--fw-medium);
}

#tbl-search-wrap { position: relative; flex: 1; max-width: 260px; }
#tbl-search {
  width: 100%; height: var(--ctrl-h); padding: 0 26px 0 30px;
  border: 1px solid var(--grey-300); border-radius: var(--radius);
  font-size: var(--text-sm); background: var(--white); color: var(--grey-900);
  transition: border-color var(--t-fast);
}
#tbl-search::placeholder { color: var(--grey-400); }
#tbl-search:focus { outline: none; border-color: var(--primary); box-shadow: var(--shadow-focus); }
#tbl-search-icon {
  position: absolute; left: var(--sp3); top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--grey-400);
}
/* Same gap as .header-right (sp3) so the button cluster reads consistently
   with the page header.  On narrow phones the action bar wraps and the
   override at the bottom of this file tightens it back to sp2. */
#tbl-action-right { display: flex; align-items: center; gap: var(--sp3); margin-left: auto; }

/* ── Dropdown buttons (extends shared btn base) ────────── */
.dd-btn { height: var(--ctrl-h); padding: 0 10px; gap: 5px; }
.dd-btn .dd-caret { margin-left: var(--sp1); color: var(--grey-400); transition: transform var(--t-base), color var(--t-fast); }
.dd-btn:hover { border-color: var(--grey-400); color: var(--grey-900); }
.dd-btn:hover .dd-caret { color: var(--grey-600); }
.dd-wrap.open .dd-btn { background: var(--grey-100); border-color: var(--grey-400); color: var(--grey-900); }
.dd-wrap.open .dd-btn .dd-caret { transform: rotate(180deg); color: var(--grey-600); }
.dd-btn.has-active { border-color: var(--primary); color: var(--primary); }
.dd-btn.has-active .dd-caret { color: var(--primary); }

/* ── Dropdown menus ────────────────────────────────────── */
.dd-wrap { position: relative; }
.dd-menu {
  position: absolute; top: calc(100% + 5px); z-index: var(--z-dropdown);
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  min-width: 160px; padding: var(--sp2);
  display: none;
  animation: ddFadeIn .1s ease;
}
@keyframes ddFadeIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.dd-wrap.open .dd-menu { display: block; }

.dd-menu-label { padding: var(--sp2) 10px var(--sp1); }
.dd-item {
  display: flex; align-items: center; gap: var(--sp2);
  padding: var(--sp2) 10px; font-size: var(--text-sm);
  cursor: pointer; white-space: nowrap; color: var(--grey-700);
  border-radius: var(--radius-sm); transition: background var(--t-fast);
}
.dd-item:hover { background: var(--grey-100); color: var(--grey-900); }
.dd-divider { height: 1px; background: var(--grey-100); margin: var(--sp2) 0; }

/* Column selector — extends .check-item */
.col-check-item,
.filter-check-item {
  display: flex; align-items: center;
  font-size: var(--text-sm); color: var(--grey-700);
  cursor: pointer; border-radius: var(--radius-sm); transition: background var(--t-fast);
}
.col-check-item:hover,
.filter-check-item:hover { background: var(--grey-100); }
.col-check-item input[type=checkbox],
.filter-check-item input[type=checkbox] { cursor: pointer; accent-color: var(--primary); }
.col-check-item { gap: var(--sp3); padding: 5px 10px; }

/* ── Filter dropdown (checkbox groups) ─────────────────── */
#tbl-filter-dd { max-height: 340px; overflow-y: auto; }
/* The dd-menu has padding: var(--sp2).  A sticky element inside that box
   is positioned at top:0 of its containing block (dd-menu's content edge,
   below the 4px padding-top), so scrolled items can briefly bleed into the
   4px gap above the sticky bar.  Negative top + margin + padding pulls
   the wrap up to cover the padding region completely; a bottom shadow +
   border give a clean visual seam. */
.filter-search-wrap {
  position: sticky; top: calc(-1 * var(--sp2)); z-index: 2;
  background: var(--white);
  margin: calc(-1 * var(--sp2)) calc(-1 * var(--sp2)) 0;
  padding: var(--sp2);
  border-bottom: 1px solid var(--grey-200);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}
.filter-search {
  width: 100%; height: var(--ctrl-h-sm); padding: 0 26px 0 var(--sp3);
  border: 1px solid var(--grey-300); border-radius: var(--radius-sm);
  font-size: var(--text-sm); background: var(--white); color: var(--grey-900);
  transition: border-color var(--t-fast);
}
.filter-search::placeholder { color: var(--grey-400); }
.filter-search:focus { outline: none; border-color: var(--primary); box-shadow: var(--shadow-focus); }
.filter-group { padding: var(--sp1) 0; }
.filter-group + .filter-group { border-top: 1px solid var(--grey-100); margin-top: var(--sp1); padding-top: var(--sp2); }
.filter-group-label { padding: 5px 10px var(--sp1); }
.filter-check-item { gap: var(--sp2); padding: var(--sp2) 10px; }

/* ── Filter pill bar ───────────────────────────────────── */
#tbl-filter-pills {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp2);
  padding: var(--sp2) var(--sp4); background: var(--grey-50); border-bottom: 1px solid var(--grey-200);
}
/* Chip-style pills: neutral grey background lets many pills coexist
   without dominating the action area.  The × button is muted by default
   and turns red on hover/focus as the destructive cue. */
.filter-pill {
  display: inline-flex; align-items: center; gap: var(--sp2);
  padding: var(--sp1) var(--sp3); font-size: var(--text-sm); line-height: 22px;
  background: var(--grey-100); color: var(--grey-800);
  border: 1px solid var(--grey-300); border-radius: var(--radius-pill);
  white-space: nowrap;
}
.pill-x {
  background: none; border: none; cursor: pointer;
  font-size: var(--text-base); line-height: 1;
  color: var(--grey-500); padding: 0 0 0 var(--sp1); font-weight: var(--fw-bold);
  transition: color var(--t-fast);
}
.pill-x:hover { color: var(--red); }
.filter-reset-link {
  background: none; border: none; cursor: pointer;
  font-size: var(--text-sm); color: var(--grey-500);
  text-decoration: underline; padding: 0 var(--sp2); white-space: nowrap;
}
.filter-reset-link:hover { color: var(--grey-700); }

.tbl-badge {
  background: var(--primary); color: var(--white);
  border-radius: var(--radius-pill); font-size: var(--text-label); padding: 1px var(--sp2);
  line-height: 14px; font-weight: var(--fw-semibold);
}

/* ── Table ─────────────────────────────────────────────── */
#table-scroll { flex: 1; overflow-y: auto; overflow-x: auto; background: var(--white); }
#tbl { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
#tbl thead { position: sticky; top: 0; background: var(--grey-100); z-index: var(--z-base); }
#tbl th {
  padding: 7px var(--sp5); text-align: left;
  font-size: var(--text-label); font-weight: var(--fw-bold); color: var(--grey-600);
  text-transform: uppercase; letter-spacing: .04em;
  border-bottom: 2px solid var(--grey-200);
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: color var(--t-fast);
}
#tbl th:hover { color: var(--primary); }
#tbl th.sort-asc::after  { content: ' ↑'; }
#tbl th.sort-desc::after { content: ' ↓'; }
#tbl td {
  padding: 7px var(--sp5); border-bottom: 1px solid var(--grey-100);
  color: var(--grey-800); white-space: nowrap;
}
#tbl tbody tr { cursor: pointer; }
#tbl tbody tr:hover td { background: var(--row-hover); }
#tbl tbody tr.row-active td { background: var(--row-active); }
/* Selected row: light primary tint, no inset border.  Hover-while-selected
   keeps the selected bg so the hover state doesn't visually override the
   selection. */
#tbl tbody tr.selected td { background: var(--row-active); }
#tbl tbody tr.selected:hover td { background: var(--row-active); }

/* ── Pagination bar ────────────────────────────────────── */
#tbl-pagination {
  display: flex; align-items: center; gap: var(--sp2);
  padding: 5px var(--sp5); border-top: 1px solid var(--grey-200);
  flex-shrink: 0; background: var(--white);
}
.pg-info { font-size: var(--text-sm); color: var(--grey-500); white-space: nowrap; text-align: right; }
.pg-spacer { flex: 1; }
#pg-pages { display: inline-flex; align-items: center; gap: var(--sp1); }

/* Pagination buttons (extends shared btn base) */
.pg-btn { min-width: var(--ctrl-h-sm); height: var(--ctrl-h-sm); padding: 0 var(--sp2); justify-content: center; }
.pg-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); background: var(--pg-hover); }
.pg-btn:disabled { opacity: 0.3; cursor: default; }
.pg-btn.pg-active { background: var(--primary); color: var(--white); border-color: var(--primary); font-weight: var(--fw-semibold); }

#pg-size-select {
  height: var(--ctrl-h-sm); padding: 0 var(--sp2); font-size: var(--text-sm);
  border: 1px solid var(--grey-300); border-radius: var(--radius);
  background: var(--white); color: var(--grey-700); cursor: pointer;
  transition: border-color var(--t-fast);
}
#pg-size-select:hover { border-color: var(--grey-400); }

/* ── Context menu ─────────────────────────────────────── */
.map-context-menu {
  position: absolute; background: var(--white);
  border: 1px solid var(--grey-200); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); min-width: 190px;
  z-index: var(--z-dropdown); display: none; overflow: hidden;
}
.map-context-menu.show { display: block; }
.map-context-menu.flip-h { transform: translateX(-100%); }
.map-context-menu.flip-v { transform: translateY(-100%); }
.map-context-menu.flip-h.flip-v { transform: translate(-100%, -100%); }

.context-menu-item {
  display: flex; align-items: center; gap: var(--sp3);
  padding: 7px var(--sp4); font-size: var(--text-sm); color: var(--grey-700);
  cursor: pointer; transition: background var(--t-fast); white-space: nowrap;
}
.context-menu-item:hover { background: var(--grey-50); }
.context-menu-item svg { flex-shrink: 0; color: var(--grey-500); }
.context-menu-coords.copied { background: var(--success-bg); color: var(--success); }
.context-menu-coords.copied svg { color: var(--success); }
.context-menu-item.measure-active { background: var(--primary-a12); color: var(--primary); }
.context-menu-item.measure-active svg { color: var(--primary); }

/* ── Measure distance ─────────────────────────────────── */
.measure-distance-display {
  position: absolute; top: var(--sp4); left: 50%; transform: translateX(-50%);
  background: var(--white); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); display: none; flex-direction: column;
  width: 260px; z-index: var(--z-dropdown); overflow: hidden;
}
.measure-distance-display.show { display: flex; }

.measure-distance-header {
  display: flex; align-items: center; gap: var(--sp2);
  padding: var(--sp3) var(--sp4); background: var(--grey-50);
  border-bottom: 1px solid var(--grey-200);
  font-weight: var(--fw-semibold); font-size: var(--text-sm); color: var(--grey-900);
}
.measure-distance-header svg { color: var(--grey-500); flex-shrink: 0; }
.measure-distance-close {
  margin-left: auto; background: none; border: none;
  padding: var(--sp1); cursor: pointer; font-size: 18px; line-height: 1;
  color: var(--grey-400); border-radius: var(--radius-sm);
  transition: background var(--t-fast), color var(--t-fast);
}
.measure-distance-close:hover { background: var(--grey-200); color: var(--grey-700); }

.measure-distance-info {
  padding: var(--sp3) var(--sp4); font-size: var(--text-xs); color: var(--grey-500);
  border-bottom: 1px solid var(--grey-100);
}
.measure-distance-result { padding: var(--sp3) var(--sp4); }
.measure-result-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: var(--sp1) 0;
}
.measure-result-label { font-size: var(--text-sm); color: var(--grey-600); }
.measure-result-value { font-size: var(--text-sm); font-weight: var(--fw-semibold); color: var(--grey-900); }

/* Measure markers + labels on map */
.measure-marker {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--white); border: 2px solid var(--grey-900);
  cursor: pointer; transition: transform .1s ease;
}
.measure-marker:hover { transform: scale(1.3); }

.measure-label {
  background: var(--white); border: 1px solid var(--grey-300);
  border-radius: var(--radius-sm); padding: var(--sp1) var(--sp2);
  font-size: var(--text-xs); font-weight: var(--fw-medium);
  color: var(--grey-800); box-shadow: var(--shadow-xs);
  white-space: nowrap; pointer-events: none;
}

/* ── Toast notifications ──────────────────────────────── */
#toast-container {
  position: absolute; top: var(--sp4); left: 50%; transform: translateX(-50%);
  z-index: var(--z-dropdown); display: flex; flex-direction: column;
  gap: var(--sp2); align-items: center; pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: var(--sp3);
  padding: var(--sp3) 14px; border-radius: var(--radius);
  font-size: var(--text-sm); color: var(--white);
  background: var(--grey-800); box-shadow: var(--shadow-md);
  animation: toastIn .2s ease, toastOut .3s ease 2.5s forwards;
  white-space: nowrap;
}
.toast.success { background: var(--success); }
.toast.error   { background: var(--red); }
@keyframes toastIn  { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toastOut { from { opacity: 1; } to { opacity: 0; } }

/* ── External-layers section in the legend sidebar ──────────────────── */
.lg-group-external { border-top: 1px solid var(--grey-200); margin-top: var(--sp3); padding-top: var(--sp2); }
/* Wrapper for the rows.  Padding-left aligned with .lg-group-head (sp3) so
   the eye icon sits at the same column as section-header eyes - otherwise
   the inherited .lg-items 34px indent pushes them further right. */
.lg-ext-items { padding: 0 var(--sp4) var(--sp2) 0; }
.lg-ext-item {
  display: flex; align-items: center; gap: var(--sp2);
  padding: 4px var(--sp4) 4px var(--sp3);
  border-radius: var(--radius-sm);
}
.lg-ext-item:hover { background: var(--grey-50); }
.lg-ext-item.group-hidden { opacity: 0.45; }
.lg-ext-label {
  flex: 1; min-width: 0;
}
.lg-ext-title {
  font-size: var(--text-sm); color: var(--grey-800); line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lg-ext-attr {
  /* grey-500 gives ~4.6:1 contrast on white, just over WCAG AA at 10 px.
     grey-400 was 3.0:1 — failed AA for non-large text. */
  font-size: var(--text-label); color: var(--grey-500); margin-top: 1px;
}
.lg-ext-attr a { color: inherit; text-decoration: none; }
.lg-ext-attr a:hover { text-decoration: underline; }
.lg-ext-opacity {
  flex-shrink: 0; width: 60px; cursor: pointer; accent-color: var(--primary);
}
.lg-ext-remove {
  flex-shrink: 0;
  width: 20px; height: 20px; border: none; background: transparent;
  color: var(--grey-400); cursor: pointer; font-size: 16px; line-height: 1;
  border-radius: var(--radius-sm); transition: color var(--t-fast), background var(--t-fast);
  display: flex; align-items: center; justify-content: center;
}
.lg-ext-remove:hover { color: var(--red); background: var(--grey-100); }

/* ── Filter sidebar (right side, mirror of #sidebar legend) ─────────── */
#filter-sidebar {
  width: var(--panel-width); background: var(--white);
  border-left: 1px solid var(--grey-300);
  display: flex; flex-direction: column; overflow: hidden; flex-shrink: 0;
  transition: width var(--t-slow), opacity var(--t-slow);
}
#filter-sidebar.collapsed { width: 0; border-left: none; opacity: 0; pointer-events: none; }

#filter-sidebar-header {
  display: flex; align-items: center; gap: var(--sp2);
  padding: var(--sp3) var(--sp5); border-bottom: 1px solid var(--grey-200);
  flex-shrink: 0;
  font-size: var(--text-label); font-weight: var(--fw-bold);
  color: var(--grey-400); text-transform: uppercase; letter-spacing: .06em;
}
#filter-sidebar-header > span:first-child { flex: 1; }
#filter-sidebar-header .tbl-badge { font-size: var(--text-label); }

#filter-sidebar-controls {
  display: flex; gap: var(--sp2); align-items: center;
  padding: var(--sp3) var(--sp4) var(--sp2);
  border-bottom: 1px solid var(--grey-100); flex-shrink: 0;
}
#filter-sidebar-search-wrap { position: relative; flex: 1; }
#filter-sidebar-search {
  width: 100%; height: var(--ctrl-h); padding: 0 28px 0 var(--sp3);
  border: 1px solid var(--grey-300); border-radius: var(--radius);
  font-size: var(--text-sm); background: var(--white); color: var(--grey-900);
  transition: border-color var(--t-fast);
}
#filter-sidebar-search:focus { outline: none; border-color: var(--primary); box-shadow: var(--shadow-focus); }
#filter-sidebar-search::placeholder { color: var(--grey-400); }
#filter-sidebar-search-wrap .input-clear-x { right: var(--sp2); }
#filter-sidebar-clear { white-space: nowrap; }

#filter-sidebar-body {
  flex: 1; overflow-y: auto; padding: var(--sp2) 0;
}

/* Filter group inside the sidebar — collapsible accordion. */
#filter-groups .filter-group {
  border-bottom: 1px solid var(--grey-100);
  padding: 0;
}
#filter-groups .filter-group:last-child { border-bottom: none; }
.filter-group-head {
  display: flex; align-items: center; gap: var(--sp2);
  width: 100%; padding: var(--sp3) var(--sp4);
  background: none; border: none; cursor: pointer;
  text-align: left;
  font-size: var(--text-sm); font-weight: var(--fw-semibold);
  color: var(--grey-800);
  transition: background var(--t-fast);
}
.filter-group-head:hover { background: var(--grey-50); }
.filter-group-head .filter-group-name { flex: 1; }
.filter-group-head .filter-group-count {
  /* grey-500 keeps the count subdued while still passing WCAG AA at 11 px. */
  font-size: var(--text-xs); color: var(--grey-500); font-weight: var(--fw-medium);
}
.filter-group-head .filter-group-active {
  font-size: var(--text-xs); color: var(--primary); font-weight: var(--fw-bold);
  background: var(--primary-bg);
  border-radius: var(--radius-pill); padding: 1px var(--sp2);
}
.filter-group-head .filter-group-caret {
  color: var(--grey-400); transition: transform var(--t-base);
  flex-shrink: 0;
}
.filter-group.collapsed .filter-group-caret { transform: rotate(-90deg); }
.filter-group-body {
  padding: 0 var(--sp4) var(--sp3);
  max-height: 320px; overflow-y: auto;
}
.filter-group.collapsed .filter-group-body { display: none; }
#filter-groups .filter-check-item {
  gap: var(--sp2); padding: var(--sp1) var(--sp2);
  font-size: var(--text-sm);
}
.filter-check-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.filter-group-empty {
  padding: var(--sp3) var(--sp4) var(--sp4);
  font-size: var(--text-xs); color: var(--grey-400); text-align: center;
}

/* Mobile: filter sidebar slides in from the RIGHT (mirror of the legend
   drawer that comes from the LEFT).  Same header-bottom inset, same scrim
   pattern. */
@media (max-width: 768px) {
  #filter-sidebar {
    position: fixed; right: 0;
    top: var(--header-height); bottom: var(--footer-height);
    width: min(85%, 340px);
    z-index: var(--z-overlay);
    transform: translateX(0);
    box-shadow: var(--shadow-drawer-r);
    transition: transform var(--t-slow);
  }
  #filter-sidebar.collapsed {
    width: min(85%, 340px);
    border-left: 1px solid var(--grey-300);
    transform: translateX(105%);
    opacity: 1;
    pointer-events: none;
  }
  #body:has(#filter-sidebar:not(.collapsed))::after {
    content: '';
    position: fixed; left: 0; right: 0;
    top: var(--header-height); bottom: var(--footer-height);
    background: var(--scrim-bg);
    z-index: calc(var(--z-overlay) - 1);
    animation: scrimIn var(--t-base) ease;
  }
}

/* ── Identify popup (vendor-rendered HTML from swisstopo) ───────────── */
.ext-popup { font-size: var(--text-sm); color: var(--grey-800); }
.ext-popup-block + .ext-popup-block { border-top: 1px solid var(--grey-100); margin-top: var(--sp3); padding-top: var(--sp3); }
.ext-popup-layer {
  font-size: var(--text-label); font-weight: var(--fw-bold);
  color: var(--grey-400); text-transform: uppercase; letter-spacing: .06em;
  margin-bottom: var(--sp2);
}
.ext-popup table { width: 100%; border-collapse: collapse; }
.ext-popup table td { padding: 2px 4px; vertical-align: top; }
.ext-popup table tr:nth-child(odd) td { background: var(--grey-50); }
.ext-popup img { max-width: 100%; height: auto; }

/* ════════════════════════════════════════════════════════════════════════
   MOBILE / TOUCH ADAPTATIONS
   Additive layer: desktop layout unchanged.  Three orthogonal queries:
     - height:    100dvh fixes iOS Safari URL-bar math
     - hover:     gates :hover styles to true hover devices (kills sticky
                  hover on iOS Safari after tap)
     - pointer:   bumps icon-button hit areas + input font-size on touch
     - max-width: layout shape changes (drawer sidebar, narrow pagination)
   ════════════════════════════════════════════════════════════════════════ */

/* 100vh is broken on iOS Safari (it equals the URL-bar-hidden height,
   pushing footer below the fold).  dvh follows the visible viewport. */
@supports (height: 100dvh) {
  #app { height: 100dvh; }
}

/* Safe-area insets for notched / Dynamic-Island devices.  The toast and
   edit banner sit at the top of the viewport — without these they render
   under the status bar / notch. */
#toast-container { top: max(var(--sp4), env(safe-area-inset-top, 0)); }
#edit-banner     { top: max(var(--sp3), env(safe-area-inset-top, 0)); }
#footer          { padding-bottom: env(safe-area-inset-bottom, 0); }
#footer          { padding-left:   max(var(--sp5), env(safe-area-inset-left, 0)); }
#footer          { padding-right:  max(var(--sp5), env(safe-area-inset-right, 0)); }

/* Edit banner: don't overflow narrow viewports. */
#edit-banner {
  max-width: calc(100% - 32px);
  white-space: normal; line-height: 1.3; text-align: center;
}

/* Universal keyboard focus ring.  Only fires for keyboard navigation, never
   for mouse clicks — :focus-visible takes care of that distinction. */
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ── Touch-only: kill sticky :hover ───────────────────────────────────────
   iOS Safari preserves the :hover state after tap until the next tap
   somewhere else.  This makes a tapped dropdown button look "still active"
   after the dropdown closes.  We strip the visible :hover outcomes for
   pure-touch devices.  Hybrid devices (laptop with touchscreen, stylus
   tablets) report `hover: hover` and keep the desktop styling. */
@media (hover: none) {
  .dd-btn:hover, .pg-btn:hover, .pg-btn:hover:not(:disabled),
  .check-item:hover, .col-check-item:hover, .filter-check-item:hover,
  .dd-item:hover, .search-item:hover, .lg-ext-item:hover,
  .bm-btn:hover, .bm-option:hover, .filter-clear-btn:hover,
  .edit-btn:hover, .input-clear-x:hover, .sidebar-close-btn:hover,
  .lg-ext-remove:hover, .legend-toggle-btn:hover, .eye-btn:hover,
  .pill-x:hover, .filter-reset-link:hover,
  .measure-distance-close:hover, .context-menu-item:hover,
  #footer-links a:hover, #pg-size-select:hover,
  #save-banner button:hover, #save-banner .cancel-btn:hover,
  #tbl tbody tr:hover td, #tbl th:hover {
    background: revert; border-color: revert; color: revert;
    box-shadow: revert; text-decoration: revert;
  }
  /* Re-apply the *intentional* state styles that share specificity with
     the now-reverted hover rules. */
  .dd-wrap.open .dd-btn { background: var(--grey-100); border-color: var(--grey-400); color: var(--grey-900); }
  #tbl tbody tr.selected td { background: var(--row-active); box-shadow: inset 3px 0 0 var(--primary); }
}

/* ── Touch input: bump hit areas + suppress iOS focus-zoom ───────────── */
@media (pointer: coarse) {
  /* iOS Safari zooms the page when an <input> with font-size < 16px gains
     focus.  Bumping inputs to 16px on touch is the universal fix. */
  #search-input, #tbl-search, .filter-search { font-size: 16px; }

  /* Icon-button hit-area floor: 32×32 (compromise between 24-AA and the
     44pt Apple HIG; visually still feels light, ergonomically OK). */
  .eye-btn { width: 32px; height: 32px; padding: 6px; }
  .lg-ext-remove,
  .input-clear-x,
  .sidebar-close-btn,
  .measure-distance-close { width: 32px; height: 32px; }
  .maplibregl-popup-close-button { padding: 8px 12px; font-size: 22px; }

  /* Dropdown buttons + pagination buttons taller on touch. */
  .dd-btn, .pg-btn, #pg-size-select { min-height: 36px; }
  .pg-btn { min-width: 36px; }
  .edit-btn { padding: 8px var(--sp4); }

  /* Resize handle: visible affordance even before drag. */
  #tbl-resize-handle { height: 14px; background: var(--grey-100); }
  #tbl-resize-handle::after { opacity: 1; background: var(--grey-400); }
  #tbl-resize-handle:hover { background: var(--grey-100); } /* no hover bump on touch */

  /* Larger tap targets for legend swatches' parent rows. */
  .lg-item { padding: 6px 0; }

  /* Filter-pill close button is 14px; bump tap area without growing visual. */
  .pill-x { padding: 4px 0 4px var(--sp1); }
}

/* ════════════════════════════════════════════════════════════════════════
   PHONE LAYOUT (≤ 768px)
   - Sidebar becomes a slide-in drawer over the map
   - Header tightens (agency tagline hidden, edit button hidden)
   - Table panel halves its default height
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Header: hide marketing line; the app name alone is enough */
  .header-agency { display: none; }
  .header-app { font-size: var(--text-sm); }
  #header { padding: 0 var(--sp3); gap: var(--sp2); }
  #search-area { padding: 0 var(--sp2); }
  #search-wrapper { max-width: none; }
  /* Edit is a placeholder; hide it on phones to reclaim header space.
     Filter / Share / Print stay visible (Filter is essential, Share/Print
     are core actions and use icon-only variants). */
  #edit-toggle { display: none; }
  /* Tighter filter button on phones so the header row fits. */
  #filter-toggle { padding: var(--sp-btn-y) var(--sp2); }

  /* Sidebar → fixed-position drawer over the map */
  #sidebar {
    position: fixed; left: 0;
    top: var(--header-height); bottom: var(--footer-height);
    width: min(85%, 320px);
    z-index: var(--z-overlay);
    transform: translateX(0);
    box-shadow: var(--shadow-drawer-l);
    transition: transform var(--t-slow);
  }
  #sidebar.collapsed {
    width: min(85%, 320px);          /* keep size, just slide off-screen */
    border-right: 1px solid var(--grey-300);
    transform: translateX(-105%);    /* extra 5% covers shadow */
    opacity: 1;                       /* slide, don't fade */
    pointer-events: none;
  }

  /* Backdrop scrim while drawer is open.  Uses :has() (Safari 15.4+,
     Chrome 105+).  Falls back to no scrim on older browsers - drawer still
     works, just without the dimming effect. */
  #body:has(#sidebar:not(.collapsed))::before {
    content: '';
    position: fixed; left: 0; right: 0;
    top: var(--header-height); bottom: var(--footer-height);
    background: var(--scrim-bg);
    z-index: calc(var(--z-overlay) - 1);
    animation: scrimIn var(--t-base) ease;
  }
  @keyframes scrimIn { from { opacity: 0; } to { opacity: 1; } }

  /* Table panel: smaller default + fully collapsable */
  #table-panel { height: 45vh; max-height: 60vh; }

  /* Identify popup: clamp to viewport with comfortable margin */
  .maplibregl-popup-content { max-width: calc(100vw - 32px) !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   NARROW PHONE (≤ 480px) — strip more chrome
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 480px) {
  /* Pagination: keep prev/next + position only.  First/last/page-numbers
     drop. */
  #pg-first, #pg-last, #pg-pages { display: none; }
  #tbl-pagination { padding: 5px var(--sp3); gap: var(--sp2); }
  .pg-info { font-size: var(--text-xs); }
  #pg-size-select { font-size: var(--text-xs); padding: 0 var(--sp1); }

  /* Table action bar: tighter spacing, smaller search */
  #tbl-action-bar { padding: var(--sp2) var(--sp3); gap: var(--sp2); flex-wrap: wrap; }
  #tbl-search-wrap { max-width: 160px; }
  /* Hide the verbose dropdown labels - keep just the icon + caret */
  #col-dd-btn, #filter-dd-btn, #export-dd-btn { padding: 0 var(--sp2); }

  /* Tabs: shrink and drop the count to fit */
  .tbl-tab { padding: 0 var(--sp3); font-size: var(--text-xs); }
  .tbl-tab-count { display: none; }

  /* Footer on narrow screens: drop the live-coords readout so the links
     get the full width. */
  #coordinates { display: none; }
  #footer { justify-content: flex-end; }
  #footer-links a { margin-left: var(--sp3); }

  /* Basemap switcher: smaller thumbnail-only button */
  .bm-btn { padding: 4px; }
  .bm-btn img { width: 56px; height: 42px; }
  .bm-btn span { display: none; }

  /* Maplibre nav: hide on narrow phones - pinch-zoom replaces it */
  .maplibregl-ctrl-top-right .maplibregl-ctrl-zoom-in,
  .maplibregl-ctrl-top-right .maplibregl-ctrl-zoom-out,
  .maplibregl-ctrl-top-right .maplibregl-ctrl-compass { display: none !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   PRINT — clean map-only output.  Hide every interactive panel so the
   printed page is just the map.  MapLibre's WebGL canvas requires
   preserveDrawingBuffer:true (set in map.js) to capture into the print
   pipeline; without it most browsers print a blank canvas.
   ════════════════════════════════════════════════════════════════════════ */
@media print {
  /* Hide every panel / control / overlay — print the map alone */
  #header, #footer, #sidebar, #filter-sidebar, #table-panel,
  #tbl-resize-handle, .legend-toggle-btn, #basemap-switcher,
  #tbl-toggle, .maplibregl-ctrl,
  #toast-container, #edit-banner, #save-banner,
  #map-prototype-banner,
  #map-context-menu, .measure-distance-display,
  #search-area { display: none !important; }
  /* Reset shell layout so the map fills the printable page */
  html, body, #app, #body, #main-content {
    height: auto !important; min-height: 0 !important;
    overflow: visible !important; display: block !important;
  }
  #map {
    position: static !important;
    width: 100% !important; height: 100vh !important;
  }
  /* Keep the maplibre attribution control visible — it's required by
     the basemap licence terms. */
  .maplibregl-ctrl-attrib { display: block !important; }
  /* Force colour fidelity for area fills (browsers strip non-essential
     backgrounds in print by default). */
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
}
