/* Search Console reskin - templates/main/index.html (the authenticated
   "Search Console") plus its floating tool windows (canvas, history,
   sessions, reports, exports, tools, filters, bins/share/import modals).
   This is a CSS-only reskin: none of the underlying markup, IDs, or
   functional classes (draggable_box, x_panel, dataTable, bar_tabs_search,
   disabledTab, dropdown-content, etc.) were renamed or restructured - every
   interaction (drag/minimize/maximize, DataTables, Cytoscape, Bootstrap
   tabs) is wired to those exact names in main_static/js/*.js, so this file
   only retargets their *appearance* to the new_ui dark/teal tokens, layered
   on top of the legacy stylesheet stack via {{ block.super }}. */

/* ---------- page chrome ---------- */
.right_col.main_height { background: transparent; }

/* Page banner above the search layout. The .search-banner / .text-size class
   names are kept from the markup this replaced; index.css styles
   .search-banner as 3em text, which is overridden here. */
.ld-search-banner {
  position: relative;
  overflow: hidden;
  margin-bottom: 16px;
  padding: 22px 20px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-bg);
  text-align: center;
}
.ld-search-banner::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0;
  height: 2px; background: var(--accent);
}
.ld-search-banner h1.search-banner {
  font-size: 28px !important;
  font-weight: 700;
  line-height: 1.2;
  color: var(--text);
  text-align: center !important;
  padding: 0 !important;
  margin: 0;
}
.ld-search-banner .text-size { font-size: inherit; color: inherit; }
@media (max-width: 760px) {
  .ld-search-banner { padding: 16px; }
  .ld-search-banner h1.search-banner { font-size: 20px !important; }
}

/* dashboard.js calls main_results_window.hide() on load, but that file runs at
   the end of the body, so the panel painted first and then vanished. Starting
   hidden in CSS removes that flash; jQuery's .show() writes an inline style,
   which outranks this, so the panel still appears normally on a search. */
.ac-resultpanel.results-window { display: none; }

/* The results panel is a sibling of .ac-searchlayout rather than a child of
   .ac-center, so the table spans the full page width instead of sharing a row
   with the 208px category rail - the columns had far too little room before. */
.ac-resultpanel.results-window {
  margin-top: 16px;
  position: relative;
  display: none;
  /* Auto side margins keep the panel centred, so the width the resize handle
     writes grows into both gutters evenly rather than only to the right. */
  margin-left: auto;
  margin-right: auto;
}
.ac-resultpanel.results-window .ac-tablescroll {
  overflow: auto;
  /* Default height; the drag handle below writes an inline height that wins. */
  max-height: 60vh;
  resize: none;
}

/* Drag-to-resize grip in the bottom-right corner of the panel. */
.ac-resize-handle {
  position: absolute;
  right: 0; bottom: 0;
  width: 18px; height: 18px;
  cursor: nwse-resize;
  z-index: 2;
  background:
    linear-gradient(135deg, transparent 0 45%, var(--line-input) 45% 55%, transparent 55% 100%),
    linear-gradient(135deg, transparent 0 70%, var(--line-input) 70% 80%, transparent 80% 100%);
  border-bottom-right-radius: 10px;
}
.ac-resize-handle:hover {
  background:
    linear-gradient(135deg, transparent 0 45%, var(--accent) 45% 55%, transparent 55% 100%),
    linear-gradient(135deg, transparent 0 70%, var(--accent) 70% 80%, transparent 80% 100%);
}
.ac-resultpanel.resizing { user-select: none; }

/* Discovery Chain panel (#chain_window) starts empty and is only populated
   by update_discovery_chain() in dashboard.js once a real chain exists -
   the reference design (search.html) has no equivalent element at all, so
   keeping this always-visible put an extra, unrelated panel between the
   search card and the results panel on every page load. Hiding it while
   empty (it un-hides itself the moment JS appends real content) matches the
   reference's layout for the common case without removing the feature. */
#discovery_window:has(#chain_window:empty) { display: none; }

/* ---------- sub-panels under the search card (discovery chain, tool row) ---------- */
.ld-subpanel {
  background: var(--panel-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  min-height: 0;
}
.ld-subpanel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.ld-subpanel-title {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-5);
  white-space: nowrap;
}
.ld-subpanel-title .fa-star-o,
.ld-subpanel-title .fa-star { color: var(--warn); font-size: 12px; cursor: pointer; }
.ld-subpanel-title .fa-star-o:hover { color: var(--warn); opacity: 0.8; }

.ld-subpanel-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: 7px;
  border: 1px solid var(--line-input);
  background: none;
  color: var(--text-3);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.ld-subpanel-btn:hover { border-color: var(--accent-60); color: var(--text); }
.ld-subpanel-btn i { color: var(--accent); font-size: 11px; }

/* Chain links are appended by update_discovery_chain() in dashboard.js with
   inline colours; those are overridden here so the row follows the theme. */
.ld-chain {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  flex: 1;
  min-width: 0;
}
.ld-chain > .ld-chain-item {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--line-input);
  background: var(--bg-sunken);
  font-size: 11.5px !important;
}
.ld-chain > .ld-chain-item strong {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-6);
}
.ld-chain > .ld-chain-item u {
  text-decoration: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  color: var(--accent-tint);
}
.ld-chain > .ld-chain-item u:hover { text-decoration: underline; }
.ld-chain .remove_from_discovery {
  color: var(--accent) !important;
  font-size: 10px !important;
  margin-left: 2px;
  cursor: pointer;
}
.ld-chain .remove_from_discovery:hover { color: var(--danger) !important; }

/* Markers sit between the pills, not inside them: fa-arrow-right separates two
   links, fa-asterisk terminates the chain. */
.ld-chain > .fa-arrow-right,
.ld-chain > .fa-asterisk {
  color: var(--accent) !important;
  font-size: 10px !important;
  flex-shrink: 0;
}
.ld-chain > .fa-asterisk { font-size: 9px !important; }

.ld-subpanel .ac-toolbtns { gap: 8px; flex-wrap: wrap; }
/* Not scoped to .ld-subpanel: these buttons also sit in the results toolbar and
   the search card, and only some of them carry an inline colour on the icon. */
.ac-toolbtn-icon i { color: var(--accent); font-size: 12px; }

/* ---------- generic panels (x_panel / x_panel_box / card-box) ---------- */
.x_panel, .x_panel_box, .x_panel_box_exports, .card-box {
  background: var(--panel-bg) !important;
  border: 1px solid var(--line) !important;
  border-radius: 10px !important;
  color: var(--text-2);
  box-shadow: none !important;
}
.x_panel .x_title, .x_panel_box_exports .x_title {
  border-bottom: 1px solid var(--line-soft) !important;
  color: var(--text) !important;
}
.x_panel .x_title h3, .x_panel_box_exports .x_title h2 {
  color: var(--text) !important;
  font-size: 14px !important;
  font-weight: 700 !important;
}
.popup_banner_text {
  color: var(--text) !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 8px;
}

/* ---------- floating / draggable windows (styled to match new_ui's .win
   floating-window chrome - see windows.css - without touching the actual
   draggable_box/draggable_header markup or the drag/minimize/maximize JS
   in dashboard.js, which is wired to these exact class names) ---------- */
.draggable_box {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--accent) !important;
  border-radius: 10px !important;
  box-shadow: var(--shadow-win) !important;
  overflow: hidden;
}
.draggable_box .x_panel { background: transparent !important; border: none !important; box-shadow: none !important; }

/* Window title bar - matched to .win-bar in windows.css so the legacy
   draggable_box popups and the new_ui floating windows read identically. */
.draggable_header {
  cursor: move;
  display: flex; align-items: center; gap: 8px;
  padding: 9px 8px 9px 12px !important;
  margin: 0 !important;
  min-height: 0 !important;
  height: auto !important;
  background: var(--bg-winbar) !important;
  color: var(--text) !important;
  border-bottom: 1px solid var(--line) !important;
  border-radius: 10px 10px 0 0;
  user-select: none;
}
.draggable_header .win-bar-icon {
  width: 18px; height: 18px; display: flex; align-items: center; justify-content: center;
  color: var(--accent); font-size: 13px; flex-shrink: 0;
}
.draggable_header .win-bar-title,
.draggable_header .canvas_title {
  font-size: 12.5px !important;
  font-weight: 700 !important;
  color: var(--text) !important;
  flex: 1;
  margin: 0 !important;
  padding: 0 !important;
  line-height: 1.3 !important;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.draggable_header .canvas_alias { font-weight: 400; color: var(--text-5); font-size: 11.5px; }
.draggable_header br { display: none; }
.draggable_header .clearfix { display: none; }

/* pattern B: header-only boxes (report/filter selection - .x_panel > .x_content > .header, no title bar) */
.draggable_box .header {
  display: flex; justify-content: flex-end; align-items: center;
  padding: 8px 8px 0 !important;
}
.draggable_box .header .clearfix { display: none; }

/* index.css positions .collapse-link / .maximize-link / .close absolutely at
   fixed right/top offsets with a 2rem glyph. That predates the flex title bar
   and is what made the buttons overlap and the bar 50-60px tall. */
.draggable_header .close,
.draggable_header .refresh,
.draggable_header .collapse-link,
.draggable_header .maximize-link,
.draggable_header .expand-link,
.close, .refresh, .collapse-link, .maximize-link, .expand-link {
  position: static !important;
  right: auto !important;
  top: auto !important;
  left: auto !important;
  bottom: auto !important;
  width: 22px !important;
  height: 22px !important;
  border-radius: 5px;
  display: inline-flex !important; align-items: center; justify-content: center;
  color: var(--text-4) !important; flex-shrink: 0;
  font-size: 12px !important;
  line-height: 1 !important;
  font-weight: 400 !important;
  cursor: pointer;
  opacity: 1 !important;
  float: none !important;
  margin: 0 !important;
  padding: 0 !important;
  text-shadow: none !important;
  background: none;
  border: none;
  transform: translate(0%, 0%);
}
.draggable_header .win-bar-btn i,
.draggable_header .close i,
.draggable_header .refresh i,
.draggable_header .collapse-link i,
.draggable_header .maximize-link i,
.draggable_header .expand-link i {
  font-size: 12px !important;
  line-height: 1 !important;
  width: 12px;
  height: 12px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}
/* fa-window-minimize's glyph sits on the baseline, so in a centred flex box it
   reads as low. Nudge it to optically match the other icons. */
.draggable_header .collapse-link i.fa-window-minimize {
  align-items: flex-end;
  padding-bottom: 2px;
  box-sizing: content-box;
}
.close:hover, .refresh:hover, .collapse-link:hover, .maximize-link:hover, .expand-link:hover {
  background: var(--bg-hover);
  color: var(--text) !important;
  opacity: 1 !important;
}
.draggable_header .refresh i { transition: transform 0.4s; }
.draggable_header .refresh:active i { transform: rotate(210deg); }

/* The in-body heading each popup used as its title is redundant now that the
   bar carries one, and its logo is what made these headers so tall. */
.draggable_box .x_panel_box_exports > .x_title,
.draggable_box .exports_container .x_title { display: none; }

/* maximize_window() toggles a "<box-id>_maximize" class, but index.css only
   ever defined the canvas one, so every other popup's expand button toggled a
   class with no rule behind it. */
.canvas_box_maximize,
.search_history_box_maximize,
.report_selection_box_maximize,
.filter_selection_box_maximize,
.cc_result_box_maximize,
.bins_result_box_maximize,
.reports_box_maximize,
.exports_box_maximize,
.passive_tools_box_maximize,
.active_tools_box_maximize,
.stealer_host_box_maximize {
  display: block;
  position: fixed;
  z-index: 9999;
  width: 98%;
  height: 98%;
  top: 1%;
  left: 1%;
  margin: 0 !important;
  max-width: none;
  max-height: none;
}

.draggable_box[class*="_maximize"] > .draggable_header { border-radius: 0; }

/* ---------- minimize dock (populated by minimize_window() in dashboard.js) ---------- */
/* Dock for minimized tool/host windows. A fixed footer bar across the bottom of
   the content area (offset by the sidebar, not under it), with an accent top
   edge. body.has-dock pads the page so the bar never covers content the way the
   old centred floating pill did. Fixed rather than in-flow because the legacy
   content markup foster-parents this node around the DOM; fixed positioning does
   not care where it lands. */
.minimized_panel {
  position: fixed; left: var(--sidebar-w); right: 0; bottom: 0; z-index: 120;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 16px;
  background: var(--bg-toolbar);
  border-top: 2px solid var(--accent);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.22);
  overflow-x: auto; overflow-y: hidden;
}
body.sidebar-collapsed .minimized_panel { left: var(--sidebar-w-collapsed); }
.minimized_panel::before {
  content: "Minimized";
  flex-shrink: 0; margin-right: 4px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent);
}
.minimized_panel:empty { display: none; }
/* Reserve room so content clears the dock while it is shown (body.has-dock is
   toggled in dashboard.js by whether the dock holds any chips). */
body.has-dock .page-wrapper { padding-bottom: 64px; }
.docked_window {
  display: flex; align-items: center; gap: 2px; flex-shrink: 0;
  background: var(--bg-sunken); border: 1px solid var(--line-input); border-radius: 8px;
  padding: 7px 4px 7px 10px;
}
.docked_window:hover { border-color: var(--accent-60); }
.docked_window .canvas_title { font-size: 11.5px; font-weight: 600; color: var(--text-2); margin: 0 6px 0 0; white-space: nowrap; }
.docked_window br { display: none; }
.docked_window .expand-link,
.docked_window .close {
  position: static !important;
  right: auto !important; top: auto !important;
  width: 22px !important; height: 22px !important;
  border-radius: 5px;
  display: inline-flex !important; align-items: center; justify-content: center;
  font-size: 12px !important; line-height: 1 !important; font-weight: 400 !important;
  color: var(--text-4) !important;
  margin: 0 !important; padding: 0 !important;
  float: none !important; opacity: 1 !important; text-shadow: none !important;
  background: none; border: none; cursor: pointer; flex-shrink: 0;
}
.docked_window .expand-link:hover,
.docked_window .close:hover { background: var(--bg-hover); color: var(--text) !important; }
.docked_window .expand-link i,
.docked_window .close i {
  font-size: 12px !important; line-height: 1 !important;
  width: 12px; height: 12px;
  display: flex !important; align-items: center; justify-content: center;
}

/* ---------- buttons (button_search / btn-* used throughout tool windows) ---------- */
.btn.button_search, .btn-success.button_search {
  background: var(--panel-bg) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
  border-radius: 999px !important;
  font-weight: 600 !important;
  box-shadow: none !important;
}
.btn.button_search:hover, .btn-success.button_search:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.btn-success.button_search:disabled { opacity: 0.4; }
#main_search_button.btn-secondary, .submit_button {
  background: var(--accent) !important;
  border: none !important;
  color: var(--on-accent) !important;
  border-radius: 7px !important;
  font-weight: 700 !important;
}
.btn-warning.button_search { background: var(--warn-bg) !important; border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent) !important; color: var(--warn) !important; }
.btn-primary.button_search, .btn-info.button_search { background: var(--accent-14) !important; border: 1px solid var(--accent-50) !important; color: var(--accent-tint) !important; }
.btn-dark-banner, .btn-dark.button_search {
  background: var(--bg-hover) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
}
.btn-dark-banner:hover, .btn-dark.button_search:hover { color: var(--text) !important; border-color: var(--accent-60) !important; }
.vertical_seperator { border-left: 1px solid var(--line-soft); }

/* ---------- DB category rail (ac-catitem, repurposed as Bootstrap tab
   triggers - data-toggle="tab" + href="#pane" still wired to Bootstrap's tab
   plugin; ac-catitem/ac-catrail/ac-catgroup-label base styles come from
   layout.css, this only layers on the tab-specific bits) ---------- */
.ac-catrail {
  position: sticky;
  top: calc(var(--topbar-h) + 16px);
  max-height: calc(100vh - var(--topbar-h) - 40px);
  transition: border-color 0.2s ease;
}
/* A search that returned results calls removeClass('disabledTab') on the tabs
   that have data (see the counts handler in dashboard.js), and reset_counts()
   puts the class back before the next search. So "at least one rail item
   without .disabledTab" means live counts are showing, and the rail takes the
   accent border the other panels use. */
.ac-catrail:has(.ac-catitem:not(.disabledTab)) { border-color: var(--accent); }
/* Below 1450px the dataset rail and the search card no longer fit side by side
   comfortably, so they stack: the rail across the top as a short scrolling list,
   the search and results beneath at full width (same as the public landing page).
   The 860px block further down lifts the rail's height cap for phones. */
@media (max-width: 1450px) {
  .ac-searchlayout { flex-direction: column; }
  .ac-catrail { position: static; flex: 0 0 auto; width: 100%; max-height: 200px; }
  .ac-center { flex: 1 1 auto; width: 100%; }
}
.ac-catitem { text-decoration: none; cursor: pointer; align-items: center; gap: 8px; }
.ac-catitem:hover { background: var(--bg-hover); color: var(--text); }
.ac-catitem.disabledTab { opacity: 0.4; pointer-events: none; }
/* layout.css styles a bare `.ac-catitem span` as the small monospace count,
   which is right for the badge but not for the item's own name - in the
   reference rail that name is plain 12px UI text. The label carries its own
   class so it opts back out. */
.ac-catitem .ac-catitem-label {
  font-family: inherit;
  font-size: 12px;
  color: inherit;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-catitem .badge { flex-shrink: 0; }
/* Bootstrap's tab plugin marks the open tab with .active; layout.css already
   styles .ac-catitem.active, this just carries it through to the count. */
.ac-catitem.active .badge { background: var(--accent-18); color: var(--accent-tint); border-color: var(--accent-50); }

@media (max-width: 760px) {
  .ac-catrail { position: static; max-height: 220px; }
}

/* ---------- search bar chip rows (universal_search's tag/action chips,
   same pattern as the public landing page's captcha_search.html) ---------- */
.universal_search .ld-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.universal_search .ld-chip-row + .ld-chip-row { margin-top: 8px; }
.universal_search .ac-chip { cursor: pointer; }
.universal_search .ac-chip:hover { border-color: var(--accent-60); color: var(--text); }

/* Reset clears the whole search area, so it reads as destructive at rest
   rather than only on hover. */
.universal_search .ac-chip.ld-reset-chip {
  color: var(--danger);
  border-color: var(--danger-border);
}
.universal_search .ac-chip.ld-reset-chip:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: var(--danger-bg);
}
.universal_search .ac-chip.active:hover { color: var(--accent-tint); }
.universal_search .ac-chip:disabled { opacity: 0.4; cursor: not-allowed; }

/* The search card is a plain vertical stack in the reference: chips, then the
   input row, then the "+N more field types" line. .ac-searchcard in
   components.css already sets that flex column and its gap, so the chip row
   only needs its own wrapping behaviour. */
.universal_search .ac-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.universal_search .ac-searchrow { margin-top: 0; }
.universal_search .ac-advanced { cursor: pointer; }
.universal_search .ld-chip-group { position: relative; display: inline-flex; }
.universal_search .ld-chip-caret { border-radius: 999px; padding: 5px 8px; margin-left: -6px; }
.universal_search .dropdown-content {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  min-width: 170px; background: var(--panel-bg-2); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: var(--shadow-menu); padding: 4px; flex-direction: column;
}
.universal_search .ld-stealer-version { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-4); }
.universal_search .ld-stealer-version .win-select { width: auto; }

/* ---------- "+N more field types" dropdown attached to the search bar
   (holds ASN/AS Org/Telephone/Name/Street/Free/Other, Sensitive, Stealer
   Version - everything not in the primary chip row) ---------- */
.universal_search .ld-search-footer-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.universal_search .ld-search-footer-actions { display: flex; gap: 8px; flex-shrink: 0; }
.universal_search .ld-more-fields { position: relative; display: inline-block; }
.universal_search .ac-advanced.dropbtn { cursor: pointer; font-size: 12px; white-space: nowrap; }
.universal_search .ac-advanced.dropbtn i { margin-left: 2px; }
.universal_search .ld-more-fields-panel {
  min-width: 420px; max-width: 90vw; padding: 12px 14px; gap: 0;
  left: 0; right: auto;
}
.universal_search .ld-more-fields-panel .ld-chip-row { margin-top: 0; }
.universal_search .ld-more-fields-panel .win-label:first-child { margin-top: 0; }
.universal_search .ld-more-fields-panel select.win-select { width: 100%; }
@media (max-width: 640px) {
  .universal_search .ld-more-fields-panel { min-width: 280px; }
}

/* ---------- shared badges (DB rail counts, search-console specific) ---------- */
.badge-success {
  background: var(--accent-18) !important;
  color: var(--accent-tint) !important;
  border-radius: 999px !important;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px !important;
}

/* ---------- dropdowns (username/password/other tag pickers, ep filter) ---------- */
.dropdown-content {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  box-shadow: var(--shadow-menu) !important;
}
.dropdown-content .dropdown-item, .dropdown-content a { color: var(--text-3) !important; }
.dropdown-content .dropdown-item:hover, .dropdown-content a:hover { background: var(--bg-hover) !important; color: var(--text) !important; }
.dropdown-content .dropdown-item.disabled {
  opacity: 0.4 !important; pointer-events: none !important; cursor: not-allowed !important;
}
.dropdown-content .dropdown-item.disabled:hover { background: none !important; color: var(--text-3) !important; }

/* ---------- search-tag picker (replaces the old static "---" badge; lists
   every set*() tag-selection function from dashboard.js in one consolidated
   menu, reusing those exact functions via onclick so tag state stays fully
   in sync with the individual chip buttons - this is purely an additional
   entry point, not a replacement for them) ---------- */
.ld-tag-picker { position: relative; display: inline-flex; flex-shrink: 0; }
.ld-tag-picker-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--bg-hover); border: 1px solid var(--line-input); border-radius: 7px;
  color: var(--text-4); font-size: 11.5px; font-weight: 600; padding: 9px 10px;
  cursor: pointer; white-space: nowrap;
}
.ld-tag-picker-btn:hover { color: var(--text); border-color: var(--accent-60); }
.ld-tag-picker-btn[aria-expanded="true"] { color: var(--text); border-color: var(--accent); }
.ld-tag-picker-icon { font-size: 11px; color: var(--accent); }
.ld-tag-picker-text { color: var(--text); }
.ld-tag-picker-text.is-empty { color: var(--text-4); font-weight: 500; }
.ld-tag-picker-caret { font-size: 9px; color: var(--text-5); margin-left: 2px; transition: transform 0.15s; }
.ld-tag-picker-btn[aria-expanded="true"] .ld-tag-picker-caret { transform: rotate(180deg); }
/* Two-column grouped popover: filter box on top, compact rows with an icon,
   the current tag marked, keyboard focus shown. Rows were 46px tall (a generic
   .dropdown-item rule gave them 12px 16px padding) in a single 950px column
   that ran off the bottom of the screen. */
.ld-tag-picker-menu {
  width: 440px; max-width: calc(100vw - 32px); max-height: min(70vh, 560px);
  overflow-y: auto; left: 0; top: calc(100% + 4px); padding: 8px !important;
  /* The legacy main_static/css/bootstrap.css gives every .dropdown-content
     margin-top: 48px, which left a 60px+ gap under the button. */
  margin-top: 0 !important;
}
.ld-tagmenu-filter {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px;
  background: var(--bg-sunken); border: 1px solid var(--line-input); border-radius: 7px; padding: 0 10px;
}
.ld-tagmenu-filter:focus-within { border-color: var(--accent-60); }
.ld-tagmenu-filter i { color: var(--text-5); font-size: 11px; }
.ld-tagmenu-filter input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none; padding: 8px 0;
  color: var(--text); font-size: 12.5px; font-family: inherit;
}
.ld-tagmenu-auto {
  display: flex; align-items: center; gap: 8px; margin: 0 0 6px; padding: 2px 8px 8px;
  border-bottom: 1px solid var(--line-soft);
}
.ld-autotag-switch {
  position: relative; flex-shrink: 0; width: 30px; height: 17px; padding: 0; border-radius: 999px;
  border: 1px solid var(--line-input); background: var(--bg-sunken); cursor: pointer; transition: background 0.15s, border-color 0.15s;
}
.ld-autotag-knob {
  position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%;
  background: var(--text-5); transition: transform 0.15s, background 0.15s;
}
.ld-autotag-switch[aria-checked="true"] { background: var(--accent-50); border-color: var(--accent-60); }
.ld-autotag-switch[aria-checked="true"] .ld-autotag-knob { transform: translateX(13px); background: #fff; }
.ld-autotag-label { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--text); cursor: pointer; }
.ld-autotag-hint { font-size: 11px; color: var(--text-5); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-tag-picker-btn.is-auto .ld-tag-picker-text::after {
  content: "auto"; margin-left: 6px; padding: 0 5px; border-radius: 4px; font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.03em; text-transform: uppercase; vertical-align: 1px; background: var(--accent-18); color: var(--accent);
}
.ld-tagmenu-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 12px; }
.ld-tagmenu-group .win-label { margin: 6px 0 3px; padding: 0 8px; }
.ld-tag-picker-menu .dropdown-item {
  display: flex !important; align-items: center; gap: 9px; width: 100%;
  padding: 6px 8px !important; border: 0; border-radius: 6px; background: none;
  font-size: 12.5px; line-height: 18px; text-align: left; cursor: pointer; white-space: nowrap;
}
.ld-tag-picker-menu .dropdown-item i { width: 14px; text-align: center; font-size: 11.5px; color: var(--accent); flex-shrink: 0; }
.ld-tag-picker-menu .dropdown-item span { overflow: hidden; text-overflow: ellipsis; }
.ld-tag-picker-menu .dropdown-item.is-focus { background: var(--bg-hover) !important; color: var(--text) !important; }
.ld-tag-picker-menu .dropdown-item.is-active { background: var(--accent-18) !important; color: var(--text) !important; font-weight: 600; }
.ld-tag-picker-menu .dropdown-item.is-active::after { content: "\f00c"; font-family: "Font Awesome 6 Free"; font-weight: 900; margin-left: auto; font-size: 10px; color: var(--accent); }
.ld-tag-picker-menu .dropdown-item.disabled { opacity: 0.45; cursor: not-allowed; }
.ld-tag-picker-menu .dropdown-item.disabled i { color: var(--text-5); }
.ld-tag-picker-menu .dropdown-item[hidden], .ld-tagmenu-group[hidden] { display: none !important; }
.ld-tagmenu-empty { margin: 10px 8px; font-size: 12px; color: var(--text-5); }
.ld-tagmenu-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 8px; padding: 8px 8px 0; border-top: 1px solid var(--line-soft);
}
.ld-tagmenu-keys { font-size: 10.5px; color: var(--text-5); font-family: 'JetBrains Mono', monospace; }
.ld-tagmenu-clear {
  background: none; border: 1px solid var(--line-input); border-radius: 6px; padding: 3px 10px;
  color: var(--text-3); font-size: 11.5px; cursor: pointer;
}
.ld-tagmenu-clear:hover { color: var(--text); border-color: var(--accent-60); }
@media (max-width: 520px) {
  .ld-tagmenu-grid { grid-template-columns: minmax(0, 1fr); }
  .ld-tagmenu-keys { display: none; }
}

/* ---------- results table ----------
   The reference design (templates_new/search.html) draws its result grid as
   flat, borderless rows sitting flush inside .ac-resultpanel: an uppercase
   micro-caps header strip, monospace cells, a single hairline between rows and
   no outer chrome of its own (the panel already supplies the border).

   Here that same look has to be produced on a real <table> instead, because
   these tables are server-side DataTables instances whose paging, column
   visibility, CSV export and expand-a-row child rows are all wired to the
   <table>/<td> structure in dashboard.js and formatters.js. So the styling
   below reshapes Bootstrap's .table-striped/.table-bordered and DataTables'
   own chrome to match the reference, rather than swapping in the div grid. */

#TabContent { color: var(--text-2) !important; }

/* The legacy .row / .col-sm-12 / .card-box / .table-responsive wrappers around
   each table were laid out for a full-width Bootstrap page and add their own
   gutters, padding, background and rounded border. Inside .ac-resultpanel that
   reads as a second card nested in the first, and pushes the table off the
   panel edges. Flatten them so the table sits flush, like the reference. */
.ac-tablescroll .row { margin: 0 !important; }
.ac-tablescroll [class^="col-"], .ac-tablescroll [class*=" col-"] { padding: 0 !important; }
.ac-tablescroll .card-box,
.ac-tablescroll .table-responsive {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  box-shadow: none !important;
  /* Bootstrap gives .card-box and .table-responsive their own overflow-x:auto.
     Nested inside .ac-tablescroll, which already scrolls, that stacked three
     scroll containers and produced a stray few-pixel scrollbar. Only the outer
     one should scroll. */
  overflow: visible !important;
  width: 100% !important;
  max-width: 100% !important;
}

/* DataTables' own furniture: the length picker, export/colvis buttons and
   "showing x of y" line live above and below the table. Paging and range are
   mirrored into .ac-tablefoot by index_console.js, so the originals are moved
   out of sight rather than removed - DataTables still owns them and still
   handles their clicks, which is what the mirrored buttons forward to. */
.ac-tablescroll .dataTables_wrapper { color: var(--text-3); padding: 0 !important; }
.ac-tablescroll .dataTables_info,
.ac-tablescroll .dataTables_paginate {
  position: absolute !important;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.ac-tablescroll .dataTables_length {
  position: absolute !important;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.ac-tablescroll .dt-buttons {
  padding: 10px 18px 0 !important;
  margin: 0 !important;
  float: none !important;
  display: inline-block;
}
.ac-tablescroll .dt-buttons .dt-button {
  background: none !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
  border-radius: 7px !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  padding: 8px 14px !important;
  margin-right: 6px !important;
  box-shadow: none !important;
  line-height: 1.2 !important;
}
.ac-tablescroll .dt-buttons .dt-button:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
/* DataTables renders the collection arrow as a ::after glyph butted against
   the label; give it room so it does not touch the text. */
.ac-tablescroll .dt-buttons .dt-button.buttons-collection::after,
.ac-tablescroll .dt-buttons .dt-button .dt-down-arrow {
  margin-left: 8px !important;
  padding-left: 0 !important;
  opacity: 0.75;
}
.ac-tablescroll .dt-buttons .dt-button span { margin-right: 2px; }

/* The table itself: no outer border, no cell borders, one hairline per row. */
table.dataTable {
  background: transparent !important;
  color: var(--text-2) !important;
  border: none !important;
  border-collapse: collapse !important;
  width: 100% !important;
  margin: 0 !important;
}
table.dataTable thead th,
table.dataTable thead td {
  background: transparent !important;
  color: var(--text-5) !important;
  border: none !important;
  border-bottom: 1px solid var(--line-soft) !important;
  padding: 10px 12px !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
table.dataTable thead th:first-child { padding-left: 18px !important; }
table.dataTable thead th:last-child { padding-right: 18px !important; }

table.dataTable tbody tr,
table.dataTable.table-striped tbody tr.odd,
table.dataTable.table-striped tbody tr.even {
  background: transparent !important;
  color: var(--text-2) !important;
}
table.dataTable tbody tr:hover,
table.dataTable.table-striped tbody tr.odd:hover { background: var(--bg-hover) !important; }
/* Row whose detail is currently open in the inspector drawer. */
table.dataTable tbody tr.selected,
table.dataTable.table-striped tbody tr.odd.selected { background: var(--accent-10) !important; }

table.dataTable tbody td,
table.dataTable tbody th {
  border: none !important;
  border-bottom: 1px solid var(--line-soft) !important;
  padding: 10px 12px !important;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px !important;
  color: var(--text-2) !important;
  vertical-align: middle;
}

/* The tables carry an inline width:99%, which forced every column to squeeze
   into the container and wrap mid-value. Letting them size to their content
   and scroll horizontally instead keeps values on one line. */
.ac-tablescroll table.dataTable {
  width: auto !important;
  min-width: 100%;
}
.ac-tablescroll table.dataTable tbody td,
.ac-tablescroll table.dataTable thead th {
  white-space: nowrap;
}
/* Long free-text columns still need a ceiling or one value can push the table
   far wider than the screen; they ellipsize and show the full value on hover. */
.ac-tablescroll table.dataTable tbody td {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ac-tablescroll table.dataTable tbody td.details-control { max-width: none; overflow: visible; }
table.dataTable tbody td:first-child { padding-left: 18px !important; }
table.dataTable tbody td:last-child { padding-right: 18px !important; }
table.dataTable tbody tr:last-child td { border-bottom: none !important; }

/* Expand-a-row control. The child row it opens is lifted into the inspector
   drawer by index_console.js; this stays the affordance that opens it. */
table.dataTable td.details-control { cursor: pointer; width: 28px; color: var(--text-5) !important; }
table.dataTable td.details-control:hover { color: var(--accent) !important; }
table.dataTable tr.shown td.details-control { color: var(--accent) !important; }
/* Kept in the DOM (it is the drawer's content source) but never shown inline. */
table.dataTable tbody tr.details_box > td { padding: 0 !important; border: none !important; }

table.dataTable th.focus, table.dataTable td.focus { box-shadow: inset 0 0 0 2px var(--accent) !important; }
table.dataTable .dataTables_empty { color: var(--text-5) !important; padding: 28px 18px !important; text-align: center; font-family: inherit; }

/* ---------- form controls inside DataTables chrome ---------- */
.dataTables_length select,
.dataTables_filter input {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
}
.dataTables_processing {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  color: var(--text-3) !important;
  box-shadow: var(--shadow-menu) !important;
}

/* Tool windows keep DataTables' own visible pager (they have no .ac-tablefoot
   to mirror it into), so it still needs new_ui colours. */
.dataTables_paginate .paginate_button {
  background: none !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
  border-radius: 6px !important;
  margin: 0 2px !important;
}
.dataTables_paginate .paginate_button.current {
  background: var(--accent) !important;
  border-color: transparent !important;
  color: var(--on-accent) !important;
}
.dataTables_paginate .paginate_button.disabled { opacity: 0.35 !important; }
.dataTables_length, .dataTables_info { color: var(--text-4) !important; }

/* ---------- per-value tools (kebab + right-click menu) ---------- */
.ld-cell { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ld-cell-prefix { flex-shrink: 0; display: inline-flex; align-items: center; line-height: 0; }
.ld-cell-prefix img { display: block; }

/* The favicon scales 5x on hover (.zoom in index.css). The cell clips for its
   ellipsis and the panel clips for its rounded corners, so both are opened up
   while a favicon is hovered. The scroll container still clips, hence the
   downward transform-origin: the image grows into the rows below rather than
   past the panel's top edge. */
.ac-tablescroll td:has(.zoom:hover),
.ac-tablescroll .ld-cell:has(.zoom:hover),
.ac-tablescroll .ld-cell-text:has(.zoom:hover) { overflow: visible !important; }
.ac-resultpanel:has(.zoom:hover) { overflow: visible; }

.ac-tablescroll img.zoom {
  position: relative;
  transform-origin: left center;
  transition: transform .2s;
}
.ac-tablescroll img.zoom:hover {
  transform: scale(5);
  z-index: 9600;
  border-radius: 2px;
  box-shadow: var(--shadow-menu);
  background: var(--panel-bg-2);
}
/* Rows near the top would still clip against the scroll container, so grow
   downward there and upward lower down. */
.ac-tablescroll tbody tr:nth-child(-n+3) img.zoom:hover { transform-origin: left top; }
.ac-tablescroll tbody tr:nth-last-child(-n+3) img.zoom:hover { transform-origin: left bottom; }
.ld-cell-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-cell-text img { vertical-align: middle; margin-right: 5px; }
.ld-cell-tools { flex-shrink: 0; width: 20px; display: flex; justify-content: flex-end; }
.ld-kebab {
  width: 20px; height: 20px; padding: 0;
  border: 1px solid transparent; border-radius: 5px;
  background: none; color: var(--text-5); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; opacity: 1;
}
.ld-kebab:hover { background: var(--bg-hover); border-color: var(--line-input); color: var(--text); }
.ld-cell-tools.menu-open .ld-kebab {
  background: var(--accent-14); border-color: var(--accent-50); color: var(--accent-tint);
}
.ld-cell-tools.is-saved .ld-kebab { color: var(--accent); }

.ld-toolmenu {
  position: absolute; z-index: 9500; min-width: 190px;
  background: var(--panel-bg-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 4px; box-shadow: var(--shadow-menu);
}
.ld-menu-label {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-6); padding: 6px 9px 3px;
}
.ld-menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 9px; border: none; border-radius: 6px;
  background: none; color: var(--text-3); font-size: 11.5px;
  text-align: left; cursor: pointer;
}
.ld-menu-item i { width: 13px; text-align: center; color: var(--accent); font-size: 11px; flex-shrink: 0; }
.ld-menu-item:hover { background: var(--bg-hover); color: var(--text); }

/* ---------- results-panel display controls (rows + highlight buttons) ---------- */
.ac-tablescroll .dt-buttons .dt-button.ac-dtbtn-highlight,
.ac-tablescroll .dt-buttons .dt-button.ac-dtbtn-rows {
  font-family: 'JetBrains Mono', monospace;
}
.ac-tablescroll .dt-buttons .dt-button.ac-dtbtn-highlight.active,
.ac-tablescroll .dt-buttons .dt-button.ac-dtbtn-rows.active {
  border-color: var(--accent-60) !important;
  color: var(--accent-tint) !important;
}
div.dt-button-collection {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  box-shadow: var(--shadow-menu) !important;
  padding: 4px !important;
}
div.dt-button-collection .dt-button {
  background: none !important;
  border: none !important;
  color: var(--text-3) !important;
  font-size: 11.5px !important;
  border-radius: 6px !important;
  text-align: left;
}
div.dt-button-collection .dt-button:hover {
  background: var(--bg-hover) !important;
  color: var(--text) !important;
}
div.dt-button-collection .dt-button.active {
  background: var(--accent-18) !important;
  color: var(--accent-tint) !important;
}

/* Inline padding on a <span> inside a table cell enlarges the line box and
   makes every highlighted row taller, so the table grew whenever highlighting
   was on. Keep the box the same size. Colours: see the search-term highlight
   rule in components.css (theme text on an accent tint, readable in every theme). */
.ac-resultpanel .highlight {
  background: color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--text);
  box-shadow: inset 0 -2px 0 var(--accent);
  border-radius: 3px;
  padding: 0;
  margin: 0;
  line-height: inherit;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ---------- results-panel footer (mirrored range + FIRST/1..n/LAST pager) ---------- */
.ac-tablefoot { border-top: 1px solid var(--line-soft); flex-wrap: wrap; gap: 8px; }
.ac-tablefoot .ac-pagebtns { flex-wrap: wrap; }
.ac-tablefoot .ac-pagebtn { cursor: pointer; min-width: 28px; text-align: center; }
.ac-tablefoot .ac-pagebtn:hover:not(:disabled) { border-color: var(--accent-60); color: var(--text); }
/* .next is reused by index_console.js to mark the *current* page, matching the
   filled-accent treatment the reference gives its primary pager button. */
.ac-tablefoot .ac-pagebtn.next { cursor: default; }
.ac-tablefoot .ac-pagebtns:empty::after { content: '-'; color: var(--text-6); }

/* ---------- inspector drawer ----------
   Rendered from the row's own JSON by index_console.js. Fields are bucketed
   into semantic sections (Identity / Contact / Credentials / Location /
   Network / Record) so the same information looks the same whichever dataset
   it came from. */
#insp-fields { display: flex; flex-direction: column; gap: 18px; overflow-y: auto; }

.ac-insp-sec { display: flex; flex-direction: column; }
.ac-insp-sechead {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 2px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--line);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.ac-insp-sechead i { font-size: 10px; opacity: 0.85; }
.ac-insp-secbody { display: flex; flex-direction: column; }

.ac-insp-row {
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr);
  gap: 14px;
  align-items: baseline;
  padding: 4px 0;
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s ease;
}
.ac-insp-secbody > .ac-insp-row:last-child { border-bottom: 0; }
.ac-insp-row:hover { background: var(--bg-hover); }
.ac-insp-key {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-6);
  line-height: 1.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ac-insp-vals { min-width: 0; display: flex; flex-wrap: wrap; gap: 5px 8px; align-items: baseline; }

.ac-insp-val {
  display: flex;
  align-items: baseline;
  gap: 5px;
  flex: 1 1 auto;
  max-width: 100%;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--text);
  word-break: break-word;
}
.ac-insp-val a { color: inherit; text-decoration: none; }
.ac-insp-val a[href] { color: var(--accent); }
.ac-insp-val a[href]:hover { text-decoration: underline; }

.ac-insp-pivot { cursor: pointer; border-bottom: 1px dotted var(--line-input); }
.ac-insp-pivot:hover { color: var(--accent); border-bottom-color: var(--accent); }

.ac-insp-host {
  cursor: pointer;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  color: var(--accent) !important;
  border-bottom: 1px dotted var(--accent-50, var(--accent));
}
.ac-insp-host i { font-size: 9px; opacity: 0.75; }
.ac-insp-host:hover { border-bottom-style: solid; }
.ac-insp-host:hover i { opacity: 1; }

.ac-insp-val .ld-cell-tools { opacity: 1; flex: 0 0 auto; margin-left: auto; }
.ac-insp-val .ld-kebab {
  background: none; border: 0; padding: 0 2px;
  color: var(--text-6); cursor: pointer; font-size: 10px; line-height: 1;
  opacity: 1;
}
.ac-insp-val .ld-kebab:hover { color: var(--accent); }

/* Multi-value fields read as chips again, but only where there is more than
   one value to separate. */
.ac-insp-chips .ac-insp-val {
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-input);
  font-size: 10.5px;
}
.ac-insp-chips .ac-insp-val:hover { border-color: var(--accent-50); }
.ac-insp-chips .ac-insp-pivot { border-bottom: 0; }

/* Genuinely repeating records (several emails, several credential entries). */
.ac-insp-group { padding: 6px 0 2px; }
.ac-insp-grouphead {
  display: flex; align-items: center; gap: 7px;
  font-size: 9px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-5);
  margin-bottom: 6px;
}
.ac-insp-grouphead span {
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent-12, rgba(35, 150, 139, 0.16));
  color: var(--accent);
  font-size: 9px;
  letter-spacing: 0;
}
.ac-insp-item {
  position: relative;
  padding: 4px 0 4px 12px;
  margin-bottom: 4px;
  border-left: 2px solid var(--accent-50, var(--line-input));
  border-radius: 0 6px 6px 0;
  background: var(--bg-sunken);
}
.ac-insp-item:last-child { margin-bottom: 0; }
.ac-insp-item .ac-insp-row { padding: 5px 10px 5px 0; }
.ac-insp-item .ac-insp-row:last-child { border-bottom: 0; }
.ac-insp-item .ac-insp-row:hover { background: transparent; }

.ac-insp-empty { margin: 0; font-size: 12px; color: var(--text-5); }

/* Source database, collapsed by default. */
.ac-insp-source {
  margin-top: 2px;
  border: 1px solid var(--line-soft);
  border-radius: 9px;
  overflow: hidden;
  background: var(--panel-bg);
}
.ac-insp-source > summary {
  display: flex; align-items: center; gap: 9px; min-width: 0;
  padding: 10px 12px;
  background: var(--bg-sunken);
  cursor: pointer; list-style: none;
  font-size: 11px;
}
.ac-insp-source > summary::-webkit-details-marker { display: none; }
.ac-insp-source > summary:hover { background: var(--bg-hover); }
.ac-insp-source > summary:before {
  content: "\f0da";
  font-family: "Font Awesome 6 Free"; font-weight: 900;
  font-size: 9px; color: var(--text-6); flex: 0 0 auto;
  transition: transform 0.15s ease;
}
.ac-insp-source[open] > summary:before { transform: rotate(90deg); }
.ac-insp-srclogo { width: 20px; height: 20px; object-fit: contain; border-radius: 4px; flex: 0 0 auto; }
.ac-insp-srcname { font-weight: 600; color: var(--text-2); white-space: nowrap; flex: 0 0 auto; }
.ac-insp-srcmeta {
  margin-left: auto; font-size: 9.5px; color: var(--text-6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.ac-insp-srcbody { padding: 4px 12px 10px; }
.ac-insp-srcinfo {
  margin: 10px 0 8px;
  padding-left: 9px;
  border-left: 2px solid var(--line-input);
  font-size: 11px; line-height: 1.65; color: var(--text-4);
}

#insp-fields img { max-width: 100%; height: auto; border-radius: 6px; }

@media (max-width: 620px) {
  .ac-insp-row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* ---------- tools totals grid / stealer host details / cc details ---------- */
.totals-grid .header { color: var(--text-5) !important; }
.totals-grid > div:not(.header) { color: var(--text) !important; font-weight: 700; }

/* ---------- screenshot viewer ---------- */
.image-preview-modal { background: oklch(0% 0 0 / 0.86) !important; padding: 16px; }
/* The wrapper is just a positioning box: the fitting is on the image, or the
   two fight over the size and a wide screenshot ends up clipped. */
.img-modal-content {
  display: flex; min-width: 0; min-height: 0;
  max-width: 100%; max-height: 100%;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
/* vw/vh do not account for the page zoom this console runs at, so the fit
   is expressed as a percentage of the overlay instead. */
.img-modal-content img {
  display: block; cursor: grab;
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  border: 1px solid var(--line); border-radius: 10px;
}

/* Pinned to the viewport: as a flex child it used to be laid out beside the
   image, and a wide screenshot pushed it off screen with no way back. */
.img-modal-close {
  position: fixed; top: 16px; right: 16px; z-index: 10;
  width: 42px; height: 42px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input);
  background: var(--panel-bg-2);
  color: var(--text-2); font-size: 18px; line-height: 1; cursor: pointer;
  box-shadow: var(--shadow-win);
}
.img-modal-close:hover { background: var(--danger); border-color: var(--danger); color: #fff; }

#screenshot_details_box {
  position: fixed !important; left: 16px !important; bottom: 16px !important;
  z-index: 10; max-width: min(520px, calc(100vw - 32px));
  padding: 12px 14px !important;
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 10px !important;
  box-shadow: var(--shadow-win);
  color: var(--text-2) !important;
}
.img-modal-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, auto)); gap: 8px 22px;
}
.img-modal-grid .wide { grid-column: 1 / -1; }
.img-modal-grid > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.img-modal-grid .k {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-6);
}
.img-modal-grid .v { font-size: 12.5px; color: var(--text); }
.img-modal-grid .v.hash {
  font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--text-3);
  overflow-wrap: anywhere;
}
.img-modal-actions {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-soft);
}
.img-modal-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 7px;
  border: 1px solid var(--accent-60); background: var(--accent-16);
  color: var(--accent-tint) !important; font-size: 12px; font-weight: 600;
  text-decoration: none !important;
}
.img-modal-btn:hover { background: var(--accent); color: var(--on-accent) !important; }
.img-modal-btn.ghost { background: none; border-color: var(--line-input); color: var(--text-3) !important; }
.img-modal-btn.ghost:hover { border-color: var(--accent-60); color: var(--accent-tint) !important; background: none; }
.img-modal-btn i { font-size: 11px; }
.img-modal-hint { font-size: 10.5px; color: var(--text-6); }

@media (max-width: 860px) {
  .img-modal-grid { grid-template-columns: repeat(2, minmax(0, auto)); }
  #screenshot_details_box { left: 8px !important; right: 8px !important; bottom: 8px !important; }
}

/* ---------- associated logs picker (stealer results table) ----------
   Replaces the native <select> that held emoji in its option text. Built by
   ldAssocMenu in index_console.js; the menu itself is attached to <body>. */
.ld-assoc-btn {
  display: inline-flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 10px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line-input); background: var(--bg-sunken);
  color: var(--text-3); font-family: inherit; font-size: 12px; text-align: left;
}
.ld-assoc-btn:hover { border-color: var(--accent-60); color: var(--text); }
.ld-assoc-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--text); }
.ld-assoc-btn > i:first-child { font-size: 11px; color: var(--accent); flex-shrink: 0; }
.ld-assoc-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-assoc-btn.chosen .ld-assoc-label { font-family: 'JetBrains Mono', monospace; color: var(--text); }
.ld-assoc-n { font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-6); flex-shrink: 0; }
.ld-assoc-caret { font-size: 9px; color: var(--text-5); flex-shrink: 0; transition: transform 0.15s; }
.ld-assoc-btn[aria-expanded="true"] .ld-assoc-caret { transform: rotate(180deg); }

.ld-assoc-menu {
  position: fixed; z-index: 10000; display: flex; flex-direction: column;
  padding: 8px; border-radius: 10px;
  background: var(--panel-bg-2); border: 1px solid var(--line);
  box-shadow: var(--shadow-win);
}
.ld-assoc-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 2px 6px 8px; margin-bottom: 6px; border-bottom: 1px solid var(--line-soft);
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-5);
}
.ld-assoc-total { font-family: 'JetBrains Mono', monospace; font-weight: 400; color: var(--text-6); }
.ld-assoc-list { overflow-y: auto; overflow-x: hidden; min-height: 0; display: flex; flex-direction: column; gap: 2px; }
.ld-assoc-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 8px; border: 1px solid transparent; border-radius: 7px;
  background: none; color: var(--text-3); font-family: inherit; font-size: 12px;
  cursor: pointer; text-align: left;
}
.ld-assoc-item:hover, .ld-assoc-item:focus { background: var(--bg-hover); color: var(--text); outline: none; }
.ld-assoc-item:focus { border-color: var(--accent-60); }
.ld-assoc-id { font-family: 'JetBrains Mono', monospace; color: var(--text); flex-shrink: 0; }
/* Fixed-width columns so counts line up across rows regardless of how many
   digits each has; combined with the compact k/M number format in the JS the
   value never outgrows its cell, so every pill column stays aligned. */
.ld-assoc-pills {
  display: grid; grid-auto-flow: column;
  grid-template-columns: repeat(4, 46px) 24px; gap: 4px;
  margin-left: auto; flex-shrink: 0; align-items: center;
}
.ld-assoc-pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  width: 100%; min-width: 0; padding: 2px 4px; border-radius: 5px;
  background: var(--bg-sunken); border: 1px solid var(--line-soft);
  font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--text-2);
}
.ld-assoc-pill i { font-size: 9.5px; }
.ld-assoc-pill.zero { background: none; border-color: transparent; color: var(--text-6); }
.ld-assoc-pill.zero i { color: var(--text-6); }
.ld-assoc-pill.pw i { color: var(--danger); }
.ld-assoc-pill.ck i { color: var(--orange); }
.ld-assoc-pill.cc i { color: var(--green); }
.ld-assoc-pill.wl i { color: var(--yellow); }
.ld-assoc-pill.img { min-width: 0; }
.ld-assoc-pill.img i { color: var(--purple); }
.ld-assoc-pill.zero.img { min-width: 0; }
.ld-assoc-more {
  width: 100%; margin-top: 6px; padding: 7px; border-radius: 7px;
  border: 1px dashed var(--line-input); background: none;
  color: var(--text-4); font-family: inherit; font-size: 11.5px; cursor: pointer;
}
.ld-assoc-more:hover:not(:disabled) { border-color: var(--accent-60); color: var(--accent-tint); }
.ld-assoc-more:disabled { opacity: 0.6; cursor: default; }

/* ---------- window resize handles (make_window_resizable in dashboard.js) ---------- */
.ld-rs { position: absolute; z-index: 5; }
.ld-rs-e { top: 0; right: 0; width: 6px; height: 100%; cursor: ew-resize; }
.ld-rs-s { left: 0; bottom: 0; height: 6px; width: 100%; cursor: ns-resize; }
.ld-rs-se { right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; z-index: 6; }
.ld-rs-se::after {
  content: ''; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px;
  border-right: 2px solid var(--line-input); border-bottom: 2px solid var(--line-input);
  border-bottom-right-radius: 2px;
}
.draggable_box:hover .ld-rs-se::after { border-color: var(--accent-60); }
/* While a resize is running the pointer must not be stolen by the content. */
body.ld-rs-active { cursor: nwse-resize; user-select: none; }
body.ld-rs-active iframe, body.ld-rs-active .lh-panes { pointer-events: none; }
.draggable_box[class*="_maximize"] .ld-rs { display: none; }

/* ---------- stealer host details window (tabbed) ----------
   One window with Overview / Files / Related / Raw, filled by ldHost in
   static/main_static/js/stealer_host_window.js (mockup:
   /srv/mockup/stealer-host-tabs.html). The old one-screen field grid
   (.ld-hd-*) and the separate directory-tree window are gone; the tree is
   the Files tab now (.lh-fm), with the viewer beside it. */
/* The class drops off while maximize_window() has the box maximized, so the
   id+class selector keeps the fixed size from outranking the maximized one. */
#stealer_host_box.stealer_host_box {
  width: 1140px; min-width: 0; max-width: calc(100vw - 40px);
  height: auto; min-height: 0; max-height: none;
}
#stealer_host_box .pop-up-container {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
}
#stealer_host_box .clearfix { display: none; }
#stealer_host_box .tippy_info_button {
  color: var(--text-6);
  font-size: 9px;
  margin-left: 3px;
  cursor: help;
}
#stealer_host_box .tippy_info_button:hover { color: var(--accent); }

/* The window is content-sized (open_popup_draggable writes display:block
   inline, so the box cannot be a flex column), which makes this the height
   the resize handles write to. */
.lh { display: flex; flex-direction: column; min-height: 0; height: min(720px, calc(100vh - 150px)); }
/* Maximized, maximize_window() drops the inline style, so the box can lay
   itself out as a column and the body takes the rest of it. */
#stealer_host_box.stealer_host_box_maximize { display: flex; flex-direction: column; }
#stealer_host_box.stealer_host_box_maximize .stealer_host_container { flex: 1; min-height: 0; }
#stealer_host_box.stealer_host_box_maximize .lh { height: 100% !important; }

/* ---------- tab strip ---------- */
.lh-tabs {
  display: flex; align-items: stretch; gap: 2px; flex-shrink: 0;
  padding: 0 10px;
  background: var(--bg-toolbar);
  border-bottom: 1px solid var(--line);
  overflow-x: auto; scrollbar-width: none;
}
.lh-tabs::-webkit-scrollbar { height: 0; }
.lh-tab {
  position: relative;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 14px 10px;
  border: none; background: none; cursor: pointer;
  color: var(--text-4); font-family: inherit; font-size: 12.5px; font-weight: 600;
  white-space: nowrap;
}
.lh-tab > i { font-size: 12px; color: var(--text-5); }
.lh-tab:hover { color: var(--text); }
.lh-tab.active { color: var(--text); }
.lh-tab.active > i { color: var(--accent); }
.lh-tab.active::after {
  content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px;
  height: 2px; border-radius: 2px 2px 0 0; background: var(--accent);
}
.lh-count {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 400;
  padding: 0 6px; border-radius: 9px; line-height: 17px;
  background: var(--bg-sunken); color: var(--text-5); border: 1px solid var(--line-soft);
}
.lh-count:empty { display: none; }
.lh-tab.active .lh-count { background: var(--accent-16); color: var(--accent-tint); border-color: transparent; }

/* ---------- panes ---------- */
.lh-panes { flex: 1; min-height: 0; position: relative; }
.lh-pane { position: absolute; inset: 0; overflow: auto; padding: 18px 20px 26px; display: none; }
.lh-pane.active { display: block; animation: lh-fade 0.16s ease-out; }
.lh-pane.flush { padding: 0; }
.lh-pane.flush.active { display: flex; }
@keyframes lh-fade { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }

/* ---------- shared pieces ---------- */
.lh-mono { font-family: 'JetBrains Mono', monospace; }
.lh-dim { color: var(--text-6); font-weight: 400; }
.lh-muted { color: var(--text-6); font-size: 11.5px; }
.lh-sp { flex: 1; }

.lh-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--line-input); background: var(--panel-bg);
  color: var(--text-2); font-family: inherit; font-size: 12px; font-weight: 600; white-space: nowrap;
}
.lh-btn i { font-size: 11px; color: var(--text-5); }
.lh-btn:hover { border-color: var(--accent-60); color: var(--text); }
.lh-btn.primary { background: var(--accent-16); border-color: var(--accent-60); color: var(--accent-tint); }
.lh-btn.primary i { color: inherit; }
.lh-btn.primary:hover { background: var(--accent); color: var(--on-accent); }
.lh-btn:disabled { opacity: 0.5; cursor: default; }
.lh-btn.sm { padding: 4px 9px; font-size: 11px; }

.lh-block-h {
  display: flex; align-items: center; gap: 8px;
  margin: 22px 0 10px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3);
}
.lh-block-h > i { color: var(--accent); font-size: 12px; width: 14px; text-align: center; }
.lh-tag {
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; font-weight: 400; letter-spacing: 0;
  text-transform: none; color: var(--text-6);
  border: 1px solid var(--line-soft); border-radius: 4px; padding: 1px 6px;
}
.lh-flag { display: inline-flex; align-items: center; gap: 5px; font-family: inherit; font-size: 12px; }
.lh-flag.yes { color: var(--ok-text); }
.lh-flag.no { color: var(--text-6); }
.lh-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 6px;
  background: var(--bg-sunken); border: 1px solid var(--line-soft);
  font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--text-2);
}
.lh-pill i { font-size: 10px; color: var(--text-5); }
.lh-pill.accent { background: var(--accent-10); border-color: var(--accent-50); color: var(--accent-tint); }
.lh-pill.accent i { color: inherit; }
.lh-pill.warn { background: var(--warn-bg); border-color: transparent; color: var(--warn); }
.lh-pill.warn i { color: inherit; }
.lh-pill.danger { background: var(--danger-bg); border-color: transparent; color: var(--danger); }
.lh-pill.danger i { color: inherit; }
.lh-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.lh-badge {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--accent-tint); margin-left: 8px;
}
.lh-c-danger { color: var(--danger) !important; }
.lh-c-orange { color: var(--orange) !important; }
.lh-c-green { color: var(--green) !important; }
.lh-c-yellow { color: var(--yellow) !important; }
.lh-c-cyan { color: var(--cyan) !important; }
.lh-c-purple { color: var(--purple) !important; }

.lh-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  height: 100%; min-height: 220px; padding: 24px; text-align: center; color: var(--text-5);
}
.lh-empty > i { font-size: 28px; color: var(--text-6); }
.lh-empty .t { font-size: 13px; font-weight: 600; color: var(--text-3); }
.lh-empty .s { font-size: 12px; max-width: 420px; }

.lh-toolbar { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; flex-wrap: wrap; }
.lh-more { display: flex; align-items: center; justify-content: center; margin-top: 12px; }

/* ---------- hero (title block) ---------- */
.lh-hero {
  display: flex; gap: 20px; align-items: flex-start; justify-content: space-between; flex-wrap: wrap;
  padding: 16px 18px;
  background: var(--bg-sunken); border: 1px solid var(--line-soft); border-radius: 10px;
}
.lh-hero-main { min-width: 0; }
.lh-eyebrow {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent-tint);
}
.lh-h1 {
  margin: 6px 0; font-size: 21px; font-weight: 800; color: var(--text);
  letter-spacing: -0.01em; word-break: break-all; line-height: 1.2;
}
.lh-h1.lh-mono { font-size: 17px; font-weight: 700; }
.lh-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; color: var(--text-5); font-size: 12px; }
.lh-meta span { display: inline-flex; align-items: center; gap: 6px; }
.lh-meta i { font-size: 11px; color: var(--text-6); }
.lh-meta .lh-mono { color: var(--text-3); font-size: 11.5px; }
.lh-hero-side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; min-width: 300px; flex: 0 1 420px; }
.lh-find { position: relative; width: 100%; }
.lh-find > i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); font-size: 11px; color: var(--text-6); pointer-events: none; }
.lh-find input { width: 100%; padding: 8px 10px 8px 31px; font-size: 12px; }
.lh-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* ---------- signals ---------- */
.lh-signals {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border: 1px solid var(--line-soft); border-radius: 10px; overflow: hidden;
}
.lh-sig {
  padding: 12px 14px 13px; min-width: 0;
  border: none; border-right: 1px solid var(--line-soft);
  background: none; text-align: left; color: inherit; font-family: inherit;
}
.lh-sig:last-child { border-right: none; }
.lh-sig-btn { cursor: pointer; }
.lh-sig-btn:hover { background: var(--bg-hover); }
.lh-sig-btn:hover .lh-sig-hint { color: var(--accent-tint); }
.lh-sig-k {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-5);
}
.lh-sig-k > i:first-child { font-size: 10px; }
.lh-sig-v {
  margin-top: 6px; font-family: 'JetBrains Mono', monospace; font-size: 22px; font-weight: 700;
  color: var(--text); line-height: 1.1;
}
.lh-sig-v.zero { color: var(--text-6); }
.lh-sig-v.flag { font-size: 15px; padding-top: 5px; }
.lh-sig-hint { margin-top: 3px; font-size: 10.5px; color: var(--text-6); }
.lh-sig-hint i { font-size: 9px; }

/* ---------- detail columns ---------- */
.lh-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; align-items: start; }
.lh-kv { border-top: 1px solid var(--line-soft); }
.lh-kv-row {
  display: grid; grid-template-columns: 150px minmax(0, 1fr) auto; align-items: center; gap: 12px;
  padding: 9px 4px; border-bottom: 1px solid var(--line-soft);
}
.lh-kv-row:hover { background: color-mix(in srgb, var(--bg-hover) 55%, transparent); }
.lh-kv-row.hit { background: var(--accent-10); }
.lh-kv-row.miss { display: none; }
.lh-kv-k {
  display: flex; align-items: center; gap: 8px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-5);
}
.lh-kv-k > i:first-child { width: 13px; text-align: center; font-size: 11px; color: var(--text-6); }
.lh-kv-v {
  font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--text);
  word-break: break-word; min-width: 0;
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
}
.lh-kv-v.plain { font-family: inherit; font-size: 12.5px; word-break: normal; }
.lh-kv-v.empty { color: var(--text-6); font-family: inherit; font-size: 12px; }
.lh-kv-v > * { max-width: 100%; }
.lh-kv-v a { color: var(--accent-tint); text-decoration: none; }
.lh-kv-v a:hover { text-decoration: underline; }
.lh-copy {
  width: 24px; height: 22px; border-radius: 5px; cursor: pointer;
  border: 1px solid transparent; background: none; color: var(--text-6); font-size: 11px;
  opacity: 0; transition: opacity 0.12s;
}
.lh-kv-row:hover .lh-copy, .lh-copy:focus-visible { opacity: 1; }
.lh-copy:hover { border-color: var(--line-input); color: var(--accent-tint); }

.lh-shot {
  display: flex; gap: 14px; align-items: center;
  padding: 10px; margin-top: 12px;
  border: 1px solid var(--line-soft); border-radius: 9px; background: var(--bg-sunken);
}
.lh-shot-thumb {
  width: 140px; height: 74px; border-radius: 6px; flex-shrink: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input); background: var(--panel-bg);
  /* These are often dual-monitor grabs (3840x1080), so the whole desktop is
     more use than a cropped middle. */
  background-size: contain; background-repeat: no-repeat; background-position: center;
  color: var(--text-6); font-size: 20px; cursor: pointer; overflow: hidden;
}
.lh-shot-thumb.filled > i { display: none; }
.lh-shot-thumb:hover { border-color: var(--accent-60); }
.lh-shot-thumb:disabled { cursor: default; }
.lh-shot-meta { font-size: 11.5px; color: var(--text-5); line-height: 1.7; min-width: 0; }
.lh-shot-meta b { color: var(--text-3); font-weight: 600; word-break: break-all; }
.lh-shot-meta .lh-btn { margin-top: 6px; }

.lh-about {
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--line-soft); border-radius: 9px; background: var(--bg-sunken);
}
.lh-about > summary {
  cursor: pointer; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--text-5);
}
.lh-about > summary:hover { color: var(--text-3); }
.lh-about > div { margin-top: 8px; font-size: 12px; line-height: 1.6; color: var(--text-3); }

.lh-analyst {
  margin-top: 4px; padding: 14px 16px;
  border: 1px solid var(--line-soft); border-left: 3px solid var(--accent); border-radius: 8px;
  background: var(--bg-sunken); color: var(--text-3); font-size: 13px; line-height: 1.65;
}
.lh-analyst b { color: var(--text); font-weight: 600; }
.lh-analyst .lh-pills { margin-top: 10px; }

/* ---------- related ---------- */
.lh-callout {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px; border-radius: 9px; margin: 14px 0 12px;
  background: var(--warn-bg); color: var(--text-3); font-size: 12px; line-height: 1.55;
}
.lh-callout > i { color: var(--warn); margin-top: 2px; }
.lh-rel-list { display: grid; gap: 8px; }
.lh-rel {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: center;
  padding: 12px 14px; border: 1px solid var(--line-soft); border-radius: 10px; background: var(--bg-sunken);
}
.lh-rel:hover { border-color: var(--accent-60); }
.lh-rel.same { border-color: var(--accent-50); background: var(--accent-10); }
.lh-rel-av {
  width: 36px; height: 36px; border-radius: 9px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-10); color: var(--accent);
}
.lh-rel-body { min-width: 0; }
.lh-rel-t { font-size: 12px; color: var(--text); display: flex; align-items: center; }
.lh-rel-m { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 4px; font-size: 11.5px; color: var(--text-5); }
.lh-rel-m span { display: inline-flex; align-items: center; gap: 5px; }
.lh-rel-m i { font-size: 10px; color: var(--text-6); }
.lh-rel-side { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.lh-rel-cnts { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------- raw ---------- */
.lh-json {
  margin: 0; padding: 16px 18px;
  border: 1px solid var(--line-soft); border-radius: 10px; background: var(--bg-sunken);
  font-family: 'JetBrains Mono', monospace; font-size: 12px; line-height: 1.7; color: var(--text-3);
  overflow: auto; white-space: pre-wrap; word-break: break-word;
}
.lh-json .jk { color: var(--accent-tint); }
.lh-json .js { color: var(--text); }
.lh-json .jn { color: var(--yellow); }
.lh-json .jb { color: var(--purple); }

/* ---------- segmented control (Credentials) ---------- */
.lh-seg {
  display: flex; gap: 4px; padding: 4px; margin-top: 16px;
  border: 1px solid var(--line-soft); border-radius: 9px; background: var(--bg-sunken);
}
.lh-seg button {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 10px; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent; background: none;
  color: var(--text-4); font-family: inherit; font-size: 12px; font-weight: 600;
}
.lh-seg button:hover { color: var(--text); }
.lh-seg button.on { background: var(--accent-16); border-color: var(--accent-50); color: var(--accent-tint); }
.lh-seg button:disabled { opacity: 0.45; cursor: default; }
.lh-seg .n { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 400; color: var(--text-6); }
.lh-seg button.on .n { color: inherit; }

/* ---------- credentials table ---------- */
/* The pane becomes a column so the rows scroll under a sticky header and
   the segments, the filter and the pager stay put. */
.lh-pane[data-lh-pane="creds"].active { display: flex; flex-direction: column; }
.lh-pane[data-lh-pane="creds"] > * { flex: 0 0 auto; }
.lh-pane[data-lh-pane="creds"] > .lh-table-wrap { flex: 1 1 0; min-height: 120px; }
.lh-table-wrap { border: 1px solid var(--line-soft); border-radius: 10px; overflow: auto; }
.lh-tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.lh-tbl th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: 8px 10px; white-space: nowrap;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-5); background: var(--panel-bg-2); border-bottom: 1px solid var(--line);
}
.lh-tbl td { padding: 9px 10px; border-bottom: 1px solid var(--line-soft); color: var(--text-2); vertical-align: middle; }
.lh-tbl td.mono { font-family: 'JetBrains Mono', monospace; font-size: 11.5px; word-break: break-all; }
.lh-tbl td.url { max-width: 340px; }
.lh-tbl td.url span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lh-tbl td.num { font-family: 'JetBrains Mono', monospace; text-align: right; }
.lh-tbl tr:hover td { background: color-mix(in srgb, var(--bg-hover) 55%, transparent); }
.lh-tbl tr.matched td { background: var(--accent-10); }
.lh-tbl tr.matched td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.lh-tbl td.empty { text-align: center; padding: 26px; color: var(--text-6); }
.lh-dom { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.lh-dom span { overflow: hidden; text-overflow: ellipsis; }
.lh-fav {
  width: 18px; height: 18px; border-radius: 4px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 800; color: #fff;
}
.lh-secret { display: inline-flex; align-items: center; gap: 8px; font-family: 'JetBrains Mono', monospace; }
.lh-secret .dots { color: var(--text-5); letter-spacing: 1px; }
.lh-secret .eye { border: none; background: none; color: var(--text-6); font-size: 11px; padding: 2px; cursor: pointer; }
.lh-secret .eye:hover { color: var(--accent-tint); }
.lh-secret .shown { color: var(--text); word-break: break-all; }
.lh-yes { color: var(--ok-text); }
.lh-no { color: var(--text-6); }
.lh-warnt { color: var(--warn); }

/* ---------- files: tree on the left, viewer on the right ---------- */
.lh-fm { display: flex; width: 100%; min-height: 0; }
.lh-fm-side {
  width: 280px; flex-shrink: 0; display: flex; flex-direction: column; min-height: 0;
  background: var(--bg-sunken);
}
/* Drag bar between the tree and the viewer. It carries the border the side
   used to draw, so the hit area is wider than the line. */
.lh-fm-grip {
  flex: 0 0 5px; cursor: col-resize; position: relative;
  background: var(--line); background-clip: content-box;
  border-left: 2px solid transparent; border-right: 2px solid transparent;
}
.lh-fm-grip:hover, .lh-fm-grip.on { background: var(--accent); }
body.lh-fm-sizing { cursor: col-resize; user-select: none; }
.lh-fm-side-h { padding: 14px 14px 10px; flex-shrink: 0; }
.lh-fm-side-h .t {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-weight: 700; color: var(--text); font-size: 13px;
}
.lh-fm-side-h .s { font-size: 11px; color: var(--text-6); margin-top: 2px; min-height: 14px; }
.lh-fm-side-h .lh-find { margin-top: 10px; }
.lh-fm-side-h .lh-find input { background: var(--panel-bg); }
.lh-fm-tree { flex: 1; overflow: auto; padding: 4px 6px 10px; }
.lh-fm-node {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 8px; padding-left: calc(8px + var(--d, 0) * 14px);
  border: none; background: none; border-radius: 6px; text-align: left; cursor: pointer;
  color: var(--text-3); font-family: inherit; font-size: 12.5px;
}
.lh-fm-node:hover { background: var(--bg-hover); color: var(--text); }
.lh-fm-node.on { background: var(--accent-16); color: var(--accent-tint); }
.lh-fm-node .tw { width: 10px; font-size: 8px; color: var(--text-6); flex-shrink: 0; }
.lh-fm-node .fi { width: 15px; text-align: center; font-size: 12px; color: var(--text-5); flex-shrink: 0; }
.lh-fm-node.folder .fi { color: var(--accent); }
.lh-fm-node .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lh-fm-node .sz { font-family: 'JetBrains Mono', monospace; font-size: 9.5px; color: var(--text-6); flex-shrink: 0; }
.lh-fm-empty { padding: 14px; font-size: 12px; color: var(--text-6); }
/* Blocked binaries: listed, dimmed, and the tooltip says why. */
.lh-fm-node.blocked { opacity: 0.45; }
.lh-fm-node.blocked:hover { opacity: 0.7; background: var(--bg-hover); }
.lh-fm-node.blocked .fi { color: var(--text-6) !important; }
/* Footer under a truncated preview. */
.lh-fm-note {
  padding: 10px 16px; border-top: 1px solid var(--line-soft);
  font-size: 11.5px; color: var(--text-6);
}
.lh-fm-vh a.lh-tool { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
/* file-type tints, as in the mockup */
.i-key { color: var(--danger) !important; }
.i-cookie { color: var(--orange) !important; }
.i-wallet { color: var(--yellow) !important; }
.i-hist { color: var(--cyan) !important; }
.i-img { color: var(--purple) !important; }
.i-card { color: var(--green) !important; }
.i-code { color: var(--blue) !important; }

.lh-fm-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.lh-fm-log {
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
  padding: 9px 16px; border-bottom: 1px solid var(--line);
  font-size: 11.5px; color: var(--text-5);
}
.lh-fm-log .lh-mono { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The tab strip scrolls; "Close all" must not, so it lives beside it. */
.lh-fm-ftabrow {
  display: none; align-items: stretch; min-width: 0;
  border-bottom: 1px solid var(--line); background: var(--bg-toolbar);
}
.lh-fm-ftabrow.on { display: flex; }
.lh-fm-ftabrow .lh-fm-ftabs { flex: 1 1 auto; border-bottom: none; background: none; }
.lh-fm-closeall {
  flex-shrink: 0; align-self: center; margin: 0 10px 0 6px; cursor: pointer;
  padding: 5px 10px; border-radius: 6px; white-space: nowrap;
  border: 1px solid var(--line-input); background: none;
  color: var(--text-6); font-family: inherit; font-size: 11.5px;
}
.lh-fm-closeall:hover { border-color: var(--accent-60); color: var(--text); }
.lh-fm-closeall i { font-size: 10px; margin-right: 4px; }
.lh-fm-ftabs {
  display: flex; gap: 2px; padding: 8px 10px 0; flex-shrink: 0;
  border-bottom: 1px solid var(--line); background: var(--bg-toolbar);
  /* A thin visible scrollbar: the strip fills up with a dozen tabs and
     hiding it left no way to reach the ones off the end. */
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
  scrollbar-color: var(--accent-50) var(--accent-14);
}
.lh-fm-ftabs::-webkit-scrollbar { height: 6px; }
.lh-fm-ftabs::-webkit-scrollbar-thumb { background: var(--accent-50); border-radius: 3px; }
.lh-fm-ftabs::-webkit-scrollbar-thumb:hover { background: var(--accent); }
.lh-fm-ftabs::-webkit-scrollbar-track { background: var(--accent-14); border-radius: 3px; }
/* The one way to take the whole log, so it reads as the accent action. */
#lh_fm_archive { border-color: var(--accent-60); color: var(--accent-tint); }
#lh_fm_archive i { color: inherit; }
#lh_fm_archive:not(:disabled):hover { border-color: var(--accent); background: var(--accent-16); }
.lh-dl-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.lh-fm-ftab {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 7px 10px 7px 12px; white-space: nowrap;
  border: 1px solid transparent; border-bottom: none; border-radius: 7px 7px 0 0;
  background: none; color: var(--text-4); font-family: inherit; font-size: 12px;
}
.lh-fm-ftab:hover { color: var(--text); }
.lh-fm-ftab.on { background: var(--panel-bg-2); border-color: var(--line); color: var(--text); margin-bottom: -1px; }
.lh-fm-ftab .x { font-size: 9px; color: var(--text-6); padding: 2px; border-radius: 3px; }
.lh-fm-ftab .x:hover { color: var(--danger); }
.lh-fm-vh {
  display: flex; align-items: center; gap: 12px; flex-shrink: 0;
  padding: 12px 16px; border-bottom: 1px solid var(--line-soft);
}
.lh-fm-vh:empty { display: none; }
.lh-fm-vh .nm { font-weight: 700; color: var(--text); font-size: 13.5px; word-break: break-all; }
.lh-fm-vh .st { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--text-6); }
.lh-tool {
  width: 30px; height: 28px; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent; background: none; color: var(--text-4); font-size: 12px;
}
.lh-tool:hover { border-color: var(--line-input); color: var(--text); }
.lh-tool:disabled { opacity: 0.35; cursor: default; }
.lh-fm-body { flex: 1; overflow: auto; min-height: 0; }

/* viewer: line-numbered text */
.lh-code {
  margin: 0; padding: 12px 0;
  font-family: 'JetBrains Mono', monospace; font-size: 12px; line-height: 1.75; counter-reset: ln;
}
.lh-code .ln { display: flex; padding-right: 16px; white-space: pre-wrap; word-break: break-word; }
.lh-code .ln::before {
  counter-increment: ln; content: counter(ln);
  width: 50px; flex-shrink: 0; text-align: right; padding-right: 16px; margin-right: 14px;
  color: var(--text-6); border-right: 1px solid var(--line-soft);
}
.lh-code .ln:hover { background: color-mix(in srgb, var(--bg-hover) 55%, transparent); }
.lh-code .k { color: var(--text-5); }
.lh-code .v { color: var(--text); }
.lh-code .u { color: var(--accent-tint); }
.lh-code .d { color: var(--text-6); }

/* viewer: what the index knows about the selected file */
.lh-view { padding: 16px 18px; display: grid; gap: 14px; align-content: start; }
.lh-view-card {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 14px 16px; border-radius: 9px;
  border: 1px solid var(--line-soft); border-left: 3px solid var(--accent); background: var(--bg-sunken);
  color: var(--text-3); font-size: 12.5px; line-height: 1.6;
}
.lh-view-card.plain { border-left-color: var(--line); }
.lh-view-card > i { font-size: 16px; color: var(--accent); margin-top: 2px; }
.lh-view-card.plain > i { color: var(--text-6); }
.lh-view-card b { color: var(--text); font-weight: 600; }
.lh-view-card .lh-btn { margin-top: 10px; }
.lh-view-shot { display: flex; justify-content: center; padding: 4px 0 16px; }
.lh-view-shot img { max-width: 100%; border: 1px solid var(--line); border-radius: 8px; }
/* The cached thumbnail holds the frame until the full image arrives. */
.lh-view-shot img.preview { width: 520px; max-width: 100%; filter: blur(1px); opacity: 0.85; }
.lh-view-empty {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; color: var(--text-5); font-size: 12.5px;
}
.lh-view-empty i { font-size: 30px; color: var(--text-6); }

@media (max-width: 860px) {
  .lh-cols { grid-template-columns: minmax(0, 1fr); }
  .lh-hero-side { min-width: 0; flex-basis: 100%; align-items: stretch; }
  .lh-actions { justify-content: flex-start; }
  .lh-kv-row { grid-template-columns: 110px minmax(0, 1fr) auto; }
  .lh-pane { padding: 14px 14px 20px; }
  .lh-rel { grid-template-columns: auto minmax(0, 1fr); }
  .lh-rel-side { grid-column: 1 / -1; justify-content: flex-start; }
}
/* ---------- history window (Search History / Discovery Chains / Saved DataPoints) ---------- */
#search_history_box .x_panel_box {
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: 0 !important;
  margin: 0 !important;
}

/* Bootstrap's .nav-tabs had no new_ui styling at all - this is the underlined
   tab strip used across the rest of the design. */
#search_history_box .nav-tabs {
  display: flex;
  gap: 2px;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 0 14px;
  margin: 0;
  list-style: none;
  background: var(--bg-toolbar);
}
#search_history_box .nav-tabs .nav-item { margin: 0; float: none; }
#search_history_box .nav-tabs .nav-link {
  position: relative;
  display: block;
  padding: 10px 14px !important;
  border: none !important;
  border-radius: 0 !important;
  background: none !important;
  color: var(--text-4) !important;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
#search_history_box .nav-tabs .nav-link:hover { color: var(--text) !important; }
#search_history_box .nav-tabs .nav-item.active .nav-link,
#search_history_box .nav-tabs .nav-link.active {
  color: var(--accent-tint) !important;
  background: none !important;
}
#search_history_box .nav-tabs .nav-item.active .nav-link::after,
#search_history_box .nav-tabs .nav-link.active::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--accent); border-radius: 2px 2px 0 0;
}

#search_history_box .tab-content { padding: 14px 16px 16px; }
/* The jQuery tab plugin (data-toggle) marks a pane .active and adds .in, while
   Bootstrap 5's CSS fades on .show. With both libraries on the page a pane can
   end up active but transparent, so make an active pane opaque either way. */
#search_history_box .tab-pane.active { opacity: 1 !important; }
#search_history_box .tab-pane > h1.popup_banner_text {
  font-size: 11px !important;
  font-weight: 700 !important;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-5) !important;
  border-bottom: none;
  padding: 0 0 10px !important;
  margin: 0;
}

/* These tables keep DataTables' own length picker and pager (dom: 'lrtip'),
   unlike the main results tables whose chrome is mirrored into the panel. */
#search_history_box table.dataTable { margin: 0 !important; }
#search_history_box .dataTables_wrapper { padding: 0; }
#search_history_box .dataTables_length {
  margin-bottom: 8px;
  font-size: 10.5px;
  color: var(--text-5);
}
#search_history_box .dataTables_length label { color: var(--text-5) !important; font-size: 10.5px !important; }
#search_history_box .dataTables_length select { padding: 3px 6px !important; margin: 0 4px; }
#search_history_box .dataTables_info { font-size: 10.5px; padding-top: 10px; }
#search_history_box .dataTables_paginate { padding-top: 8px; }

/* Row action icons (delete, star, rerun) rendered by the column renderers. */
#search_history_box .action_icon {
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input); border-radius: 6px;
  color: var(--text-4); font-size: 11px; cursor: pointer;
}
#search_history_box .action_icon:hover { border-color: var(--accent-60); color: var(--text); }
#search_history_box .del_icon:hover { border-color: var(--danger-border); color: var(--danger); }
#search_history_box .td-align-center { display: flex; justify-content: center; }

/* ---------- filter/report side panels (openNav pattern) ---------- */
#filter_selection_box .x_panel, #report_selection_box .x_panel { background: var(--panel-bg) !important; }
#filter_selection_box h1.popup_banner_text, #report_selection_box h1.popup_banner_text,
#filter_selection_box h2, #report_selection_box h2 { color: var(--text) !important; }

/* ---------- filter window ---------- */
#filter_selection_box {
  width: 450px;
  min-height: 0 !important;
  display: flex; flex-direction: column;
}
#filter_selection_box .x_panel,
#filter_selection_box .x_content {
  min-height: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
#filter_selection_box form { margin: 0; }

.ld-filter-layout { display: flex; align-items: stretch; gap: 0; }
.ld-filter-main {
  width: 430px; flex-shrink: 0;
  padding: 14px 16px 16px;
  display: flex; flex-direction: column;
}
.ld-filter-side { flex: 1 1 auto; min-width: 0; border-left: 1px solid var(--line-soft); }
.ld-filter-side:empty { border-left: none; }

.ld-filter-enable {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; margin: 0 0 4px;
  background: var(--bg-sunken);
  border: 1px solid var(--line-input);
  border-radius: 8px;
  cursor: pointer;
}
.ld-filter-enable:hover { border-color: var(--accent-60); }
.ld-filter-enable-text { font-size: 12px; font-weight: 600; color: var(--text-2); }
.ld-filter-enable-text em {
  font-style: normal; font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--accent-tint); background: var(--accent-18);
  border-radius: 999px; padding: 2px 7px; margin-left: 6px;
}

.ld-filter-nav { display: flex; flex-direction: column; gap: 4px; }
.ld-filter-navitem {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 11px; border-radius: 7px;
  background: none; border: 1px solid transparent;
  color: var(--text-3); font-size: 12px; font-weight: 600;
  text-align: left; cursor: pointer;
}
.ld-filter-navitem > i:first-child { color: var(--accent); font-size: 12px; width: 14px; flex-shrink: 0; }
.ld-filter-navitem span { flex: 1; }
.ld-filter-chev { font-size: 9px !important; color: var(--text-6); flex-shrink: 0; }
.ld-filter-navitem:hover { background: var(--bg-hover); color: var(--text); }
.ld-filter-navitem.active {
  background: var(--accent-14); border-color: var(--accent-50); color: var(--accent-tint);
}
.ld-filter-navitem.active .ld-filter-chev { color: var(--accent); transform: rotate(90deg); }

.ld-filter-hint { font-size: 11px; color: var(--text-5); margin: 0 0 8px; }
.ld-filter-addbtn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 7px;
  background: none; border: 1px dashed var(--line-input);
  color: var(--text-3); font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.ld-filter-addbtn:hover { border-color: var(--accent-60); color: var(--text); border-style: solid; }
.ld-filter-addbtn i { font-size: 10px; color: var(--accent); }

/* Sub-panels slide in beside the list when a section is opened. */
#filter_selection_box .filter_box {
  padding: 14px 16px 16px;
  background: var(--bg-sunken);
  min-height: 100%;
}
#filter_selection_box .filter_box .header { padding: 0 !important; justify-content: flex-start; }
#filter_selection_box .filter_box h1.popup_banner_text {
  font-size: 12px !important; font-weight: 700 !important;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-5) !important;
  border-bottom: none; padding: 0 0 10px !important; margin: 0;
}
.ld-filter-back {
  width: 24px !important; height: 24px !important;
  border: 1px solid var(--line-input) !important;
  border-radius: 6px; margin-bottom: 10px !important;
}
.ld-filter-back:hover { border-color: var(--accent-60) !important; }

/* The checkbox rows inside each sub-panel. */
#filter_selection_box .filter_box .container { display: block !important; padding: 0; }
#filter_selection_box .filter_box .form-group { margin: 0; }
#filter_selection_box .report_class:not(.ld-year-grid),
#filter_selection_box .filter_class { display: flex; flex-direction: column; gap: 2px; width: 100%; }
#filter_selection_box .checkbox { margin: 0; }
#filter_selection_box .checkbox label {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; margin: 0; border-radius: 6px;
  font-size: 12px; color: var(--text-3); font-weight: 500; cursor: pointer;
  width: 100%;
}
#filter_selection_box .checkbox label:hover { background: var(--bg-hover); color: var(--text); }
#filter_selection_box .checkbox label > span:last-child { padding-left: 0 !important; }

#filter_selection_box .form-control,
#filter_selection_box select,
#filter_selection_box input[type="text"] {
  background: var(--panel-bg) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
  font-size: 12px !important;
  box-shadow: none !important;
}
/* Years: three fixed columns filled top-to-bottom, so 21 entries read as a
   compact block rather than one long list. */
#filter_selection_box .ld-year-grid {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(7, auto);
  grid-auto-flow: column;
  gap: 1px 8px;
  width: 100%;
}
#filter_selection_box .ld-year-grid .checkbox { margin: 0; }
#filter_selection_box .ld-year-grid label {
  padding: 5px 7px !important;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px !important;
  gap: 7px;
}
@media (max-width: 900px) {
  #filter_selection_box .ld-year-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(11, auto);
  }
}

/* Filters toolbar button - clearly different when filters are active. */
#filters-toolbtn.filters-on {
  background: var(--accent-14);
  border-color: var(--accent) !important;
}
#filters-toolbtn.filters-on .ac-toolbtn-icon { background: var(--accent); }
#filters-toolbtn.filters-on .ac-toolbtn-icon i { color: var(--on-accent) !important; }
#filters-toolbtn.filters-on .ac-toolbtn-label { color: var(--accent-tint); font-weight: 700; }
#filters-toolbtn.filters-on::after {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  margin-left: 2px; flex-shrink: 0;
}

/* The report window shares the filter window's layout and controls. */
#report_selection_box {
  width: 450px;
  min-height: 0 !important;
  display: flex; flex-direction: column;
}
#report_selection_box .x_panel,
#report_selection_box .x_content {
  min-height: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
#report_selection_box form { margin: 0; }
#report_selection_box .report_class:not(.ld-year-grid) { display: flex; flex-direction: column; gap: 2px; width: 100%; }
#report_selection_box .checkbox { margin: 0; }
#report_selection_box .checkbox label {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; margin: 0; border-radius: 6px;
  font-size: 12px; color: var(--text-3); font-weight: 500; cursor: pointer; width: 100%;
}
#report_selection_box .checkbox label:hover { background: var(--bg-hover); color: var(--text); }
#report_selection_box .checkbox label > span:last-child { padding-left: 0 !important; }
#report_selection_box .checkbox input[disabled] + span,
#report_selection_box .checkbox label:has(input[disabled]) { opacity: 0.45; cursor: not-allowed; }
#report_selection_box .checkbox label:has(input[disabled]):hover { background: none; color: var(--text-3); }
#report_selection_box .form-group { margin: 0; }
#report_selection_box h1.popup_banner_text {
  font-size: 12px !important; font-weight: 700 !important;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-5) !important;
  border-bottom: none; padding: 0 0 10px !important; margin: 0;
}

.ld-report-actions { margin-top: auto; padding-top: 14px; }
.ld-filter-primarybtn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 10px 14px;
  border-radius: 7px; border: none;
  background: var(--accent); color: var(--on-accent);
  font-size: 12px; font-weight: 700; cursor: pointer;
}
.ld-filter-primarybtn:hover { filter: brightness(1.08); }
.ld-filter-primarybtn i { font-size: 12px; }

#filter_selection_box .content_container { padding: 0; }

/* Word-filter rows are appended by add_form_field in dashboard.js with inline
   360px widths and a text "X Delete" link. */
#filter_selection_box .add_cont {
  width: auto !important;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
#filter_selection_box .add_cont br { display: none; }
#filter_selection_box .add_cont label {
  grid-column: 1 / -1;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-5) !important; margin: 0;
}
#filter_selection_box .add_cont .form-control {
  width: 100% !important;
  padding: 7px 9px !important;
  margin: 0 !important;
}
#filter_selection_box .add_cont .delete {
  float: none !important;
  padding: 0 !important;
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input); border-radius: 6px;
  color: var(--text-5) !important; font-size: 0;
  text-decoration: none; flex-shrink: 0;
}
#filter_selection_box .add_cont .delete::before {
  content: '\f00d'; font-family: 'Font Awesome 6 Free'; font-weight: 900; font-size: 11px;
}
#filter_selection_box .add_cont .delete:hover {
  border-color: var(--danger-border); color: var(--danger) !important;
}

/* ---------- canvas toolbar / info tooltips ----------
   custom.css styles these as .tippy-box[data-theme~=...], which is the tippy 6
   structure; the bundled tippy is 4 and renders .tippy-tooltip.<theme>-theme,
   so both forms are covered here. */
.tippy-tooltip.tippy_dropdown_details-theme,
.tippy-tooltip.tippy_dropdown_details_stealer-theme,
.tippy-box[data-theme~="tippy_dropdown_details"],
.tippy-box[data-theme~="tippy_dropdown_details_stealer"] {
  background-color: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  color: var(--text-2) !important;
  font-size: 11.5px !important;
  padding: 7px 10px !important;
  box-shadow: var(--shadow-menu) !important;
}
.tippy-tooltip.tippy_dropdown_details-theme .tippy-arrow,
.tippy-tooltip.tippy_dropdown_details_stealer-theme .tippy-arrow { display: none !important; }

/* ---------- cytoscape node tooltip (the "clarity" tippy theme) ----------
   Rewritten for tippy 6. The previous block targeted `.tippy-tooltip
   .clarity-theme`, which is tippy *4* structure -- tippy 6 renders
   `.tippy-box[data-theme~="clarity"]` with a `.tippy-content` inside, so not
   one of those selectors matched anything and the card had been rendering in
   tippy's default grey (#333) with a white border all along. */
.tippy-box[data-theme~='clarity'] {
  background: var(--panel-bg);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .55);
  color: var(--text-2);
  text-align: left;
  max-width: 320px !important;
  overflow: hidden;            /* so the header band meets the rounded corners */
}
.tippy-box[data-theme~='clarity'] .tippy-content { padding: 0; }
/* The card sits over the graph at z-index 9999. Taking pointer events made
   every node underneath an open card dead to clicks -- and on a busy graph
   there is nearly always a card open, which read as the canvas randomly not
   responding. Events fall through to Cytoscape now; only the parts that are
   really interactive take them back. Staying open while the pointer is on the
   card is done by geometry instead (canvas_tooltip.js). */
/* tippy writes pointer-events on the ROOT wrapper, inline, for an interactive
   instance -- so styling .tippy-box alone changed nothing. !important on the
   root is what actually lets clicks through. */
#canvas_box [data-tippy-root],
#canvas_box [data-tippy-root] * { pointer-events: none !important; }
#canvas_box [data-tippy-root] a,
#canvas_box [data-tippy-root] .ld-tip-images img { pointer-events: auto !important; }
.tippy-box[data-theme~='clarity'][data-placement^='bottom'] > .tippy-arrow::before { border-bottom-color: var(--panel-bg-2); }
.tippy-box[data-theme~='clarity'][data-placement^='top'] > .tippy-arrow::before { border-top-color: var(--panel-bg-2); }
.tippy-box[data-theme~='clarity'][data-placement^='left'] > .tippy-arrow::before { border-left-color: var(--panel-bg-2); }
.tippy-box[data-theme~='clarity'][data-placement^='right'] > .tippy-arrow::before { border-right-color: var(--panel-bg-2); }

/* The body reuses .x_panel markup, which is a card elsewhere. */
.tippy-box[data-theme~='clarity'] .x_panel {
  background: transparent; border: none; box-shadow: none; padding: 0; margin: 0;
}
/* Header band: the node's own name, set apart from its fields. */
.tippy-box[data-theme~='clarity'] .x_title {
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg-toolbar);
  margin: 0; padding: 9px 13px;
  /* Title left, chips hard right. Stacked in source order they sat against
     the end of the term, which read as one crowded line. */
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}
.tippy-box[data-theme~='clarity'] .x_title h2 {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; font-weight: 700;
  color: var(--accent-tint); margin: 0;
  word-break: break-all; line-height: 1.35;
  flex: 1 1 auto; min-width: 0; padding-top: 1px;
}
.tippy-box[data-theme~='clarity'] .x_content {
  padding: 11px 13px 12px;
  /* A node with a long note must not produce a card taller than the graph. */
  max-height: 46vh; overflow-y: auto;
}
/* Label / value as two columns, so the values line up down the card. */
.tippy-box[data-theme~='clarity'] .x_content h2 {
  font-size: 11.5px; font-weight: 400; color: var(--text-2);
  margin: 0; padding: 4px 0; display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  gap: 10px; align-items: baseline; line-height: 1.45;
  border-bottom: 1px solid var(--line-soft);
}
.tippy-box[data-theme~='clarity'] .x_content h2:last-child { border-bottom: none; padding-bottom: 0; }
.tippy-box[data-theme~='clarity'] .x_content h2 strong {
  font-size: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-6); padding-top: 2px;
}
.tippy-box[data-theme~='clarity'] .x_content h2 span { min-width: 0; word-break: break-word; }
.tippy-box[data-theme~='clarity'] .ld-tip-empty {
  font-style: normal; color: var(--text-7, var(--text-6)); opacity: .6; font-size: 10.5px;
}
.tippy-box[data-theme~='clarity'] .x_content a { color: var(--accent-tint); text-decoration: none; }
.tippy-box[data-theme~='clarity'] .x_content a:hover { text-decoration: underline; }
/* Type / lock chips in the header band. */
.tippy-box[data-theme~='clarity'] .ld-tip-chips {
  display: flex; flex-wrap: wrap; gap: 5px;
  flex: 0 0 auto; justify-content: flex-end;
}
/* .x_title carries a bootstrap clearfix that would otherwise take a flex slot. */
.tippy-box[data-theme~='clarity'] .x_title .clearfix { display: none; }
.tippy-box[data-theme~='clarity'] .ld-tip-chip {
  font-size: 9px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-6); background: var(--panel-bg-2);
  border: 1px solid var(--line-soft); border-radius: 999px; padding: 2px 8px;
}
.tippy-box[data-theme~='clarity'] .ld-tip-chip.is-locked {
  color: var(--accent); border-color: var(--accent);
}
/* Confirmed / unconfirmed as a labelled state, not a bare glyph. */
.tippy-box[data-theme~='clarity'] .ld-tip-state {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
}
.tippy-box[data-theme~='clarity'] .ld-tip-state.is-yes { color: var(--ok, #35c27a); }
.tippy-box[data-theme~='clarity'] .ld-tip-state.is-no { color: var(--text-6); }
/* Confidence reads as a bar on the same ramp as the node's border. */
.tippy-box[data-theme~='clarity'] .ld-tip-conf span:last-child {
  display: flex; align-items: center; gap: 8px;
}
.tippy-box[data-theme~='clarity'] .ld-tip-meter {
  flex: 1 1 auto; height: 5px; border-radius: 3px;
  background: var(--panel-bg-2); border: 1px solid var(--line-soft); overflow: hidden;
}
.tippy-box[data-theme~='clarity'] .ld-tip-meter-fill { display: block; height: 100%; }
.tippy-box[data-theme~='clarity'] .ld-tip-meter-num {
  flex: 0 0 auto; font-family: 'JetBrains Mono', monospace; font-size: 10.5px; color: var(--text-2);
}
/* Thumbnails open in the full-screen viewer. index.css scales .zoom 5x on
   hover, which inside a card that clips and scrolls meant the image grew into
   the card and pushed the layout around. In here it stays its own size and the
   zoom happens outside the card. */
.tippy-box[data-theme~='clarity'] .ld-tip-images img {
  max-width: 100%; max-height: 64px; border-radius: 5px;
  border: 1px solid var(--line-soft); margin-top: 3px;
  cursor: zoom-in; transition: border-color .15s, filter .15s;
}
.tippy-box[data-theme~='clarity'] .ld-tip-images img.zoom:hover {
  transform: none;
  border-color: var(--accent); filter: brightness(1.12);
}
.tippy-box[data-theme~='clarity'] .ld-tip-images {
  display: flex; flex-wrap: wrap; gap: 5px;
}
/* Rows are baseline-aligned, which drops the label to the foot of a tall
   thumbnail. An image row aligns to the top instead. */
.tippy-box[data-theme~='clarity'] .x_content h2:has(.ld-tip-images) { align-items: start; }
.tippy-box[data-theme~='clarity'] .x_content h2 > span { min-width: 0; word-break: break-word; }
.tippy-box[data-theme~='clarity'] a { color: var(--accent-tint); text-decoration: underline; }
.tippy-box[data-theme~='clarity'] a:hover { color: var(--accent); }
.tippy-box[data-theme~='clarity'] img {
  border: 1px solid var(--line-input); border-radius: 5px;
  margin: 2px 4px 2px 0; cursor: zoom-in;
}
.tippy-box[data-theme~='clarity'] .ld-yes { color: var(--ok, #3fb950); }
.tippy-box[data-theme~='clarity'] .ld-no { color: var(--danger); }
.tippy-box[data-theme~='clarity'] .ld-dimtext { color: var(--text-5); }

/* ---------- cytoscape context menu (right-click on a node/edge) ---------- */
.cy-context-menus-cxt-menu {
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  background: var(--panel-bg-2) !important;
  box-shadow: var(--shadow-menu) !important;
  padding: 4px !important;
  overflow: hidden;
}
.cy-context-menus-cxt-menuitem {
  background-color: transparent !important;
  color: var(--text-3) !important;
  font-size: 11.5px !important;
  padding: 7px 12px !important;
  border-radius: 6px !important;
}
.cy-context-menus-cxt-menuitem:enabled { color: var(--text-3) !important; }
.cy-context-menus-cxt-menuitem:hover {
  background-color: var(--bg-hover) !important;
  color: var(--text) !important;
}
/* Menu labels are written inside the icon element itself
   (`<i class="fa fa-edit"> Edit Node</i>`), so the text inherited Font Awesome
   and rendered in the icon font. ::before keeps the glyph while the element's
   own text falls back to the page font. */
.cy-context-menus-cxt-menuitem i,
.cy-context-menus-cxt-menuitem span {
  color: inherit !important;
  font-style: normal;
  font-family: 'Archivo', system-ui, sans-serif !important;
  font-weight: 400 !important;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cy-context-menus-cxt-menuitem i::before,
.cy-context-menus-cxt-menuitem span::before {
  font-family: 'Font Awesome 6 Free' !important;
  font-weight: 900;
  color: var(--accent);
  font-size: 11px;
  width: 13px;
  text-align: center;
  flex-shrink: 0;
}
.cy-context-menus-divider { border-bottom: 1px solid var(--line-soft) !important; }

/* ---------- cytoscape pan/zoom control ---------- */
.cy-panzoom {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
}
.cy-panzoom-zoom-button,
.cy-panzoom-slider-handle {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
}
.cy-panzoom-zoom-button:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.cy-panzoom-slider-background { background: var(--line-soft) !important; }
.cy-panzoom-pan-indicator { background: var(--accent) !important; }

/* ---------- cytoscape canvas ---------- */
.cy_box, #cy { background: var(--bg-sunken) !important; }
.canvas_container, .parent_cy_box { background: var(--bg-sunken) !important; }

.canvas_buttons {
  background: var(--bg-toolbar) !important;
  border-bottom: 1px solid var(--line) !important;
  color: var(--text-3) !important;
  gap: 4px;
  align-items: center;
  padding: 8px 10px !important;
  height: auto !important;
  flex-wrap: wrap;
}
.canvas_buttons .btn-dark-banner,
.canvas_buttons .btn {
  border-radius: 7px !important;
  width: 30px; height: 30px;
  display: inline-flex !important; align-items: center; justify-content: center;
  padding: 0 !important;
  margin: 0 !important;
  background: none !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-3) !important;
  float: none !important;
}
.canvas_buttons .btn-dark-banner:hover,
.canvas_buttons .btn:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.canvas_buttons .canvas_button { color: inherit !important; font-size: 12px; }
/* index.css paints .vertical_seperator with a hardcoded #208a7c and gives it
   its own width, so a border-left here left a teal hairline beside a themed
   one. The background is what actually draws, so that is what gets set. */
.canvas_buttons .vertical_seperator {
  border-left: none;
  background-color: var(--accent) !important;
  opacity: .55;
  width: 1px; height: 20px; margin: 0 5px 0 0; padding: 0;
  flex-shrink: 0; align-self: center;
}
.canvas_buttons .info_button { color: var(--accent) !important; font-size: 13px; }
/* Canvas side panel (load / import / update). It slides in from the right of
   the graph, so it needs its own surface and a divider against the canvas. */
#canvas_box .canvas_side_box,
#canvas_box .canvas_load_box {
  background: var(--panel-bg) !important;
  border-left: 1px solid var(--line) !important;
  padding-bottom: 20px !important;
  overflow-y: auto;
}
#canvas_box .canvas_load_box > br { display: none; }
#canvas_box .canvas_load_box > .close {
  display: flex !important;
  margin: 8px 8px 0 auto;
}
#canvas_box .canvas_side_box label {
  color: var(--text-4) !important;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  margin-bottom: 4px;
}
#canvas_box .canvas_side_box .form-control,
#canvas_box .canvas_side_box select,
#canvas_box .canvas_side_box textarea,
#canvas_box .canvas_side_box input[type="text"] {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
  font-size: 12px !important;
  box-shadow: none !important;
}
#canvas_box .canvas_side_box .form-control:focus,
#canvas_box .canvas_side_box select:focus,
#canvas_box .canvas_side_box textarea:focus { border-color: var(--accent-60) !important; outline: none !important; }
#canvas_box .canvas_side_box optgroup { color: var(--text-6); font-size: 10.5px; }
#canvas_box .canvas_side_box option { color: var(--text-2); background: var(--panel-bg-2); }
/* The import/update forms use Bootstrap column wrappers for spacing. */
#canvas_box .canvas_side_box [class*="col-md-"] { padding: 0 !important; }
#canvas_box .canvas_side_box .image_box { border-bottom-color: var(--line-soft) !important; }
#canvas_box .canvas_side_box .range span { color: var(--text-4); font-family: 'JetBrains Mono', monospace; font-size: 11px; }
#canvas_box .update_image_text_box {
  font-size: 11.5px !important;
  color: var(--text-3);
  display: flex; align-items: center; gap: 7px;
  padding: 5px 0;
}
#canvas_box .update_image_text_box .delete-X { color: var(--danger); cursor: pointer; margin: 0 !important; }

/* Import / update forms: even spacing, one field per row. */
#canvas_box .import_box,
#canvas_box .update_box { display: flex; flex-direction: column; gap: 12px; padding: 4px 2px; }
#canvas_box .import_box > [class*="col-md-"],
#canvas_box .update_box > [class*="col-md-"] {
  padding: 0 !important;
  margin: 0 !important;
  width: 100%;
  float: none !important;
}
#canvas_box .import_box > [class*="col-md-"] > div,
#canvas_box .update_box > [class*="col-md-"] > div { display: flex; flex-direction: column; gap: 5px; }
#canvas_box .canvas_side_box textarea { min-height: 68px; resize: vertical; }

/* Confirmed checkbox and confidence slider sit inline with their labels. */
#canvas_box .import_box .flat,
#canvas_box .update_box .flat { margin: 0; }
#canvas_box .import_box .range,
#canvas_box .update_box .range { flex-direction: row !important; align-items: center; gap: 10px; flex-wrap: wrap; }
#canvas_box .import_box .range label,
#canvas_box .update_box .range label { margin: 0; flex-shrink: 0; }
#canvas_box .import_box .range input[type="range"],
#canvas_box .update_box .range input[type="range"] {
  flex: 1; min-width: 90px;
  -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 999px; background: var(--line-input); outline: none;
}
#canvas_box .import_box .range input[type="range"]::-webkit-slider-thumb,
#canvas_box .update_box .range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent); cursor: pointer;
  border: 2px solid var(--panel-bg);
}
#canvas_box .import_box .image_box,
#canvas_box .update_box .image_box {
  border-bottom: none !important;
  padding-bottom: 0 !important;
}
#canvas_box .canvas_side_box input[type="file"] {
  font-size: 11px; color: var(--text-4);
  border: 1px dashed var(--line-input); border-radius: 7px;
  padding: 9px; width: 100%; cursor: pointer;
}
#canvas_box .canvas_side_box input[type="file"]:hover { border-color: var(--accent-60); }
#canvas_box .canvas_side_box .btn-group { width: 100%; }
/* The submit button anchors the form. */
#canvas_box .import_box .btn,
#canvas_box .update_box .btn {
  width: 100%;
  margin: 4px 0 0 !important;
  padding: 9px 12px !important;
  background: var(--accent) !important;
  border-color: transparent !important;
  color: var(--on-accent) !important;
  border-radius: 7px !important;
  font-weight: 700 !important;
  float: none !important;
}
#canvas_box .import_box .btn:hover,
#canvas_box .update_box .btn:hover { filter: brightness(1.08); color: var(--on-accent) !important; }

/* The edgehandles drag layer draws over the graph. */
.eh-handle { background: var(--accent) !important; }

/* ---------- canvas side panel: load / import / update ---------- */
.canvas_load_box .close { margin: 8px 8px 0 auto; }
.cy_load_box, .cy_import_box, .cy_update_box { color: var(--text-2); }

/* Saved-canvas list is a DataTable inside the side panel. */
.canvas_saved_table { width: 100% !important; margin: 0 !important; }
.cy_load_box table.dataTable thead th,
.cy_load_box table.dataTable thead td {
  background: transparent !important;
  border-bottom: 1px solid var(--line-soft) !important;
  color: var(--text-6) !important;
  font-size: 9.5px !important;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 8px 8px !important;
}
.cy_load_box table.dataTable tbody td {
  border: none !important;
  border-bottom: 1px solid var(--line-soft) !important;
  padding: 9px 8px !important;
  font-size: 11.5px !important;
  color: var(--text-2) !important;
  vertical-align: middle;
}
.cy_load_box table.dataTable tbody tr:hover { background: var(--bg-hover) !important; }
.cy_load_box .dataTables_wrapper { padding: 0; }
.cy_load_box .dataTables_filter input {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
  padding: 5px 8px !important;
}
.cy_load_box .dataTables_filter label,
.cy_load_box .dataTables_length label,
.cy_load_box .dataTables_info { color: var(--text-5) !important; font-size: 10.5px !important; }

/* Compact pager: in a narrow side panel the default buttons stretch to full
   width and stack into a column. */
.cy_load_box .dataTables_paginate {
  display: flex; flex-wrap: wrap; gap: 4px;
  justify-content: flex-end; padding-top: 8px; float: none !important;
}
.cy_load_box .dataTables_paginate .paginate_button {
  display: inline-flex !important; align-items: center; justify-content: center;
  width: auto !important; min-width: 26px; height: 26px;
  padding: 0 7px !important; margin: 0 !important;
  float: none !important;
  font-size: 10.5px !important;
  border: 1px solid var(--line-input) !important;
  border-radius: 6px !important;
  background: none !important;
  color: var(--text-3) !important;
}
.cy_load_box .dataTables_paginate .paginate_button.current {
  background: var(--accent) !important;
  border-color: transparent !important;
  color: var(--on-accent) !important;
}
.cy_load_box .dataTables_paginate .paginate_button:hover:not(.disabled) {
  border-color: var(--accent-60) !important; color: var(--text) !important;
}
.cy_load_box .dataTables_paginate .ellipsis { color: var(--text-6); padding: 0 2px; }

/* Row action icons in the saved-canvas list. */
.cy_load_box table.dataTable tbody td .fa {
  cursor: pointer;
  font-size: 13px;
  float: none !important;
  vertical-align: middle;
}
.cy_load_box table.dataTable tbody td .fa-pencil { color: var(--text-5); margin-left: 6px; }
.cy_load_box table.dataTable tbody td .fa-pencil:hover { color: var(--accent); }
.cy_load_box table.dataTable tbody td .fa-upload { color: var(--accent); }
.cy_load_box table.dataTable tbody td .fa-trash { color: var(--danger); }
.cy_load_box table.dataTable tbody td:first-child {
  font-family: 'JetBrains Mono', monospace;
  word-break: break-all;
}
.cy_load_box table.dataTable tbody td:not(:first-child) { text-align: center; width: 44px; }

/* The refresh control above the list. */
.cy_load_box .dt-buttons { float: none !important; margin-bottom: 8px; }
.cy_load_box .dt-button.ld-canvas-refresh {
  display: inline-flex !important;
  align-items: center;
  gap: 7px;
  padding: 7px 12px !important;
  margin: 0 !important;
  border: 1px solid var(--line-input) !important;
  border-radius: 7px !important;
  background: none !important;
  color: var(--text-3) !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  box-shadow: none !important;
}
.cy_load_box .dt-button.ld-canvas-refresh:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.cy_load_box .dt-button.ld-canvas-refresh i { color: var(--accent); font-size: 11px; }
.cy_load_box .dataTables_filter { float: none !important; text-align: left !important; margin-bottom: 8px; }
.cy_load_box .btn,
.cy_import_box .btn,
.cy_update_box .btn {
  border-radius: 7px !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  border: 1px solid var(--line-input) !important;
  background: none !important;
  color: var(--text-3) !important;
  box-shadow: none !important;
}
.cy_load_box .btn:hover,
.cy_import_box .btn:hover,
.cy_update_box .btn:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.cy_load_box .btn-success,
.cy_import_box .btn-info,
.cy_update_box .btn-info {
  background: var(--accent) !important;
  border-color: transparent !important;
  color: var(--on-accent) !important;
}
.cy_load_box .btn-danger { border-color: var(--danger-border) !important; color: var(--danger) !important; }
.cy_load_box .btn-danger:hover { background: var(--danger-bg) !important; border-color: var(--danger) !important; }

/* Save / share popovers hanging off the canvas toolbar. */
.text-input-popup {
  background: var(--panel-bg-2) !important;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  box-shadow: var(--shadow-menu) !important;
  padding: 10px !important;
}
.text-input-popup .form-control {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
  font-size: 12px !important;
}
.text-input-popup .btn {
  border-radius: 7px !important;
  font-size: 11.5px !important;
  font-weight: 600 !important;
  border: 1px solid var(--line-input) !important;
  background: none !important;
  color: var(--text-3) !important;
}
.text-input-popup .btn:hover { border-color: var(--accent-60) !important; color: var(--text) !important; }
.text-input-popup .btn-success {
  background: var(--accent) !important;
  border-color: transparent !important;
  color: var(--on-accent) !important;
}
.text-input-popup .btn-primary { margin-bottom: 5px; }
.text-input-popup .btn-primary i { color: inherit !important; font-style: normal; }

/* Popover buttons (save / export / share). */
.ld-popover-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  margin: 0 0 4px;
  border: 1px solid var(--line-input);
  border-radius: 7px;
  background: none;
  color: var(--text-3);
  font-family: 'Archivo', system-ui, sans-serif;
  font-size: 11.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.ld-popover-btn:last-child { margin-bottom: 0; }
.ld-popover-btn:hover { border-color: var(--accent-60); color: var(--text); }
.ld-popover-btn i { color: var(--accent); font-size: 12px; width: 14px; text-align: center; flex-shrink: 0; }
.ld-popover-btn.primary {
  margin-top: 8px;
  background: var(--accent);
  border-color: transparent;
  color: var(--on-accent);
  justify-content: center;
}
.ld-popover-btn.primary i { color: var(--on-accent); }
.ld-popover-btn.primary:hover { filter: brightness(1.08); color: var(--on-accent); }

/* Autosave toggle: clearly off when disabled. */
.canvas_buttons .autosave_canvas_button.autosave-off,
.canvas_buttons .autosave_canvas_button.disabled {
  border-color: var(--danger-border) !important;
  color: var(--danger) !important;
}
.canvas_buttons .autosave_canvas_button.autosave-off .canvas_button,
.canvas_buttons .autosave_canvas_button.disabled .canvas_button { color: var(--danger) !important; }
.canvas_buttons .autosave_canvas_button.autosave-on {
  border-color: var(--accent) !important;
  background: var(--accent-14) !important;
}
.canvas_buttons .autosave_canvas_button.autosave-on .canvas_button { color: var(--accent) !important; }

/* Load panel: refresh on the left, search on the right, one row. */
.cy_load_box .dataTables_wrapper > .dt-buttons,
.cy_load_box .dataTables_wrapper > .dataTables_filter {
  display: inline-flex !important;
  align-items: center;
  width: 50%;
  margin: 0 0 10px !important;
  vertical-align: middle;
}
.cy_load_box .dataTables_wrapper > .dataTables_filter { justify-content: flex-end; }
.cy_load_box .dataTables_filter label {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  width: 100%; justify-content: flex-end;
}
.cy_load_box .dataTables_filter input { margin: 0 !important; max-width: 130px; }

/* ---------- form fields (filters/report/session panels, stealer version picker) ---------- */
.right_col .form-control,
.right_col select,
.stealer-form-control,
.win-input, .win-select {
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px !important;
  box-shadow: none !important;
}
.right_col .form-control:focus, .right_col select:focus, .stealer-form-control:focus {
  border-color: var(--accent-60) !important;
  outline: none !important;
}
.right_col label, .right_col .control-label { color: var(--text-3) !important; }

/* iCheck select boxes: a square radio -- an outlined box with a filled box
   inside -- instead of the solid block the sprite override used to draw. A
   solid block reads as "a coloured square is here", not as "this one is
   chosen"; the inset fill reads the way a radio does.

   The sprite (green.png) is replaced outright: background-image none, and the
   inner square drawn with ::after so there is nothing to load. The nested rule
   matters -- index.html used to hand-write the wrapper that iCheck then wrapped
   again, giving two elements with this class and therefore two indicators. The
   template no longer does that, and this keeps a nested one from ever drawing
   a second box. */
.right_col .icheckbox_flat-green {
  position: relative !important;
  width: 15px !important; height: 15px !important;
  border: 1.5px solid var(--line-input) !important;
  border-radius: 3px !important;
  background: var(--bg-sunken) !important;
  background-image: none !important;
  transition: border-color .12s, background-color .12s;
}
.right_col .icheckbox_flat-green::after {
  content: ""; position: absolute; inset: 2px;
  border-radius: 1px; background: transparent;
  transition: background-color .12s;
}
.right_col .icheckbox_flat-green.checked { border-color: var(--accent) !important; background: var(--bg-sunken) !important; }
.right_col .icheckbox_flat-green.checked::after { background: var(--accent); }
.right_col .icheckbox_flat-green.disabled { opacity: .45; cursor: not-allowed !important; }
/* A wrapper inside a wrapper never draws its own indicator. */
.right_col .icheckbox_flat-green .icheckbox_flat-green {
  border: 0 !important; background: none !important; width: 100% !important; height: 100% !important;
}
.right_col .icheckbox_flat-green .icheckbox_flat-green::after { content: none; }

/* ---------- PDF Reports / Data Exports window ---------------------------- */
/* The Manage column used to be two 85px buttons stacked, which forced the
   window wider than the content needed. Icon buttons on one row instead. */
.re-actions{ display:flex; gap:5px; justify-content:flex-end; }
.re-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:5px;
  min-width:26px; height:24px; padding:0 7px;
  border:1px solid var(--line-input); border-radius:6px;
  background:var(--bg-sunken); color:var(--text-3);
  font-size:11px; line-height:1; cursor:pointer;
  transition:background-color .12s, border-color .12s, color .12s;
}
.re-btn:hover{ border-color:var(--accent); color:var(--accent); background:var(--accent-10); }
.re-btn-danger:hover{ border-color:var(--danger); color:var(--danger); background:var(--danger-bg); }
/* Armed state for the two-step delete: it says "Sure?" and reverts itself. */
.re-btn.is-armed{
  border-color:var(--danger); color:#fff; background:var(--danger);
  min-width:46px; font-weight:600;
}
.re-btn.is-armed:hover{ color:#fff; background:var(--danger); }

/* Which sections a report contains, in place of the old per-dataset counts. */
.re-sec{
  display:inline-block; margin:1px 3px 1px 0; padding:1px 6px;
  border:1px solid var(--line-soft); border-radius:999px;
  background:var(--bg-sunken); color:var(--text-3);
  font-size:10px; line-height:15px; white-space:nowrap;
}
.re-dim{ color:var(--text-5); }
/* error_message on a failed export. Clamped to one line so a long exception
   string cannot triple the row's height; the full text is in the title. */
.re-err{
  /* A concrete width, not max-width:100%: the table auto-sizes to its content,
     so a percentage gives the ellipsis nothing to clip against and a long
     exception string pushes the Manage column off the window instead. */
  display:block; max-width:290px; margin-top:2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  color:var(--text-5); font-size:11px; font-weight:400; cursor:help;
}

/* The table itself: same hierarchy the PDF uses -- one hairline, no striping,
   the identity column at full ink. */
table.reports_exports{ width:100% !important; border-collapse:collapse; }
table.reports_exports thead th{
  font-size:10px; text-transform:uppercase; letter-spacing:.7px;
  color:var(--text-5); font-weight:600; text-align:left;
  padding:6px 8px; border-bottom:1.5px solid var(--line); white-space:nowrap;
}
table.reports_exports tbody td{
  padding:7px 8px; border-bottom:1px solid var(--line-soft);
  color:var(--text-3); font-size:12px; vertical-align:middle;
}
table.reports_exports tbody tr:last-child td{ border-bottom:none; }
table.reports_exports tbody td:nth-child(2){ color:var(--text); font-weight:600; }
table.reports_exports tbody tr:hover td{ background:var(--bg-hover); }
table.reports_exports.table-striped tbody tr:nth-of-type(odd){ background:transparent; }

/* ---------- report section list: drag to order, untick to drop out -------- */
.rs-list { list-style: none; margin: 0 0 10px; padding: 0; }
.rs-item {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; margin-bottom: 4px;
  border: 1px solid var(--line-soft); border-radius: 7px;
  background: var(--panel-bg);
}
.rs-item.ui-sortable-helper { box-shadow: var(--shadow-card); border-color: var(--accent-50); }
.rs-item.is-off { opacity: .5; }
.rs-item.is-off .rs-name { text-decoration: line-through; }
.rs-grip { cursor: grab; color: var(--text-5); font-size: 12px; padding: 0 2px; }
.rs-grip:active { cursor: grabbing; }
.rs-label { display: flex; align-items: center; gap: 8px; flex: 1; margin: 0; cursor: pointer; }
.rs-name { color: var(--text-2) !important; font-size: 12.5px; }
.badge-sev {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  padding: 2px 6px; border-radius: 4px; white-space: nowrap;
}
.badge-sev.sev-critical { background: var(--danger-bg); color: var(--danger); }
.badge-sev.sev-high     { background: var(--danger-bg); color: var(--danger); }
.badge-sev.sev-medium   { background: var(--warn-bg);   color: var(--warn); }
.badge-sev.sev-low      { background: var(--warn-bg);   color: var(--warn); }
.badge-sev.sev-info     { background: var(--bg-sunken); color: var(--text-4); }

/* ==========================================================================
   Mobile / narrow viewports
   The legacy popups carry fixed widths (940-950px) and hardcoded left/top
   offsets from index.css, so on a phone they opened mostly off-screen. The
   panels added during the reskin had fixed widths of their own. Everything
   below reflows those to the viewport.
   ========================================================================== */
@media (max-width: 860px) {

  /* ---- popups become near-full-screen sheets ---- */
  .draggable_box {
    position: fixed !important;
    left: 8px !important;
    right: 8px !important;
    top: 8px !important;
    width: auto !important;
    max-width: none !important;
    max-height: calc(100vh - 16px);
    margin: 0 !important;
    overflow: auto;
  }
  /* Dragging a full-width sheet has no purpose and only loses it off-screen. */
  .draggable_header { cursor: default; }

  /* Maximize is meaningless when the sheet already fills the screen. */
  .draggable_header .maximize-link { display: none !important; }

  /* ---- filter / report windows ---- */
  #filter_selection_box,
  #report_selection_box { width: auto !important; }
  .ld-filter-layout { flex-direction: column; }
  .ld-filter-main { width: 100% !important; }
  .ld-filter-side { border-left: none; border-top: 1px solid var(--line-soft); }
  #filter_selection_box .filter_box { min-height: 0; }

  /* ---- stealer host details (Overview + Files tabs) ---- */
  #stealer_host_box.stealer_host_box { width: auto !important; }
  .lh { height: calc(100vh - 120px); }
  .lh-signals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lh-sig { border-bottom: 1px solid var(--line-soft); }
  .lh-fm { flex-direction: column; }
  .lh-fm-side { width: 100%; max-height: 190px; border-right: none; border-bottom: 1px solid var(--line); }
  .lh-fm-main { min-height: 320px; }
  .lh-seg { flex-wrap: wrap; }
  .lh-seg button { flex: 1 1 40%; }

  /* ---- search area ---- */
  .ac-searchlayout { flex-direction: column; }
  .ac-catrail {
    position: static;
    flex: 1 1 auto;
    width: 100%;
    max-height: none;
  }
  .ac-center { width: 100%; }
  .universal_search .ac-searchrow { flex-wrap: wrap; }
  .universal_search .ac-searchinput { flex: 1 1 100%; min-width: 0; }
  .universal_search .ld-more-fields-panel { min-width: 0; width: calc(100vw - 32px); }
  .ld-tag-picker-menu { max-height: 60vh; }

  /* ---- results panel ---- */
  .ac-resultpanel.results-window {
    width: auto !important;
    max-width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }
  /* Touch devices have no hover, so a drag grip is unusable - the table
     scrolls instead. */
  .ac-resize-handle { display: none; }
  .ac-resultpanel .ac-tablescroll { max-height: none; height: auto !important; }

  .ac-toolbar { gap: 10px; }
  .ac-toolbtns { width: 100%; }
  .ac-toolbtn { flex: 1 1 auto; justify-content: center; }

  /* ---- per-value tools: no hover on touch, so always show the kebab ---- */
  .ld-kebab { opacity: 1; }
  .ld-toolmenu { min-width: 180px; max-width: calc(100vw - 24px); }

  /* ---- sub-panels ---- */
  .ld-subpanel { align-items: flex-start; flex-direction: column; }
  .ld-subpanel .ac-toolbtns { width: 100%; }

  /* ---- banner ---- */
  .ld-search-banner { padding: 14px 12px; }

  /* ---- history window tabs ---- */
  #search_history_box .nav-tabs { overflow-x: auto; padding: 0 8px; }
  #search_history_box .nav-tabs .nav-link { padding: 9px 10px !important; font-size: 11.5px; }

  /* ---- minimized dock ---- */
  .minimized_panel { left: 0; padding: 8px 12px; }
}

/* Coarse pointers (touch) at any width: hover-only affordances never appear. */
@media (hover: none) {
  .ld-kebab { opacity: 1; }
}

/* ---------- Export Results to CSV window ---------- */
#export_count_modal { width: 360px; max-width: calc(100vw - 32px); }
.ld-export .win-row span:first-child { color: var(--text-3); }
.ld-export .win-row .dim { color: var(--text); font-size: 11.5px; }
.ld-export-pages { display: flex; align-items: center; gap: 10px; }
.ld-export-pages .win-input { width: 96px; font-family: 'JetBrains Mono', monospace; }
.ld-export-pages .win-input:focus { outline: none; border-color: var(--accent-60); }
.ld-export-of { font-size: 12px; color: var(--text-4); }
.ld-export-summary { margin: 10px 0 0; font-size: 11.5px; color: var(--text-4); min-height: 1.4em; }
.ld-export-summary.is-short { color: var(--warn); background: var(--warn-bg); border-radius: 6px; padding: 6px 9px; }

/* ---------- Active / Passive tools windows ------------------------------- */
/* These two windows were still wearing the Bootstrap skin the rest of the
   console has moved off: a white block for the active tab on a dark sheet,
   btn-primary blue for "Go!", btn-success green for "Load Searches", and
   DataTables' default chrome. The tab strip below is the same one
   #search_history_box uses; the rest is new but built from the same tokens. */

#active_tools_box .nav-tabs.ld-tooltabs,
#passive_tools_box .nav-tabs.ld-tooltabs {
  display: flex;
  gap: 2px;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 0 14px;
  margin: 0;
  list-style: none;
  background: var(--bg-toolbar);
  /* overflow-y must be stated. Per spec, setting one axis to something other
     than `visible` computes the other to `auto`, and the tab content is a
     hair taller than the strip -- which drew a vertical scrollbar beside the
     last tab. */
  overflow-x: auto;
  overflow-y: hidden;
}
.ld-tooltabs .nav-item { margin: 0; float: none; }
.ld-tooltabs .nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 14px !important;
  border: none !important;
  border-radius: 0 !important;
  background: none !important;
  color: var(--text-4) !important;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.ld-tooltabs .nav-link:hover { color: var(--text) !important; }
/* Only the <a>, kept in step by the click handler in dashboard.js -- matching
   .nav-item.active as well would light a second tab, because the two tab
   libraries on this page mark different elements. */
.ld-tooltabs .nav-link.active { color: var(--accent-tint) !important; background: none !important; }
.ld-tooltabs .nav-link.active::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--accent); border-radius: 2px 2px 0 0;
}

/* Credit cost. Replaces a 30x30 inline SVG that drew a teal "C" with two
   strokes through it and the number beside it -- at tab size it read as a
   stray glyph rather than a price. */
.ld-cost {
  display: inline-flex; align-items: center;
  padding: 1px 6px;
  border: 1px solid var(--line-soft); border-radius: 999px;
  background: var(--bg-sunken);
  color: var(--text-5);
  font-size: 9.5px; font-weight: 700; line-height: 15px;
  text-transform: uppercase; letter-spacing: .04em;
}
.ld-tooltabs .nav-link.active .ld-cost { border-color: var(--accent-60); color: var(--accent-tint); }
.ld-cost.is-free { opacity: .7; }

#active_tools_box .tab-content,
#passive_tools_box .tab-content { padding: 16px; }
#active_tools_box .tab-pane.active,
#passive_tools_box .tab-pane.active { opacity: 1 !important; }

.ld-tool-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 14px;
}
.ld-tool-title {
  margin: 0 0 3px;
  font-size: 13px; font-weight: 700; color: var(--text);
  letter-spacing: .01em;
}
.ld-tool-hint { margin: 0; font-size: 11.5px; color: var(--text-5); }

/* Was `btn btn-success pull-right` -- a green Bootstrap button floated into a
   row of its own, which pushed the table down by its full height. */
.ld-tool-saved {
  display: inline-flex; align-items: center; gap: 6px;
  flex: none;
  padding: 6px 11px;
  border: 1px solid var(--line-input); border-radius: 7px;
  background: var(--bg-sunken); color: var(--text-3);
  font-size: 11.5px; font-weight: 600; cursor: pointer;
  transition: border-color .12s, color .12s, background-color .12s;
}
.ld-tool-saved:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-10); }

.ld-tool-form { display: flex; gap: 8px; align-items: stretch; }
.ld-tool-input {
  flex: 1 1 auto; min-width: 0;
  padding: 8px 11px;
  border: 1px solid var(--line-input); border-radius: 7px;
  background: var(--bg-sunken); color: var(--text);
  font-size: 12.5px; font-family: inherit;
}
.ld-tool-input::placeholder { color: var(--text-5); }
.ld-tool-input:focus {
  outline: none; border-color: var(--accent-60);
  box-shadow: 0 0 0 3px var(--accent-10);
}
.ld-tool-input.is-invalid { border-color: var(--danger-border); }
.ld-tool-select {
  flex: 0 0 auto; width: 110px;
  padding: 8px 9px;
  border: 1px solid var(--line-input); border-radius: 7px;
  background: var(--bg-sunken); color: var(--text-3);
  font-size: 12px; font-family: inherit;
}
.ld-tool-hashtype { width: 124px; color: var(--text); }
/* One line under the field saying what the pasted hash looks like, so the type choice is never a guess. */
.ld-tool-detect { margin: 6px 2px 0; min-height: 14px; font-size: 11px; color: var(--text-4); }
.ld-tool-detect:empty { margin: 0; min-height: 0; }
.ld-tool-detect b { color: var(--text-2); font-weight: 600; }
/* Was `btn btn-primary` -- Bootstrap blue, on a console whose accent is red. */
.ld-tool-go {
  display: inline-flex; align-items: center; gap: 7px;
  flex: none;
  padding: 8px 16px;
  border: 1px solid var(--accent); border-radius: 7px;
  background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 600; cursor: pointer;
  transition: filter .12s, opacity .12s;
}
.ld-tool-go:hover:not(:disabled) { filter: brightness(1.12); }
.ld-tool-go:disabled { opacity: .5; cursor: not-allowed; }

/* Replaces a native alert() for an empty field, which blocked the page. */
.ld-tool-error {
  margin: 7px 2px 0; min-height: 14px;
  font-size: 11px; color: var(--danger);
}
.ld-tool-error:empty { margin: 0; min-height: 0; }

.ld-tool-progress {
  display: flex; align-items: center; gap: 8px;
  margin: 12px 0 0;
  font-size: 11.5px; color: var(--text-4);
}
.ld-tool-progress strong { color: var(--accent-tint); font-weight: 700; }
.ld-tool-spark {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  animation: ld-tool-pulse 1.1s ease-in-out infinite;
}
@keyframes ld-tool-pulse { 0%,100% { opacity: .25; } 50% { opacity: 1; } }

/* Same table hierarchy as the Reports/Exports rebuild: one hairline per row,
   no Bootstrap striping or outer border. */
table.ld-tool-table { width: 100% !important; border-collapse: collapse; margin-top: 12px !important; }
table.ld-tool-table thead th {
  padding: 6px 8px;
  border-bottom: 1.5px solid var(--line);
  color: var(--text-5); font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .7px; text-align: left; white-space: nowrap;
}
table.ld-tool-table tbody td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--text-3); font-size: 12px; vertical-align: middle;
}
table.ld-tool-table tbody tr:last-child td { border-bottom: none; }
table.ld-tool-table tbody tr:hover td { background: var(--bg-hover); }
table.ld-tool-table.table-striped tbody tr:nth-of-type(odd) { background: transparent; }
/* DataTables' own `display` class brings stripe + row-border + cell dividers.
   Rows here are separated by one hairline and nothing else, as in Reports. */
table.ld-tool-table.dataTable.display tbody tr.odd > .sorting_1,
table.ld-tool-table.dataTable.display tbody tr.even > .sorting_1,
table.ld-tool-table.dataTable.display tbody tr.odd,
table.ld-tool-table.dataTable.display tbody tr.even { background: transparent !important; }
/* `display` also brings order-column, which tints whichever column the table
   is sorted on -- a lighter block down the middle of the panel. */
table.ld-tool-table.dataTable tbody td.sorting_1,
table.ld-tool-table.dataTable tbody td.sorting_2,
table.ld-tool-table.dataTable tbody td.sorting_3 { background: transparent !important; }
table.ld-tool-table.dataTable tbody tr:hover > td { background: var(--bg-hover) !important; }
table.ld-tool-table.dataTable tbody td,
table.ld-tool-table.dataTable tbody th {
  border-top: none !important;
  border-left: none !important;
  border-right: none !important;
}
table.ld-tool-table.dataTable thead th, table.ld-tool-table.dataTable thead td { border-bottom: 1.5px solid var(--line) !important; }
table.ld-tool-table.dataTable { border: none !important; }

/* DataTables' chrome, given room to breathe. Its default layout stacks the
   length picker and the filter straight onto the table with no margins, which
   left the controls jammed between the search box and the header row. */
#active_tools_box .dataTables_wrapper,
#passive_tools_box .dataTables_wrapper { padding: 0; color: var(--text-3); }
#active_tools_box .dataTables_length, #passive_tools_box .dataTables_length,
#active_tools_box .dataTables_filter, #passive_tools_box .dataTables_filter,
#active_tools_box .dataTables_info, #passive_tools_box .dataTables_info {
  font-size: 10.5px;
  color: var(--text-5) !important;
  margin: 0;
  padding: 0;
  line-height: 26px;
}
#active_tools_box .dataTables_length, #passive_tools_box .dataTables_length { float: left; }
#active_tools_box .dataTables_filter, #passive_tools_box .dataTables_filter { float: right; }
#active_tools_box .dataTables_length label, #passive_tools_box .dataTables_length label,
#active_tools_box .dataTables_filter label, #passive_tools_box .dataTables_filter label {
  margin: 0; font-weight: 500; color: var(--text-5) !important;
  display: inline-flex; align-items: center; gap: 7px;
}
#active_tools_box .dataTables_length select, #passive_tools_box .dataTables_length select {
  padding: 3px 6px !important; margin: 0 !important;
}
/* The length/filter row sits between the form and the table, so it carries the
   gap on both sides rather than either neighbour guessing at it. */
#active_tools_box .dataTables_wrapper > .row:first-child,
#passive_tools_box .dataTables_wrapper > .row:first-child { margin: 14px 0 10px; }
#active_tools_box .dataTables_info, #passive_tools_box .dataTables_info { padding-top: 12px; }
#active_tools_box .dataTables_paginate, #passive_tools_box .dataTables_paginate { padding-top: 10px; }

/* DataTables' copy/csv/excel buttons, which shipped with its own default
   styling -- grey boxes on a dark sheet. */
#active_tools_box .dt-buttons, #passive_tools_box .dt-buttons { margin: 12px 0 0; float: none; }
#active_tools_box .dt-button, #passive_tools_box .dt-button {
  padding: 4px 10px !important;
  margin: 0 5px 0 0 !important;
  border: 1px solid var(--line-input) !important;
  border-radius: 6px !important;
  background: var(--bg-sunken) !important;
  background-image: none !important;
  box-shadow: none !important;
  color: var(--text-4) !important;
  font-size: 10.5px !important;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
}
#active_tools_box .dt-button:hover, #passive_tools_box .dt-button:hover {
  border-color: var(--accent-60) !important;
  color: var(--accent-tint) !important;
  background: var(--accent-10) !important;
}
#active_tools_box .dataTables_filter input, #passive_tools_box .dataTables_filter input {
  padding: 4px 8px !important;
  border: 1px solid var(--line-input) !important;
  border-radius: 6px !important;
  background: var(--bg-sunken) !important;
  color: var(--text-3) !important;
}

/* A row arriving over the websocket flashes once and settles. Replaces a
   jQuery animate() to literal `white`, which left the colour inline forever. */
@keyframes ld-row-flash {
  from { background-color: var(--accent-10); }
  to   { background-color: transparent; }
}
td.ld-row-flash { animation: ld-row-flash 1.4s ease-out; }

/* The saved-searches drawer's own close control, matching the canvas drawer. */
.ld-drawer-close {
  position: absolute; top: 10px; right: 12px; z-index: 3;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input); border-radius: 6px;
  background: var(--bg-sunken); color: var(--text-4);
  font-size: 11px; cursor: pointer;
  transition: border-color .12s, color .12s, background-color .12s;
}
.ld-drawer-close:hover { border-color: var(--danger-border); color: var(--danger); background: var(--danger-bg); }
.active_tools_side_box, .passive_tools_side_box { position: relative; }
/* Keep the drawer heading clear of the close button. */
.ld-tool-saved-panel { padding-right: 44px; }

/* Row action icons in the saved-searches drawer -- same treatment as the
   Search History window, which renders them with the same classes. */
#active_tools_box .action_icon, #passive_tools_box .action_icon {
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-input); border-radius: 6px;
  color: var(--text-4) !important; font-size: 11px; cursor: pointer;
}
#active_tools_box .action_icon:hover, #passive_tools_box .action_icon:hover {
  border-color: var(--accent-60); color: var(--text) !important;
}
#active_tools_box .del_icon:hover, #passive_tools_box .del_icon:hover {
  border-color: var(--danger-border); color: var(--danger) !important;
}
#active_tools_box .td-align-center, #passive_tools_box .td-align-center { display: flex; justify-content: center; }

/* The saved-searches drawer. */
.ld-tool-saved-panel { padding: 14px 16px; }
/* These tables auto-sized to their content, so one long saved search term --
   a favicon URL, typically -- pushed the Delete column past the drawer's right
   edge and out of reach. Fixed layout makes the widths bind and each cell
   truncates instead of widening its column.

   Percentages, not pixels, and every column specified:
     * DataTables writes its own `width: 1%` inline on the narrow columns,
       which beats any stylesheet selector, hence !important. 1% left Count,
       Load and Delete narrower than their own headers (35px against 64-74px),
       so the headers were themselves being ellipsised to "C...", "L...", "D...".
     * a column left at `auto`, `unset` or `calc(100% - Npx)` computes to *zero*
       under table-layout: fixed here rather than taking the remainder, so the
       term column vanished. Only an explicit width binds.
     * percentages resolve against the content box and the cell padding is
       added on top, so these sum to the full table width and keep doing so if
       the drawer is ever resized. */
.ld-tool-saved-panel table.ld-tool-table { table-layout: fixed; width: 100% !important; }
.ld-tool-saved-panel table.ld-tool-table th,
.ld-tool-saved-panel table.ld-tool-table td {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* # | Search term | Date | Count | Load | Delete */
.ld-tool-saved-panel table.ld-tool-table th:nth-child(1),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(1) { width: 9% !important; }
.ld-tool-saved-panel table.ld-tool-table th:nth-child(2),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(2) { width: 30% !important; }
.ld-tool-saved-panel table.ld-tool-table th:nth-child(3),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(3) { width: 20% !important; }
.ld-tool-saved-panel table.ld-tool-table th:nth-child(4),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(4) { width: 14% !important; }
.ld-tool-saved-panel table.ld-tool-table th:nth-child(5),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(5) { width: 12% !important; text-align: center; }
.ld-tool-saved-panel table.ld-tool-table th:nth-child(6),
.ld-tool-saved-panel table.ld-tool-table td:nth-child(6) { width: 15% !important; text-align: center; }
/* The pw-hash drawer is Hash | Cleartext Password | Date | Delete -- no # and
   no count, so the positional rules above do not describe it. */
.passive_pw_hash_load_box table.ld-tool-table th:nth-child(1),
.passive_pw_hash_load_box table.ld-tool-table td:nth-child(1) { width: 28% !important; text-align: left; }
/* "Cleartext Password" is the longest header in either drawer, so it gets the
   extra; the hashes beside it are fixed-length and truncate cleanly. */
.passive_pw_hash_load_box table.ld-tool-table th:nth-child(2),
.passive_pw_hash_load_box table.ld-tool-table td:nth-child(2) { width: 40% !important; text-align: left; }
.passive_pw_hash_load_box table.ld-tool-table th:nth-child(3),
.passive_pw_hash_load_box table.ld-tool-table td:nth-child(3) { width: 20% !important; text-align: left; }
.passive_pw_hash_load_box table.ld-tool-table th:nth-child(4),
.passive_pw_hash_load_box table.ld-tool-table td:nth-child(4) { width: 12% !important; text-align: center; }
/* Nothing inside a cell may widen it either. */
.ld-tool-saved-panel table.ld-tool-table td > *,
.ld-tool-saved-panel table.ld-tool-table td a {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; display: inline-block; vertical-align: middle;
}
.ld-tool-saved-panel table.ld-tool-table td .td-align-center { display: flex; }
/* And the drawer itself never scrolls sideways. */
.active_tools_side_box, .passive_tools_side_box { overflow-x: hidden; }
.ld-tool-saved-title {
  margin: 0 0 10px;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-5);
}

@media (max-width: 900px) {
  .ld-tool-head { flex-direction: column; gap: 10px; }
  .ld-tool-form { flex-wrap: wrap; }
  .ld-tool-input { flex: 1 1 100%; }
}

/* ---------- canvas: find and filter -------------------------------------- */
.canvas_find_wrap {
  position: absolute; top: 10px; right: 12px; z-index: 4;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 9px; height: 28px;
  border: 1px solid var(--line-input); border-radius: 8px;
  background: var(--panel-bg);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.canvas_find_icon { color: var(--text-5); font-size: 10px; }
.canvas_find_input {
  width: 130px; border: 0; background: none; outline: none;
  color: var(--text); font-size: 11.5px; font-family: inherit; padding: 0;
}
.canvas_find_input::placeholder { color: var(--text-5); }
.canvas_find_type {
  border: 0; background: none; outline: none;
  color: var(--text-4); font-size: 10.5px; font-family: inherit;
  max-width: 96px; cursor: pointer;
}
.canvas_find_type option { background: var(--panel-bg-2); color: var(--text-2); }
.canvas_find_count { color: var(--text-5); font-size: 10px; white-space: nowrap; min-width: 0; }
.canvas_find_wrap:focus-within { border-color: var(--accent-60); }

/* Inline rename in the saved-canvas list. Was a 3px solid black inline style. */
#canvas_saved_table td.ld-editing {
  outline: 1px solid var(--accent-60);
  border-radius: 5px;
  background: var(--bg-sunken);
}

/* Hover-card states, replacing inline color:green / color:red / #ff0000. */

/* Canvas minimap. Appears once the graph is large enough to need navigating. */
.canvas_minimap {
  position: absolute; bottom: 12px; right: 12px; z-index: 4;
  width: 168px; height: 118px;
  border: 1px solid var(--line-input); border-radius: 8px;
  background: var(--panel-bg);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
  cursor: crosshair; display: none;
}

/* ---------- canvas: context submenu, layouts, locked nodes ---------------- */
/* cytoscape-context-menus appends <img src="assets/submenu-indicator-default.svg">
   for the arrow. That path is relative to the page URL, so it 404s here and
   rendered as a broken-image glyph. Hide it and draw the caret in CSS. */
.cy-context-menus-submenu-indicator { display: none !important; }
.cy-context-menus-cxt-menuitem:has(> .cy-context-menus-cxt-menu)::after {
  /* A plain glyph rather than a FontAwesome codepoint: the icon font's family
     name varies between the FA 4 and FA 6 bundles this page loads. */
  content: '\25B8';
  float: right; opacity: .55; margin-left: 10px; font-size: 11px;
}
.cy-context-menus-cxt-menu .cy-context-menus-cxt-menu {
  max-height: 70vh; overflow-y: auto;
}

/* The layouts menu in the toolbar. */
#canvas_layout_menu {
  min-width: 190px; padding: 6px;
  display: none;
}
#canvas_layout_menu .ld-popover-btn {
  display: flex; align-items: center; gap: 9px;
  width: 100%; text-align: left; margin: 0 0 3px;
}
#canvas_layout_menu .ld-popover-btn:last-child { margin-bottom: 0; }

/* A locked node cannot be dragged, which reads as "broken" unless it is
   obvious. 22 of the saved canvases contain locked nodes. */
.canvas_minimap { touch-action: none; }

/* The find box and the minimap are positioned against the graph column, not
   .canvas_container -- the latter also holds the 400px side drawer, so both
   slid across the moment the drawer opened. */
#canvas_box .parent_cy_box { position: relative; }
/* The graph runs outside the page's CSS zoom.
 *
 * Cytoscape takes its live hit area from the container's clientWidth and
 * clientHeight (layout px) but its origin from getBoundingClientRect (visual
 * px). With `zoom` on <html> those disagree, and at 120% the bottom 156px and
 * right 331px of the graph were drawn but could not be clicked, dragged or
 * hovered. Undoing the zoom here and scaling the box up to compensate leaves
 * the graph the same size on screen with layout and visual pixels in step.
 * canvas_init.js keeps --ld-zoom in sync with the text-size setting. */
/* The unzoom goes on .cy_box, the graph's own wrapper, and no higher: popper
   positions the hover card against its offsetParent, and an offsetParent
   carrying its own `zoom` collapses its horizontal offsets -- every card ended
   up pinned to the left edge of the graph. .parent_cy_box therefore keeps only
   the inherited page zoom, which popper has always handled, and the anchor
   converts between the two frames (canvas_tooltip.js).

   The percentages need no compensation: Chrome resolves them against the
   parent in this element's own units, so with the zoom undone they land on the
   parent's edges and layout pixels equal visual pixels. */
#canvas_box .cy_box {
  zoom: var(--ld-graph-unzoom, 1);
  width: 100%;
  height: 113%;
}

/* The hover card's reference lives inside the graph box so that popper's
   reference, boundary and transform all share one coordinate system under the
   page's `zoom`. It is a positioning target only -- never visible, never
   clickable. */
#canvas_box .ld-canvas-tip-anchor {
  position: absolute; pointer-events: none; visibility: hidden; z-index: 0;
}

/* Canvas form checkbox - the box-in-box the rest of the console uses, but a
   native input. These were iCheck widgets whose plugin was never bound to
   them: the wrapper markup was present and styled, and clicking did nothing,
   so "Confirmed" could not be set and never saved. */
#canvas_box input.ld-check {
  appearance: none; -webkit-appearance: none;
  position: relative; margin: 0; vertical-align: middle;
  width: 16px; height: 16px; flex: none; cursor: pointer;
  border: 1.5px solid var(--line-input); border-radius: 3px;
  background: var(--bg-sunken);
  transition: border-color .12s, background-color .12s;
}
#canvas_box input.ld-check::after {
  content: ''; position: absolute; inset: 2px;
  border-radius: 1px; background: transparent;
  transition: background-color .12s;
}
#canvas_box input.ld-check:hover { border-color: var(--accent-60); }
#canvas_box input.ld-check:checked { border-color: var(--accent); }
#canvas_box input.ld-check:checked::after { background: var(--accent); }
#canvas_box input.ld-check:focus-visible { outline: 2px solid var(--accent-60); outline-offset: 2px; }
/* A disabled box (an expand result already on the canvas) still has to read as
   a checkbox rather than as empty space where one should be. */
#canvas_box input.ld-check:disabled {
  opacity: .4; cursor: default; border-style: dashed;
}
#canvas_box input.ld-check:disabled:hover { border-color: var(--line-input); }

/* ---- expand picker ------------------------------------------------------
 * Lives in the canvas drawer. The drawer is a fixed 400px column, so the list
 * is the only part that scrolls: header, tools and footer stay put while the
 * results page in underneath.
 */
#canvas_box .cy_expand_box { height: 100%; }
#canvas_box .ld-expand {
  display: flex; flex-direction: column;
  height: calc(100% - 16px);
  padding: 0 12px 12px;
  min-height: 0;
}
#canvas_box .ld-expand-head { padding: 0 0 9px; border-bottom: 1px solid var(--line-soft); }
#canvas_box .ld-expand-title {
  display: flex; align-items: baseline; gap: 8px; justify-content: space-between;
}
#canvas_box .ld-expand-term {
  font-family: 'JetBrains Mono', monospace; font-size: 12.5px; font-weight: 700;
  color: var(--accent-tint); word-break: break-all; min-width: 0;
}
#canvas_box .ld-expand-chip {
  flex: none; font-size: 9px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-6);
  background: var(--panel-bg-2); border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 2px 8px;
}
#canvas_box .ld-expand-sub { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 7px; }
#canvas_box .ld-expand-rel {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-6);
}
#canvas_box .ld-expand-rel b {
  font-family: 'JetBrains Mono', monospace; color: var(--text-3); font-weight: 700;
  text-transform: none; letter-spacing: 0; margin-left: 3px;
}
/* Without a mark between them the counts read as one run of text:
   "dns records 12subdomains 1certs 62". */
#canvas_box .ld-expand-rel + .ld-expand-rel::before {
  content: '\00b7'; color: var(--text-7, var(--text-6)); margin-right: 8px;
}
#canvas_box .ld-expand-dim { font-size: 11px; color: var(--text-6); }

/* Datasets across the top, types within the one that is open. */
#canvas_box .ld-expand-datasets,
#canvas_box .ld-expand-types { display: flex; flex-wrap: wrap; gap: 4px; }
#canvas_box .ld-expand-datasets { padding: 9px 0 0; }
#canvas_box .ld-expand-types { padding: 7px 0 0; }
#canvas_box .ld-expand-tab,
#canvas_box .ld-expand-type {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--panel-bg-2); border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 3px 9px; cursor: pointer;
  font-size: 10px; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; color: var(--text-5);
  transition: border-color .12s, color .12s, background-color .12s;
}
#canvas_box .ld-expand-tab b,
#canvas_box .ld-expand-type b {
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; font-weight: 700;
  color: var(--text-3); letter-spacing: 0;
}
#canvas_box .ld-expand-tab:hover:not(:disabled),
#canvas_box .ld-expand-type:hover { border-color: var(--accent-60); color: var(--text-2); }
#canvas_box .ld-expand-tab.is-on,
#canvas_box .ld-expand-type.is-on {
  border-color: var(--accent); color: var(--accent-tint); background: var(--accent-16);
}
#canvas_box .ld-expand-tab.is-on b,
#canvas_box .ld-expand-type.is-on b { color: var(--accent-tint); }
/* An empty dataset stays visible: "none here" is an answer, and hiding it
   would make the set of datasets look different from one node to the next. */
#canvas_box .ld-expand-tab.is-empty {
  opacity: .38; cursor: default; border-style: dashed;
}
#canvas_box .ld-expand-type { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 10.5px; }

#canvas_box .ld-expand-tools {
  display: flex; align-items: center; gap: 10px; padding: 9px 0;
}
#canvas_box .ld-expand-all {
  display: flex; align-items: center; gap: 7px; margin: 0 !important;
  cursor: pointer; flex: none;
}
#canvas_box .ld-expand-all span {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-5); font-weight: 700;
}
#canvas_box input.ld-expand-filter {
  flex: 1 1 auto; min-width: 0;
  background: var(--bg-sunken) !important;
  border: 1px solid var(--line-input) !important;
  color: var(--text-2) !important;
  border-radius: 6px; font-size: 11.5px; padding: 5px 9px;
}
#canvas_box input.ld-expand-filter:focus { border-color: var(--accent-60) !important; outline: none; }

#canvas_box .ld-expand-list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  border: 1px solid var(--line-soft); border-radius: 8px;
  background: var(--bg-sunken);
}
#canvas_box .ld-expand-row {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 8px 10px; margin: 0 !important; cursor: pointer;
  border-bottom: 1px solid var(--line-soft);
  text-transform: none !important; letter-spacing: 0 !important;
  font-weight: 400 !important; font-size: 12px !important;
  color: var(--text-2) !important;
}
#canvas_box .ld-expand-row:last-child { border-bottom: none; }
#canvas_box .ld-expand-row:hover { background: var(--panel-bg-2); }
#canvas_box .ld-expand-row input.ld-check { margin-top: 1px; }
#canvas_box .ld-expand-row.is-here { opacity: .55; cursor: default; }
/* A record that matched but had nothing to add: visible so the count and the
   list agree, greyed so it is clearly not on offer. */
#canvas_box .ld-expand-row.is-unavailable { opacity: .45; cursor: default; }
#canvas_box .ld-expand-row.is-unavailable .ld-expand-value { text-decoration: line-through; }
#canvas_box .ld-expand-missing {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  border-radius: 999px; padding: 1px 7px;
  color: var(--text-6); border: 1px dashed var(--line-soft);
}
#canvas_box .ld-expand-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#canvas_box .ld-expand-value {
  font-family: 'JetBrains Mono', monospace; font-size: 11.5px;
  color: var(--text-2); word-break: break-all; line-height: 1.35;
}
#canvas_box .ld-expand-meta { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
#canvas_box .ld-expand-tag,
#canvas_box .ld-expand-relation,
#canvas_box .ld-expand-here,
#canvas_box .ld-expand-note {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  border-radius: 999px; padding: 1px 7px; border: 1px solid var(--line-soft);
}
#canvas_box .ld-expand-tag { color: var(--text-5); background: var(--panel-bg-2); }
#canvas_box .ld-expand-relation { color: var(--accent-tint); border-color: var(--accent-60); }
#canvas_box .ld-expand-here { color: var(--text-6); border-style: dashed; }
#canvas_box .ld-expand-note {
  color: var(--text-6); border: none; padding: 1px 0;
  text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 10.5px;
}
#canvas_box .ld-expand-loading,
#canvas_box .ld-expand-end,
#canvas_box .ld-expand-empty {
  padding: 12px 10px; text-align: center;
  font-size: 11px; color: var(--text-6);
}
#canvas_box .ld-expand-end { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; }

#canvas_box .ld-expand-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding-top: 10px;
}
#canvas_box .ld-expand-count {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-6);
}
#canvas_box .ld-expand-add:disabled { opacity: .45; cursor: default; }

/* Toolbar toggles that stay lit while their feature is on. */
#canvas_box .minimap_canvas_button.is-on .canvas_button { color: var(--accent) !important; }


/* ---------- Stealer Host Details: archive history + unlock wait ---------- */

.lh-wait-actions { margin-top: 12px; }
.lh-wait-armed { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ok-text); }

/* Two tabs down the side of the Files pane: the tree for this log, and every
   archive the account has opened. */
.lh-fm-sidetabs { display: flex; flex-shrink: 0; border-bottom: 1px solid var(--line); }
.lh-fm-sidetab {
  flex: 1 1 0; min-width: 0; padding: 11px 8px 9px; border: 0; background: none;
  font: inherit; font-size: 11.5px; font-weight: 600; color: var(--text-5);
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .12s;
}
.lh-fm-sidetab:hover { color: var(--text-2); }
.lh-fm-sidetab.is-on { color: var(--accent); border-bottom-color: var(--accent); }
.lh-fm-sidetab .lh-dim { font-weight: 400; color: var(--text-6); margin-left: 3px; }
.lh-fm-sidetab.is-on .lh-dim { color: var(--accent); opacity: .75; }

.lh-fm-sidepane { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.lh-fm-sidepane[hidden] { display: none; }

.lh-arch-panel { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 0 0 14px; }

.lh-arch-empty {
  padding: 26px 14px; text-align: center; font-size: 12.5px; color: var(--text-5);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.lh-arch-empty > i { font-size: 20px; color: var(--text-6); }
.lh-arch-note { margin: 10px 12px 0; font-size: 11px; line-height: 1.5; color: var(--text-6); }

/* Full-bleed rows: the panel has no side padding, so each one spans the whole
   sidepane and they are separated by a rule rather than being inset cards.
   Name on top, count and state beneath -- 280px will not hold all three on one
   line. The left border is the state marker. */
.lh-arch-row {
  display: flex; align-items: stretch; width: 100%; min-width: 0; box-sizing: border-box;
  border-bottom: 1px solid var(--line-soft);
  border-left: 2px solid transparent;
  transition: border-left-color .12s, background .12s;
}
.lh-arch-row:hover { background: var(--bg-hover); }
.lh-arch-row:hover:not(.is-here):not(.is-failed):not(.is-processing) { border-left-color: var(--accent); }

/* The clickable content; a button when the log can be reopened, a plain div
   when it cannot (processing, failed, or the log already on screen). */
.lh-arch-main {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px;
  box-sizing: border-box; padding: 10px 6px 10px 10px;
  border: 0; background: none; color: var(--text-2); font: inherit; font-size: 12px;
  text-align: left; cursor: pointer;
}
.lh-arch-static { cursor: default; }

.lh-arch-top { display: flex; align-items: center; gap: 7px; min-width: 0; }
.lh-arch-top > i { color: var(--accent); font-size: 12px; flex: none; }
.lh-arch-name {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-family: ui-monospace, monospace; font-size: 11.5px;
}
.lh-arch-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding-left: 19px; }
.lh-arch-count { font-size: 11px; color: var(--text-5); }
.lh-arch-state { font-size: 11px; color: var(--ok-text); white-space: nowrap; }

/* Remove-from-history (x); only on expired/failed rows. */
.lh-arch-clear {
  flex: none; width: 30px; border: 0; background: none; cursor: pointer;
  color: var(--text-6); font-size: 12px;
}
.lh-arch-clear:hover { color: var(--danger); }

/* Expired: kept as a record, but visibly spent. */
.lh-arch-row.is-expired { opacity: .6; }
.lh-arch-row.is-expired .lh-arch-top > i,
.lh-arch-row.is-expired .lh-arch-state { color: var(--text-6); }

/* Being processed right now. */
.lh-arch-row.is-processing .lh-arch-top > i { color: var(--accent); }
.lh-arch-row.is-processing .lh-arch-state { color: var(--text-4); font-style: italic; }

/* Failed to extract. */
.lh-arch-row.is-failed .lh-arch-top > i { color: var(--danger); }
.lh-arch-row.is-failed .lh-arch-state { color: var(--danger); }

.lh-arch-row.is-here { background: var(--bg-hover); border-left-color: var(--accent); }
.lh-arch-row.is-here .lh-arch-top > i,
.lh-arch-row.is-here .lh-arch-state { color: var(--accent); }

/* Toolbar above the list (Clear expired). */
.lh-arch-tools { display: flex; justify-content: flex-end; padding: 8px 12px 4px; }
.lh-linkbtn { background: none; border: 0; padding: 0; font: inherit; font-size: 12px; color: var(--accent); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.lh-linkbtn:hover { text-decoration: underline; }

/* Credential cells carry the shared .ld-cell-tools kebab. */
#lh .lh-cell { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; }
#lh .lh-cell .ld-cell-tools { flex: none; }
#lh .lh-secret .lh-cell { gap: 6px; }

/* ---------- bulk export menu -------------------------------------------------
   Lives in the results panel, OUTSIDE .universal_search, so it cannot use the
   .universal_search-scoped .dropdown-content rules (that was why the old popup
   had no positioning and picked up bootstrap.css's margin-top:48px). Its own
   themed popover, matching the .ld-tag-picker pattern. */
.ld-bulk-row { align-items: center; }
.ld-bulk { position: relative; display: inline-flex; }
.ld-bulk-trigger {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  line-height: 18px;
}
.ld-bulk-trigger:hover { border-color: var(--accent-60); color: var(--text); }
.ld-bulk-trigger i { font-size: 11px; color: var(--accent); }
.ld-bulk-trigger .ld-bulk-caret { color: var(--text-5); font-size: 9px; margin-left: 1px; transition: transform 0.15s; }
.ld-bulk-trigger[aria-expanded="true"] { border-color: var(--accent); color: var(--text); }
.ld-bulk-trigger[aria-expanded="true"] .ld-bulk-caret { transform: rotate(180deg); }
.ld-bulk-menu {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
  min-width: 212px; padding: 6px;
  background: var(--panel-bg-2); border: 1px solid var(--line);
  border-radius: 9px; box-shadow: var(--shadow-menu);
}
.ld-bulk-menu.is-open { display: block; }
.ld-bulk-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: 6px; background: none;
  color: var(--text-3); font-size: 12.5px; font-weight: 500; line-height: 18px;
  text-align: left; cursor: pointer; white-space: nowrap; font-family: inherit;
}
.ld-bulk-item i { width: 15px; text-align: center; font-size: 12px; color: var(--accent); flex-shrink: 0; }
.ld-bulk-item:hover { background: var(--bg-hover); color: var(--text); }
.ld-bulk-item:disabled { opacity: 0.45; cursor: not-allowed; }
.ld-bulk-item:disabled:hover { background: none; color: var(--text-3); }

/* ---------- recent / frequent search suggestions (search_suggest.js) ---------- */
.universal_search .ld-suggest { position: absolute; z-index: 40; max-height: 320px; overflow-x: hidden; overflow-y: auto; padding: 4px; background: var(--panel-bg); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-menu); }
.universal_search .ld-suggest[hidden] { display: none; }
.ld-suggest-head { padding: 6px 8px 3px; font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-5); }
.ld-suggest-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; padding: 7px 8px; border: 0; border-radius: 6px; background: transparent; color: var(--text); font-size: 12.5px; text-align: left; cursor: pointer; }
.ld-suggest-item:hover, .ld-suggest-item.is-active { background: var(--accent-10); }
.ld-suggest-term { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-suggest-tag { flex-shrink: 0; font-size: 10.5px; color: var(--text-5); }

/* ---------- click-to-sort result table headers (table_sort.js) ---------- */
.ld-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.ld-sortable::after { content: '\2195'; margin-left: 6px; font-size: 10px; opacity: .3; }
.ld-sortable:hover::after { opacity: .7; }
.ld-sortable:focus-visible { outline: 2px solid var(--accent-60); outline-offset: -2px; }
.ld-sortable[aria-sort="ascending"]::after { content: '\25B2'; opacity: 1; color: var(--accent); }
.ld-sortable[aria-sort="descending"]::after { content: '\25BC'; opacity: 1; color: var(--accent); }
.ld-sort-note { color: var(--text-5); }

/* ---------- saved data points: the star on a saved value, and the Saved DataPoints window (saved_points.js) ---------- */
.ld-saved-star { flex-shrink: 0; font-size: 10px; color: var(--accent); line-height: 1; }
.ld-dp-muted { font-size: 11px; color: var(--text-5); }
.ld-dp-note-btn { background: none; border: 0; padding: 2px 6px; color: var(--text-5); cursor: pointer; border-radius: 4px; }
.ld-dp-note-btn:hover { background: var(--bg-hover); color: var(--text); }
.ld-dp-note-btn.has-note { color: var(--accent); }
#saved_datapoint_table tbody tr:not(.ld-dp-detail-row) { cursor: pointer; }
#saved_datapoint_table tr.ld-dp-open > td { border-bottom-color: transparent; }
.ld-dp-detail { display: flex; flex-direction: column; gap: 8px; padding: 6px 4px 10px; cursor: default; }
.ld-dp-ctx { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 3px 14px; margin: 0; font-size: 12px; }
.ld-dp-ctx dt { color: var(--text-5); font-weight: 600; }
.ld-dp-ctx dd { margin: 0; color: var(--text); overflow-wrap: anywhere; }
.ld-dp-label { margin: 4px 0 0; font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-5); }
.ld-dp-note { width: 100%; min-height: 64px; resize: vertical; padding: 8px 10px; font-size: 12.5px; color: var(--text); background: var(--bg-sunken); border: 1px solid var(--line-input); border-radius: 6px; }
.ld-dp-note:focus { outline: none; border-color: var(--accent-60); }
.ld-dp-actions { display: flex; align-items: center; gap: 10px; }
.ld-dp-status { font-size: 11px; color: var(--text-5); }

/* DataTables tints whichever column a table is sorted on (a light block, white in a dark window). The history-window tables
   (search history, discovery chains, saved data points) never got the override the other pages carry. */
table.history-window.dataTable tbody tr > .sorting_1,
table.history-window.dataTable tbody tr > .sorting_2,
table.history-window.dataTable tbody tr > .sorting_3,
table.history-window.dataTable tbody tr:hover > .sorting_1 { background: transparent !important; }
/* One line, cut with an ellipsis: the full text is in the cell's tooltip, so a long search term cannot widen the table. */
#saved_datapoint_table td.ld-dp-searched { max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- search history: grouped rows, the drawer under a row, the x N count (dashboard.js get_history) ---------- */
.ld-hx-count { margin-left: 6px; padding: 1px 6px; font-size: 10.5px; font-weight: 700; color: var(--text-4, var(--text-5)); background: var(--bg-sunken); border: 1px solid var(--line-input); border-radius: 999px; }
.ld-hx-when { white-space: nowrap; }
#search_history_table tbody tr:not(.details_box) { cursor: pointer; }
#search_history_table tr.shown > td { border-bottom-color: transparent; }
.ld-hd { display: flex; flex-direction: column; gap: 6px; padding: 10px 14px 12px 44px; background: var(--bg-sunken); border-left: 2px solid var(--accent); }
.ld-hd-run { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.ld-hd-when { flex: 0 0 150px; font-size: 11.5px; color: var(--text-5); }
.ld-hd-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.ld-hchip { padding: 2px 8px; font-size: 11.5px; color: var(--text); background: var(--accent-10); border: 1px solid var(--accent-50); border-radius: 999px; white-space: nowrap; }
.ld-hchip b { font-weight: 600; margin-right: 3px; color: var(--accent-tint); }
/* the inline "Sure?" delete lives in narrow table cells */
.history-window .re-actions, #saved_datapoint_table .re-actions { justify-content: center; }

/* Dataset name at the top of the results panel, so it is always clear which dataset the table is showing. */
.ac-resulthead { display: flex; align-items: baseline; gap: 10px; padding: 11px 18px 10px; border-bottom: 1px solid var(--line); }
.ac-resulthead-icon { color: var(--accent); font-size: 12px; align-self: center; }
.ac-resulthead-name { font-size: 14px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.ac-resulthead-count { font-size: 11.5px; color: var(--text-4); font-variant-numeric: tabular-nums; }
.ac-resulthead-name:empty, .ac-resulthead:has(.ac-resulthead-name:empty) { display: none; }

/* Screenshot thumbnail states: spinner while the NAS wakes, retry icon on failure. */
.lh-shot-thumb[data-state="loading"] { cursor: progress; color: var(--accent); }
.lh-shot-thumb[data-state="failed"] { color: var(--danger); border-color: var(--danger-border); }
.lh-shot-status { font-size: 11px; color: var(--text-4); line-height: 1.5; margin-top: 2px; max-width: 34ch; }
.lh-shot-status.error { color: var(--danger); }
