/* Inter, vendored locally (no CDN) - the ONE face for every text in the app (Luka, 2026-10-20):
   the chrome here, and through APP_FONT in app.js the map labels, the charts, the canvas
   columns and the section SVG. Widths that used to lean on monospace are measured now. */
@import url('/vendor/fonts/inter.css');

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* The map's right column: the buttons (#toolbar) and every block under them - the INKL, LITOLOGIJA and
     Cu legends - are ONE width, read from here so they cannot drift apart (Luka, 2026-10-12). Not a
     theme token: the same in both themes. */
  --right-col-w: 172px;
  /* LIGHT theme tokens (default). Data colours (lithology/amber/violet/lab) are NOT here - they
     live literal in app.js and the few data rules below. Chrome only. The DARK set overrides in
     [data-theme="dark"] and, with no explicit choice, follows the system (prefers-color-scheme). */
  --bg: #DED8D3;
  --sidebar: #D6CFC8;
  --panel: #EEEAE6;
  --surface: #F2EFEB;
  --panel-3: #E7E2DD;
  --btn-bg: #E4DED7;
  --btn-hover: #D9D2CB;
  --badge-bg: #DED8D1;
  --border: #C7C0B7;
  --border-2: #BCB4AA;
  --border-3: #A69C90;
  --text: #404040;
  --heading: #2E2E2E;
  --text-dim: #5A5852;
  --text-muted: #6B6A67;
  --accent2: #A99F94;
  --state-on: #86A65C;
  --state-on-bg: rgba(134,166,92,0.42);
  /* Theme-slider sun/moon. A warm, muted yellow (a MODE choice, not the olive "on"). Defined once here,
     constant across both themes like --accent. Deliberately distinct from the data yellows/ambers -
     lithology lemon #F4D03F, DEM amber #f0b429, grain-size sand #c9a84c, Cu orange #f0883e - and it
     never sits beside them (header only). Closest is the dark DMT badge #e3b341, which is not adjacent. */
  --theme-accent: #E0B23A;
  --panel-float: rgba(238,234,230,0.96);
  --panel-float-2: rgba(240,236,232,0.97);
  --overlay: rgba(240,237,233,0.88);
  --swatch-border: rgba(0,0,0,0.28);
  /* Longitudinal-section sheet (D3). Drawn as SVG in app.js, so these are read via getComputedStyle
     and baked in at render - they are the section's half of the CSS enumeration, not outside it. */
  --sec-bg: #E9E4DF;
  --sec-grid: #D2CBC3;
  --sec-axis: #8F887E;
  --sec-ink: #3A3A3A;
  --sec-ink-dim: #6B6A67;
  --sec-guide: #CDC6BE;
  --inkl-inactive: #a8a29b;   /* INKL: shown inactive readings, dotted - lighter than the reference grey */
  --cpt-bg: #E3EFE0;
  --cpt-fg: #2E7D32;
  --dmt-bg: #F2ECD6;
  --dmt-fg: #8A6A00;
  --lab-bg: #E1EBF5;
  --lab-fg: #1565C0;
  --noz-bg: #F2ECD6;
  --noz-fg: #8A6A00;
  --user-bg: #F2E3E2;
  --user-bd: #E3C9C6;
  --error-bg: #FBEAE8;
  --draft-bg: #F2ECD6;
  --draft-fg: #8A6A00;
  --ok-bg: #E3EFE0;
  --ok-fg: #2E7D32;
  --incl-bg: #E1EBF5;
  --incl-fg: #1565C0;
  --piez-bg: #E0F0F2;
  --piez-fg: #0E7C8C;
  --rep-save-bd: #C9A24A;
  --rep-save-fg: #8A6A00;
  --accent:     #EE2E27;   /* brand red - ACTION only, both themes */
  --accent-hover: #c00000;
  --danger:     #c0392b;
  --font-ui:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:  var(--font-ui);   /* no monospace left (Luka, 2026-10-20: Inter everywhere) */
  --radius:     6px;
  --sidebar-w:  280px;
  --detail-h:   320px;
}
:root[data-theme="dark"] {
  --bg: #2d2d2d;
  --sidebar: #222222;
  --panel: #3a3a3a;
  --surface: #2a2a2a;
  --panel-3: #2e2e2e;
  --btn-bg: #444444;
  --btn-hover: #4e4e4e;
  --badge-bg: #505050;
  --border: #575757;
  --border-2: #646464;
  --border-3: #808080;
  --text: #f2f2f2;
  --heading: #ffffff;
  --text-dim: #d0d0d0;
  --text-muted: #A8A9AA;
  --accent2: #7a7a7a;
  --state-on: #86A65C;
  --state-on-bg: rgba(134,166,92,0.30);
  --panel-float: rgba(26,26,26,0.94);
  --panel-float-2: rgba(26,26,26,0.97);
  --overlay: rgba(13,17,23,.85);
  --swatch-border: rgba(255,255,255,0.15);
  --sec-bg: #141414;
  --sec-grid: #2c2c2c;
  --sec-axis: #555555;
  --sec-ink: #e8e8e8;
  --sec-ink-dim: #8a8a8a;
  --sec-guide: #3f3f3f;
  --inkl-inactive: #c9d1d9;
  --cpt-bg: #0a2a0a;
  --cpt-fg: #3fb950;
  --dmt-bg: #2a2500;
  --dmt-fg: #e3b341;
  --lab-bg: #0a1a2a;
  --lab-fg: #58a6ff;
  --noz-bg: #2a1a00;
  --noz-fg: #e3b341;
  --user-bg: #5a0000;
  --user-bd: #7a0000;
  --error-bg: #2a0000;
  --draft-bg: #4a3608;
  --draft-fg: #f0c060;
  --ok-bg: #10391f;
  --ok-fg: #6fe0a0;
  --incl-bg: #1a2438;
  --incl-fg: #7aa2f7;
  --piez-bg: #0a2430;
  --piez-fg: #4fc4d6;
  --rep-save-bd: #7a5a10;
  --rep-save-fg: #f0c060;
  --danger: #cc2200;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --bg: #2d2d2d;
  --sidebar: #222222;
  --panel: #3a3a3a;
  --surface: #2a2a2a;
  --panel-3: #2e2e2e;
  --btn-bg: #444444;
  --btn-hover: #4e4e4e;
  --badge-bg: #505050;
  --border: #575757;
  --border-2: #646464;
  --border-3: #808080;
  --text: #f2f2f2;
  --heading: #ffffff;
  --text-dim: #d0d0d0;
  --text-muted: #A8A9AA;
  --accent2: #7a7a7a;
  --state-on: #86A65C;
  --state-on-bg: rgba(134,166,92,0.30);
  --panel-float: rgba(26,26,26,0.94);
  --panel-float-2: rgba(26,26,26,0.97);
  --overlay: rgba(13,17,23,.85);
  --swatch-border: rgba(255,255,255,0.15);
  --sec-bg: #141414;
  --sec-grid: #2c2c2c;
  --sec-axis: #555555;
  --sec-ink: #e8e8e8;
  --sec-ink-dim: #8a8a8a;
  --sec-guide: #3f3f3f;
  --inkl-inactive: #c9d1d9;
  --cpt-bg: #0a2a0a;
  --cpt-fg: #3fb950;
  --dmt-bg: #2a2500;
  --dmt-fg: #e3b341;
  --lab-bg: #0a1a2a;
  --lab-fg: #58a6ff;
  --noz-bg: #2a1a00;
  --noz-fg: #e3b341;
  --user-bg: #5a0000;
  --user-bd: #7a0000;
  --error-bg: #2a0000;
  --draft-bg: #4a3608;
  --draft-fg: #f0c060;
  --ok-bg: #10391f;
  --ok-fg: #6fe0a0;
  --incl-bg: #1a2438;
  --incl-fg: #7aa2f7;
  --piez-bg: #0a2430;
  --piez-fg: #4fc4d6;
  --rep-save-bd: #7a5a10;
  --rep-save-fg: #f0c060;
    --danger: #cc2200;
  }
}

/* ── Brand overrides ── */

/* Sidebar header */
.sidebar-header {
  background: var(--sidebar);   /* match the rest of the left panel, not a lighter strip */
  border-bottom: 2px solid var(--accent);
}
.sidebar-header h1 {
  color: var(--heading);
  letter-spacing: 2px;
  border-left: 4px solid var(--accent);
  padding-left: 10px;
}
.sidebar-header p { color: var(--text-muted); }

/* Section labels */
.sidebar-section .section-header { color: var(--text-dim) !important; }
.sidebar-section .section-header:hover { color: var(--heading) !important; }

/* Buttons - !important ensures these win over original cascade */
.btn { background: var(--btn-bg); border-color: var(--border-2); color: var(--text) !important; }
.btn:hover { border-color: var(--accent) !important; color: var(--heading) !important; background: var(--btn-hover); }
.btn.primary { background: var(--accent) !important; color: #ffffff !important; border-color: var(--accent) !important; }
.btn.primary:hover { background: #c00000 !important; border-color: #c00000 !important; color: #ffffff !important; }

#chat-send-btn, #chat-send-btn:hover { color: #ffffff !important; }

/* Borehole list */
.bh-item:hover { background: var(--btn-bg); }
.bh-item.selected { background: rgba(134,166,92,0.14); border-left-color: var(--accent2); }
.bh-item .bh-id { color: var(--text); }

/* Badges */
.badge { background: var(--badge-bg); color: var(--text-dim); }
.badge.cpt { background: var(--cpt-bg); color: var(--cpt-fg); }
.badge.dmt { background: var(--dmt-bg); color: var(--dmt-fg); }
.badge.lab { background: var(--lab-bg); color: var(--lab-fg); }
.badge.noz { background: var(--noz-bg); color: var(--noz-fg); }

/* Export selection highlight */
.bh-item.export-selected { background: rgba(120,120,120,0.15); border-left-color: var(--accent); }
#export-count { color: var(--text-muted); }

/* Chart tabs */
.chart-tab.active { color: var(--heading) !important; border-bottom-color: var(--heading); }

/* Detail title */
#detail-title { color: var(--heading) !important; }
#detail-header { background: var(--panel-3); }

/* Inputs */
input[type=text], input[type=number] {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}
input[type=text]:focus,
input[type=number]:focus { border-color: var(--accent); outline: none; }

/* Scrollbar */
::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-3); }

/* Spinner & loading */
.spinner { border-color: var(--border); border-top-color: var(--accent); }
#loading { color: var(--accent); }

/* Interval click popup */
#interval-popup {
  position: absolute;
  z-index: 1000;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0;
  min-width: 200px;
  max-width: 320px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  font-family: var(--font-ui);
  font-size: 11px;
  pointer-events: auto;
  animation: popupFadeIn 0.12s ease;
}
@keyframes popupFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.interval-popup-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  border-radius: 6px 6px 0 0;
}
.interval-popup-boreid { color: var(--accent); font-size: 11px; font-weight: bold; flex: 1; }
.interval-popup-depth  { color: var(--text-muted); font-size: 10px; white-space: nowrap; }
.interval-popup-close  { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; line-height: 1; padding: 0 0 0 4px; flex-shrink: 0; }
.interval-popup-close:hover { color: var(--text); }
.interval-popup-lithology { padding: 7px 10px 4px; color: var(--text); font-size: 12px; font-weight: bold; }
.interval-popup-desc { padding: 0 10px 10px; color: var(--text-muted); font-size: 11px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }

/* Lab colour legend on map */
/* Both legends live in #legend-stack, a single column anchored to the bottom-right, LAB
   above LITOLOGIJA. They were previously two panels absolutely positioned into the same
   corner 10 px apart, so the taller lithology legend covered this one entirely. Stacking
   also removes the need to guess either one's height: the column's bottom edge is fixed,
   so collapsing the lithology legend shortens it and this rides down with it.
   Visibility is a class, not an inline style, so `display:none` genuinely removes it from
   the flex flow (an inline style set by JS would too, but the class keeps both toggle
   call sites saying the same thing). */
#lab-color-legend { display: none; }
#lab-color-legend.visible { display: block; }

#legend-stack {
  position: absolute;
  /* 10px, matching right:10px. Was 54px to clear the attribution strip's vertical band, but measured
     2026-09-17 the attribution is bottom-LEFT (x 6..156) and this stack is bottom-RIGHT (x 1470..1630)
     - they never overlap horizontally, so the clearance was inherited, not chosen. */
  bottom: 10px;
  right: 10px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;   /* children opt back in; the gap must not eat map drags */
  /* Never ride into the top-right controls (buttons + Naklon + Podlaga, ~270 px tall). The cap is a
     % of #map's height, so it ADAPTS as the detail panel shrinks the map - which the old fixed 320 px
     body cap did not, hence the overlap (2026-09-15). The map-legend body scrolls within it. */
  /* The stack is bottom-anchored and grows UP, so its top edge at full extension sits (K - bottom) px
     from the map top, where K is this subtrahend. The right side has ONE rhythm: 6 px between every
     stacked element (the toolbar's own gap, and this stack's Cu->legend gap) and a 10 px inset from the
     map edge (toolbar top/right, and this stack's bottom:10/right:10). The gap from the last control to
     the Cu scale is an inter-element gap, so it is 6 px like the rest - not the 16 it was (that value
     was an anti-overlap guess). Controls end at ~296 px, so the stack top = 296 + 6 = 302, and
     K - bottom = 302 -> K = 302 + 10 = 312. Floor 96 so a tiny map degrades to a small scroll rather
     than a vanished legend. */
  max-height: max(96px, calc(100% - 312px));
  min-height: 0;
}

#lab-color-legend {
  flex: 0 0 auto;   /* the Cu scale keeps its size; the lithology legend below absorbs the shrink */
  background: var(--panel-float);
  padding: 5px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  font-size: 9px;
  color: var(--text);
  font-family: var(--font-ui);
  z-index: 10;
  width: var(--right-col-w);
  pointer-events: none;
}
#lab-legend-title { font-weight: bold; margin-bottom: 3px; color: var(--text-muted); }
#lab-legend-bar { height: 8px; background: linear-gradient(to right, #313695, #fee090, #a50026); border-radius: 2px; margin-bottom: 2px; }
#lab-legend-labels { display: flex; justify-content: space-between; }

/* Lab param select */
#lab-param-row select {
  width: 100%;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 5px;
  font-size: 10px;
  font-family: var(--font-ui);
}

/* Cross-plot controls */
#cross-controls {
  display: none;
  flex-direction: row;
  gap: 4px;
  padding: 3px 4px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
#cross-controls select {
  flex: 1;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px 4px;
  font-size: 9px;
  font-family: var(--font-ui);
}

/* Chat */
.chat-msg.user { background: var(--user-bg); border-color: var(--user-bd); color: var(--text); }
.chat-msg.assistant { background: var(--panel-3); border-color: var(--border); }
.chat-msg.thinking { color: var(--text-muted); }
.chat-action-btn { border-color: var(--text-muted); color: var(--text); }
.chat-action-btn:hover { background: rgba(160,0,0,0.15); }
.suggestion { border-color: var(--border); color: var(--text-muted); }
.suggestion:hover { border-color: var(--accent); color: #ff8080; }

/* Bottom / chat header bar */
#bottom-header { background: var(--surface); }
#chat-section { background: var(--surface); }

/* Legend swatches */
.legend-swatch { border-color: var(--swatch-border); }

/* ── End brand overrides ── */

html, body { height: 100%; width: 100%; overflow: hidden; background: var(--bg); color: var(--text); font-family: var(--font-ui); font-size: 12px; }

/* ── Layout ── */
#layout { display: flex; height: 100vh; }

#sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: var(--sidebar);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  /* The scrollbar's space is always reserved: a panel that makes the sidebar scroll (a model's
     versions) must not narrow it and re-wrap everything above (Luka, 2026-10-16). */
  scrollbar-gutter: stable;
}
/* Nothing inside may make the sidebar scroll sideways ('hidden' still lets focus scroll it). */
.sidebar-section { overflow-x: clip; }

#map-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

#map { flex: 1; position: relative; overflow: hidden; }
#deck-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: block; }

/* ── Bottom row: unified container ── */
#bottom-row {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  transition: height 0.2s ease;
  height: var(--detail-h);
  overflow: hidden;
}
#bottom-row.collapsed { height: 34px; }

#bottom-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .8px;
  color: var(--text-muted);
  flex-shrink: 0;
  cursor: pointer;
  user-select: none;
  background: var(--panel);
  height: 34px;
  box-sizing: border-box;
}
#bottom-header:hover { color: var(--text); }
#bottom-header-labels { display: flex; align-items: center; font-size: 10px; text-transform: uppercase; }
#bottom-header-actions { display: flex; align-items: center; gap: 6px; }
#bottom-toggle-icon { font-size: 10px; color: var(--text-muted); }

#detail-close {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1;
  border: none;
  background: none;
  margin-left: 4px;
  padding: 0 2px;
}
#detail-close:hover { color: var(--text); }


/* Content area: chat left, detail right */
#bottom-content {
  display: flex;
  flex-direction: row;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* The chat column scales with the window (400 px wide, 355 at 1366, 266 at 1024) and can be hidden.
   A plain flex-shrink would never fire: #detail-panel has min-width 0 and absorbs any shortfall first,
   which is how the chart column reached 0 px below ~1150 px (Luka, 2026-10-12). */
#chat-section {
  flex: 0 0 clamp(240px, 26vw, 400px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-right: 1px solid var(--border);
  background: var(--panel);
}

#detail-panel {
  flex: 1;
  min-width: 0;
  background: var(--panel);
  display: none;
  flex-direction: column;
}
#detail-panel.visible { display: flex; }
#bottom-content.chat-hidden #chat-section { display: none; }

/* ── Sidebar sections ── */
.sidebar-header {
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.sidebar-header h1 { font-size: 14px; color: var(--accent); letter-spacing: .5px; }
.sidebar-header p  { color: var(--text-muted); font-size: 11px; margin-top: 2px; }

.sidebar-header-top {
  display: flex;
  align-items: center;              /* title + one control row on a single line */
  justify-content: space-between;
  gap: 8px;
}
.app-subtitle { margin-top: 2px; }  /* full-width line below the title/controls row */

.sidebar-section {
  padding: 0;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

/* Collapsible label row */
.sidebar-section .section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  color: var(--text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .5px;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
  margin: 0;
}
.sidebar-section .section-header:hover { color: var(--accent); }

/* ── Inline layer-load spinner ── */
.btn-spinner {
  display: inline-block;
  width: 9px;
  height: 9px;
  border: 1.5px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .6s linear infinite;
  vertical-align: middle;
  margin-left: 5px;
  flex-shrink: 0;
}

.section-chevron {
  font-size: 10px;
  transition: transform .18s;
  flex-shrink: 0;
}
.section-toggle-icon { font-size: 10px; flex-shrink: 0; }

.section-body {
  padding: 0 12px 10px;
}

/* The boreholes section grows to fill remaining space */
.sidebar-section.flex-section {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.sidebar-section.flex-section .section-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-bottom: 0;
}

/* ── Inputs / buttons ── */
input[type=text], input[type=number], select {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 8px;
  border-radius: 6px;
  font-family: var(--font-ui);
  font-size: 12px;
}

input[type=text]:focus, input[type=number]:focus, select:focus {
  outline: none;
  border-color: var(--accent);
}

.btn {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 12px;
  transition: border-color .15s, color .15s;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent); color: #000; border-color: var(--accent); }
.btn.primary:hover { opacity: .85; color: #000; }
.btn-row { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
/* A fixed 2-column grid for a row of chips (the layer toggles). The columns are fixed, so
   the arrangement is always 2x2 and never reflows 3+1 vs 2+2 when the language changes -
   and it reserves no extra width: the chips split the fixed sidebar, they are not padded to
   the longer language. Same idea the IFC row already uses with flex:1. */
.btn-row.btn-grid { display: grid; grid-template-columns: 1fr 1fr; }
.btn-row.btn-grid .btn { width: 100%; }
.layer-group-label { font-size: 9px; text-transform: uppercase; letter-spacing: 0.8px; color: var(--text-muted); margin-top: 4px; margin-bottom: 2px; }

/* ── Search ── */
#search-input { margin-top: 2px; margin-bottom: 6px; }

/* ── Borehole list ── */
#select-all-row {
  display: flex;
  gap: 6px;
  padding: 4px 0 5px;
  flex-shrink: 0;
}
/* One row, always: narrower padding so the three fit beside a full-width scrollbar, and never wrapped. */
/* Each label keeps the width of its longer language (data-i18n-fit), so a switch never moves its neighbours (Luka, 2026-10-20). */
#select-all-row .btn { flex: 1 1 auto; white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                       padding-left: 8px; padding-right: 8px; }

#borehole-list {
  flex: none;
  height: auto;
  max-height: 240px;
  overflow-y: auto;
  padding: 4px 0;
  min-height: 0;
}

#export-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0 2px;
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
#export-count { font-size: 10px; color: var(--accent2); min-width: 60px; }
#btn-export-csv:disabled { opacity: 0.4; cursor: not-allowed; }

.bh-item {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background .1s, border-color .1s;
}
.bh-item:hover { background: var(--panel); }
.bh-item.selected { background: rgba(134,166,92,0.14); border-left-color: var(--accent2); }
.bh-item.export-selected { background: var(--panel); border-left-color: var(--accent); }
.bh-item.selected.export-selected { background: rgba(134,166,92,0.14); border-left-color: var(--accent2); }

.bh-check {
  flex-shrink: 0;
  margin-right: 8px;
  accent-color: var(--accent2);
  cursor: pointer;
  width: 13px;
  height: 13px;
}

.bh-content { flex: 1; min-width: 0; }
.bh-item .bh-id { color: var(--text); font-size: 12px; }
.bh-item .bh-meta { color: var(--text-muted); font-size: 10px; margin-top: 1px; }

/* ── Rectangle area-select overlay ── */
#rect-overlay {
  position: absolute;
  border: 1px dashed var(--accent2);
  background: rgba(134,166,92,0.16);
  pointer-events: none;
  display: none;
  z-index: 20;
}

.badge {
  display: inline-block;
  padding: 1px 5px;
  border-radius: 6px;
  font-size: 9px;
  margin-left: 4px;
  background: var(--border);
  color: var(--text-muted);
}
.badge.cpt { background: var(--cpt-bg); color: var(--cpt-fg); }
.badge.dmt { background: var(--dmt-bg); color: var(--dmt-fg); }
.badge.lab { background: var(--lab-bg); color: var(--lab-fg); }
.badge.noz { background: var(--noz-bg); color: var(--noz-fg); }

/* Borehole kind (T1-Kp): instrument holes distinguished from cored boreholes. Only shown when
   the hole is NOT a plain borehole, so a single-kind project (Koper) never sees one. */
.kind-badge {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--radius);
  font-size: 10px;
  font-weight: 600;
}
.kind-badge.kind-inclinometer { background: var(--incl-bg); color: var(--incl-fg); }
.kind-badge.kind-piezometer   { background: var(--piez-bg); color: var(--piez-fg); }

/* A declared interval_class extra (GT, geološka starost) shown beside the USCS/ISO chips. */
.cls-extra {
  padding: 0 4px;
  border-radius: 4px;
  background: var(--panel);
  color: var(--text-muted);
}

/* Lab table in detail panel */
.lab-table { border-collapse: collapse; width: 100%; font-size: 10px; margin-top: 4px; }
.lab-table th { background: var(--panel); color: var(--heading); border: 1px solid var(--border); padding: 3px 6px; text-align: left; }
.lab-table td { color: var(--text); border: 1px solid var(--border); padding: 3px 6px; }

/* ── Area report panel (D1) ── */
/* Top-left of the map, opposite the legend, so the scope polygon stays visible. */
#report-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 110;
  display: none;
  width: 260px;
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  font-size: 11px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#report-panel.visible { display: block; }
#report-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
#report-panel-header .btn { padding: 1px 6px; font-size: 11px; line-height: 1.2; }
#report-preview { padding: 8px 10px; max-height: 260px; overflow-y: auto; }
.report-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0;
  color: var(--text-muted);
}
.report-row strong { color: var(--text); font-weight: 600; }
.report-gaps {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  color: #e0a030;
  font-size: 10px;
  line-height: 1.35;
}
.report-msg {
  margin-top: 6px;
  color: var(--text-muted);
  font-size: 10px;
  font-style: italic;
  line-height: 1.35;
}
#report-form { padding: 0 10px 8px; display: flex; flex-direction: column; gap: 4px; }
#report-form input {
  width: 100%;
  box-sizing: border-box;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 10px;
  padding: 3px 6px;
}
#btn-report-generate,
#btn-report-save {
  width: calc(100% - 20px);
  margin: 0 10px 6px;
  text-align: center;
  font-size: 11px;
  padding: 6px;
}
#btn-report-save { margin-bottom: 10px; border-color: var(--rep-save-bd); color: var(--rep-save-fg); }
#btn-report-generate:disabled,
#btn-report-save:disabled { opacity: .45; cursor: not-allowed; }
#report-tools { display: flex; gap: 6px; }
#report-tools .btn { flex: 1; font-size: 11px; padding: 5px 6px; text-align: center; }
/* Both live top-left; when the report panel is open the measure readout drops below it.
   Relies on #report-panel preceding #measure-readout in the DOM. */
#report-panel.visible ~ #measure-readout { top: auto; bottom: 26px; }

/* ── Report archive (D2) ── */
/* Top-right, so it never fights the report panel (top-left) - both can be open at once
   while an area is being drawn over an older report's footprint. */
/* ── Data import ──────────────────────────────────────────────────────────── */
/* Below #tooltip (1200), like every floating panel. Shares the top-right corner with the
   report archive, which opens from a map click rather than from a button - so it can
   appear underneath this one at any moment. It cannot be pushed aside itself (it precedes
   this panel in the DOM and `~` only reaches forward), so this panel is the one that
   steps left when both are open. Both are fixed-width, so the offset is exact:
   270 px archive + 10 px margin + 10 px gap. */
#reports-panel.visible ~ #import-panel { right: 290px; }

#import-panel {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 112;
  display: none;
  width: 320px;
  max-height: calc(100% - 90px);
  overflow-y: auto;
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  font-size: 11px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#import-panel.visible { display: block; }
#import-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
  position: sticky;
  top: 0;
  background: var(--panel-float-2);
}
#import-form { padding: 8px 10px; }
#import-form label {
  display: block;
  color: var(--text-muted);
  font-size: 10px;
  margin: 6px 0 2px;
}
#import-form input[type=file] {
  width: 100%;
  font-family: var(--font-ui);
  font-size: 10px;
  color: var(--text);
}
.imp-limit { color: var(--text-muted); font-size: 10px; margin-top: 3px; }

/* 3D model import (docs/MODEL-IMPORT-DESIGN.md) - the same floating panel as the data import. */
#model-import-panel {
  position: absolute; top: 10px; right: 10px; z-index: 113; display: none; width: 340px;
  max-height: calc(100% - 90px); overflow-y: auto; background: var(--panel-float);
  border: 1px solid var(--border); border-radius: 6px; backdrop-filter: blur(4px);
  font-family: var(--font-ui); font-size: 11px; box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#model-import-panel.visible { display: block; }
#ags-panel {
  position: absolute; top: 10px; right: 10px; z-index: 113; display: none; width: 480px;
  max-height: calc(100% - 90px); overflow-y: auto; background: var(--panel-float);
  border: 1px solid var(--border); border-radius: 6px; backdrop-filter: blur(4px);
  font-family: var(--font-ui); font-size: 11px; box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#ags-panel.visible { display: block; }
#ags-header {
  display: flex; justify-content: space-between; align-items: center; padding: 6px 10px;
  color: var(--text-muted); font-size: 10px; letter-spacing: .8px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--panel-float-2);
}
#ags-body { padding: 10px; color: var(--text); }
#ags-body .note { color: var(--text-muted); margin: 0 0 8px; }
#ags-row { display: flex; gap: 4px; margin-top: 6px; }
#ags-row .btn { flex: 1; white-space: nowrap; padding-left: 4px; padding-right: 4px; }
.ags-field { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; color: var(--text-muted); }
.ags-check { display: flex; gap: 6px; align-items: center; margin-bottom: 8px; }
.ags-actions { display: flex; gap: 6px; margin-top: 10px; }
.ags-status { margin-bottom: 6px; }
.ags-bar { height: 5px; background: var(--border); border-radius: 3px; overflow: hidden; }
.ags-bar i { display: block; height: 100%; width: 0; background: #4ec9a0; }
.ags-error { color: #ff8a80; margin-bottom: 8px; }
.ags-done { color: #4ec9a0; font-weight: 700; margin-bottom: 8px; }
.ags-head { color: var(--text-muted); font-size: 10px; letter-spacing: .8px; margin: 10px 0 4px; }
.ags-line { padding: 1px 0; }
.ags-line span { color: var(--text-muted); }
.ags-item { padding: 1px 0; }
.ags-table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.ags-table th { color: var(--text-muted); font-weight: 600; text-align: right; padding: 3px 4px; border-bottom: 1px solid var(--border); }
.ags-table td { text-align: right; padding: 3px 4px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.ags-table th:first-child, .ags-table td:first-child { text-align: left; }
#model-import-header {
  display: flex; justify-content: space-between; align-items: center; padding: 6px 10px;
  color: var(--text-muted); font-size: 10px; letter-spacing: .8px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--panel-float-2);
}
#mi-body { padding: 8px 10px; }
#mi-body > label, .mi-legend { display: block; color: var(--text-muted); font-size: 10px; margin: 6px 0 2px; }
#mi-body input[type=file] { width: 100%; font-family: var(--font-ui); font-size: 10px; color: var(--text); }
.mi-note { color: var(--text-muted); font-size: 10px; margin-top: 3px; line-height: 1.3; }
.mi-radio { display: block; font-size: 11px; margin: 3px 0; }
.mi-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 8px; margin-top: 4px; }
.mi-grid label { font-size: 10px; color: var(--text-muted); }
.mi-grid input { width: 100%; box-sizing: border-box; font-size: 11px; }
#mi-progress { margin-top: 8px; }
#mi-bar { width: 100%; }
#mi-summary table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 10px; }
#mi-summary td, #mi-summary th { border-bottom: 1px solid var(--border); padding: 2px 3px; text-align: left; }
#mi-message { margin-top: 8px; font-size: 11px; line-height: 1.35; white-space: pre-line; }
#mi-message.mi-error { color: #a03020; }
/* The version selector under a model imported through the app. */
.mv-row { display: flex; gap: 3px; margin-bottom: 3px; }
.mv-row > .btn:first-child { flex: 1; min-width: 0; }
/* A model's layer button: the name ends in an ellipsis, the marks after it stay visible. */
.btn.ifc-layer { display: flex; align-items: center; gap: 3px; white-space: nowrap; min-width: 0; }
.ifc-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.mv-panel, .mv-banner { font-size: 10px; color: var(--text-dim); margin: 0 0 6px 6px; line-height: 1.35; }
.mv-panel { min-width: 0; overflow-wrap: anywhere; }   /* the details wrap inside the panel */
.mv-ell { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mv-panel .btn { font-size: 10px; padding: 1px 5px; margin: 2px 3px 2px 0; }
.mv-color { display: flex; align-items: center; gap: 6px; margin: 2px 0 4px; }
.mv-color input[type=color] { width: 34px; height: 18px; padding: 0; border: 1px solid var(--border); background: none; cursor: pointer; }
.mv-color input[type=color]:disabled { cursor: default; }
.mv-version { border-left: 2px solid var(--border); padding-left: 5px; margin-top: 4px; }
.mv-version.mv-active { border-left-color: var(--state-on); }
#import-preview { padding: 0 10px; }
#import-preview > div { margin-bottom: 4px; line-height: 1.45; }
.imp-ok    { color: #4ec9a0; }
.imp-warn  { color: #f0b429; }
.imp-skip  { color: var(--text-muted); }
/* The unrecognised-column warning is meant to STOP a skimming eye: a filled amber block with
   a left bar, not a coloured line among the others. It sits at the top of the preview. */
.imp-unrecognised {
  background: rgba(240,180,41,0.12);
  border: 1px solid rgba(240,180,41,0.55);
  border-left: 4px solid #f0b429;
  border-radius: var(--radius);
  padding: 7px 10px;
  margin-bottom: 8px !important;
}
.imp-unrec-head { color: #f0b429; font-weight: 700; margin-bottom: 4px; text-transform: uppercase; letter-spacing: .3px; font-size: 11px; }
.imp-unrec-col  { color: var(--text); font-size: 11px; padding: 1px 0; }
.imp-unrec-col b { color: #ffd98a; }
.imp-unrec-eg   { color: var(--text-muted); }
.imp-err   { color: #ff6b6b; }
.imp-file  { color: var(--text-muted); font-size: 10px; }
.imp-file code, .imp-log-row code { color: var(--text); }
#import-actions { display: flex; gap: 6px; padding: 8px 10px; }
#import-actions .btn { flex: 1; }
#import-log { padding: 0 10px 10px; }
.imp-log-title {
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  margin: 6px 0 4px;
  border-top: 1px solid var(--border);
  padding-top: 6px;
}
.imp-log-row { color: var(--text-muted); font-size: 10px; line-height: 1.5; }
.imp-sum { color: var(--text-muted); font-size: 10px; margin-top: 6px; }
.imp-sum-skip { color: #f0b429; }

#reports-panel {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 111;
  display: none;
  width: 270px;
  max-height: calc(100% - 90px);
  overflow-y: auto;
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  font-size: 11px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#reports-panel.visible { display: block; }
#reports-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
  position: sticky;
  top: 0;
  background: var(--panel-float-2);
}
#reports-panel-header .btn { padding: 1px 6px; font-size: 11px; line-height: 1.2; }
#reports-list { padding: 6px 10px 10px; }
/* One card per report covering the clicked point. Several cards = overlapping areas,
   which is expected: the same ground investigated again years later. */
.rep-card {
  border: 1px solid var(--border);
  border-left: 3px solid #e0a030;
  border-radius: 6px;
  padding: 6px 8px;
  margin-top: 6px;
}
/* Green = a geologist has uploaded a corrected document over the generated draft. */
.rep-card.reviewed { border-left-color: #3ec880; }
.rep-title { color: var(--text); font-weight: 600; margin-bottom: 4px; }
.rep-status {
  font-size: 9px;
  letter-spacing: .6px;
  padding: 1px 5px;
  border-radius: 6px;
  display: inline-block;
  margin-bottom: 5px;
}
.rep-status.draft { background: var(--draft-bg); color: var(--draft-fg); }
.rep-status.ok    { background: var(--ok-bg); color: var(--ok-fg); }
/* One version per line, newest first - a wrapping row read as one run-on sentence.
   Collapsed behind the summary once there are more than three (set in app.js). */
.rep-versions {
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px solid var(--border);
  font-size: 9px;
  color: var(--text-muted);
}
.rep-versions > summary {
  cursor: pointer;
  user-select: none;
  letter-spacing: .4px;
  padding: 1px 0;
}
.rep-ver {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0 2px 8px;
  color: #8ab4f8;
  text-decoration: none;
  border-left: 1px solid var(--border);
  margin-left: 2px;
}
.rep-ver:hover { text-decoration: underline; }
.rep-ver-date { color: var(--text-muted); }
.rep-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 1px 0;
  color: var(--text-muted);
  font-size: 10px;
}
.rep-row b { color: var(--text); font-weight: 600; }
.rep-drift { color: #e0a030; font-weight: 400; margin-left: 4px; }
/* Deliberately NOT the amber of .rep-drift: this states the document's scope as a fact,
   it does not warn that anything has changed. Muted, so it reads as a footnote. */
.rep-scoped { color: var(--text-muted); font-weight: 400; margin-left: 4px; }
.rep-actions { display: flex; gap: 6px; margin-top: 6px; }
.rep-actions .btn { flex: 1; font-size: 10px; padding: 3px 6px; text-align: center; }

/* ── Floating map legend ── */
#map-legend {
  pointer-events: auto;   /* the header is clickable; #legend-stack is not */
  display: flex;          /* column so the body can flex/scroll within the height-capped stack */
  flex-direction: column;
  flex: 1 1 auto;         /* AS a stack child: absorb the cap's shrink, so the Cu scale above stays put */
  min-height: 0;
  overflow: hidden;       /* clip to the rounded box; the body scrolls, the header stays */
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  width: var(--right-col-w);   /* was 160-220 px by content; a long lithology name now wraps instead */
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  font-size: 11px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#map-legend-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
#map-legend-header:hover { color: var(--text); }
#map-legend-toggle { font-size: 9px; }
#map-legend-body {
  padding: 8px 10px;
  /* Was a FIXED max-height: 320px, which did not shrink when the detail panel shrinks #map, so a tall
     legend (Koper ~14 rows) rode up into the Naklon/Podlaga controls (its top clipped above the map).
     Now it FLEXES within the height-capped stack below and scrolls - adaptive to the map height AND the
     legend length (2026-09-15). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
#map-legend.collapsed #map-legend-body { display: none; }
#map-legend.collapsed #map-legend-header {
  border-bottom: none;
  border-radius: 6px;
}

/* ── Legend ── */
/* NO own max-height / overflow. Since 2026-09-15 the SCROLL lives on #map-legend-body, which flexes
   within the height-capped #legend-stack. Keeping a second 180px cap + overflow-y here meant that
   when the map shrank (detail panel open) BOTH engaged and the legend showed TWO scrollbars side by
   side (2026-09-17). One scroll container: the body. This one just lays the rows out. */
#legend-container {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
}
.legend-item > :last-child { min-width: 0; overflow-wrap: anywhere; }   /* wraps inside the fixed width */

.legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  flex-shrink: 0;
  border: 1px solid rgba(255,255,255,.1);
}

/* ── Borehole markers ── */
.bh-marker {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--color, #58a6ff);
  border: 2px solid var(--heading);
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(0,0,0,.4);
  transition: transform .1s;
}
.bh-marker:hover { transform: scale(1.4); }
.bh-marker.selected {
  transform: scale(1.5);
  box-shadow: 0 0 0 3px #58a6ff, 0 0 0 5px rgba(88,166,255,.3);
}



/* ── Detail panel ── */
#detail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
#detail-title { font-size: 12px; color: var(--accent); font-weight: 600; }
#detail-close {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1;
  border: none;
  background: none;
}
#detail-close:hover { color: var(--text); }

#detail-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}

#detail-info {
  width: 260px;
  min-width: 260px;
  padding: 10px 14px;
  border-right: 1px solid var(--border);
  overflow-y: auto;
  font-size: 11px;
}

#detail-info .info-row { margin-bottom: 4px; }
#detail-info .info-label { color: var(--text-muted); }
#detail-info .info-val { color: var(--text); }
/* A collar level sampled off the DEM, not surveyed. Same amber the section outlines it
   in, so the two readings of the same fact match. */
/* The DEM-fill mark is a QUALIFIER on a number ("estimated, not surveyed"), not a state or an
   action - so it is typographic, not a colour: italic in the muted text token (which follows the
   theme, dark or light), never amber. Amber read as generic AI-UI and would collide with nothing
   in the red=action / olive=state scheme. The "~" marker is added in the string, and matches the
   section's ~DMR. */
#detail-info .z-derived { color: var(--text-muted); font-style: italic; font-size: 11px; }

#detail-intervals {
  width: 200px;
  min-width: 180px;
  overflow-y: auto;
  border-right: 1px solid var(--border);
  padding: 6px 0;
}

/* Two lines: depth + lithology always readable on the main line; the classification chips
   (USCS/ISO and any project extras like GT / geološka starost) sit on a secondary line below,
   only when present. Before, all of it shared one flex row and the fixed-width chips squeezed
   the lithology to "F..." - the one thing that must stay legible without hovering. */
.interval-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 10px;
  font-size: 10px;
  cursor: pointer;   /* rows are clickable: click selects the band on the map, click again clears */
}
.interval-row:hover { background: var(--border); }
/* Selected must out-signal hover the way the map's selected band out-lifts map hover: hover is a
   bare background change, selected KEEPS that background AND adds an accent bar + a brighter tint,
   so a hovered row and the selected row are never confusable. Needs Luka's eye. */
.interval-row.selected {
  background: var(--border);
  box-shadow: inset 3px 0 0 var(--accent);
}
.interval-row.selected .interval-lith { color: var(--text); font-weight: 600; }
.iv-main { display: flex; align-items: center; gap: 6px; }

.interval-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.interval-depths { color: var(--text-muted); min-width: 60px; flex-shrink: 0; }
/* flex:1 so it takes the row width and reads in full; no ellipsis - chips no longer compete */
.interval-lith { color: var(--text); flex: 1; }
.interval-class {
  /* indented under the lithology (swatch 10 + gap 6 + depth 60), so the chips read as a
     sub-line of the interval rather than a separate row */
  padding-left: 76px;
  color: var(--text-muted);
  font-size: 9px;
  font-family: var(--font-ui);
  letter-spacing: 0.3px;
}
.interval-class b { color: var(--text); font-weight: 600; }

#detail-chart-area {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#chart-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.chart-tab {
  padding: 5px 12px;
  font-size: 11px;
  cursor: pointer;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  font-family: var(--font-ui);
}
.chart-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.chart-tab:hover:not(.active) { color: var(--text); }
/* Enlarge (the overlay below). At the right end of the tab row. */
.chart-enlarge { margin-left: auto; background: none; border: none; color: var(--text-muted);
                 cursor: pointer; font-size: 14px; padding: 2px 10px; line-height: 1; }
.chart-enlarge:hover { color: var(--accent); }
.chart-enlarge[hidden] { display: none; }
/* The enlarged chart. z-index under #tooltip (1200 - it must out-stack every floating panel) and the
   two top bars; over the section sheet (115). */
#chart-overlay { position: fixed; inset: 0; z-index: 1150; background: rgba(0,0,0,.55);
                 display: flex; align-items: center; justify-content: center; }
#chart-overlay[hidden] { display: none; }
/* --panel, as the detail panel: the charts' grid and ring colours are chosen against it, and on --bg (#2d2d2d
   in the dark theme) the #2c2c2c rings vanished. */
#chart-overlay-box { width: min(1500px, 95vw); height: 90vh; background: var(--panel); border: 1px solid var(--border);
                     border-radius: 8px; padding: 8px; display: flex; flex-direction: column; gap: 4px;
                     box-shadow: 0 6px 24px rgba(0,0,0,.5); }
/* While the overlay is open the button lives INSIDE #chart-tabs (openChartOverlay moves it there), at the
   row's right end, centred on the row by layout - at any zoom (a fixed `top` matched one browser and sat
   high in Luka's). A FIXED 20 px box, smaller than the row's 26 px content: equal space above and below,
   and it never reaches the line under the tabs (stretched to the row, its outline sat on that line -
   Luka, 2026-10-12). */
#chart-overlay-close { margin: 0 4px 0 auto; align-self: center; height: 20px; padding: 0 10px;
                       display: inline-flex; align-items: center; font-size: 11px; line-height: 1; }
#chart-overlay-slot { flex: 1; min-height: 0; display: flex; }
#chart-overlay-slot #detail-chart-area { flex: 1; min-width: 0; }

#chart-canvas-wrap { flex: 1; position: relative; overflow: hidden; padding: 6px; }
canvas#cptChart { display: block; }
canvas#dmtChart { display: block; }

/* ── Toolbar overlay ── */
#toolbar {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  z-index: 10;
  /* Fixed width so the right-anchored toolbar does not shift when a label changes length
     on a language toggle (widest observed label ~168px in either language). */
  width: var(--right-col-w);
}

/* Toggle STATE: olive/green = ON, neutral = OFF. Red is ACTION only (both themes), so OFF is the
   plain button, never red. --state-on is olive in light, the old neon green in dark. */
.btn.active-mode { border-color: var(--state-on) !important; color: var(--heading) !important; background: var(--state-on-bg); }
.btn.layer-off   { border-color: var(--border) !important; color: var(--text-muted) !important; background: transparent; }
/* The layer toggles show the same red border on hover as an idle basemap button (Luka, 2026-10-20) */
#content-layers .btn.active-mode:hover,
#content-layers .btn.layer-off:hover { border-color: var(--accent) !important; }

/* ── Measurement tools (A2) ── */
#measure-tools { display: flex; gap: 6px; }
#measure-tools .btn { flex: 1; font-size: 11px; padding: 5px 6px; text-align: center; }
#measure-tools #btn-measure-clear { flex: 0 0 auto; padding: 5px 9px; }

/* ── Share / print tools (B3) ── */
#share-tools { display: flex; gap: 6px; }
#share-tools .btn { flex: 1; font-size: 11px; padding: 5px 6px; text-align: center; }

/* ── Basemap gallery (A1) ── */
#basemap-gallery { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
#basemap-gallery .btn { text-align: left; font-size: 11px; padding: 4px 8px; }
#basemap-attribution {
  position: absolute;
  bottom: 4px;
  left: 6px;
  z-index: 9;
  font-size: 9px;
  color: rgba(255,255,255,0.78);
  background: rgba(0,0,0,0.5);
  padding: 1px 6px;
  border-radius: 6px;
  font-family: var(--font-ui);
  pointer-events: none;
  max-width: 55%;
}
#basemap-attribution.notice { color: #ffd479; }

#measure-readout {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 11px;
  color: var(--text);
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;   /* fixed-width digits so live values do not jitter */
  line-height: 1.5;
  pointer-events: none;
  display: none;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#measure-readout strong { color: var(--text-muted); font-weight: 600; }
#measure-readout .measure-hint { color: var(--text-muted); font-size: 10px; margin-top: 2px; font-style: italic; }

#pitch-control {
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 7px;
  font-size: 10px;
  color: var(--text-muted);
  transition: border-color 0.2s;
}
#pitch-control.underground {
  border-color: #b060f0;
}
#pitch-control input[type=range] {
  width: 80px;
  accent-color: var(--accent);
  cursor: pointer;
}
#pitch-control.underground input[type=range] { accent-color: #b060f0; }
#pitch-value { min-width: 28px; text-align: right; color: var(--text); }
#pitch-control.underground #pitch-value { color: #b060f0; }
#pitch-control.underground #pitch-label { color: #b060f0; }

#sat-opacity-control {
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 7px;
  font-size: 10px;
  color: var(--text-muted);
}
#sat-opacity-control input[type=range] {
  width: 70px;
  accent-color: var(--accent);
  cursor: pointer;
}
#opacity-value { min-width: 28px; text-align: right; color: var(--text); }


/* ── Coordinate bar (A3) ── */
#coord-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  background: var(--sidebar);
  border-top: 1px solid var(--border);
  padding: 3px 10px;
  font-size: 10px;
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-variant-numeric: tabular-nums;   /* fixed-width digits so live values do not jitter */
  overflow: hidden;
}
#coord-readout {
  display: flex;
  gap: 14px;
  align-items: center;
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
}
#coord-readout .coord-sys b { color: var(--text-muted); font-weight: 600; margin-right: 4px; }
/* ' | ' between the systems (Luka, 2026-10-12). Drawn by CSS, so it is never copied with a value. */
#coord-readout .coord-sys + .coord-sys::before { content: '|'; color: var(--text-muted); margin-right: 14px; }
#coord-readout .coord-sys span { color: var(--text); }
#coord-readout .coord-approx { color: #e3b341; cursor: help; margin-left: 3px; font-weight: bold; }
#coord-goto { display: flex; gap: 5px; align-items: center; flex-shrink: 0; }
#coord-goto select { width: auto; padding: 2px 4px; font-size: 10px; }
#coord-goto input { width: 80px; padding: 2px 6px; font-size: 10px; }
#coord-goto .btn { padding: 3px 10px; font-size: 10px; }
#goto-msg { font-size: 10px; }

/* ── Status bar ── */
#statusbar {
  background: var(--sidebar);
  border-top: 1px solid var(--border);
  padding: 3px 12px;
  font-size: 10px;
  color: var(--text-muted);
  display: flex;
  gap: 16px;
  flex-shrink: 0;
}
/* The EPSG code on the right edge, so the count's length in one language never moves it (Luka, 2026-10-20). */
#stat-epsg { margin-left: auto; }

/* ── Scrollbar styling ── */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ── Loading overlay ── */
#loading {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  font-size: 14px;
  color: var(--accent);
  flex-direction: column;
  gap: 10px;
}
#loading.hidden { display: none; }
.spinner {
  width: 28px; height: 28px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* #chat-panel removed - replaced by #chat-section inside #bottom-content */


#chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.chat-msg {
  max-width: 88%;
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 11px;
  line-height: 1.5;
}
.chat-msg.user      { align-self: flex-end; background: var(--user-bg); border: 1px solid var(--user-bd); color: var(--text); }
.chat-msg.assistant { align-self: flex-start; background: var(--bg); border: 1px solid var(--border); color: var(--text); }
.chat-msg.thinking  { align-self: flex-start; color: var(--text-muted); font-style: italic; font-size: 11px; padding: 4px 0; background: none; border: none; }
.chat-msg.error     { align-self: flex-start; background: var(--error-bg); border: 1px solid var(--danger); color: var(--danger); }

/* The chat as a job (CHAT_JOBS): phase, an indeterminate bar (the model gives no percentage), elapsed time,
   cancel. The bar moves - it says "working", never "this far". */
.chat-msg.chat-job  { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-style: normal; }
.chat-job-bar       { position: relative; width: 60px; height: 3px; border-radius: 2px; overflow: hidden;
                      background: var(--border); }
.chat-job-bar::after { content: ''; position: absolute; top: 0; bottom: 0; width: 40%; left: -40%;
                       background: var(--accent); animation: chatJobBar 1.2s ease-in-out infinite; }
@keyframes chatJobBar { to { left: 100%; } }
.chat-job-time      { font-variant-numeric: tabular-nums; }
.chat-job-cancel    { padding: 1px 8px; font-size: 10px; }
#chat-recent        { margin: 6px 10px 0; padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px;
                      font-size: 11px; max-height: 40%; overflow-y: auto; }
.chat-recent-head   { color: var(--heading); font-weight: 600; margin-bottom: 4px; }
.chat-recent-row    { padding: 2px 0; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-recent-row:hover { color: var(--accent); }
.chat-recent-row.chat-recent-inactive { cursor: default; color: var(--text-muted); }
.chat-recent-note   { color: var(--text-muted); font-size: 10px; margin-top: 4px; }

.chat-msg.assistant strong { color: var(--heading); }
/* Markdown headings in an answer (renderMarkdown). Divs, not h1-h4, so the page's heading rules
   never apply; sized just above the body text so a heading reads as a heading, not a banner. */
.chat-msg .chat-h  { color: var(--heading); font-weight: 600; margin: 6px 0 3px; line-height: 1.3; }
.chat-msg .chat-h:first-child { margin-top: 0; }
.chat-msg .chat-h1 { font-size: 13px; }
.chat-msg .chat-h2 { font-size: 12.5px; }
.chat-msg .chat-h3 { font-size: 12px; }
.chat-msg.assistant code   { background: var(--border); padding: 1px 4px; border-radius: 6px; font-family: var(--font-mono); font-size: 10px; }
.chat-msg.assistant ul     { margin: 4px 0 4px 14px; padding: 0; }
.chat-msg.assistant li     { margin-bottom: 2px; }
.chat-msg.assistant table  { border-collapse: collapse; width: 100%; margin-top: 6px; font-size: 10px; }
.chat-msg.assistant th,
.chat-msg.assistant td     { border: 1px solid var(--border); padding: 3px 7px; text-align: left; }
.chat-msg.assistant th     { color: var(--heading); background: var(--panel); }
.chat-msg.assistant td     { color: var(--text); }

.chat-action-btn {
  display: inline-block;
  margin-top: 6px;
  padding: 3px 8px;
  font-size: 10px;
  border: 1px solid var(--text-muted);
  border-radius: 6px;
  color: var(--text);
  cursor: pointer;
  font-family: var(--font-ui);
  background: none;
}
.chat-action-btn:hover { background: rgba(88,166,255,0.1); }

#chat-suggestions { display: flex; flex-wrap: wrap; gap: 5px; padding: 4px 10px 6px; flex-shrink: 0; }
.suggestion {
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 10px;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  font-family: var(--font-ui);
}
.suggestion:hover { border-color: var(--accent); color: var(--accent); }

#chat-input-row { display: flex; gap: 6px; padding: 6px 10px; border-top: 1px solid var(--border); flex-shrink: 0; }
#chat-input { flex: 1; }
#chat-send-btn { width: 32px; flex-shrink: 0; padding: 5px; font-size: 14px; line-height: 1; }
#chat-send-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ── Tooltip ── */
#tooltip {
  position: fixed;
  background: var(--sidebar);
  border: 1px solid var(--border);
  padding: 6px 10px;
  border-radius: 5px;
  font-size: 11px;
  pointer-events: none;
  display: none;
  /* Above every floating panel (#section-panel is 115, #interval-popup 1000). It was
     100, so the profile's hover readout rendered behind the sheet the cursor was on -
     i.e. never visible. It is pointer-events:none, so it can never block anything. */
  z-index: 1200;
  max-width: 200px;
}

/* ── Print view (B3) - hidden on screen, shown only when printing ── */
#print-area { display: none; }
@media print {
  /* drop the app's overflow:hidden / fixed height so the print page isn't clipped */
  html, body { height: auto !important; overflow: visible !important; background: var(--heading) !important; }
  /* hide everything except the print view (robust regardless of DOM nesting) */
  body > *:not(#print-area) { display: none !important; }
  #print-area {
    display: block !important;
    padding: 0;
    background: var(--heading);
  }
  #print-area, #print-area * { color: #000 !important; }
  #print-area h2 { font-size: 15px; margin: 0 0 8px; }
  #print-map-img { display: block; width: 100%; height: auto; border: 1px solid #999; }
  #print-legend { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 4px 18px; }
  #print-filters { margin-top: 8px; font-size: 11px; }
  /* swatches carry background colours - force the browser to actually print them */
  .print-swatch {
    display: inline-block; width: 12px; height: 12px; border: 1px solid #999;
    vertical-align: middle; margin-right: 4px;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* Selected-borehole detail */
  #print-detail { margin-top: 12px; font-size: 11px; }
  .print-detail-title { font-weight: bold; margin-bottom: 3px; }
  .print-interval { margin: 1px 0; }
  .print-interval-sel { font-weight: bold; border-left: 3px solid #000; padding-left: 4px; }
  #print-attribution { margin-top: 8px; font-size: 9px; }
  @page { margin: 12mm; }
}

/* ── Longitudinal section (D3) ── */
/* Full-width sheet along the bottom of the map: a profile is a wide, short drawing and
   anything narrower forces horizontal scrolling on even a short axis. */
#section-panel {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 10px;
  z-index: 115;
  display: none;
  /* Empty - the hint shown before any axis exists - the sheet is only as tall as its own
     text. Half the map for one sentence is not a sheet, it is a blindfold. */
  height: auto;
  max-height: 88%;
  background: var(--panel-float-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  box-shadow: 0 2px 18px rgba(0,0,0,0.6);
  overflow: hidden;
}
#section-panel.visible { display: flex; flex-direction: column; }
/* With a drawing in it the sheet takes a stable working height and gains a drag handle:
   it must not resize itself every time the axis changes, and a crowded section needs to
   be pulled open beyond any sensible default. */
#section-panel.has-data { height: 50%; min-height: 130px; resize: vertical; }
#section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
#section-controls { display: flex; align-items: center; gap: 6px; }
#section-controls label { font-size: 10px; letter-spacing: 0; }
/* The global `input, select { width: 100% }` rule (see the Inputs block above) makes any
   select in a flex row stretch to the whole line - which is what put each control of this
   header on a row of its own. Every select here states its own width. */
#section-controls select {
  width: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 10px;
  padding: 2px 4px;
}
#section-exag, #section-corridor { width: 76px; }
#section-controls .btn { padding: 2px 7px; font-size: 10px; line-height: 1.3; }
#section-info {
  padding: 4px 10px;
  font-size: 10px;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}
#section-info b { color: var(--text); }
/* Missing ground is stated, never silently skipped - a profile drawn without a terrain
   line over part of its length must not read as flat ground. */
/* Separator between adjacent warnings comes from the JS, not a CSS ::before escape. */
.section-warn { color: #e0a030; }
/* The drawing scrolls inside its own box; the page never scrolls horizontally. */
#section-body { flex: 1 1 auto; overflow: auto; padding: 6px 10px 10px; }
#section-body svg { display: block; }
.section-msg { color: var(--text-muted); font-size: 11px; font-style: italic; padding: 10px 0; }
#section-tools { display: flex; gap: 6px; }
#section-tools .btn { flex: 1; font-size: 11px; padding: 5px 6px; text-align: center; }
/* Profile hover readout: reuses #tooltip, widened for the layer description (the
   lithology code alone does not answer "what is there"). */
#tooltip.wide { max-width: 340px; }
#tooltip .tip-litho { color: var(--text); font-weight: bold; margin-top: 3px; }
#tooltip .tip-desc  { color: var(--text-muted); margin-top: 3px; line-height: 1.45; }
#tooltip .tip-zone  { color: #8ab4f8; margin-top: 3px; font-size: 10px; }
/* Lab readout on the profile - same violet as the brackets on the sheet, so the tooltip
   and the thing it describes are visibly the same kind of fact. */
#tooltip .tip-lab   { color: #c586ff; font-size: 10px; }
.section-lab-n      { color: #c586ff; }
.section-why { margin: 4px 0 0 16px; font-style: normal; }
.section-why li { margin: 2px 0; }

/* "Upoštevaj filtre" - the same control in two places, one piece of state. */
.chk-row {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.chk-row input { width: 13px; height: 13px; accent-color: var(--accent2); cursor: pointer; }
/* The per-interval filter is inert until a lithology is chosen - say so by greying it out
   rather than letting a tick appear to do nothing. */
#filter-iv-row { margin-top: 6px; }   /* it sat flush against the lithology select */
.chk-row input:disabled { cursor: default; }
.chk-row:has(input:disabled) { opacity: .45; cursor: default; }
#report-panel .chk-row { padding: 0 10px 6px; }

/* Section header controls: labels must not break, and the axis picker has to be wide
   enough for a whole file name - a truncated one is not a choice, it is a guess. */

/* "Upoštevaj filtre" is a toggle button beside "Izvozi XLSX" (Luka, 2026-10-20); neither label may wrap. */
#export-footer { flex-wrap: wrap; row-gap: 3px; }
#export-count:empty { display: none; }
#export-count:not(:empty) { flex-basis: 100%; }   /* the selection count on its own line, the two buttons below */
#export-actions { display: flex; gap: 4px; flex: 1; }
#export-actions .btn { flex: 1; white-space: nowrap; padding-left: 4px; padding-right: 4px; }
/* On and off look the same apart from the colour and the ✓ (Luka, 2026-10-20): the text keeps the plain
   button's colour, which active-mode would otherwise brighten. */
#btn-respect-filters.active-mode { color: var(--text) !important; }

/* Section header buttons keep their own width - they were being squashed into three-line
   labels by the flex row. */
/* ...and the control group wraps rather than overflowing when the header runs out of
   room. A taller header beats a button whose label is broken across three lines. */

/* Section header, settled: one row that never squashes its contents. Labels and buttons
   keep their natural width; only the axis picker is fixed, wide enough for a whole file
   name. If the window is genuinely too narrow the group wraps as a block rather than
   crushing a button label onto three lines. */
#section-controls { flex-wrap: wrap; row-gap: 4px; justify-content: flex-end; }
#section-controls label { white-space: nowrap; flex: 0 0 auto; }
#section-controls .btn { white-space: nowrap; flex: 0 0 auto; }
#section-axis-file { width: 180px; min-width: 180px; flex: 0 0 auto; }
#section-header { flex-wrap: wrap; row-gap: 4px; }
/* Station-window inputs. The selector needs the id: the global rule is
   `input[type=text], … { width: 100% }` - element + attribute, specificity 0-0-1-1 -
   which beats a bare class at 0-0-1-0, so `.section-range` alone lost and the inputs
   stretched across the header a row at a time. */
#section-controls input.section-range {
  width: 68px; min-width: 68px; flex: 0 0 auto;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  color: var(--text); font-family: var(--font-ui); font-size: 10px; padding: 2px 4px;
  text-align: right;
}
.section-range-dash { color: var(--text-muted); flex: 0 0 auto; }


/* Project + user strip (Phase 1). Deliberately quiet: it is orientation, not a control. */
/* Same ink as the rest of the page - the project label, the user and Odjava are content here,
   not a distinct pale sub-strip. The name is a <span>, not a link (the home button navigates). */
#project-strip { margin-top: 6px; font-size: 11px; line-height: 1.5; color: var(--text); }
#project-strip .proj  { color: var(--text); font-weight: 600; }
#project-strip .who   { color: var(--text); }
#project-strip a      { color: var(--text); text-decoration: underline; cursor: pointer; }
#project-strip a:hover{ color: var(--accent); }
/* The user row: one line, always (Luka, 2026-10-20). Its links keep the width of their longer language
   (tFit), so a language switch moves nothing; a long name is shortened with … rather than wrapping the row. */
#project-strip .user-row { display: flex; white-space: nowrap; }
#project-strip .user-row .who { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#project-strip .user-row .sep { flex: none; padding: 0 2px; }
#project-strip .user-row a { flex: none; }
/* Each label centred in its reserved slot, so the spare room splits on both sides of it and the gaps
   around each · even out in both languages (Luka, 2026-10-22, option A). */
#project-strip .user-row .i18n-fit { justify-items: center; }
/* The row's drawn icons (Luka, 2026-11-03): the bin (the owner's deleted items) and the help. One text line high, so the row keeps
   its height; the ink of the row's links, the accent on hover, a ring on keyboard focus; fixed size, so nothing moves on a switch. */
#project-strip .hdr-icons { flex: none; display: inline-flex; align-items: center; gap: 2px; }
#project-strip a.hdr-icon { display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 16px;
  border-radius: 4px; color: var(--text); text-decoration: none; }
#project-strip a.hdr-icon svg { width: 13px; height: 13px; display: block; }
#project-strip a.hdr-icon:hover { color: var(--accent); background: var(--btn-hover); }
#project-strip a.hdr-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The chat header's recent-questions clock: the size of the ↺ beside it. */
.chat-icon-btn { display: inline-flex; align-items: center; }
.chat-icon-btn svg { width: 12px; height: 12px; display: block; }

/* A label sized to its LONGEST translation (i18n.js, data-i18n-fit / tFit): every language in one grid
   cell, only the current one visible - so a language switch moves nothing beside it. */
.i18n-fit { display: inline-grid; }
.i18n-fit > span { grid-area: 1 / 1; }
.i18n-fit > .i18n-fit-off { visibility: hidden; }


/* Session-expired banner. Deliberately loud and deliberately not a modal: it must be
   impossible to miss and impossible to trap the user behind. */
#session-expired {
  position: fixed; top: 0; left: 0; right: 0; z-index: 2000;
  background: #7a2d2d; color: #ffe9e9; font-size: 13px;
  padding: 10px 16px; display: flex; gap: 18px; align-items: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
#session-expired a { color: var(--heading); text-decoration: underline; }
/* A newer app is deployed than this page loaded (_checkNewVersion). Top centre, below the session bar's
   z-index so an expired session - the more urgent message - stays on top if both are up. */
#new-version-bar {
  position: fixed; top: 8px; left: 50%; transform: translateX(-50%); z-index: 1990;
  background: #1f4f7a; color: #e8f2ff; font-size: 13px; border-radius: 6px;
  padding: 8px 14px; display: flex; gap: 14px; align-items: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.4);
  border: 0; font-family: inherit; font-weight: 600; cursor: pointer;   /* the whole bar is the reload button */
}
#new-version-bar:hover { background: #276196; }
#new-version-bar:focus-visible { outline: 2px solid #e8f2ff; outline-offset: 2px; }
/* ── Header controls: home button + theme slider + language slider, on ONE row (2026-09-29) ── */
/* All three side by side, sharing the first line with the title; the subtitle sits full-width below
   (see .app-subtitle) so it is never squeezed into the narrow column beside these controls. */
.header-controls { display: flex; flex-direction: row; align-items: center; gap: 6px; flex: 0 0 auto; }

/* Home -> project picker. Its own surface (var(--surface), like the theme slider) so it reads as a
   control against the header; hover tints, pressed goes red (red = action, and this navigates). It sits
   on --surface rather than --btn-bg because --btn-bg (#E4DED7) is nearly the sidebar-header background
   (--sidebar #D6CFC8) - the rule applied but did not separate; --surface (#F2EFEB) is the lighter one. */
.home-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border: 1px solid var(--border); border-radius: 6px; color: var(--text-muted); background: var(--surface);
  cursor: pointer; text-decoration: none; transition: background .15s, color .15s, border-color .15s; }
.home-btn:hover  { background: var(--btn-hover); color: var(--text); border-color: var(--accent); }
.home-btn:active { background: var(--accent); color: #fff; border-color: var(--accent); }
.home-btn svg { width: 15px; height: 15px; display: block; }

/* Theme slider: sun (left) - pill track - moon (right), a knob that slides to the active side. */
.theme-toggle { position: relative; display: inline-flex; align-items: center; justify-content: space-between;
  width: 52px; height: 24px; padding: 0 5px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); cursor: pointer; }
.theme-toggle svg { width: 12px; height: 12px; position: relative; z-index: 1; color: var(--text-muted); }
.theme-knob { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--btn-bg); border: 1px solid var(--border); z-index: 0; transition: transform .18s ease; }
/* The lit icon is warm yellow, NOT the olive "on": the theme slider is a choice between two modes,
   neither of which is "off", so it stays out of the olive state vocabulary (--theme-accent). */
/* .theme-toggle prefix so this beats the base `.theme-toggle svg` muted rule (0-1-1); a bare
   `.theme-ic-sun` (0-1-0) loses to it and the sun rendered muted instead of the accent. */
.theme-toggle .theme-ic-sun { color: var(--theme-accent); }   /* sun = light active */
:root[data-theme="dark"] .theme-knob { transform: translateX(28px); }
:root[data-theme="dark"] .theme-ic-sun  { color: var(--text-muted); }
:root[data-theme="dark"] .theme-ic-moon { color: var(--theme-accent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-knob { transform: translateX(28px); }
  :root:not([data-theme="light"]) .theme-ic-sun  { color: var(--text-muted); }
  :root:not([data-theme="light"]) .theme-ic-moon { color: var(--theme-accent); }
}

/* Language slider: SL | EN, mirroring the theme slider's FORM so the two read as a pair. Deliberately
   NEUTRAL - no accent - because SL|EN is a mode choice with no "on"/"off" and no warm/cool meaning; the
   active side is just the strong ink, the other dimmed. Keyed off <html lang>, which i18n.js keeps
   current (applyI18nAttributes), exactly as the theme slider keys off [data-theme]. */
.lang-toggle { position: relative; display: inline-flex; align-items: center; justify-content: space-between;
  width: 52px; height: 24px; padding: 0 5px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface); cursor: pointer; font: 600 10px/1 var(--font-ui); letter-spacing: .5px; }
/* Equal-width CENTRED label boxes: "SL" and "EN" are unequal glyph widths, so without a fixed width
   space-between aligns their edges and their centres land asymmetrically about the pill (measured
   ~0.74px). Fixed 18px + text-align:center makes the two symmetric, and the knob then centres on each. */
.lang-toggle .lang-sl, .lang-toggle .lang-en { position: relative; z-index: 1; width: 18px; text-align: center; color: var(--text-muted); transition: color .18s; }
.lang-toggle .lang-sl { color: var(--heading); }                       /* SL active by default (lang=sl) */
.lang-knob { position: absolute; top: 2px; left: 3px; width: 22px; height: 18px; border-radius: 9px;
  background: var(--btn-bg); border: 1px solid var(--border); z-index: 0; transition: transform .18s ease; }
:root[lang="en"] .lang-toggle .lang-sl { color: var(--text-muted); }
:root[lang="en"] .lang-toggle .lang-en { color: var(--heading); }
:root[lang="en"] .lang-knob { transform: translateX(22px); }

/* Phase 2 roles. A control the caller's role cannot use is disabled with the reason as its
   title (applyRole in app.js); the dimming says "not for you", not "broken". */
.btn.role-off { opacity: .45; cursor: not-allowed; }
/* DEV_FORCE_ROLE announces itself (MULTIPROJECT-PLAN.md §3.5) - the whole point of forcing a role
   is to make the app behave in a way that looks like a bug. Below #tooltip (1200). */
#role-forced-bar {
  position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 1100;
  background: var(--danger, #EE2E27); color: #fff; font-size: 11px; font-weight: 600;
  padding: 2px 10px; border-radius: 0 0 6px 6px; pointer-events: none;
}

/* The supersede choice in the import preview: a long sentence beside a checkbox, so it wraps
   instead of running off the panel's edge (seen on screen 2026-10-09). */
.imp-supersede { display: flex; align-items: flex-start; gap: 6px; white-space: normal; line-height: 1.3; margin-top: 6px; }
.imp-supersede input { flex: 0 0 auto; margin-top: 1px; }

/* ── Project members (Phase 3) ────────────────────────────────────────────── */
/* Top-right like the import panel, one step above it (both open is rare: the member panel
   opens from the header strip). Below #tooltip (1200), like every floating panel. */
#members-panel, #hidden-panel {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 114;
  display: none;
  width: 340px;
  max-height: calc(100% - 90px);
  overflow-y: auto;
  background: var(--panel-float);
  border: 1px solid var(--border);
  border-radius: 6px;
  backdrop-filter: blur(4px);
  font-family: var(--font-ui);
  font-size: 11px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
#members-panel.visible, #hidden-panel.visible { display: block; }
#members-panel-header, #hidden-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  color: var(--text-muted);
  font-size: 10px;
  letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
  user-select: none;
  position: sticky;
  top: 0;
  background: var(--panel-float-2);
}
#members-body, #hidden-body { padding: 0 10px 10px; }
#hidden-panel { z-index: 115; }
.hide-btn.armed { border-color: #d9534f; color: #ff8a80; }
.purge-btn { color: #ff8a80; }
.purge-btn.armed { border-color: #d9534f; background: rgba(217,83,79,0.18); }
.mem-h { color: var(--text-muted); font-size: 10px; letter-spacing: .6px; text-transform: uppercase; margin: 10px 0 4px; }
.mem-row { display: flex; align-items: center; gap: 6px; padding: 4px 0; border-bottom: 1px solid var(--border); }
.mem-who { flex: 1; min-width: 0; overflow-wrap: anywhere; color: var(--text); line-height: 1.35; }
.mem-sub { color: var(--text-muted); font-size: 10px; }
.mem-rolelabel { color: var(--text-muted); }
/* The global `select { width: 100% }` / `input[type=text] { width: 100% }` would stretch these
   across the row - id selectors to out-rank them (the Inputs block in this file). */
#members-panel select.mem-role, #members-panel #member-role { width: auto; font-size: 10px; }
#members-panel #member-email, #members-panel #member-link { flex: 1; width: auto; min-width: 0; font-size: 10px; }
.mem-rm { padding: 2px 6px; font-size: 10px; }
.mem-rm.armed { border-color: #d9534f; color: #ff8a80; }
.mem-rm:disabled { opacity: .45; cursor: not-allowed; }
.mem-stale .mem-who { color: #f0b429; }
.mem-stale-note { color: #f0b429; font-size: 10px; }
.mem-empty, .mem-note { color: var(--text-muted); font-size: 10px; line-height: 1.4; margin-top: 4px; }
.mem-add, .mem-link { display: flex; gap: 6px; align-items: center; }
.mem-msg { margin: 8px 0 4px; padding: 6px 8px; border-radius: var(--radius); line-height: 1.4; }
.mem-ok   { color: #4ec9a0; border: 1px solid rgba(78,201,160,.45); }
.mem-warn { color: #f0b429; border: 1px solid rgba(240,180,41,.55); background: rgba(240,180,41,0.12); }
.mem-err  { color: #ff8a80; border: 1px solid rgba(217,83,79,.6); }

/* ── Inclinometer tab (2026-10-12) ─────────────────────────────────────────── */
#inkl-wrap { position: absolute; inset: 6px; flex-direction: column; gap: 4px; }
/* ONE row, always (Luka, 2026-10-12): in a narrow tab it scrolls sideways rather than wrapping - every
   wrapped row was height taken from the plot (five rows at 1366 px left the plot 93 px). */
#inkl-controls { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; font-size: 10px; flex: 0 0 auto;
                 overflow-x: auto; overflow-y: hidden; white-space: nowrap; scrollbar-width: thin; padding-bottom: 2px; }
#inkl-controls > * { flex: 0 0 auto; }
#inkl-controls .btn { padding: 2px 8px; font-size: 10px; }
#inkl-controls .btn.on { border-color: var(--accent); color: var(--accent); }
#inkl-controls .chk-row { display: inline-flex; align-items: center; gap: 4px; color: var(--text-muted); }
#inkl-controls select { width: auto; font-size: 10px; }
.inkl-hidden { color: var(--text-muted); }
#inkl-plot { flex: 1 1 auto; min-height: 0; position: relative; overflow: hidden; }
#inkl-profiles { display: flex; gap: 8px; height: 100%; }
#inklChartP { display: block; margin: 0 auto; }
#inklChartT { display: block; }
#inkl-note { flex: 0 0 auto; font-size: 10px; color: var(--text-muted); line-height: 1.35;
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#inkl-side { position: absolute; left: 0; top: 0; bottom: 0; overflow: hidden; font-size: 10px; line-height: 1.35; }
/* The notes: label / value, a FIXED label width so every row lines up (Luka, 2026-10-12). */
.inkl-notes { width: 100%; table-layout: fixed; border-collapse: collapse; }
.inkl-notes th { width: 148px; text-align: left; font-weight: 400; color: var(--text-muted); vertical-align: top;
                 padding: 2px 8px 2px 0; }
.inkl-notes td { color: var(--text); vertical-align: top; padding: 2px 0; overflow-wrap: anywhere; }
.inkl-notes tr + tr th, .inkl-notes tr + tr td { border-top: 1px solid var(--border); }
/* The right column's width (--right-col-w), like the buttons above it (Luka, 2026-10-12). The labels
   wrap inside it; the map uses the rows' SHORT labels. */
#inkl-legend {
  background: var(--panel-float); border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 8px; margin-bottom: 6px; font-size: 10px; color: var(--text);
  width: var(--right-col-w);
}
.inkl-legend-row > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.inkl-legend-title { color: var(--text-muted); letter-spacing: .5px; font-size: 9.5px; }
.inkl-legend-sub { color: var(--text-muted); font-size: 9.5px; margin-bottom: 4px; }
.inkl-legend-row { display: flex; align-items: center; gap: 6px; margin: 2px 0; line-height: 1.3; }
.inkl-swatch {
  flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%; border: 2px solid;
  display: inline-flex; align-items: center; justify-content: center;
  font: bold 9px var(--font-ui); color: #141414;
  print-color-adjust: exact; -webkit-print-color-adjust: exact;
}
/* Quote lines in a chat answer (renderMarkdown, "> ..."). */
.chat-msg .chat-quote { border-left: 2px solid var(--border); padding-left: 8px; color: var(--text-muted); margin: 1px 0; }

/* The upload dialogs' steps (6e/6f, Luka 2026-10-22). A step that waits for the one before it is greyed and
   never clickable, with the reason under the buttons (.step-hint, a line kept even when empty so the dialog
   does not jump) and in its tooltip. The question "stop and close?" is asked IN the dialog (.dlg-confirm) -
   never a browser modal, which would freeze the browser tests. */
#model-import-panel .btn:disabled, #import-actions .btn:disabled, .bm-block .btn:disabled {
  opacity: .45; cursor: not-allowed;
}
#model-import-panel .btn:disabled:hover, #import-actions .btn:disabled:hover, .bm-block .btn:disabled:hover {
  border-color: var(--border-2) !important; color: var(--text) !important; background: var(--btn-bg);
}
.step-hint { color: var(--text-muted); font-size: 10px; line-height: 1.3; min-height: 1.3em; padding: 0 10px 6px; }
#mi-body .step-hint { padding: 3px 0 0; }
.dlg-confirm {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 10px; padding: 6px 8px;
  border: 1px solid var(--danger, #EE2E27); border-radius: 6px; font-size: 11px; color: var(--text);
}
.dlg-confirm > span { flex: 1 1 100%; }

/* ── Locked controls look locked (Luka, 2026-10-23, fixes 3 + 4) ──
   A button that is disabled - by the role (.role-off, applyRole) or because its step is not ready - is greyed,
   shows the not-allowed cursor and does NOTHING on hover: the rest and the hover state are the same rule, and it
   outranks every `.btn:hover` / `.btn.primary:hover` above (those are !important too, at a lower specificity).
   The settings cards' Shrani keeps its own transparent look (page.css, .card-save). Fields: the same cursor. */
.btn:is(:disabled, .role-off):not(.card-save),
.btn:is(:disabled, .role-off):not(.card-save):hover {
  background: var(--btn-bg) !important; border-color: var(--border-2) !important; color: var(--text) !important;
  opacity: .45; cursor: not-allowed !important; box-shadow: none !important; transform: none !important;
}
button:disabled, :is(input, select, textarea):disabled, .chk-row:has(input:disabled),
.mv-color:has(input:disabled) { cursor: not-allowed !important; }
/* A locked field must not look editable (browser check 2026-10-23: dimmer text alone was not enough): no fill,
   a dashed edge. */
:is(input, select, textarea):disabled { opacity: .55; background: transparent !important; border-style: dashed !important; }
:is(input, select, textarea):disabled:focus { border-color: var(--border-2); outline: none; }
/* One short line per card or panel saying which role may change it (applyRole sets the text, or hides it). */
.card-lock-note { color: var(--text-muted); font-size: 11px; line-height: 1.35; margin: 6px 0 0; }
.card-lock-note[hidden] { display: none; }
#report-panel .card-lock-note { margin: -4px 10px 10px; }
#reports-panel .card-lock-note { margin: 6px 10px 0; }
/* Its own full-width last row, so the controls wrap the same in both languages (the note keeps its size). */
#section-controls .card-lock-note { margin: 0; font-size: 10px; flex: 1 0 100%; order: 99; text-align: right; }

/* ── Edition switches (services/edition, written into <html> at serve time by views/frontend._page) ──
   The product beta has no chat and no reports (Luka, 2026-10-23). Hidden by the attribute the server wrote,
   so nothing is drawn and then removed; !important because applyBootstrap sets some of these inline. */
html[data-chat="0"] .ed-chat,
html[data-reports="0"] .ed-reports { display: none !important; }

/* ── What a permanent delete takes (services/purge; the hidden panel and the deleted-projects page, 2026-10-23) ──
   A two-column list: each label (with its colon) keeps its longer language's width (tFit), so a language switch
   moves nothing; the counts right-aligned in their own column. */
.goes { margin-top: 4px; color: var(--text-muted); font-size: 11px; line-height: 1.45; }
.goes-grid { display: grid; grid-template-columns: max-content max-content; column-gap: 10px; padding-left: 8px; }
.goes-grid > span:nth-child(even) { text-align: right; font-variant-numeric: tabular-nums; }

/* Named point clouds in 3D MODELI (static/pointclouds.js) */
#clouds { margin-top: 8px; }
.cloud-head { margin: 8px 0 3px; font-size: 10px; color: var(--text-muted); }
.cloud-row { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; font-size: 11px; margin-bottom: 4px; }
.cloud-name { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 5px; overflow: hidden; }
.cloud-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-size { flex: 0 0 100%; color: var(--text-muted); font-size: 9px; }
.cloud-go { flex: 0 0 56px; padding: 1px 0; font-size: 10px; }
.cloud-hide { flex: 0 0 auto; padding: 1px 5px; font-size: 10px; }
.cloud-px { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 11px; margin-bottom: 5px; }
.cloud-px input { flex: 0 0 90px; }
.cloud-import { width: 100%; margin-top: 6px; }
.cloud-panel { margin-top: 6px; display: flex; flex-direction: column; gap: 5px; font-size: 11px; }
.cloud-field { display: flex; flex-direction: column; gap: 2px; color: var(--text-muted); }
.cloud-field input { width: 100%; box-sizing: border-box; }
.cloud-actions { display: flex; gap: 5px; }
.cloud-actions .btn { flex: 1 1 0; }
.cloud-status { margin-top: 5px; font-size: 10px; color: var(--text-muted); line-height: 1.35; }
.cloud-status.err { color: var(--danger, #e5534b); }

/* A project with no holes yet (2026-11-02): over the map, under every floating panel; renderEmptyProject in app.js. */
#empty-project { position: absolute; top: 16%; left: 50%; transform: translateX(-50%); z-index: 105; width: 440px;
                 max-width: calc(100% - 40px); box-sizing: border-box; padding: 20px 24px; background: var(--panel-float);
                 border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: 6px;
                 backdrop-filter: blur(4px); box-shadow: 0 2px 12px rgba(0,0,0,0.5); font-family: var(--font-ui); color: var(--text); }
#empty-project[hidden] { display: none; }
#empty-project h3 { font-size: 16px; font-weight: 600; margin: 0 0 8px; }
#empty-project p { font-size: 13px; line-height: 1.5; margin: 0 0 8px; }
#empty-project p.note { font-size: 12px; color: var(--text-muted); }
#empty-project .empty-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
#empty-project a.btn { text-decoration: none; display: inline-block; }
#empty-project .empty-close { position: absolute; top: 8px; right: 8px; }
.bh-empty { color: var(--text-muted); font-size: 12px; padding: 8px 4px; margin: 0; }
#ags-next a { color: var(--accent2); }
/* The help link, at the end of the project's row: the row above it is full. */
#project-strip .proj-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
#project-strip .proj { min-width: 0; overflow-wrap: anywhere; }
/* The panel's buttons stay in sight under a long report. */
#ags-body > .ags-actions:last-child { position: sticky; bottom: -10px; margin: 10px -10px -10px; padding: 8px 10px;
                                      background: var(--panel-float-2); border-top: 1px solid var(--border); }
