body { background: #0b1220; color: #cbd5e1;
       font-family: system-ui, "Segoe UI", sans-serif; margin: 0;
       height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
/* One-screen shell: topbar keeps its natural height; #page fills the rest. Inside
   a page, .explorer-shell stacks the map STAGE (hero, flexes) over the timeline
   DOCK (fixed height) so the whole workflow fits one viewport without scrolling. */
#page { flex: 1 1 auto; min-height: 0; display: flex; }
/* Explicit viewport height (topbar 54px + its 1px border = 55px) so the shell
   doesn't depend on Dash's wrapper divs (#react-entry-point + the layout root)
   propagating flex height — they're content-height blocks that break the chain. */
.explorer-shell { flex: 1 1 auto; width: 100%; height: calc(100vh - 55px);
                  min-height: 0; display: flex; flex-direction: column;
                  position: relative; }
.stage { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden;
         margin: 8px 8px 0; border: 1px solid #1e293b; border-radius: 8px; }
.dock { flex: 0 0 auto; background: #0f1827; border-top: 1px solid #1e293b;
        padding: 4px 10px 8px; display: flex; flex-direction: column;
        position: relative; }
/* Timeline chart height: defaults to 130px (its size before the drag feature);
   the drag handle sets --tl-h on the dock to grow/shrink just the chart. */
.tl-graph { min-height: 0; height: var(--tl-h, 130px); }
.tl-graph .js-plotly-plot, .tl-graph .plot-container { height: 100% !important; }
/* Drag handle across the top edge of the dock (see assets/resize.js). */
.dock-resizer { position: absolute; top: -4px; left: 0; right: 0; height: 9px;
                cursor: ns-resize; z-index: 30; }
.dock-resizer::after { content: ""; position: absolute; left: 50%; top: 4px;
                       width: 46px; height: 3px; transform: translateX(-50%);
                       background: #334155; border-radius: 2px;
                       transition: background .15s ease; }
.dock-resizer:hover::after { background: #5eead4; }
.dock-foot { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
/* Centre the primary CTA under the timeline and let it keep its full prominent
   size (the base .btn-estimate style) — it's the key action on the platform. */
.dock-foot .estimate-cta { margin: 0 auto; border: none; padding: 0; }
.dock-foot .aw-chip { margin-left: 0; }
.topbar { display:flex; align-items:center; gap:18px; height:54px;
          box-sizing:border-box; flex:0 0 auto;
          background:#0f1827; border-bottom:1px solid #1e293b; padding:10px 16px; }
.brand { color:#5eead4; font-weight:700; letter-spacing:.5px; }
/* Mobile hamburger for the tab row (hidden on desktop — see RESPONSIVE block). */
.topbar-burger { display:none; background:#1e293b; color:#5eead4; border:none;
                 border-radius:6px; width:36px; height:32px; font-size:17px;
                 cursor:pointer; flex:0 0 auto; }
/* Desktop default: the menu wrapper is layout-transparent, so the tab buttons
   sit in the topbar flex row exactly as before; mobile turns it into a dropdown. */
.topbar-menu { display:contents; }
.byline { color:#64748b; font-size:12px; font-weight:400; letter-spacing:.3px;
          margin-left:auto; text-decoration:none; transition:color .15s ease; }
.byline:hover { color:#5eead4; text-decoration:underline; }
.tabbtn { background:#1e293b; color:#94a3b8; border:none; border-radius:6px;
          padding:6px 14px; margin-right:6px; cursor:pointer; }
.tabbtn.active { background:#134e4a; color:#5eead4; font-weight:600; }
.panel { background:#0f1827; border:1px solid #1e293b; border-radius:8px;
         padding:12px; margin:8px; }
/* Floating info card over the map (was the left sidebar column). */
.float { position:absolute; z-index:500; background:#0f1827e8;
         border:1px solid #1e293b; border-radius:10px; backdrop-filter:blur(4px);
         box-shadow:0 6px 22px rgba(0,0,0,.45); }
.info-card { top:12px; left:12px; width:244px; padding:11px 12px;
             max-height:calc(100% - 24px); display:flex; flex-direction:column;
             overflow:visible; }
/* Dial down only the section titles (EVENTS TONIGHT / SUGGESTED MATCHES) and the
   big tile numbers inside this card; the tile labels and date stay as-is. */
.info-card .brand { font-size:12px; }
.info-card .stat-num { font-size:17px; }
/* Mobile collapse chevron pinned to the card's bottom-right corner (desktop
   hides it and always shows the body — see the RESPONSIVE block at the end). */
.card-toggle { position:absolute; right:6px; bottom:4px; background:transparent;
               border:none; color:#5eead4; font-size:16px; line-height:1;
               cursor:pointer; padding:2px 6px; }
/* Only the long list scrolls (one scrollbar); the date/stats (Explorer) and
   progress/export (Verification) stay pinned, so the card never grows its own
   second scrollbar or swallows the whole left edge. */
#exp-worklist { flex:0 1 auto; max-height:240px; overflow:auto; }
#ver-roster { flex:0 0 auto; max-height:240px; overflow:auto; }
/* Suggested-matches collapse: a click-to-toggle disclosure so the card can shrink
   when it's closed. */
.worklist-details > summary { cursor:pointer; list-style:none; outline:none;
  display:flex; align-items:center; gap:6px; margin-top:10px; }
.worklist-details > summary::-webkit-details-marker { display:none; }
.worklist-details > summary::before { content:"\25be"; color:#5eead4; font-size:11px; }
.worklist-details:not([open]) > summary::before { content:"\25b8"; }
.worklist-details > summary .who-count { color:#9da7b3; font-size:12px; font-weight:400; }
/* Right event viewer = a drawer that slides in OVER the map (it no longer steals a
   column, so the map keeps full width). Toggled via transform from the
   exp/ver-panel-open store (see toggle_panel / ver_toggle_panel). */
.review { position:absolute; top:0; right:0; bottom:0; width:360px; z-index:1200;
          display:flex; flex-direction:column; padding:12px; overflow:auto;
          background:#0f1827; border-left:1px solid #1e293b;
          box-shadow:-10px 0 30px rgba(0,0,0,.45);
          transform:translateX(100%); transition:transform .25s ease; }
#exp-media, #ver-review { flex:1 1 auto; }
.row { display:flex; align-items:stretch; }
.fill { flex:1; min-width:0; }

/* Date-picker popup must float above the Leaflet map, not be clipped behind it. */
.SingleDatePicker, .SingleDatePickerInput { background:transparent; }
.SingleDatePicker_picker { z-index:1200 !important; }
/* Dark-theme the date field + its calendar popup so it stops reading as a bright
   white box on the dark info card. */
.SingleDatePickerInput { border:1px solid #30363d !important; border-radius:6px;
                         background:#0d1117 !important; overflow:hidden; }
.DateInput { background:transparent !important; width:132px; }
.DateInput_input { font-size:14px; font-weight:600; padding:7px 9px; text-align:center;
                   background:#0d1117 !important; color:#e6edf3 !important;
                   border-bottom:2px solid transparent !important; }
/* ‹ date › stepper row: arrows hugging a centred, natural-width date field. */
.date-row { display:flex; align-items:stretch; justify-content:center; gap:4px; }
.date-nav { flex:0 0 auto; width:28px; background:#1e293b; color:#5eead4; border:none;
            border-radius:6px; cursor:pointer; font-size:18px; font-weight:700;
            line-height:1; }
.date-nav:hover { background:#334155; color:#99f6e4; }
.DateInput_input__focused { border-bottom-color:#5eead4 !important; }
.DayPicker, .CalendarMonthGrid, .CalendarMonth, .DayPicker_transitionContainer,
.DayPicker_weekHeader { background:#0f1827 !important; color:#cbd5e1 !important; }
.CalendarMonth_caption, .DayPicker_weekHeader, .DayPicker_weekHeader_li small {
  color:#e6edf3 !important; }
.CalendarDay__default { background:#0f1827 !important; color:#cbd5e1 !important;
                        border:1px solid #1e293b !important; }
.CalendarDay__default:hover { background:#1e293b !important; color:#fff !important; }
.CalendarDay__selected, .CalendarDay__selected:hover { background:#134e4a !important;
  color:#5eead4 !important; border-color:#5eead4 !important; }
.DayPickerNavigation_button__default { background:#0f1827 !important;
  border:1px solid #30363d !important; }

/* Timeline scope toggle (This night / All nights) under the date picker. */
.scope-toggle { font-size:13px; color:#94a3b8; margin-top:6px; }
.scope-toggle label { cursor:pointer; }
.scope-toggle input { vertical-align:middle; margin-right:3px; }

/* Right-panel empty state (panel open, nothing selected yet). */
.panel-empty { padding:18px 8px; color:#94a3b8; }
.panel-empty .pe-title { color:#cbd5e1; font-weight:700; font-size:15px;
                         margin-bottom:6px; }
.panel-empty .pe-body { font-size:13.5px; line-height:1.45; margin-bottom:14px; }
.panel-empty .pe-hints { border-top:1px solid #1e293b; padding-top:10px; }
.panel-empty .pe-hint { display:flex; align-items:center; gap:8px;
                        font-size:13px; margin:6px 0; }
.panel-empty .pe-glyph { display:inline-block; width:20px; text-align:center;
                         color:#5eead4; }

/* Timeline is fully clickable: signal it with a pointer cursor over the plot
   area and the marks, and a subtle brighten on the marks under the cursor. */
#exp-timeline .nsewdrag, #ver-timeline .nsewdrag,
#exp-timeline .bars path, #ver-timeline .bars path,
#exp-timeline .scatterlayer path, #ver-timeline .scatterlayer path,
#exp-timeline .points path, #ver-timeline .points path {
    cursor: pointer !important;
}
#exp-timeline .bars path:hover, #ver-timeline .bars path:hover,
#exp-timeline .points path:hover, #ver-timeline .points path:hover {
    opacity: 0.82;
}

/* Map markers/trails read as clickable too. */
.sens-ico, .jwedge-wrap, .pin-wrap, .leaflet-interactive { cursor: pointer; }

/* Verification keyboard triage: progress bar, key-hint chips, focused row. */
.prog-text { font-size:12.5px; color:#94a3b8; margin:2px 0 4px; }
.prog-bar { height:6px; background:#1e293b; border-radius:4px; overflow:hidden; }
.prog-fill { height:100%; background:#3fb950; transition:width .2s ease; }
.key-hints { display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.key-hint { display:inline-flex; align-items:center; gap:3px; font-size:11px;
            color:#94a3b8; }
.key-hint kbd { background:#1e293b; border:1px solid #334155; border-radius:4px;
                padding:0 5px; font-size:11px; color:#cbd5e1;
                font-family:ui-monospace, monospace; line-height:1.5; }
.jrow.jrow-focus { outline:2px solid #5eead4; outline-offset:1px;
                   border-radius:8px; }

/* Map: basemap switcher + audio. */
.leaflet-tooltip { font-size:13px; padding:2px 7px; font-weight:700;
                   pointer-events:none; }
.leaflet-control-layers { font-size:12px; color:#1f2937; }
/* Dark-theme the Leaflet zoom +/- buttons to match the panel chrome. */
.leaflet-bar { border:1px solid #1e293b !important; box-shadow:0 1px 6px rgba(0,0,0,.5); }
.leaflet-bar a, .leaflet-control-zoom a { background:#0f1827; color:#cbd5e1;
  border-bottom:1px solid #1e293b; }
.leaflet-bar a:hover, .leaflet-control-zoom a:hover { background:#1e293b; color:#5eead4; }
audio { width:100%; display:block; margin-top:6px; }

/* Sensor markers: camera / microphone glyphs. The shape tells cameras from
   mics; STATE drives only the color — grey when idle, filled (white) when an
   event is active, accent + glow while triangulating. */
.pin-wrap, .sens-wrap { background:transparent; border:none; }
/* Glyph colour is set inline per state from config.py (SENSOR_IDLE/ACTIVE/TRI);
   fill:currentColor makes the SVG follow it. No glow. */
.sens-ico { position:relative; width:22px; height:22px; cursor:pointer;
            display:flex; align-items:center; justify-content:center;
            line-height:0; transition:color .15s ease; }
.sens-ico svg { display:block; }
.sens-ico svg path { fill:currentColor; }
/* "How many individuals" badge on an active sensor icon. */
.sens-badge { position:absolute; top:-6px; right:-6px; min-width:15px; height:15px;
              padding:0 3px; border-radius:8px; background:#5eead4; color:#06281f;
              font:700 10px/15px system-ui, sans-serif; text-align:center;
              box-shadow:0 1px 2px rgba(0,0,0,.5); }
/* Fusion pie marker: wedges = contributing sensor colors. */
.fpie { width:16px; height:16px; border-radius:50%;
        border:2px solid #0b1220; box-shadow:0 1px 3px rgba(0,0,0,.45); cursor:pointer; }

/* In-map layers control (collapsible, like the basemap switcher). Collapsed to
   a small button; expands to the checklist on hover. */
.map-wrap { position:absolute; inset:0; }
.map-layers { position:absolute; z-index:1000; top:78px; right:10px;
              background:#0f1827ee; border:1px solid #1e293b; border-radius:6px;
              color:#cbd5e1; box-shadow:0 1px 6px rgba(0,0,0,.5);
              overflow:hidden; max-width:34px; max-height:34px;
              transition:max-width .18s ease, max-height .18s ease; }
.map-layers:hover, .map-layers:focus-within { max-width:340px; max-height:320px; }
/* Layers + Basemap shown as two lists side by side inside the one control. */
.map-layers .ml-cols { display:flex; gap:20px; }
.map-layers .ml-col { min-width:118px; }
.map-layers .ml-head { display:flex; align-items:center; gap:6px; height:34px;
                       padding:0 8px; font-size:18px; white-space:nowrap;
                       user-select:none; }
.map-layers .ml-head .ml-title { font-size:11px; font-weight:700; letter-spacing:.5px;
                                 color:#5eead4; }
.map-layers .ml-body { padding:2px 10px 8px 10px; font-size:12px; white-space:nowrap; }
.map-layers .ml-basemap-note { font-size:11.5px; color:#94a3b8; white-space:normal;
                               max-width:170px; line-height:1.35; }

/* Combined legend popover: floats top-LEFT of the map (the layers/basemap control
   stays top-right) so there is one legend surface and one layers surface. */
/* The info card owns the full LEFT edge; layers/basemap top-right; the Leaflet
   zoom control and the legend stack at the bottom-right (above the attribution),
   so nothing overlaps the card. */
/* Legend sits in the bottom-RIGHT corner (covering the tile attribution, which we
   hide); it expands UPWARD (bottom-anchored, column-reverse) so it never runs off
   the map. Zoom is centred along the bottom; the panel handle is lifted to the
   right-middle so the corner icons don't crowd each other. */
.legend-pop { left:auto; right:6px; top:auto; bottom:6px;
              display:flex; flex-direction:column-reverse; }
.map-wrap .leaflet-control-attribution { display:none; }
/* Leaflet zoom control: centre it along the bottom edge and lay the +/- buttons
   out horizontally (side by side) instead of stacked. */
.map-wrap .leaflet-top.leaflet-left { top:auto; bottom:10px; left:50%; right:auto;
                                      transform:translateX(-50%); }
.map-wrap .leaflet-control-zoom { display:flex; }
.map-wrap .leaflet-control-zoom a { border-bottom:none !important; }
.map-wrap .leaflet-control-zoom-in { border-radius:6px 0 0 6px !important; }
.map-wrap .leaflet-control-zoom-out { border-radius:0 6px 6px 0 !important;
                                      border-left:1px solid #1e293b; }
.legend-pop:hover, .legend-pop:focus-within { max-width:240px; max-height:320px;
                                              overflow-y:auto; }

/* Right-panel slide handle: a tab on the right edge that pulls the panel in
   (‹) and pushes it back out (›). Replaces the toggle near the Play button. */
.panel-handle { position:absolute; top:50%; bottom:auto; right:0; transform:translateY(-50%);
                z-index:1300; width:22px; height:54px; border:none; cursor:pointer;
                background:#134e4a; color:#5eead4; font-size:16px; font-weight:700;
                border-radius:6px 0 0 6px; box-shadow:-1px 0 5px rgba(0,0,0,.4); }
.panel-handle:hover { background:#155e57; }

.label { font-size:12px; letter-spacing:.6px; color:#64748b; text-transform:uppercase; }
.panel-x { background:#1e293b; color:#cbd5e1; border:none; border-radius:6px;
           width:26px; height:26px; font-size:14px; cursor:pointer; }
.panel-x:hover { background:#334155; }
.btn-ok { background:#10b981; color:#06281f; border:none; border-radius:6px;
          padding:6px 14px; font-weight:600; cursor:pointer; }
.btn-no { background:#7f1d1d; color:#fecaca; border:none; border-radius:6px;
          padding:6px 14px; cursor:pointer; }
.badge { background:#ef4444; color:#fff; border-radius:10px; padding:1px 8px; font-size:11px; }
.badge.warn { background:#f59e0b; color:#1f2937; }
.roster-item { background:#0f1827; border:1px solid #1e293b; border-radius:6px;
               padding:7px 9px; margin:4px 0; display:flex; justify-content:space-between;
               align-items:center; gap:8px; cursor:pointer; font-size:14px; }
.count-chip { background:#134e4a; color:#5eead4; border-radius:10px; padding:2px 9px;
              font-size:12.5px; white-space:nowrap; flex:0 0 auto; }
.roster-item.sel { outline:1px solid #5eead4; }
.statcard { background:#0f1827; border:1px solid #1e293b; border-radius:6px;
            padding:8px; margin:6px 0; }
.statcard b { font-size:20px; color:#e2e8f0; }
/* Event-count summary (left sidebar) */
.stat-row { display:flex; gap:8px; margin-top:6px; }
.stat-cell { flex:1; background:#0f1827; border:1px solid #1e293b; border-radius:8px;
             padding:9px 6px; text-align:center; }
.stat-cell.total { background:#0c2823; border-color:#155e57; }
.stat-num { font-size:22px; font-weight:700; color:#e2e8f0; line-height:1.1; }
.stat-cell.total .stat-num { color:#5eead4; }
.stat-lbl { font-size:11.5px; color:#9da7b3; margin-top:2px; }

/* Timeline controls: a toolbar (Play + zoom presets + speed) above a range
   slider that is aligned to the chart's time axis below it. */
.timeline-controls { margin:2px 0 0 0; }
/* Three-zone transport bar: equal-flex sides keep the centre column (Play) truly
   centred under the map no matter how wide the Zoom / Speed groups are. */
.tl-toolbar { display:flex; align-items:center; margin:0 10px 2px 12px; }
.tl-zone { display:flex; align-items:center; gap:6px; }
.tl-zone-left { flex:1 1 0; justify-content:flex-start; }
.tl-zone-center { flex:0 0 auto; justify-content:center; }
.tl-zone-right { flex:1 1 0; justify-content:flex-end; }
/* Play = the primary action: filled teal, a touch larger than the side controls. */
.tl-play { background:#14b8a6; color:#04211e; border:none; border-radius:8px;
           padding:7px 22px; font-size:14px; font-weight:700; cursor:pointer; }
.tl-play:hover { background:#2dd4bf; }
.zoombtn { background:#1e293b; color:#94a3b8; border:none; border-radius:6px;
           padding:3px 10px; font-size:12px; cursor:pointer; }
.zoombtn:hover { background:#334155; color:#cbd5e1; }
/* Mobile zoom-preset burger (hidden on desktop; the menu wrapper is
   layout-transparent so the desktop row is unchanged — see RESPONSIVE block). */
.zoom-burger { display:none; background:#1e293b; color:#94a3b8; border:none;
               border-radius:6px; width:32px; height:28px; font-size:14px;
               cursor:pointer; }
.zoom-menu { display:contents; }
/* Align the slider track with the chart plot area (chart margins l=92, r=10);
   top margin leaves room for the always-on HH:MM handle tooltips. */
.view-slider { margin:4px 10px 0 92px; }
.view-slider .rc-slider-rail { background:#1e293b; }
.view-slider .rc-slider-track { background:#5eead4; }
.view-slider .rc-slider-handle { border-color:#5eead4; background:#0f1827; opacity:1; }
.view-slider .rc-slider-dot { border-color:#334155; background:#0f1827; }
.view-slider .rc-slider-mark-text { color:#94a3b8; font-size:11px; }
/* Quiet ruler: hide the intermediate hour marks (the chart's own axis is the
   detailed ruler for the zoom window); keep the 00:00 / 24:00 ends. Dragging a
   handle reveals them all (.sliding via assets/slider_marks.js). */
.view-slider .rc-slider-mark-text { display:none; }
.view-slider .rc-slider-mark-text:first-child,
.view-slider .rc-slider-mark-text:last-child { display:block; }
.view-slider.sliding .rc-slider-mark-text { display:block; }
.view-slider .rc-slider-tooltip-inner { background:#134e4a; color:#5eead4; }

/* Timeline legend strip under the timeline. */
.timeline-legend { display:flex; flex-wrap:wrap; align-items:center; gap:14px;
                   margin-top:6px; border-top:1px solid #1e293b; padding-top:6px; }
.timeline-legend > div { margin:0 !important; }

/* Jackal "facing the camera" wedge: a teardrop pointing up (0deg = north),
   rotated toward the camera; coloured by the jackal's own colour (--jc). */
.jwedge-wrap { background: none; border: none; }
.jwedge {
  width: 0; height: 0;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-bottom: 14px solid var(--jc);
  transform-origin: 50% 70%;
  filter: drop-shadow(0 0 1px #fff);
}

/* Tabbed event viewer */
.tab-strip { display:flex; gap:6px; margin:10px 0 14px; flex-wrap:wrap; }
.viewer-body video, .viewer-body audio, .viewer-body img { margin-bottom:4px; }
.tab { background:#0f1827; color:#cbd5e1; border:1px solid #1e293b; border-radius:6px;
       padding:4px 10px; cursor:pointer; font-size:13px; }
.tab.active { background:#1e293b; color:#5eead4; border-color:#5eead4; }
.mini-profile { display:flex; align-items:center; gap:10px; margin:6px 0 10px;
                padding:8px; background:#0f1827; border:1px solid #1e293b; border-radius:8px; }

/* --- Per-jackal event viewer (Option E) --- */
.evsum{background:#0d1117;border:1px solid #30363d;border-radius:6px;
  padding:9px 11px;margin-bottom:8px;line-height:1.5}
.evsum-t{font-size:13px}.evsum-t b{color:#fff}
.evsum-s{font-size:12px;color:#9da7b3;margin-top:3px}
.evmedia{margin-bottom:8px}
.who-here>summary{cursor:pointer;font-size:13px;padding:7px 0;color:#e6edf3;list-style:none}
.who-here>summary::-webkit-details-marker{display:none}
.who-here>summary .who-count{color:#9da7b3;font-size:12px}
.jrow-summary{font-size:12px;color:#c9d1d9;border-left:3px solid #1f6feb;
  background:#0d1117;border-radius:5px;padding:7px 9px;margin:6px 0 8px}
.jrow{background:#0d1117;border:1px solid #30363d;border-radius:8px;
  padding:11px 12px;margin-bottom:7px}
.jrow-top{display:flex;gap:11px;align-items:flex-start}
.jrow-photo{width:52px;height:52px;border-radius:7px;background:#21262d;flex:none}
/* Real profile thumbnails reuse the placeholder slots; keep them cropped square. */
img.jrow-photo, img.pf-photo { object-fit:cover; }
.jrow-info b{color:#fff;font-size:14px}
.jrow-meta{margin-top:4px;display:flex;gap:6px;flex-wrap:wrap}
.pill{font-size:11px;padding:1px 7px;border-radius:10px;border:1px solid #30363d;
  color:#9da7b3;white-space:nowrap}
.pill.ai{color:#d2a8ff;border-color:#3c2e58;background:#1d1530}
.pill.collar{color:#58a6ff;border-color:#1c3a5e;background:#0f2438}
.pill.ok{color:#3fb950;border-color:#234d2c;background:#10261a}
.pill.edit{color:#e3b341;border-color:#4d3c12;background:#2b2310}
.pill.rej{color:#f85149;border-color:#5e2326;background:#2b1213}
.jrow-acts{display:flex;align-items:center;margin-top:11px;gap:7px}
.jrow-link{font-size:12px;color:#58a6ff;cursor:pointer}
.jrow-spacer{margin-left:auto}
.jrow-changed{margin-top:9px;font-size:12px;color:#e3b341}
.jrow-changed .jrow-why{color:#9da7b3;font-style:italic;margin-top:2px}
.jrow-edit{margin-top:11px;border-top:1px solid #21262d;padding-top:10px}
.jrow-edit label{font-size:11.5px;color:#9da7b3;display:block;margin:6px 0 3px}
.jrow-edit input{width:100%;background:#161b22;border:1px solid #30363d;color:#e6edf3;
  border-radius:5px;padding:6px;font-size:12px}
.btn-approve{background:#238636;color:#fff;border:none;border-radius:6px;
  padding:6px 11px;font-size:12px;cursor:pointer}
.btn-edit{background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:6px;
  padding:6px 11px;font-size:12px;cursor:pointer}
.btn-undo{background:transparent;color:#9da7b3;border:1px solid #30363d;
  border-radius:6px;padding:5px 9px;font-size:12px;cursor:pointer}
.btn-cancel{background:transparent;color:#9da7b3;border:1px solid #30363d;
  border-radius:6px;padding:6px 10px;font-size:12px;margin-left:6px;cursor:pointer}
.media-gallery{display:flex;flex-direction:column;gap:10px}
.gallery-tile{background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:7px}

/* --- Timeline legend row + the activity-window chip beside it --- */
.legend-row{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap}
.legend-row .timeline-legend{flex:1 1 auto}
.aw-chip{display:flex;align-items:center;gap:6px;background:#0b1320;
  border:1px solid #24344a;border-radius:8px;padding:5px 9px;margin-left:auto;
  white-space:nowrap}
.aw-chip label{font-size:11.5px;color:#cbd5e1}
.aw-chip .aw-input{width:50px;background:#0f1827;border:1px solid #30363d;color:#fff;
  border-radius:5px;padding:3px 5px;font-size:13px;text-align:center}
.aw-chip span{font-size:11.5px;color:#9da7b3}
.aw-help{width:15px;height:15px;border-radius:50%;border:1px solid #3b4a61;
  color:#7c8aa0 !important;font-size:10px;display:inline-flex;align-items:center;
  justify-content:center;cursor:help}

/* --- Population-estimate trigger + modal (de-duplication funnel) --- */
.estimate-cta{display:flex;justify-content:center;margin-top:12px;
  border-top:1px solid #1e293b;padding-top:13px}
.btn-estimate{background:#14b8a6;color:#04211e;border:none;border-radius:9px;
  padding:11px 26px;font-size:15px;font-weight:700;cursor:pointer}
.btn-estimate:hover{background:#2dd4bf}
.modal-overlay{position:fixed;inset:0;background:rgba(1,4,9,.66);z-index:1000;
  display:flex;align-items:center;justify-content:center;padding:20px}
.modal-card{background:#161b22;border:1px solid #30363d;border-radius:14px;padding:26px;
  color:#e6edf3;width:600px;max-width:94vw;max-height:92vh;overflow:auto;
  box-shadow:0 14px 44px rgba(0,0,0,.55)}
.modal-head{display:flex;align-items:flex-start;justify-content:space-between}
.modal-title{font-size:24px;font-weight:700;margin-bottom:18px}
.modal-decide{display:flex;align-items:center;margin-top:20px;gap:12px;
  border-top:1px solid #21262d;padding-top:18px}
.modal-decide label{font-size:17px}
.estimate-num{width:96px;background:#0d1117;border:1px solid #30363d;color:#fff;
  font-size:26px;text-align:center;border-radius:8px;padding:9px}
.modal-decide .btn-ok{font-size:16px;padding:10px 20px}
.modal-msg{font-size:15px;color:#3fb950;margin-top:12px;min-height:18px}
.fn-raw{background:#0d1117;border:1px solid #30363d;border-radius:9px;
  padding:15px 17px;margin-bottom:8px}
.fn-raw-big{font-size:20px}.fn-raw-big b{color:#fff}
.fn-raw-note{font-size:14px;color:#8b949e;margin-top:5px}
.fn-step{position:relative;padding:13px 14px 13px 36px;border-left:2px dashed #30363d;
  margin-left:16px}
.fn-step::before{content:"";position:absolute;left:-9px;top:18px;width:15px;height:15px;
  border-radius:50%;background:#21262d;border:2px solid #e3b341}
.fn-lead{font-size:16px}.fn-lead b{color:#fff;font-size:18px}
.fn-det{font-size:14px;color:#9da7b3;margin-top:4px;line-height:1.45}
.fn-chips{display:flex;gap:7px;flex-wrap:wrap;margin-top:8px}
.fn-chip{font-size:13px;padding:3px 10px;border-radius:11px;border:1px solid #3c2e58;
  color:#d2a8ff;background:#1d1530}
.fn-chip.b{border-color:#1c3a5e;color:#58a6ff;background:#0f2438}
.fn-land{background:#0d1117;border:1px solid #234d2c;border-radius:9px;
  padding:16px 17px;margin-top:10px}
.fn-n{font-size:34px;font-weight:800;color:#3fb950}
.fn-lbl{font-size:16px;color:#cbd5e1}

/* --- Jackal profile (tabbed, single-column) --- */
.pf-head{display:flex;gap:12px;align-items:flex-start;margin-bottom:8px}
.pf-photo{width:64px;height:64px;border-radius:10px;background:#21262d;border:2px solid #8b8b8b;
  flex:none;display:flex;align-items:center;justify-content:center;font-size:24px}
.pf-name{font-size:19px;font-weight:800;color:#fff}
.pf-class{font-size:12px;color:#e3b341;margin-top:2px}
.pf-sig{display:flex;gap:6px;margin-top:7px;flex-wrap:wrap}
.sig-chip{font-size:11.5px;padding:2px 8px;border-radius:10px;border:1px solid #1c3a5e;
  color:#58a6ff;background:#0f2438}
.sig-chip.mut{opacity:.45;border-color:#30363d;color:#9da7b3;background:transparent}
.pf-tabs{display:flex;gap:4px;border-bottom:1px solid #30363d;margin-bottom:10px}
.pf-tab{font-size:13px;padding:8px 10px;color:#9da7b3;border-bottom:2px solid transparent;cursor:pointer}
.pf-tab.on{color:#5eead4;border-bottom-color:#5eead4}
.pf-badge{font-size:10.5px;background:#21262d;border-radius:9px;padding:0 6px;margin-left:5px;color:#cbd5e1}
.pf-kv{display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px solid #1b2230;font-size:13px}
.pf-kv span:first-child{color:#9da7b3}
.pf-media{display:flex;flex-direction:column;gap:9px}
.pf-tile{background:#0d1117;border:1px solid #30363d;border-radius:7px;padding:8px}
.pf-cap{font-size:11.5px;color:#9da7b3;margin-bottom:6px}
.pf-empty{text-align:center;color:#6e7681;padding:22px 10px;font-size:13px}
.pf-filter{display:flex;align-items:center;gap:6px;margin-bottom:10px;font-size:12.5px;color:#9da7b3;flex-wrap:wrap}
.pf-count{margin-left:auto;color:#5eead4}
.merge-banner{background:#11203a;border:1px solid #1c3a5e;border-radius:8px;padding:10px 12px;
  margin-bottom:10px;font-size:13px}
.merge-banner b{color:#fff}
.merge-acts{display:flex;gap:7px;align-items:center;margin-top:8px;flex-wrap:wrap}
.mbtn-y{background:#238636;color:#fff;border:none;border-radius:6px;padding:5px 11px;font-size:12px;cursor:pointer}
.mbtn-n{background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:6px;padding:5px 11px;font-size:12px;cursor:pointer}
.mbtn-q{background:transparent;color:#9da7b3;border:1px solid #30363d;border-radius:6px;padding:5px 11px;font-size:12px;cursor:pointer}
.mbtn-compare{color:#58a6ff;font-size:12px;cursor:pointer;margin-left:auto}

/* --- One-screen layout: quality floor --- */
@media (prefers-reduced-motion: reduce){ .review { transition:none; } }
.panel-handle:focus-visible, .zoombtn:focus-visible, .tabbtn:focus-visible,
.btn-ok:focus-visible, .btn-estimate:focus-visible, .tl-play:focus-visible {
  outline:2px solid #5eead4; outline-offset:2px; }

/* --- Admin panel --- */
/* The app body is height:100vh; overflow:hidden (one-screen layout), so the admin
   page must be its OWN scroll container or its lower sections get clipped. */
.admin-shell{padding:18px 22px;width:100%;max-width:1100px;margin:0 auto;
  height:calc(100vh - 54px);overflow-y:auto;box-sizing:border-box;color:#cbd5e1}
.admin-gate{max-width:380px;margin:60px auto;background:#0f1827;border:1px solid #1e293b;
  border-radius:10px;padding:24px;text-align:center}
.admin-gate h2{margin:0 0 8px;color:#fff}
.admin-hint{font-size:12.5px;color:#64748b;margin:6px 0}
.admin-input{background:#0d1117;border:1px solid #30363d;border-radius:6px;color:#e6edf3;
  padding:6px 9px;font-size:13px}
.admin-gate .admin-input{display:block;width:100%;margin:10px 0;box-sizing:border-box}
.admin-msg{min-height:18px;font-size:12.5px;color:#5eead4;margin:6px 0}
.admin-section-title{margin:4px 0 4px;color:#fff;font-size:18px}
/* Sub-tab bar — one focused section at a time */
.admin-subtabs{display:flex;gap:6px;margin-bottom:16px;border-bottom:1px solid #1e293b;
  padding-bottom:0}
.admin-subtab{background:transparent;color:#9da7b3;border:none;border-bottom:2px solid transparent;
  padding:8px 14px;font-size:14px;cursor:pointer;margin-bottom:-1px}
.admin-subtab:hover{color:#e6edf3}
.admin-subtab.active{color:#5eead4;border-bottom-color:#5eead4;font-weight:600}
/* Rules grouped into cards (grid, low cognitive load) */
.admin-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:14px;margin-top:8px}
.admin-card{background:#0f1827;border:1px solid #1e293b;border-radius:10px;padding:14px 16px}
.admin-group{margin:0 0 10px;color:#9da7b3;font-size:11.5px;text-transform:uppercase;
  letter-spacing:.05em}
.admin-rule-row{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
  padding:9px 0;font-size:13px;border-top:1px solid #161f2e}
.admin-rule-row:first-of-type{border-top:none}
.admin-rule-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.admin-rule-label{color:#e6edf3}
.admin-rule-help{font-size:11.5px;color:#6e7681;line-height:1.35}
.admin-rule-ctl{display:flex;align-items:center;gap:6px;flex:0 0 auto;padding-top:1px}
.admin-num{background:#0d1117;border:1px solid #30363d;border-radius:6px;color:#e6edf3;
  padding:5px 8px;font-size:13px;width:96px}
.admin-reset{background:#21262d;color:#e6edf3;border:1px solid #30363d;border-radius:6px;
  padding:4px 10px;font-size:12px;cursor:pointer}
.admin-readonly-tag{font-size:11px;color:#6e7681;font-style:italic}
.admin-sensor-grid{display:grid;grid-template-columns:300px 1fr;gap:18px;align-items:start}
.admin-sensor-form label{display:block;margin:8px 0 3px;font-size:12px;color:#9da7b3}
.admin-sensor-form .admin-input,.admin-sensor-form .admin-num{width:100%;box-sizing:border-box}
.admin-dd{color:#0d1117}
.admin-btn-row{display:flex;gap:8px;margin-top:12px}
.btn-bad{background:#3d1418;color:#ffb4ba;border:1px solid #5e1c22;border-radius:6px;
  padding:6px 12px;font-size:13px;cursor:pointer}
.admin-map-wrap{height:420px;border-radius:8px;overflow:hidden}
/* Jackals table: tighter, fixed columns; collar centered; no per-row save */
.admin-jk-toolbar{display:flex;align-items:center;gap:10px;margin:6px 0 12px}
.admin-jk-toolbar .admin-msg{margin:0}
.admin-jk-table{display:flex;flex-direction:column;gap:2px;max-height:560px;overflow-y:auto}
.admin-jk-row{display:grid;grid-template-columns:58px 150px 132px 64px 150px;gap:10px;
  align-items:center;padding:1px 0}
.admin-jk-head{font-size:11px;color:#64748b;text-transform:uppercase;letter-spacing:.04em;
  padding-bottom:4px}
.admin-jk-row .admin-input{width:100%;box-sizing:border-box}
.jk-id{color:#9da7b3;font-size:12px}
.jk-collar{display:flex;justify-content:center;align-items:center;text-align:center}
.jk-collar label{margin:0}
.jk-color-cell{display:flex;align-items:center;gap:6px}
.jk-swatch{width:20px;height:20px;border-radius:4px;border:1px solid #30363d;flex:0 0 auto}
.jk-hex{flex:1 1 auto;min-width:0}
/* Edited (unsaved) cell highlight */
.dirty, .dirty input{border-color:#d8a657 !important;background:#2a210f !important;
  color:#f7e6c4 !important}
.jk-collar.dirty{background:#2a210f;border-radius:6px}

/* ============================= RESPONSIVE ============================= */
/* Mobile-only layout (<=768px). Desktop (>=769px) keeps today's layout: the
   burgers/chevron stay hidden (their base styles) and the topbar/zoom menu
   wrappers stay display:contents, so nothing above this block changes. */
@media (min-width: 769px){
  .card-toggle { display:none; }
}
@media (max-width: 768px){
  /* Topbar: burger left, brand next, byline pinned right. Tabs become a
     dropdown under the bar. */
  .topbar { gap:10px; padding:10px 10px; }
  .topbar-burger { display:inline-flex; align-items:center; justify-content:center; }
  .topbar-menu { display:none; position:absolute; top:54px; left:0; z-index:2000;
                 flex-direction:column; align-items:stretch; gap:2px;
                 background:#0f1827; border:1px solid #1e293b; border-top:none;
                 border-radius:0 0 10px 0; padding:8px;
                 box-shadow:0 10px 24px rgba(0,0,0,.5); }
  .topbar-menu.open { display:flex; }
  .topbar-menu .tabbtn { margin:0; text-align:left; padding:10px 14px; }

  /* Info card: collapsed = just the date strip; the chevron expands it. */
  .info-card { width:auto; max-width:calc(100% - 24px); }
  .info-card .info-body:not(.open) { display:none; }
  .card-toggle { display:block; }
  /* Leave room so the chevron never overlaps the date strip's last button. */
  .info-card .date-row { padding-right:16px; }

  /* Timeline dock: full-bleed. The chart's left margin is 44px on mobile (see
     build_timeline), so the slider aligns to the same 44/10 gutters. */
  .dock { padding-left:0; padding-right:0; }
  .tl-toolbar { margin:0 8px 2px; position:relative; }
  .view-slider { margin:4px 10px 0 44px; }

  /* Zoom presets behind a burger; the menu drops UPWARD above the toolbar
     (the dock hugs the bottom of the screen). */
  .zoom-burger { display:inline-flex; align-items:center; justify-content:center; }
  .zoom-menu { display:none; position:absolute; bottom:34px; left:0; z-index:1500;
               flex-direction:column; align-items:stretch; gap:4px;
               background:#0f1827; border:1px solid #1e293b; border-radius:8px;
               padding:8px; box-shadow:0 10px 24px rgba(0,0,0,.5); }
  .zoom-menu.open { display:flex; }
  .zoom-menu .label { display:none; }
  .zoom-menu .zoombtn { text-align:left; padding:8px 12px; font-size:13px; }

  /* Speed control: number + unit only. */
  .speed-label { display:none; }
}
