/* ── Reset / base ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
.hidden { display: none !important; }

:root {
    --bg:        #1a1a1e;
    --bg2:       #232328;
    --bg3:       #2c2c33;
    --border:    #3a3a44;
    --accent:    #4a9eff;
    --accent2:   #ff7b4a;
    --text:      #e0e0e8;
    --text-muted:#8888a0;
    /* Height/inset vars fold in safe-area insets (notch/home-indicator) so every
       consumer below (top/bottom offsets, stacked second-layer toolbars) stays
       correct without duplicating the env() math at each use site. */
    --toolbar-h: calc(44px + env(safe-area-inset-top, 0px));
    --timeline-h: calc(52px + env(safe-area-inset-bottom, 0px));
    --sidebar-w: 220px;
    --axis-x:   #ff4444;
    --axis-y:   #44dd44;
    --axis-z:   #4488ff;
}

/* ── Light mode ─────────────────────────────────────────────── */
/* Toggled via #btn-theme-toggle (app.js), persisted in localStorage. Every
   panel/button/toolbar already reads these custom properties, so this one
   block re-themes the whole app's chrome. The one thing NOT driven by CSS is
   the 2D plane drawing's <canvas> — hand-drawn pixels need their own palette,
   see PALETTE/_theme() in plane2d.js. The 3D point-cloud viewport's background
   isn't CSS either: it's Potree's radial gradient texture, swapped for a light
   copy in light mode (_applyTheme in app.js). */
body.light-mode {
    --bg:        #f4f4f6;
    --bg2:       #ffffff;
    --bg3:       #e9e9ec;
    --border:    #d5d5da;
    --accent:    #2f6fd6;
    --accent2:   #cc5a29;
    --text:      #1a1a1e;
    --text-muted:#5c5c68;
    --axis-x:    #c62828;
    --axis-y:    #2e7d32;
    --axis-z:    #1565c0;
}

html, body {
    width: 100%; height: 100%;
    background: var(--bg);
    color: var(--text);
    font-family: 'Segoe UI', system-ui, sans-serif;
    font-size: 13px;
    overflow: hidden;
}

/* ── Toolbar ────────────────────────────────────────────────── */
#toolbar {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--toolbar-h);
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: env(safe-area-inset-top, 0px) 12px 0;
    z-index: 100;
}

.toolbar-brand {
    font-weight: 600;
    font-size: 14px;
    color: var(--accent);
    white-space: nowrap;
    margin-right: 4px;
}

#session-select, #project-select {
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    max-width: 280px;
}
#session-select:focus, #project-select:focus { outline: 1px solid var(--accent); }
#project-select { max-width: 180px; }

#move-axis-select {
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 4px 6px;
    border-radius: 4px;
    font-size: 12px;
    cursor: pointer;
}
#move-axis-select:focus { outline: 1px solid var(--accent); }

.toolbar-sep {
    flex: 1;
}

.tool-btn {
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    white-space: nowrap;
    transition: background 0.15s, border-color 0.15s;
}
.btn-icon {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -2px;
}

.tool-btn:hover        { background: var(--bg); border-color: var(--accent); }
.tool-btn.active       { background: var(--accent); color: #fff; border-color: var(--accent); }
/* Visual "greyed out" is reserved for actually-disabled buttons (see below) —
   every other tool-btn is equally pressable and should look it, consistently. */
.tool-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.tool-btn:disabled:hover { background: var(--bg3); border-color: var(--border); }

/* ── Stacked toolbars ───────────────────────────────────────────────────
   Up to three single-row bars stack under #toolbar: #tools-toolbar (toggled),
   then #segment-toolbar or #plane2d-section (mode-dependent). Each --row-*
   is 0/1; --bars-bottom is where the viewport, sidebar and floating hints
   start, so every combination lines up without per-combination rules. */
body {
    --row-tools: 0;
    --row-seg:   0;
    --row-pick:  0;
    --bars-bottom: calc(var(--toolbar-h) * (1 + var(--row-tools) + var(--row-seg) + var(--row-pick)));
}
body.tools-open                 { --row-tools: 1; }
body.tools-open.plane2d-active  { --row-tools: 0; }
body.segment-active             { --row-seg: 1; }
body.plane2d-picking            { --row-pick: 1; }

/* ── Tools second-layer toolbar (Distance / Origin / Move Axis / Segment) ── */
#tools-toolbar {
    display: none;
    position: fixed;
    top: var(--toolbar-h);
    left: 0; right: 0;
    height: var(--toolbar-h);
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    z-index: 99;
}
body.tools-open #tools-toolbar { display: flex; }
body.plane2d-active #tools-toolbar,
body.plane2d-active #btn-tools-toggle { display: none; }
/* Toggle shows "open" separately from .active, which _deactivateTools() clears */
.tool-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

/* ── Segment second-layer toolbar (shown only in segment mode, same pattern
   as #plane2d-toolbar) ────────────────────────────────────────────────── */
#segment-toolbar {
    display: none;
    position: fixed;
    top: calc(var(--toolbar-h) * (1 + var(--row-tools)));
    left: 0; right: 0;
    height: var(--toolbar-h);
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    z-index: 99;
}
body.segment-active #segment-toolbar { display: flex; }

/* Segment sidebar section only makes sense while segment mode is active —
   same idea as #plane2d-section only showing during that mode. */
#segment-section { display: none; }
body.segment-active #segment-section { display: block; }

/* Distance / Set Origin / Move Axis operate on the 3D scene and don't apply
   once viewing the flattened 2D drawing. Segment (lasso) mode likewise
   doesn't apply there — Plane2D also force-exits it on open (see plane2d.js). */
body.plane2d-active #btn-distance,
body.plane2d-active #btn-set-origin,
body.plane2d-active #move-axis-select,
body.plane2d-active #btn-move-axis,
body.plane2d-active #btn-segment,
body.plane2d-active #segment-toolbar,
body.plane2d-active #segment-section {
    display: none;
}

/* ── Plane-fit second-layer toolbar (shown only while previewing a freshly
   picked plane, same second-layer-bar pattern as #segment-toolbar) ──────── */
#plane2d-section {
    position: fixed;
    top: calc(var(--toolbar-h) * (1 + var(--row-tools)));
    left: 0; right: 0;
    height: var(--toolbar-h);
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    z-index: 99;
}
#plane2d-fit-status { color: var(--text-muted); font-size: 12px; }
#plane2d-thickness-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    font-size: 12px;
    color: var(--text);
}
#plane2d-thickness { flex: none; width: 140px; }
#plane2d-thickness-value {
    width: 4.5em;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* ── Main layout ────────────────────────────────────────────── */
#main {
    position: fixed;
    top: var(--bars-bottom);
    left: 0;
    right: var(--sidebar-w);
    bottom: var(--timeline-h);
    background: #111;
}

/* ── Potree viewport ────────────────────────────────────────── */
#potree_render_area {
    position: absolute;
    inset: 0;
    /* Without this, the browser's own pinch-zoom/double-tap-zoom/pan gestures
       compete with Potree's own touch handling (OrbitControls already does
       1-finger orbit, 2-finger pinch-dolly, 3-finger pan) — the two fighting
       over the same gesture is what "not gesture compatible" looks like. */
    touch-action: none;
}
#potree_render_area canvas { display: block; }

/* Override Potree's internal GUI (we have our own) */
#potree_sidebar_container { display: none !important; }

/* ── Label layer (HTML POI labels overlay on canvas) ─────────── */
#label-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.poi-label {
    position: absolute;
    transform: translate(-50%, -100%);
    background: rgba(255, 123, 74, 0.9);
    color: #fff;
    padding: 2px 6px;
    border-radius: 3px;
    white-space: nowrap;
    pointer-events: none;
    border: 1px solid rgba(255,255,255,0.2);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
}
.lbl-name {
    font-size: 11px;
    font-weight: 600;
    line-height: 1.2;
}
.lbl-coords {
    font-size: 9px;
    font-family: 'Courier New', monospace;
    opacity: 0.88;
    letter-spacing: -0.02em;
    line-height: 1.2;
}
.poi-label::after {
    content: '';
    position: absolute;
    top: 100%; left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: rgba(255, 123, 74, 0.9);
}

/* ── Coordinate readout bar ─────────────────────────────────────
   Overlays the bottom edge of #main (whichever of the 3D viewport /
   2D drawing is currently showing) — moved out of the sidebar so that
   panel can stay focused on session content (Events/Segment/Notes/POIs).
   #main has position:fixed, which ALWAYS opens its own stacking context
   (unlike absolute/relative, fixed does this regardless of z-index) — so
   everything inside #main, including Potree's own internal DOM (its CSS
   uses z-index up to 10000, e.g. #potree_quick_buttons), is compared
   against #coord-bar within that one shared context. DOM order alone
   only wins between z-index:auto siblings; Potree's explicit high
   z-index descendants paint above that regardless of DOM order, which
   is why the bar was invisible over the 3D view — needs its own z-index
   higher than anything Potree uses to reliably win. */
#coord-bar {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 10001;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 6px 12px;
    background: rgba(17, 17, 20, 0.72);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-top: 1px solid var(--border);
    overflow-x: auto;
    white-space: nowrap;
}
.coord-group {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: none;
    font-family: 'Courier New', monospace;
    font-size: 11px;
    color: var(--text);
}
.coord-group-label {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-right: 1px;
}
.coord-group .axis {
    font-weight: 700;
    font-size: 10px;
}
.coord-group .axis.x { color: var(--axis-x); }
.coord-group .axis.y { color: var(--axis-y); }
.coord-group .axis.z { color: var(--axis-z); }
.coord-dist { color: var(--text-muted); }

/* ── Sidebar ────────────────────────────────────────────────── */
#sidebar {
    position: fixed;
    top: var(--bars-bottom);
    right: 0;
    width: var(--sidebar-w);
    bottom: var(--timeline-h);
    background: var(--bg2);
    border-left: 1px solid var(--border);
    overflow-y: auto;
    z-index: 50;
}

.sidebar-section {
    border-bottom: 1px solid var(--border);
    padding: 10px 12px;
}

.section-header {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* ── Buttons ────────────────────────────────────────────────── */
.small-btn {
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 3px 8px;
    border-radius: 3px;
    cursor: pointer;
    font-size: 11px;
    margin-top: 4px;
}
.small-btn:hover   { border-color: var(--accent); }
.small-btn.secondary { color: var(--text-muted); }
.small-btn.inline  { margin-top: 0; }

/* ── POI label (floating 3D overlay) ───────────────────────── */
.empty-hint {
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.5;
}

.poi-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
}
.poi-item:last-child { border-bottom: none; }
.poi-item:hover .poi-name { color: var(--accent); }

.poi-dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--accent2);
    flex-shrink: 0;
}
.poi-info { flex: 1; min-width: 0; }
.poi-name {
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.poi-time { font-size: 10px; color: var(--text-muted); }

/* Sidebar thumbnail for a POI/event that has a photo attached (annotations.js) —
   reserves its footprint via width/height + a background so it doesn't pop in
   once the authenticated fetch resolves (see Annotations.fetchImageBlobUrl). */
.poi-thumb {
    display: block;
    width: 72px;
    height: 48px;
    margin-top: 4px;
    border-radius: 4px;
    object-fit: cover;
    background: var(--bg3);
    border: 1px solid var(--border);
    cursor: pointer;
}

.poi-actions { display: flex; gap: 2px; flex-shrink: 0; }
.poi-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 12px;
    padding: 2px 4px;
    border-radius: 2px;
}
.poi-btn:hover { color: var(--text); background: var(--bg3); }
.poi-btn.del:hover { color: #ff4444; }

.event-item .poi-info { cursor: pointer; }
/* Hidden with its own eye icon — kept in the list so it can be shown again */
.event-item.event-hidden .poi-info,
.event-item.event-hidden .poi-dot { opacity: 0.4; }
.event-item.event-hidden [data-action="toggle-visibility"] { opacity: 0.5; text-decoration: line-through; }

.events-invalid summary {
    font-size: 11px;
    color: var(--text-muted);
    cursor: pointer;
    padding: 5px 0;
}
.events-invalid summary:hover { color: var(--text); }
.events-invalid .poi-item { cursor: default; }
.events-invalid .poi-time { font-style: italic; }

/* ── Timeline ───────────────────────────────────────────────── */
#timeline-bar {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: var(--timeline-h);
    background: var(--bg2);
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px env(safe-area-inset-bottom, 0px);
    z-index: 100;
}

.tl-label {
    font-size: 11px;
    color: var(--text-muted);
    font-family: monospace;
    min-width: 36px;
    white-space: nowrap;   /* wall-clock + elapsed labels must not wrap */
    flex-shrink: 0;
}

#tl-track {
    flex: 1;
    position: relative;
    height: 28px;
    display: flex;
    align-items: center;
}

#tl-slider {
    width: 100%;
    height: 4px;
    -webkit-appearance: none;
    appearance: none;
    background: var(--bg3);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    position: relative;
    z-index: 2;
}
#tl-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
    border: 2px solid #fff;
}

#tl-poi-canvas {
    position: absolute;
    left: 0; right: 0;
    top: 0; bottom: 0;
    width: 100%; height: 100%;
    pointer-events: none;
    z-index: 1;
}

#tl-time-current {
    font-size: 12px;
    font-family: monospace;
    color: var(--accent);
    min-width: 44px;
    white-space: nowrap;
    flex-shrink: 0;
}

/* ── Overlay message ────────────────────────────────────────── */
#overlay-msg {
    position: fixed;
    top: var(--bars-bottom);
    left: 0;
    right: var(--sidebar-w);
    bottom: var(--timeline-h);
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(20, 20, 24, 0.85);
    z-index: 200;
    pointer-events: none;
}
#overlay-msg.hidden { display: none; }

#overlay-content {
    text-align: center;
    padding: 32px 40px;
    background: var(--bg2);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.overlay-title {
    font-size: 20px;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: 8px;
}
.overlay-hint { color: var(--text-muted); font-size: 13px; }
#overlay-no-sessions {
    margin-top: 12px;
    color: var(--accent2);
    font-size: 12px;
    line-height: 1.6;
}
#overlay-no-sessions code {
    background: var(--bg3);
    padding: 2px 5px;
    border-radius: 3px;
    font-family: monospace;
}

/* ── Origin cursor hint ─────────────────────────────────────── */
#origin-cursor-hint {
    position: fixed;
    top: calc(var(--bars-bottom) + 10px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(74, 158, 255, 0.9);
    color: #fff;
    padding: 6px 14px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    z-index: 150;
    pointer-events: none;
}
#origin-cursor-hint.hidden { display: none; }

/* ── POI dialog / Settings panel / Annotation dialog (shared modal/overlay
   pattern) ─ */
#poi-dialog, #settings-dialog, #annotation-dialog {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0,0,0,0.6);
    z-index: 300;
}
#poi-dialog.hidden, #settings-dialog.hidden, #annotation-dialog.hidden { display: none; }

.dialog-box {
    background: var(--bg2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 20px 24px;
    width: min(280px, calc(100vw - 32px));
}
.dialog-title {
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 12px;
}
.dialog-box input[type=text] {
    width: 100%;
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 13px;
    margin-bottom: 12px;
}
.dialog-box input[type=text]:focus {
    outline: 1px solid var(--accent);
}
.dialog-buttons {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}
.dialog-buttons .small-btn { margin-top: 0; padding: 5px 14px; }

/* ── Settings panel (atn_mapping#33) ─────────────────────────────
   Wider than the POI name-entry dialog (it holds a scrollable event-type
   list, not a single input) and its title carries a close (X) button
   instead of the POI dialog's Cancel/OK pair — there's nothing here to
   confirm, just toggles that take effect immediately. */
.settings-box {
    width: min(420px, calc(100vw - 32px));
}
.settings-box .dialog-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.settings-section { margin-bottom: 18px; }
.settings-section:last-child { margin-bottom: 0; }
.settings-section-title {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    margin-bottom: 8px;
}
#settings-event-types {
    max-height: 240px;
    overflow-y: auto;
    /* keep the scrollbar off the last (opacity slider) column */
    scrollbar-gutter: stable;
    padding-right: 6px;
}
.settings-event-grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    color: var(--text);
}
.settings-event-grid th,
.settings-event-grid td {
    padding: 6px 4px;
    border-bottom: 1px solid var(--border);
    text-align: center;
}
.settings-event-grid tbody tr:last-child td { border-bottom: none; }
.settings-event-grid th {
    position: sticky;
    top: 0;
    background: var(--bg2);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
}
.settings-event-grid th:first-child,
.settings-event-grid .settings-event-type {
    text-align: left;
    overflow-wrap: anywhere;
}
.settings-event-grid th label {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}
.settings-event-grid input[type=checkbox] {
    accent-color: var(--accent);
    width: 14px;
    height: 14px;
    margin: 0;
    cursor: pointer;
}
.settings-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.settings-cell-empty { color: var(--text-muted); }
.settings-slider-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    font-size: 13px;
    color: var(--text);
}
.settings-slider-row label { flex-shrink: 0; }
.settings-slider-row span {
    flex-shrink: 0;
    width: 2.5em;
    text-align: right;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.settings-slider {
    flex: 1;
    height: 4px;
    -webkit-appearance: none;
    appearance: none;
    background: var(--bg3);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
}
.settings-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
    border: 2px solid #fff;
}

/* ── Event label (floating 3D overlay for operation events) ───── */
.event-label {
    position: absolute;
    transform: translate(-50%, -100%);
    background: var(--event-color, #999);
    color: #fff;
    padding: 2px 6px;
    border-radius: 3px;
    white-space: nowrap;
    pointer-events: none;
    border: 1px solid rgba(255,255,255,0.2);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
}
.event-label::after {
    content: '';
    position: absolute;
    top: 100%; left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: var(--event-color, #999);
}
.event-item .poi-time { font-style: italic; }

/* ── Notes body ─────────────────────────────────────────────── */
.notes-body {
    display: block;
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    font-size: 12px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg3);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 6px 8px;
    min-height: 70px;
    max-height: 200px;
    resize: vertical;
}
.notes-body:focus { outline: 1px solid var(--accent); }

/* ── Loading indicator ──────────────────────────────────────── */
#loading-bar {
    position: fixed;
    top: var(--bars-bottom);
    left: 0;
    height: 2px;
    background: var(--accent);
    transition: width 0.3s;
    z-index: 150;
    width: 0;
}

/* ── Segment tool ───────────────────────────────────────────────── */
#segment-canvas {
    cursor: crosshair;
    touch-action: none;
}

#segment-hint {
    position: fixed;
    top: calc(var(--bars-bottom) + 10px);
    left: 50%;
    transform: translateX(-50%);
    background: rgba(255, 123, 74, 0.92);
    color: #fff;
    padding: 6px 14px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    z-index: 160;
    pointer-events: none;
    white-space: nowrap;
    display: none;
}

/* ── 2D plane-slice drawing view ────────────────────────────── */
/* Replaces just the point-cloud viewport inside #main — toolbar, sidebar
   and timeline all stay visible/usable (path, event markers, timeline
   scrubbing, POI/Origin/Events tools all still apply). */
body.plane2d-active #potree_render_area,
body.plane2d-active #label-layer {
    display: none;
}

#plane2d-view {
    position: absolute;
    inset: 0;
    background: var(--bg);
    display: flex;
    flex-direction: column;
}
#plane2d-view.hidden { display: none; }

#plane2d-toolbar {
    height: var(--toolbar-h);
    flex-shrink: 0;
    background: var(--bg2);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
}
#plane2d-status {
    color: var(--text-muted);
    font-size: 12px;
    margin-left: 8px;
}

#plane2d-canvas {
    flex: 1;
    width: 100%;
    display: block;
    cursor: grab;
    touch-action: none;
}
#plane2d-canvas:active { cursor: grabbing; }

/* Image overlay panel (overlay2d.js) — floats over the 2D drawing's right
   edge, below its toolbar; the drawing stays interactive to its left. */
#overlay-panel {
    position: absolute;
    top: var(--toolbar-h);
    right: 0;
    bottom: 0;
    width: min(320px, 90vw);
    overflow-y: auto;
    background: var(--bg2);
    border-left: 1px solid var(--border);
    padding: 12px 14px;
    font-size: 12px;
    z-index: 5;
}
#overlay-panel.hidden { display: none; }
#overlay-panel .dialog-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
#overlay-panel label { display: inline-flex; align-items: center; gap: 4px; }
#overlay-panel input[type=number] { width: 52px; }
#overlay-panel input[type=range] { width: 120px; }
#overlay-panel select, #overlay-panel input[type=number] {
    background: var(--bg3);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 3px;
    font-size: 11px;
}
.overlay-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    margin-bottom: 8px;
}
.overlay-row-end { justify-content: flex-end; margin-bottom: 0; }
#overlay-base-controls.dimmed { opacity: 0.45; }
.small-btn.active { border-color: var(--accent); color: var(--accent); }
.overlay-muted { color: var(--text-muted); font-size: 11px; }
.overlay-hint { color: var(--accent); font-size: 11px; margin: 4px 0; }
.overlay-pair-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 1px 0;
}
.overlay-pair-row .overlay-res { flex: 1; color: var(--text-muted); text-align: right; }
.overlay-type {
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 8px;
    margin-bottom: 8px;
}
.overlay-type-title { font-weight: 600; margin-bottom: 6px; }
.overlay-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px 8px;
    margin-bottom: 6px;
}
#overlay-panel .overlay-grid label { min-width: 0; white-space: nowrap; }
#overlay-panel .overlay-grid select { flex: 1; min-width: 0; }
.overlay-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    padding: 3px 0;
    border-top: 1px solid var(--border);
}
.overlay-item .overlay-muted { flex: 1; }
#overlay-panel .overlay-grid .overlay-type-opacity { display: flex; align-items: center; gap: 6px; }
#overlay-panel .overlay-type-opacity input { flex: 1; min-width: 0; }
.overlay-flight {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 5px 0 2px;
    border-top: 1px solid var(--border);
    font-size: 0.9em;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#overlay-crop-dialog {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0,0,0,0.6);
    z-index: 300;
}
#overlay-crop-dialog.hidden { display: none; }
.overlay-crop-box { width: min(720px, calc(100vw - 32px)); }
#overlay-crop-canvas {
    width: 100%;
    height: min(60vh, 480px);
    display: block;
    background: var(--bg3);
    margin-bottom: 8px;
    touch-action: none;
}

/* Busy overlay during apply/reset */
#segment-busy {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
    z-index: 500;
}
#segment-busy-box {
    background: var(--bg2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 24px 32px;
    text-align: center;
    min-width: 240px;
}
#segment-busy-msg {
    font-size: 14px;
    color: var(--accent);
    margin-bottom: 8px;
}
#segment-busy-sub {
    font-size: 12px;
    color: var(--text-muted);
}

/* Subtract-mode button accent */
[data-seg-mode="subtract"].active {
    background: var(--accent2);
    border-color: var(--accent2);
    color: #fff;
}

/* ── Mobile / touch responsive ─────────────────────────────────────
   Two independent concerns:
   - narrow viewports (max-width) get an off-canvas sidebar drawer and
     narrower selects in the (horizontally scrolling) toolbars.
   - coarse pointers (touch, any viewport size) get bigger tap targets. */

.mobile-only { display: none; }

/* Toolbars scroll sideways instead of wrapping, at any width (a small desktop
   window overflows too) — wrapping would break every stacked-toolbar height
   assumption above (they all key off the constant --toolbar-h). Scrollbar
   hidden; touch/trackpad swipe, and app.js maps the mouse wheel to it. */
#toolbar, #tools-toolbar, #segment-toolbar, #plane2d-toolbar, #plane2d-section {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
}
#toolbar::-webkit-scrollbar,
#tools-toolbar::-webkit-scrollbar,
#segment-toolbar::-webkit-scrollbar,
#plane2d-toolbar::-webkit-scrollbar,
#plane2d-section::-webkit-scrollbar { display: none; }
/* Keep controls at full size and let the bar scroll, rather than squeezing them */
#toolbar > *, #tools-toolbar > *, #segment-toolbar > *, #plane2d-toolbar > *, #plane2d-section > * {
    flex-shrink: 0;
}

#sidebar-backdrop { display: none; }

@media (max-width: 860px) {
    .mobile-only { display: inline-flex; align-items: center; justify-content: center; }

    /* Sidebar becomes an off-canvas drawer instead of a permanent right rail */
    #sidebar {
        width: min(85vw, 320px);
        transform: translateX(100%);
        transition: transform 0.25s ease;
        box-shadow: -6px 0 16px rgba(0, 0, 0, 0.45);
        z-index: 220;
    }
    body.sidebar-open #sidebar { transform: translateX(0); }

    /* Viewport + "no session" overlay take the full width; the drawer floats over them */
    #main, #overlay-msg { right: 0; }

    body.sidebar-open #sidebar-backdrop {
        display: block;
        position: fixed;
        top: var(--bars-bottom);
        left: 0; right: 0;
        bottom: var(--timeline-h);
        background: rgba(0, 0, 0, 0.45);
        z-index: 210;
    }

    .sidebar-close-btn {
        display: flex;
        justify-content: flex-end;
        position: sticky;
        top: 0;
        width: 100%;
        padding: 10px 12px;
        background: var(--bg2);
        border: none;
        border-bottom: 1px solid var(--border);
        color: var(--text-muted);
        font-size: 16px;
        cursor: pointer;
    }

    #session-select { max-width: 150px; }
    #project-select { max-width: 110px; }
    .toolbar-sep { flex: 0 0 8px; }
}

@media (max-width: 480px) {
    .toolbar-brand { display: none; }
}

/* Comfortable tap areas on touch devices, independent of viewport width
   (a touch laptop at desktop width still benefits). */
@media (pointer: coarse) {
    .tool-btn  { padding: 9px 12px; font-size: 13px; }
    .small-btn { padding: 6px 10px; font-size: 12px; }
    .poi-btn   { padding: 6px 8px; font-size: 14px; }
    .poi-item  { padding: 8px 0; }
    #session-select, #project-select, #color-mode-select, #move-axis-select { padding: 7px 9px; }
    #tl-slider::-webkit-slider-thumb { width: 20px; height: 20px; }
}

/* "Done" button for closing a lasso on touch (see segment.js) — sits just
   below #segment-hint, mobile-only regardless of pointer type (a touch
   laptop still has Enter/dblclick available). */
#btn-segment-done {
    position: fixed;
    top: calc(var(--bars-bottom) + 46px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 160;
}

/* ── Annotations (photos on a POI/event marker) ───
   Dialog reuses .dialog-box.settings-box; these style its own sections. */

.poi-btn.has-annotations { color: var(--accent); }

.annotation-photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
    gap: 6px;
    margin-bottom: 8px;
}
.annotation-thumb {
    position: relative;
    aspect-ratio: 1;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid var(--border);
}
.annotation-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: zoom-in;
    display: block;
}
.annotation-thumb-del {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 18px;
    height: 18px;
    line-height: 16px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0,0,0,0.6);
    color: #fff;
    font-size: 13px;
    cursor: pointer;
}
.annotation-thumb-del:hover { background: #ff4444; }
.annotation-status { font-size: 11px; color: var(--text-muted); margin-left: 8px; }

#annotation-lightbox {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0,0,0,0.85);
    cursor: zoom-out;
}
#annotation-lightbox img {
    max-width: min(90vw, 1200px);
    max-height: 90vh;
    object-fit: contain;
    border-radius: 4px;
}

/* ── Login screen ───────────────────────────────────────────────────
   Deliberately its own bone-white/chrome palette rather than the app's
   dark --bg tokens — an android-OS boot-screen read, independent of
   light/dark mode (the rest of the UI is still loading behind it). */
#login-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        linear-gradient(rgba(234, 231, 221, 0.94), rgba(234, 231, 221, 0.94)),
        repeating-linear-gradient(0deg, rgba(20, 20, 18, 0.05) 0 1px, transparent 1px 28px),
        repeating-linear-gradient(90deg, rgba(20, 20, 18, 0.05) 0 1px, transparent 1px 28px);
    color: #1c1b17;
    font-family: 'Courier New', ui-monospace, monospace;
}
#login-overlay.hidden { display: none; }

#login-card {
    position: relative;
    width: min(360px, calc(100vw - 48px));
    padding: 36px 32px 28px;
    background: #eae7dd;
    border: 1px solid #1c1b17;
    box-shadow: 0 0 0 1px rgba(28, 27, 23, 0.15), 10px 10px 0 rgba(28, 27, 23, 0.9);
}
.login-busy #login-card { opacity: 0.6; }

/* Viewfinder corner brackets — the one overt "sci-fi menu" flourish */
.login-corner {
    position: absolute;
    width: 16px;
    height: 16px;
    border: 2px solid #1c1b17;
}
.login-corner.tl { top: -1px;    left: -1px;    border-right: none;  border-bottom: none; }
.login-corner.tr { top: -1px;    right: -1px;   border-left: none;   border-bottom: none; }
.login-corner.bl { bottom: -1px; left: -1px;    border-right: none;  border-top: none; }
.login-corner.br { bottom: -1px; right: -1px;   border-left: none;   border-top: none; }

.login-heading { margin-bottom: 24px; }
.login-title {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-align: center;
}
.login-rule {
    height: 1px;
    margin: 10px 0;
    background: linear-gradient(90deg, transparent, #1c1b17 15%, #1c1b17 85%, transparent);
}
.login-subtitle {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-align: center;
    color: #5a584e;
}

#login-form { display: flex; flex-direction: column; }

.login-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    margin: 14px 0 6px;
}
.login-label:first-of-type { margin-top: 0; }

#login-form input {
    background: #f6f4ec;
    border: 1px solid #1c1b17;
    color: #1c1b17;
    padding: 9px 10px;
    font: inherit;
    font-size: 13px;
    letter-spacing: 0.04em;
    border-radius: 0;
}
#login-form input:focus {
    outline: none;
    box-shadow: inset 0 0 0 1px #1c1b17, 0 0 0 3px rgba(28, 27, 23, 0.18);
}

#login-error {
    margin-top: 14px;
    padding: 8px 10px;
    border: 1px solid #8a2f1f;
    background: rgba(138, 47, 31, 0.08);
    color: #8a2f1f;
    font-size: 11px;
    letter-spacing: 0.04em;
}
#login-error.hidden { display: none; }

#login-submit {
    margin-top: 20px;
    padding: 10px;
    background: #1c1b17;
    border: 1px solid #1c1b17;
    color: #eae7dd;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.18em;
    cursor: pointer;
    transition: opacity 0.15s ease;
}
#login-submit:hover { opacity: 0.85; }
#login-submit:active { opacity: 0.7; }
#login-submit:disabled { opacity: 0.5; cursor: default; }

@media (max-width: 480px) {
    #login-card { padding: 28px 22px 22px; }
}

/* ── Project section (projects.js) — flights of the active project, each
   overlayable, with the solid color it gets in "By flight" mode ───────── */
.project-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    margin-bottom: 4px;
}
.project-toolbar-btns { display: flex; gap: 4px; flex-shrink: 0; }
.project-flight {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    border-bottom: 1px solid var(--border);
}
.project-flight:last-child { border-bottom: none; }
.project-swatch {
    width: 10px; height: 10px;
    border-radius: 2px;
    flex-shrink: 0;
}
.project-flight-name {
    flex: 1;
    min-width: 0;
    background: none;
    border: none;
    padding: 0;
    color: var(--text);
    font-size: 12px;
    line-height: 1.35;
    text-align: left;
    overflow-wrap: anywhere;   /* the meaningful part ("Reppischtal GPR 3-6") is at the end */
    cursor: pointer;
}
.project-flight-name:hover:not(:disabled) { color: var(--accent); }
.project-flight-name:disabled { cursor: default; }
.project-flight.primary .project-flight-name { font-weight: 600; }
.project-flight-status { font-size: 10px; color: var(--text-muted); }
.project-remove {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1;
    padding: 0 2px;
    cursor: pointer;
}
.project-remove:hover { color: var(--accent2); }
.project-add-row {
    display: flex;
    gap: 6px;
    margin-top: 6px;
}
.project-select-small {
    flex: 1;
    min-width: 0;
    background: var(--bg3);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 3px 6px;
    border-radius: 3px;
    font-size: 11px;
}
.project-note { margin-top: 6px; }

/* ── Align panel (align.js) — under the project's flight list ───────── */
.project-align {
    background: none;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--text-muted);
    font-size: 10px;
    padding: 1px 5px;
    cursor: pointer;
    white-space: nowrap;
}
.project-align:hover { border-color: var(--accent); color: var(--accent); }
#align-panel {
    margin-top: 8px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg3);
    font-size: 11px;
}
.align-title { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-bottom: 4px; }
.align-summary { font-family: monospace; font-size: 10px; color: var(--text); margin-bottom: 6px; line-height: 1.5; }
.align-group { margin-top: 8px; }
.align-label {
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--text-muted);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 4px;
}
.align-label .project-select-small { flex: 0 0 auto; text-transform: none; padding: 1px 4px; }
.align-group .small-btn, .align-actions .small-btn { margin: 0 2px 3px 0; }
.small-btn:disabled { opacity: 0.45; cursor: default; }
.small-btn:disabled:hover { border-color: var(--border); }
.align-nudge { display: flex; flex-wrap: wrap; }
.align-hint { margin-top: 4px; color: var(--accent); line-height: 1.4; }
.align-check { display: inline-flex; align-items: center; gap: 3px; color: var(--text-muted); }
.align-fit { margin-top: 4px; line-height: 1.4; color: var(--text); }
.align-fit.busy { color: var(--accent); }
.align-fit.warn, .align-fit.error { color: var(--accent2); }
.align-actions { margin-top: 10px; padding-top: 6px; border-top: 1px solid var(--border); }

/* Settings: marker opacity per event type (category). The dialog grows with
   the screen (it's shared .settings-box, so only #settings-dialog's) to give
   the event-type names and the slider room. */
#settings-dialog .settings-box { width: min(600px, calc(100vw - 32px)); }
.settings-event-grid .settings-opacity-cell { width: 30%; }
.settings-event-grid th.settings-opacity-head { white-space: normal; }
.settings-opacity { width: 100%; min-width: 44px; vertical-align: middle; margin: 0; }
@media (max-width: 480px) {
    #settings-dialog .settings-box { padding: 16px 14px; }
    .settings-event-grid th,
    .settings-event-grid td { padding: 5px 2px; }
}

/* ── Project view (projectview.js): all flights, no main flight ─────────── */
.project-only { display: none; }
body.project-view .project-only { display: block; }
/* Per-flight tools stay in the flights' own views */
body.project-view #segment-section,
body.project-view #poi-section,
body.project-view #btn-rename-session,
body.project-view #btn-set-origin,
body.project-view #move-axis-select,
body.project-view #btn-move-axis,
body.project-view #btn-segment { display: none; }

.project-view-row .project-view-icon {
    width: 13px;
    flex-shrink: 0;
    text-align: center;
    color: var(--accent);
}

/* Shared timeline: a band per flight under the (then transparent) slider track */
#tl-band-canvas {
    position: absolute;
    left: 0; right: 0;
    top: 0; bottom: 0;
    width: 100%; height: 100%;
    pointer-events: none;
    z-index: 0;
}
body.timeline-bands #tl-slider { background: transparent; }
.tl-flight-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    margin-right: 5px;
}

/* Operation events grouped by flight */
.event-flight-header {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 0 3px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.event-flight-header + .event-item { border-top: none; }

/* Notes: project (editable) + every flight's (read-only) */
.notes-subtitle {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    margin: 4px 0 4px;
}
#btn-save-notes + .notes-subtitle { margin-top: 12px; }
.notes-flight { margin-bottom: 8px; }
.notes-flight-head {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    margin-bottom: 2px;
}
.notes-flight-head:hover { color: var(--accent); }
.notes-flight-text {
    font-size: 12px;
    color: var(--text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    padding-left: 16px;
}
.notes-flight-text.empty { color: var(--text-muted); font-style: italic; }
