/* Safari/Chrome auto-detect 强制覆盖：数字不变色 */
#batch-fixed-info a, #batch-fixed-info a:visited,
.scan-table-wrap a, .scan-table-wrap a:visited,
.metrics-bar a, .metrics-bar a:visited {
  color: inherit !important; text-decoration: none !important; font-weight: inherit !important;
}
/* CodeMirror 适配 */
.CodeMirror { height: 100%; font-size: 12px; font-family: 'SF Mono', monospace; border: 1px solid var(--c-input-border); border-radius: 4px; }

/* color-scheme 告诉浏览器 UA 控件 (date picker 日历图标 / select 箭头 / scrollbar /
   autofill / 原生表单) 用哪套配色. 没这个默认 light, 导致深色主题里 UA 图标是
   黑色的 bug (用户反馈"icon 都是黑色的"). */
:root, [data-theme="dark"] { color-scheme: dark; }
[data-theme="light"] { color-scheme: light; }

:root, [data-theme="dark"] {
  /* 色彩系统: 对齐 tfund3 / Mantine dark, 中性灰, 不偏蓝紫 */
  --c-long: #51cf66;
  --c-short: #ff6b6b;
  --c-long-fill: 81,207,102;
  --c-short-fill: 255,107,107;
  --c-pnl: #e9ecef;
  --c-text: #c1c2c5;
  --c-text-dim: #909296;
  --c-legend-bg: rgba(26,27,30,0.94);
  --c-ic: #fcc419;
  --c-factor: #cc5de8;
  /* Layer 0: 页面底色 */
  --c-body: #1a1b1e;
  --c-body-text: #c1c2c5;
  /* Layer 1: 面板/工具栏/表头 */
  --c-surface: #25262b;
  /* Layer 2: 内容区 — 图表、卡片 */
  --c-bg: #2c2e33;
  /* Layer 2b: 表格区 — 与 body 一致, 避免白花花 */
  --c-table-bg: #1a1b1e;
  /* Layer 3: 输入框 */
  --c-input-bg: #2c2e33;
  --c-input-border: #373a40;
  --c-input-text: #c1c2c5;
  /* 边框与分隔线 */
  --c-border: #373a40;
  --c-grid: #25262b;
  --c-chart-text: #909296;
  --c-sep: #373a40;
  --c-label: #909296;
  /* 按钮 — Mantine blue-6 */
  --c-btn: #4dabf7;
  --c-btn-sec: #373a40;
  /* 表单控件系统级尺寸 (input / select / textarea / .cdd-trigger / date picker
     全部用这几个变量, 单一真源). 改这里 = 改全站 form 高度. */
  --form-h: 24px;
  --form-pad-y: 3px;
  --form-pad-x: 6px;
  --form-fs: 12px;
  --form-radius: 3px;
  /* 下拉/select 默认最大宽度 — 即便所在 flex 行很空也别撑满整行 (Grafana 风) */
  --dd-max-w: 288px;
  /* 按钮系统级尺寸 (Button.js 所有按钮 + 顶级 button 规则都读这组, 改这里 = 全站统一) */
  --ui-btn-h: 26px;
  --ui-btn-h-sm: 22px;
  --ui-btn-h-xs: 18px;
  --ui-btn-fs: 12px;
  --ui-btn-fs-sm: 11px;
  --ui-btn-fs-xs: 10px;
  --ui-btn-pad-x: 10px;
  --ui-btn-pad-x-sm: 8px;
  --ui-btn-pad-x-xs: 6px;
  --ui-btn-radius: 3px;
  /* Icon 尺寸 (button 内嵌 icon / 独立 icon 都读这组).
     v2 整体上调 +2~4px: 小图标视觉可读性强, 减少"点不到"的感觉. */
  --ui-icon-lg: 22px;    /* 全屏 ⛶ / 关闭 ✕ / 下拉箭头 / 删除 × */
  --ui-icon-md: 17px;    /* 齿轮 ⚙ / 中等状态指示 / 表头 sort 箭头 */
  --ui-icon-sm: 13px;    /* 小圆点 / 小标记 */
}
[data-theme="light"] {
  --c-long: #15803d;
  --c-short: #b91c1c;
  --c-long-fill: 22,128,61;
  --c-short-fill: 185,28,28;
  --c-pnl: #111;
  --c-text: #333;
  --c-text-dim: #999;
  --c-legend-bg: rgba(255,255,255,0.9);
  --c-ic: #d97706;
  --c-factor: #7c3aed;
  --c-bg: #ffffff;
  --c-surface: #f5f5f5;
  --c-border: #e0e0e0;
  --c-body: #fafafa;
  --c-body-text: #222;
  --c-input-bg: #fff;
  --c-input-border: #ccc;
  --c-input-text: #222;
  --c-grid: #f0f0f0;
  --c-chart-text: #666;
  --c-sep: #ddd;
  --c-label: #888;
  --c-btn: #2563eb;
  --c-btn-sec: #d1d5db;
  --c-table-bg: #f8f8f8;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, 'SF Mono', monospace; background: var(--c-body); color: var(--c-body-text); font-size: 13px; }

/* ==== Layout utilities (替代散落 inline style="display:flex; align-items:center; gap:Npx") ==== */
.row { display: flex; align-items: center; }
.col { display: flex; flex-direction: column; }
.gap-2 { gap: 2px; } .gap-3 { gap: 3px; } .gap-4 { gap: 4px; }
.gap-6 { gap: 6px; } .gap-8 { gap: 8px; } .gap-10 { gap: 10px; } .gap-12 { gap: 12px; }
.ml-auto { margin-left: auto; }
.flex-1 { flex: 1; }
.flex-fill { flex: 1; min-height: 0; min-width: 0; }
.no-shrink { flex-shrink: 0; }
.text-dim { color: var(--c-text-dim); }
.text-label { color: var(--c-label); }
.text-body { color: var(--c-body-text); }
.text-short { color: var(--c-short); }
.text-long { color: var(--c-long); }
.fs-9 { font-size: 9px; } .fs-10 { font-size: 10px; } .fs-11 { font-size: 11px; }
.fs-12 { font-size: 12px; } .fs-13 { font-size: 13px; } .fs-14 { font-size: 14px; }
.fw-400 { font-weight: 400; } .fw-500 { font-weight: 500; } .fw-600 { font-weight: 600; } .fw-700 { font-weight: 700; }
.nowrap { white-space: nowrap; }
.center { text-align: center; }
.right { text-align: right; }
.hidden { display: none !important; }
.mono { font-family: 'SF Mono', monospace; }
.cur-pointer { cursor: pointer; }
.bd-input { border-bottom: 1px solid var(--c-input-border); }
.bd-border { border-bottom: 1px solid var(--c-border); }
.h-100 { height: 100%; }
.pos-rel { position: relative; }
.empty-msg { color: var(--c-text-dim); text-align: center; padding: 12px; }
/* 数据树叶子行 meta cell: 时间/大小列 (data tab 搜索结果). */
.dtree-meta {
  padding: 1px 6px; border-bottom: 1px solid var(--c-input-border);
  white-space: nowrap; color: var(--c-text-dim); font-size: 10px; text-align: left;
}
/* 紧凑表 cell padding 3x6 (favorites/portfolio/scan 等紧凑列表共用). */
.cell-3-6 { padding: 3px 6px; }
.cell-3-6-r { padding: 3px 6px; text-align: right; }

/* === Dashboard variables bar (Grafana Variables 风) === */
.an-varbar {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-bottom: 1px solid var(--c-border);
  background: var(--c-surface); flex-shrink: 0; min-height: 32px;
}
.an-varbar-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 6px 3px 8px; border-radius: 11px;
  background: var(--c-bg);
  border: 1px solid var(--c-input-border);
  color: var(--c-text-dim);
  font-size: 11px; line-height: 1.2; cursor: pointer;
  user-select: none; transition: all 0.15s;
}
.an-varbar-chip:hover { border-color: var(--c-btn); color: var(--c-body-text); }
.an-varbar-chip.has-value { color: var(--c-body-text); border-color: var(--c-btn); background: color-mix(in srgb, var(--c-btn) 12%, transparent); }
.an-varbar-chip-icon { font-size: 12px; line-height: 1; }
.an-varbar-chip-label {
  font-family: ui-monospace, monospace; font-weight: 500;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.an-varbar-chip-arrow { color: var(--c-text-dim); font-size: 9px; margin-left: 2px; }
.an-varbar-clear { margin-left: auto; }
.an-dashboard-host-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.an-dashboard-section { display: flex; flex-direction: column; height: 100%; }

.an-varbar-pop {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 4px; padding: 6px; min-width: 200px; max-width: 320px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  font-size: 11px;
}
.an-varbar-pop-head {
  font-weight: 600; padding: 2px 4px 6px; border-bottom: 1px solid var(--c-border); margin-bottom: 6px;
}
.an-varbar-pop-row { display: flex; align-items: center; gap: 6px; padding: 4px 0; }
.an-varbar-pop-input { flex: 1; min-width: 0; font-size: 11px; }
.an-varbar-pop-list { max-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: 1px; }
.an-varbar-pop-item {
  padding: 4px 8px; border-radius: 3px; cursor: pointer;
  font-family: ui-monospace, monospace;
}
.an-varbar-pop-item:hover { background: rgba(125,125,140,0.15); }
.an-varbar-pop-item.active { background: color-mix(in srgb, var(--c-btn) 20%, transparent); color: var(--c-btn); font-weight: 600; }
.an-varbar-pop-quick { display: flex; gap: 4px; flex-wrap: wrap; padding: 2px 0; }

/* === ChipFilterBar (Linear/Notion 风 chip 过滤器) === */
.cfb { width: 100%; }
.cfb-chips {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  padding: 4px 0;
}
.cfb-chip {
  --cfb-c: var(--c-text-dim);
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 4px 2px 8px; border-radius: 10px;
  background: color-mix(in srgb, var(--cfb-c) 18%, transparent);
  color: var(--c-body-text);
  border: 1px solid color-mix(in srgb, var(--cfb-c) 35%, transparent);
  font-size: 11px; line-height: 1; cursor: pointer; max-width: 280px;
  user-select: none;
}
.cfb-chip:hover { background: color-mix(in srgb, var(--cfb-c) 28%, transparent); }
.cfb-chip-field { color: var(--c-text-dim); font-weight: 400; }
.cfb-chip-op { color: var(--c-text-dim); margin: 0 1px; }
.cfb-chip-val { color: var(--c-body-text); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 200px; }
.cfb-chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%; cursor: pointer;
  color: var(--c-text-dim); font-size: 14px; line-height: 1;
  margin-left: 2px;
}
.cfb-chip-x:hover { background: rgba(0,0,0,0.25); color: #fff; }
.cfb-chip-multi .cfb-chip-val { font-style: italic; }
/* + add 按钮: chip 风虚线灰底, 容纳 '+' 或 '(+筛选)' 这种带文案. 与 .data-chip-add
   视觉一致 (虚线 + 透明底 + hover 亮起) — 单字符时居中收紧, 多字符时自适应宽度. */
.cfb-add {
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  min-width: 22px; height: 22px; padding: 0 8px; border-radius: 11px;
  border: 1px dashed var(--c-border);
  background: color-mix(in srgb, var(--c-text-dim) 8%, transparent);
  color: var(--c-text-dim);
  font-size: 11px; line-height: 1; cursor: pointer; user-select: none;
  transition: all 0.15s;
}
.cfb-add:hover {
  border-color: var(--c-btn); color: var(--c-btn); border-style: solid;
  background: color-mix(in srgb, var(--c-btn) 12%, transparent);
}
.cfb-popover {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 4px; padding: 6px; min-width: 220px; max-width: 320px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  font-size: 11px;
}
.cfb-pop-head {
  font-weight: 600; padding: 4px 6px 6px; border-bottom: 1px solid var(--c-border);
  margin-bottom: 6px;
}
.cfb-pop-search {
  width: 100%; box-sizing: border-box; margin-bottom: 4px;
  font-size: 11px;
}
.cfb-pop-list {
  max-height: 300px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 1px;
}
.cfb-pop-item {
  padding: 4px 8px; border-radius: 3px; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
}
.cfb-pop-item:hover { background: rgba(125,125,140,0.15); }
.cfb-pop-label { color: var(--c-body-text); }
.cfb-pop-type {
  color: var(--c-text-dim); font-family: 'SF Mono', monospace;
  font-size: 10px; opacity: 0.6;
}
.cfb-pop-row {
  display: flex; align-items: center; gap: 6px; padding: 4px 0;
}
.cfb-pop-3seg { gap: 4px; }
.cfb-pop-3seg .cfb-pop-input { flex: 1; min-width: 0; font-size: 11px; }
/* op dropdown — 1-2 字符 op 视觉收一档, arrow 缩, 不动 bg/border 保留可见性 */
.cfb-pop-3seg .cfb-op-dd .cdd-trigger { padding-left: 6px; padding-right: 2px; justify-content: center; }
.cfb-pop-3seg .cfb-op-dd .cdd-arrow { font-size: 8px; opacity: 0.5; margin-left: 1px; }
/* multi-chip 编辑器顶部已有值列表 */
.cfb-pop-vals {
  display: flex; flex-wrap: wrap; gap: 4px; padding: 4px 2px;
  border-bottom: 1px solid var(--c-border); margin-bottom: 4px;
  max-height: 120px; overflow-y: auto;
}
.cfb-pop-val-row {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px 4px 2px 6px; border-radius: 8px;
  background: rgba(125,125,140,0.18); font-size: 10px;
}
.cfb-pop-val-text { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfb-pop-actions {
  display: flex; justify-content: flex-end; padding: 6px 0 2px;
  gap: 4px;
}
.cfb-pop-checks { padding: 2px 0; }
.cfb-pop-check {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 6px; border-radius: 3px; cursor: pointer;
  user-select: none;
}
.cfb-pop-check:hover { background: rgba(125,125,140,0.15); }
.cfb-pop-check input { margin: 0; }
.cfb-pop-empty { padding: 8px; color: var(--c-text-dim); text-align: center; }
.cfb-suggest-slot { display: contents; }
.cfb-suggest {
  display: flex; flex-wrap: wrap; gap: 3px;
  padding: 4px 0 0; max-width: 100%;
  flex-basis: 100%;   /* 换行到 input 下方 */
  max-height: 120px; overflow-y: auto;
}
.cfb-suggest-item {
  display: inline-flex; align-items: center;
  padding: 1px 6px; border-radius: 8px;
  background: rgba(125,125,140,0.15); color: var(--c-body-text);
  font-size: 10px; cursor: pointer; user-select: none;
}
.cfb-suggest-item:hover { background: rgba(125,125,140,0.30); }
.cfb-suggest-empty {
  font-size: 10px; color: var(--c-text-dim); padding: 2px 6px;
}

/* === Drilldown side panel (cell click 后右侧 slide-in) === */
.drill-panel {
  position: fixed; right: 0; top: 0; bottom: 0;
  width: 40%; min-width: 420px; max-width: 720px;
  background: var(--c-surface); border-left: 1px solid var(--c-border);
  box-shadow: -4px 0 20px rgba(0,0,0,0.4);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform 0.25s ease-out;
  z-index: 9000;
}
.drill-panel.open { transform: translateX(0); }
.drill-panel-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--c-border);
  background: var(--c-bg);
}
.drill-panel-title { flex: 1; font-weight: 600; font-size: 12px; }
.drill-panel-actions { flex-shrink: 0; }
.drill-panel-body {
  flex: 1; overflow: auto; display: flex; flex-direction: column;
  padding: 8px;
}

/* 全局表单元素暗色适配 — checkbox/radio 除外.
   尺寸/配色由 --form-* 变量统一管理, 保证 input/select/cdd-trigger 整齐. */
input:not([type="checkbox"]):not([type="radio"]), select, textarea {
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  font-family: inherit; font-size: var(--form-fs); border-radius: var(--form-radius);
  padding: var(--form-pad-y) var(--form-pad-x);
  box-sizing: border-box; line-height: 1.4;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="date"]):not([type="color"]):not([type="range"]),
select, textarea { height: var(--form-h); }
/* 原生 <select> 还没迁到 createDropdown 的, 暂时跟着 cdd 同样的 max-width 卡 */
select { max-width: var(--dd-max-w); }
select[style*="width"] { max-width: none; }  /* 显式 width 覆盖 */

/* 统一 input "最大长度 = 视觉宽度" 模式. 用法:
     <input maxlength="5" data-fit="maxlength">  -> width ≈ 5 字符宽
     <select data-fit="content">                 -> width: auto 按内容
   配合 input[maxlength] 的 attr() 尚不普适, 退而用 JS 在 DOMContentLoaded
   遍历设 inline style. 若未设 maxlength, fit=maxlength 回落到 content.
   select 永远按 content 算. */
input[data-fit="maxlength"], input[data-fit="content"],
select[data-fit="content"], select[data-fit="maxlength"] {
  width: auto; min-width: 0;
}

/* ==== 统一 Button 组件 (createButton → .btn). 不再有 .sec / .ghost fallback;
   .cfg-btn 重命名为 .btn--cfg (见下方). ==== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  height: var(--ui-btn-h); padding: 0 var(--ui-btn-pad-x);
  font-size: var(--ui-btn-fs); font-weight: 500; font-family: inherit;
  border: none; border-radius: var(--ui-btn-radius); cursor: pointer;
  background: var(--c-btn); color: #fff;
  box-sizing: border-box; line-height: 1; white-space: nowrap;
  transition: filter .12s, background .12s, border-color .12s;
}
.btn:hover { filter: brightness(1.1); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; filter: none; }
.btn--sm { height: var(--ui-btn-h-sm); padding: 0 var(--ui-btn-pad-x-sm); font-size: var(--ui-btn-fs-sm); }
.btn--xs { height: var(--ui-btn-h-xs); padding: 0 var(--ui-btn-pad-x-xs); font-size: var(--ui-btn-fs-xs); }
.btn--sec { background: color-mix(in srgb, var(--c-btn-sec) 55%, transparent); color: var(--c-body-text); }
.btn--sec:hover { background: var(--c-btn-sec); filter: none; }
/* ghost: 几乎透明 (6%) — 静态时减少"灰色洪水"观感, hover 时显色块反馈 (24%).
   2026-04-28 36e1652 改成色块 16% (太重), 2026-05-05 用户反馈降到 6%. */
.btn--ghost { background: color-mix(in srgb, var(--c-text-dim) 6%, transparent); border: none; color: var(--c-text-dim); }
.btn--ghost:hover { background: color-mix(in srgb, var(--c-text-dim) 24%, transparent); color: var(--c-body-text); filter: none; }
.btn--danger { background: var(--c-short); color: #fff; }
.btn--icon {
  width: var(--ui-btn-h); padding: 0; font-size: var(--ui-icon-lg);
}
.btn--icon.btn--sm { width: var(--ui-btn-h-sm); font-size: var(--ui-icon-md); }
.btn--icon.btn--xs { width: var(--ui-btn-h-xs); font-size: var(--ui-icon-sm); }
.btn__icon { font-size: var(--ui-icon-lg); line-height: 1; display: inline-flex; align-items: center; }
.btn--sm .btn__icon { font-size: var(--ui-icon-md); }
.btn--xs .btn__icon { font-size: var(--ui-icon-sm); }

/* kiosk 模式: 收缩顶部 nav 和分析左侧 leftbar, dashboard 独占全屏 */
body.an-kiosk .nav-tabs,
body.an-kiosk #analysis-leftbar { display: none !important; }
body.an-kiosk #tab-analysis,
body.an-kiosk .an-root { height: 100vh !important; }

/* 顶部 Tab 导航 */
.nav-tabs { display: flex; background: var(--c-surface); border-bottom: 1px solid var(--c-border); position: sticky; top: 0; z-index: 101; height: 36px; }
.nav-tab { padding: 0 20px; font-size: 12px; cursor: pointer; color: var(--c-text-dim); border-bottom: 2px solid transparent; transition: all .15s; display: flex; align-items: center; }
.nav-tab:hover { color: var(--c-body-text); }
.nav-tab.active { color: var(--c-body-text); border-bottom-color: var(--c-btn); font-weight: 600; }
.nav-tab-right { margin-left: auto; display: flex; align-items: center; gap: 6px; padding-right: 12px; }

/* 控制栏 */
.controls { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 6px; height: 36px; background: var(--c-surface); border-bottom: 1px solid var(--c-border); align-items: center; position: sticky; top: 36px; z-index: 100; }
.control-group { display: flex; align-items: center; gap: 3px; }
.control-group label { color: var(--c-label); font-size: 11px; }
.control-group select, .control-group input {
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  padding: 3px 6px; border-radius: 3px; font-size: 12px; font-family: inherit;
}
.control-group input { width: 60px; }
.control-group select { min-width: 70px; }
.sep { width: 1px; height: 18px; background: var(--c-sep); margin: 0 2px; }
button {
  background: var(--c-btn); color: #fff; border: none; padding: 3px 10px;
  border-radius: 3px; cursor: pointer; font-size: 12px; font-family: inherit;
  height: 26px; box-sizing: border-box; font-weight: 500;
}
button:hover { filter: brightness(1.1); }
/* (旧 button.sec / button.ghost fallback 已删, 全部改用 .btn .btn--sec / .btn--ghost) */
/* factor-params 在 modal 内部 */

/* 指标卡片 */
.metrics-bar {
  display: flex; flex-direction: column; gap: 0; padding: 0;
  background: var(--c-surface); border-bottom: 1px solid var(--c-border);
  flex-shrink: 0;
  /* 回测 Loading 时 innerHTML 会被替换成单个小 div, 这里固定高度避免塌陷 */
  min-height: 73px;
}
.metrics-row {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 0; padding: 0 16px;
  overflow-x: auto; height: 36px;
}
.metrics-row + .metrics-row { border-top: 1px solid var(--c-border); }
.mc { padding: 2px 10px; border-right: 1px solid var(--c-border); white-space: nowrap; }
.mc .l { font-size: 9px; color: #555; text-transform: uppercase; line-height: 1.2; }
.mc .v { font-size: 13px; font-weight: 600; line-height: 1.2; }
.mc .v.pos { color: var(--c-long); }
.mc .v.neg { color: var(--c-short); }
.mc .v.neu { color: var(--c-text); }
.mc.hl-toggle { cursor: pointer; user-select: none; transition: opacity 0.15s; }
.mc.hl-toggle:hover { background: rgba(255,255,255,0.04); }
.mc.hl-toggle.disabled { opacity: 0.35; }
.perf-tip { position: relative; cursor: help; }
.perf-tip .perf-detail {
  display: none; position: absolute; top: calc(100% + 4px); left: 50%;
  transform: translateX(-50%); background: var(--c-surface); color: var(--c-body-text); padding: 5px 10px;
  border: 1px solid var(--c-border); border-radius: 4px; font-size: 10px; white-space: nowrap; z-index: 999;
  box-shadow: 0 4px 12px rgba(0,0,0,0.4); pointer-events: none;
}
.perf-tip:hover .perf-detail { display: block; }

/* 图表容器 — 满宽 */
.charts { padding: 0; display: flex; flex-direction: column; gap: 0; }
#pnl-chart, #kline-chart, #pos-chart, #factor-chart, #quantile-chart { height: 100%; }
/* 因子指标栏夹在两个 charts 之间，视觉连续 */
#main-chart-stack .chart-box:last-child { border-radius: 0; }
#factor-stats-bar { border-bottom: 1px solid var(--c-border); background: var(--c-bg); flex-shrink: 0; }
#factor-chart-stack .chart-box:first-child { border-radius: 0; }
.chart-box { background: var(--c-bg); border-bottom: 1px solid var(--c-border); overflow: hidden; position: relative; }
.rf-ch-h {
  min-height: 18px; display: flex; align-items: center; gap: 8px; overflow: hidden;
  color: var(--c-text); font-size: 11px; line-height: 18px; white-space: nowrap;
}
.rf-ch-main { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rf-ch-readout {
  flex: 0 0 auto; margin-left: auto; padding-left: 8px; border-left: 1px solid var(--c-border);
  color: var(--c-text); font-family: 'SF Mono', monospace; font-size: 10px;
}
.rf-tip {
  position: absolute; top: 4px; left: 6px; z-index: 5; pointer-events: none;
  padding: 4px 7px; border: 1px solid var(--c-border); border-radius: 4px;
  background: var(--c-legend-bg); color: var(--c-text); font: 10px/1.45 'SF Mono', monospace;
  white-space: nowrap;
}
.rf-tip-dot { display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; }
.mm-book-view-switch {
  display: flex; align-items: center; gap: 4px; min-height: 26px; flex: 0 0 auto;
  padding: 2px 0; border-bottom: 1px solid var(--c-border);
}
/* 激活的视图按钮要明显 (之前太淡, 反而不激活的底色更抢眼 → 看着像选反了)。填充强调色 + 白字, !important 压过 .btn--ghost。 */
.mm-book-view-btn.active {
  color: #fff !important; border-color: var(--c-accent, #3b82f6) !important;
  background: var(--c-accent, #3b82f6) !important; font-weight: 600;
}
.mm-book-view-btn:not(.active) { background: transparent !important; color: var(--c-text-dim) !important; }
.mm-book-view-btn:not(.active):hover { background: color-mix(in srgb, var(--c-accent, #3b82f6) 12%, transparent) !important; }
.mm-book-view-panel { display: flex; flex: 1 1 auto; flex-direction: column; min-height: 0; }
.chart-box.standalone { margin: 8px 16px 0; border: 1px solid var(--c-border); border-radius: 4px; }

.chart-legend {
  position: absolute; top: 4px; left: 8px; z-index: 10;
  pointer-events: none; font-size: 11px; line-height: 1.5;
  color: #999;
  background: var(--c-legend-bg); padding: 2px 6px; border-radius: 3px;
  /* 同 .lc-legend: 原 nowrap 会一路溢出到右侧按钮组 (全屏/最细/放大) 底下被盖住,
     下钻 tooltip 的振幅/叠加线值就这么"消失"了。限宽 + 折行, 让内容全在可视区内。 */
  white-space: normal; max-width: calc(100% - 120px);
}
/* 可点击的系列 toggle 标签 — right 让出全屏按钮空间 */
.series-toggles {
  position: absolute; top: 4px; right: 6px; z-index: 10;
  display: flex; gap: 8px; font-size: 11px;
  background: var(--c-legend-bg); padding: 2px 8px; border-radius: 4px;
}
.series-toggles span {
  cursor: pointer; padding: 1px 5px; border-radius: 3px;
  user-select: none; transition: opacity 0.15s;
}
.series-toggles span.off { opacity: 0.3; text-decoration: line-through; }
#fav-tree > div:hover, #fav-tree .fav-tree-node:hover { background: rgba(255,255,255,0.06); }
#fav-tree .fav-folder-actions { opacity: 0; transition: opacity 0.15s; }
#fav-tree div:hover > .fav-folder-actions { opacity: 1; }
/* Mac-style folder picker */
.fav-pick-node {
  display: flex; align-items: center; padding: 4px 8px; border-radius: 6px;
  cursor: pointer; user-select: none; transition: background 0.1s;
}
.fav-pick-node:hover { background: rgba(255,255,255,0.06); }
.fav-pick-node.active { background: var(--c-btn); color: #fff; }
.fav-pick-node.last-used { border: 1px solid var(--c-btn); }
.fav-pick-node:not(.last-used) { border: 1px solid transparent; }
.mac-folder {
  display: inline-block; width: 16px; height: 14px; flex-shrink: 0; margin-right: 6px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 14'%3E%3Cpath d='M1 2C1 1.45 1.45 1 2 1h4l2 2h6c.55 0 1 .45 1 1v8c0 .55-.45 1-1 1H2c-.55 0-1-.45-1-1V2z' fill='%234A95F2'/%3E%3Cpath d='M1 5h14v7c0 .55-.45 1-1 1H2c-.55 0-1-.45-1-1V5z' fill='%236CB4F8'/%3E%3C/svg%3E");
  background-size: contain; background-repeat: no-repeat;
}
.fav-pick-node.active .mac-folder { filter: brightness(2) saturate(0); }
.fav-pick-arrow {
  display: inline-block; width: 14px; flex-shrink: 0; text-align: center;
  font-size: 8px; color: var(--c-text-dim); transition: transform 0.15s; cursor: pointer;
}
.fav-pick-arrow.expanded { transform: rotate(90deg); }
.fav-pick-arrow.loading { animation: tree-spin 0.6s linear infinite; }
@keyframes tree-spin { to { transform: rotate(360deg); } }
.fav-pick-node-actions { opacity: 0; transition: opacity 0.15s; margin-left: auto; }
.fav-pick-node:hover .fav-pick-node-actions { opacity: 1; }
.fav-pick-node-actions span {
  cursor: pointer; font-size: 14px; color: var(--c-text-dim); padding: 0 4px; border-radius: 3px;
}
.fav-pick-node-actions span:hover { color: var(--c-btn); background: rgba(255,255,255,0.1); }
.chart-legend .lg { color: var(--c-long); }
.chart-legend .lr { color: var(--c-short); }
.chart-legend .lw { color: var(--c-text); }
.chart-legend .ld { color: var(--c-text-dim); }
/* depth 模态 kline 的 OHLC 图例: 格子横排, hover 到 bar 显示 HH:MM O H L C */
.depth-kline-legend { display: flex; gap: 10px; font-family: 'SF Mono', monospace; font-variant-numeric: tabular-nums; }
.depth-kline-legend span { display: inline-flex; gap: 3px; }
.depth-kline-legend .kl-t { color: var(--c-body-text); font-weight: 600; }
.depth-kline-legend .kl-o { color: var(--c-text-dim); }
.depth-kline-legend .kl-h { color: var(--c-long); }
.depth-kline-legend .kl-l { color: var(--c-short); }
.depth-kline-legend .kl-c { color: var(--c-body-text); }
.depth-kline-legend b { font-weight: 600; }
/* 全屏按钮 */
.chart-fit-btn {
  position: absolute; top: 4px; right: 60px; z-index: 12;
  width: 22px; height: 22px; padding: 0; border: none; border-radius: 3px;
  background: var(--c-legend-bg); color: #888; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--ui-icon-md); line-height: 1; opacity: 0; transition: opacity 0.15s;
}
.chart-box:hover .chart-fit-btn { opacity: 1; }
.chart-fit-btn:hover { color: #fff; background: rgba(255,255,255,0.15); }
.chart-fs-btn {
  position: absolute; top: 4px; right: 8px; z-index: 12;
  width: 26px; height: 26px; padding: 0; border: none; border-radius: 4px;
  background: var(--c-legend-bg); color: #888; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--ui-icon-lg); line-height: 1; opacity: 0; transition: opacity 0.15s;
}
.chart-box:hover .chart-fs-btn { opacity: 1; }
.chart-fs-btn:hover { color: #fff; background: rgba(255,255,255,0.15); }

/* 全屏状态 */
.chart-box.fullscreen {
  position: fixed !important; inset: 0 !important; z-index: 9999 !important;
  margin: 0 !important; border: none !important; border-radius: 0 !important;
  width: 100vw !important; height: 100vh !important;
}
.chart-box.fullscreen > div:first-child { width: 100% !important; height: 100% !important; }
.chart-box.fullscreen .chart-fs-btn { opacity: 1; }

/* Data detail fullscreen */
#data-detail.fullscreen {
  position: fixed !important; inset: 0 !important; z-index: 9999 !important;
  width: 100vw !important; height: 100vh !important;
  border: none !important;
}

/* crosshair 浮动时间标签 — 跟随 crosshair x 位置，显示在图表底部 */
.crosshair-time-label {
  position: absolute; bottom: 2px; z-index: 11;
  pointer-events: none; font-size: 10px; font-family: 'SF Mono', monospace;
  color: var(--c-text); background: var(--c-bg); border: 1px solid var(--c-border);
  padding: 1px 5px; border-radius: 3px; white-space: nowrap;
  transform: translateX(-50%); display: none;
}

/* loading 状态.
   why min-height:200px: 父级 (e.g. #scan-chart) 在初始/optuna 启动时若高=0
   (布局未算 / 内容还没填), height:100% = 0 → flex 居中退化为贴顶. min-height
   保底让文字可见且确实居中. height:100% 仍在父级有高时填满. */
.chart-loading {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  height: 100%; min-height: 200px;
  color: var(--c-text-dim); font-size: 11px; letter-spacing: 1px;
}
.chart-loading::before {  /* 转圈 spinner (统一: loading 只转圈, 不搞深色底/纯文字) */
  content: ''; display: inline-block; width: 16px; height: 16px; flex-shrink: 0;
  border: 2px solid var(--c-border); border-top-color: var(--c-btn);
  border-radius: 50%; animation: loading-spin 0.7s linear infinite;
}
@keyframes pulse { 0%,100% { opacity: 0.3; } 50% { opacity: 1; } }
.chart-loading span { animation: pulse 1.2s ease-in-out infinite; }
/* toolbar btn loading 态 — btn 上 pulse 表示禁 click */
.btn.is-loading { pointer-events: none; opacity: 0.85; }
/* ⟳ icon 自身高速旋转 */
@keyframes spin-cw { to { transform: rotate(360deg); } }
.btn .spin-icon {
  display: inline-block; transform-origin: center;
  animation: spin-cw 0.9s linear infinite;
}

/* 拉取进度浮层 — 右下角, click ✕ 关 / 拉完不自动隐 (用户要看 log) */
.pull-progress {
  position: fixed; right: 12px; bottom: 12px; z-index: 800;
  width: 360px; max-height: 320px; display: none; flex-direction: column;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 5px; box-shadow: 0 6px 20px rgba(0,0,0,0.35);
  font-size: 11px; color: var(--c-body-text);
}
.pull-progress.visible { display: flex; }
.pull-progress .pp-hdr {
  display: flex; align-items: center; padding: 6px 10px;
  border-bottom: 1px solid var(--c-border); flex-shrink: 0;
}
.pull-progress .pp-title { font-weight: 600; flex: 1; }
.pull-progress .pp-close {
  background: transparent; border: none; color: var(--c-text-dim);
  cursor: pointer; font-size: 13px; padding: 0 4px;
}
.pull-progress .pp-close:hover { color: var(--c-body-text); }
.pull-progress .pp-log {
  flex: 1; overflow-y: auto; padding: 6px 10px;
  font-family: 'SF Mono', monospace; font-size: 10px; line-height: 1.6;
}
.pull-progress .pp-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pull-progress .pp-line .pp-ts { color: var(--c-text-dim); margin-right: 6px; }
.pull-progress .pp-info { color: var(--c-body-text); }
.pull-progress .pp-ok   { color: var(--c-long, #22c55e); }
.pull-progress .pp-warn { color: var(--c-warn, #f59e0b); }
.pull-progress .pp-err  { color: var(--c-short, #ef4444); }

/* ========== 通用 loading 占位 (面板/modal/list 空数据加载态) ========== */
@keyframes loading-spin { to { transform: rotate(360deg); } }
.loading {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 24px 16px; color: var(--c-text-dim); font-size: 11px;
}
.loading::before {
  content: ''; display: inline-block; width: 14px; height: 14px;
  border: 2px solid var(--c-input-border); border-top-color: var(--c-btn);
  border-radius: 50%; animation: loading-spin 0.6s linear infinite;
  flex-shrink: 0;
}
.loading--inline {  /* 行内 (toolbar 里跟文字并列) — 无 padding, 小尺寸 */
  display: inline-flex; padding: 0; font-size: 10px;
}
.loading--inline::before { width: 10px; height: 10px; border-width: 1.5px; }
/* 粒度提示 */
.interval-hint {
  position: fixed; top: 50px; right: 16px; z-index: 150;
  background: rgba(37,99,235,0.9); color: white;
  padding: 4px 12px; border-radius: 4px; font-size: 12px; font-family: inherit;
  pointer-events: none; opacity: 0; transition: opacity 0.3s;
}
.interval-hint.show { opacity: 1; }

/* 隐藏 lightweight-charts 水印 — 只在 chart 容器内匹配, 不影响 markdown 表格里
   intentional 的 TV indicator 链接 (报告 §3 "[name](tradingview.com/script/...)") */
.tv-lightweight-charts .apply-common-tooltip { display: none !important; }
.tv-lightweight-charts a[href*="tradingview"] { display: none !important; }

/* section 标题 */
.section-title {
  font-size: 11px; color: #555; padding: 10px 16px 4px; text-transform: uppercase; letter-spacing: 0.5px;
}

/* 配置按钮组 */
.cfg-btns { display: flex; gap: 4px; }
/* .btn--cfg: "config 按钮" 变体 — 内嵌一个 .cfg-val span 显当前值. 配 .btn 基础尺寸. */
.btn--cfg {
  background: var(--c-input-bg); border: none; color: var(--c-input-text);
  font-weight: 500; gap: 4px; transition: background 0.15s;
}
.btn--cfg:hover { background: color-mix(in srgb, var(--c-btn) 22%, var(--c-input-bg)); filter: none; }
.btn--cfg .cfg-val { color: var(--c-text-dim); font-size: 11px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ================= 策略组合 (portfolio) tab ================= */
#tab-portfolio { display: none; flex-direction: column; height: calc(100vh - 36px); overflow: hidden; }
#tab-portfolio .controls { flex-shrink: 0; top: 0; }
.pf-title { font-size: 12px; color: var(--c-body-text); font-weight: 600; }
.pf-fees { display: flex; gap: 8px; align-items: center; font-size: 11px; color: var(--c-text-dim); }
.pf-fees input { width: 48px; margin-left: 2px; }
.pf-actions { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.pf-current { font-size: 12px; font-weight: 600; color: var(--c-accent, #4dabf7); margin-left: 8px;
  max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* split pane */
#portfolio-body { flex: 1; min-height: 0; display: flex; gap: 0; }
/* 组合库文件夹树面板 */
#portfolio-tree-panel { width: 206px; flex-shrink: 0; display: flex; flex-direction: column;
  background: var(--c-table-bg); border-right: 1px solid var(--c-border); overflow: hidden; }
#portfolio-tree-toolbar { flex-shrink: 0; display: flex; align-items: center; gap: 4px;
  padding: 5px 6px; border-bottom: 1px solid var(--c-border); }
#portfolio-tree-toolbar .pft-title { font-size: 11px; font-weight: 600; color: var(--c-text-dim); margin-right: auto; }
#portfolio-tree { flex: 1; overflow: auto; padding: 3px 0; font-size: 12px; }
.pft-node { display: flex; align-items: center; gap: 3px; padding: 3px 6px; cursor: pointer;
  white-space: nowrap; border: 1px solid transparent; user-select: none; }
.pft-node:hover { background: rgba(150,150,150,0.10); }
.pft-node.active { background: color-mix(in srgb, var(--c-accent, #4dabf7) 18%, transparent);
  border-color: color-mix(in srgb, var(--c-accent, #4dabf7) 40%, transparent); }
.pft-node.drop-into { background: color-mix(in srgb, var(--c-long) 18%, transparent);
  border-color: var(--c-long); }
.pft-caret { width: 12px; text-align: center; color: var(--c-text-dim); flex-shrink: 0; }
.pft-icon { flex-shrink: 0; }
.pft-name { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.pft-count { font-size: 10px; color: var(--c-text-dim); flex-shrink: 0; }
.pft-act { display: none; gap: 2px; flex-shrink: 0; }
.pft-node:hover .pft-act { display: flex; }
.pft-act > span { padding: 0 3px; color: var(--c-text-dim); border-radius: 3px; }
.pft-act > span:hover { color: var(--c-text); background: rgba(150,150,150,0.2); }
#portfolio-tree.drop-root { background: color-mix(in srgb, var(--c-long) 8%, transparent); }
.pft-empty { padding: 12px 8px; color: var(--c-text-dim); font-size: 11px; }
/* 行内 ＋ 常驻可见 (不藏 hover), 让"加"随时可点 */
.pft-add { flex-shrink: 0; color: var(--c-long); font-weight: 700; font-size: 14px; line-height: 1;
  padding: 0 4px; opacity: 0.5; cursor: pointer; border-radius: 3px; }
.pft-node:hover .pft-add, .pft-node.active .pft-add { opacity: 1; }
.pft-add:hover { background: color-mix(in srgb, var(--c-long) 20%, transparent); opacity: 1; }
/* 文件夹 ＋ 弹出小菜单 (在此文件夹内新建 组合/子文件夹) */
.pft-menu { position: fixed; z-index: 2000; background: var(--c-bg); border: 1px solid var(--c-border);
  border-radius: 5px; box-shadow: 0 4px 14px rgba(0,0,0,0.28); padding: 3px; min-width: 132px; font-size: 12px; }
.pft-menu > div { padding: 5px 9px; cursor: pointer; border-radius: 3px; white-space: nowrap; }
.pft-menu > div:hover { background: rgba(150,150,150,0.16); }
#portfolio-left { width: 40%; flex-shrink: 0; overflow: hidden; background: var(--c-table-bg);
  border-right: 1px solid var(--c-border); display: flex; flex-direction: column; }
#portfolio-optbar { flex-shrink: 0; }
#portfolio-optbar:empty { display: none; }
#portfolio-list { flex: 1; overflow: auto; }
#portfolio-charts { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
#portfolio-metrics { flex-shrink: 0; }
.pf-chart-main { flex: 2; min-height: 0; }
.pf-chart-pos { flex: none; height: 68px; }
#portfolio-yearly-table { padding: 0 55px 0 16px; font-size: 11px; flex-shrink: 0; overflow: auto; max-height: 30%; background: var(--c-bg); }
#portfolio-symbol-bar { padding: 4px 16px; font-size: 11px; align-items: center; flex-wrap: wrap; flex-shrink: 0; }
#portfolio-symbol-bar > span { color: var(--c-text-dim); }
#portfolio-symbol-btns { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.pf-sym-btn.active { background: var(--c-btn); color: #fff; border-color: var(--c-btn); }
#portfolio-pnl-chart, #portfolio-pos-chart, #portfolio-individual-chart, #portfolio-kline-chart { height: 100%; }
/* --- optimizer bar (权重优化器) --- */
.pf-optbar { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; padding: 8px 12px 2px; }
.pf-optbar .pf-opt-label { font-size: 10px; color: var(--c-text-dim); margin-right: 2px; }
/* --- item cards (权重工作台) --- */
.pf-empty { color: var(--c-text-dim); padding: 20px; text-align: center; font-size: 12px; }
.pf-card { display: flex; flex-direction: column; gap: 5px; padding: 8px 12px; border-bottom: 1px solid var(--c-border); }
.pf-card.disabled { opacity: 0.42; }
.pf-card-head { display: flex; align-items: center; gap: 6px; }
.pf-card-head input[type=checkbox] { margin: 0; flex-shrink: 0; }
.pf-swatch { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
.pf-card-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; font-weight: 600; }
.pf-badge { font-size: 9px; color: var(--c-text-dim); flex-shrink: 0; }
.pf-card-x { cursor: pointer; color: var(--c-text-dim); font-size: 14px; line-height: 1; padding: 0 2px; flex-shrink: 0; }
.pf-card-x:hover { color: var(--c-short); }
.pf-spark { height: 24px; width: 100%; display: block; }
.pf-chips { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 10px; color: var(--c-text-dim); }
.pf-chips .pos { color: var(--c-long); font-weight: 600; }
.pf-chips .neg { color: var(--c-short); font-weight: 600; }
.pf-wrow { display: flex; align-items: center; gap: 6px; }
.pf-wrow input[type=range] { flex: 1; height: 4px; accent-color: var(--c-btn); cursor: pointer; }
.pf-wval { font-size: 10px; color: var(--c-text-dim); width: 78px; text-align: right; font-variant-numeric: tabular-nums; flex-shrink: 0; }
.pf-contrib { height: 4px; border-radius: 2px; background: var(--c-input-bg); overflow: hidden; position: relative; }
.pf-contrib > i { position: absolute; top: 0; bottom: 0; left: 0; display: block; border-radius: 2px; }
/* --- 加策略结果 picker (搜索/收藏/参数/二层明细) --- */
.pk-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex: none; }
.pk-search { flex: 1; height: 26px; padding: 2px 8px; background: var(--c-input-bg); border: 1px solid var(--c-input-border);
  border-radius: 4px; color: var(--c-input-text); font-size: 12px; }
.pk-favonly { font-size: 11px; color: var(--c-text-dim); display: flex; align-items: center; gap: 4px; cursor: pointer; white-space: nowrap; }
.pk-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-bottom: 1px solid var(--c-input-border); cursor: pointer; }
.pk-row:hover { background: rgba(150, 150, 150, 0.08); }
.pk-row.added { opacity: 0.5; }
.pk-star { cursor: pointer; color: var(--c-text-dim); font-size: 14px; width: 16px; text-align: center; flex-shrink: 0; }
.pk-star.on, .pk-star:hover { color: #f5b301; }
.pk-main { flex: 1; min-width: 0; }
.pk-l1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pk-id { color: var(--c-text-dim); font-size: 11px; }
.pk-id code, .rd-ids code { font-family: monospace; }
.pk-params { color: var(--c-text-dim); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.pk-ret { width: 60px; text-align: right; font-weight: 600; flex-shrink: 0; }
.pk-shp { width: 56px; text-align: right; color: var(--c-text-dim); flex-shrink: 0; }
.pk-add { width: 28px; text-align: center; color: var(--c-long); font-size: 16px; cursor: pointer; flex-shrink: 0; }
/* picker 表内行操作按钮 (详情 / +添加) */
.pk-detail, .pk-add2 { display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 11px; cursor: pointer; border: 1px solid var(--c-input-border); }
.pk-detail { color: var(--c-text-dim); margin-right: 4px; }
.pk-detail:hover { border-color: var(--c-text); color: var(--c-text); }
.pk-add2 { color: var(--c-long); border-color: color-mix(in srgb, var(--c-long) 45%, transparent); }
.pk-add2:hover { background: color-mix(in srgb, var(--c-long) 14%, transparent); }
.pk-add2.added { color: var(--c-text-dim); border-color: var(--c-input-border); cursor: default; }
.pk-preset-act { flex-shrink: 0; white-space: nowrap; }   /* 预设行右侧 去调 / ▶跑并加入 */
.dt td .pk-star { font-size: 13px; }
.rd-ids { color: var(--c-text-dim); font-size: 11px; margin-top: 2px; }
.rd-params-title { margin: 8px 0 4px; font-weight: 600; color: var(--c-text-dim); font-size: 11px; }
.rd-params { width: 100%; border-collapse: collapse; font-size: 11px; }
.rd-params td { padding: 2px 6px; border-bottom: 1px solid var(--c-input-border); }
.rd-params .pk-pk { color: var(--c-text-dim); width: 45%; }
.rd-syms { margin-top: 8px; color: var(--c-text-dim); font-size: 11px; line-height: 1.5; word-break: break-all; }
/* --- 品种集合: 标签chip + 折叠 (universeHtml) --- */
.rd-tag { display: inline-block; padding: 1px 8px; border-radius: 10px; border: 1px solid var(--c-border); background: rgba(77,171,247,.12); color: #4dabf7; font-size: 11px; font-weight: 600; margin-right: 6px; }
.rd-uni { margin-top: 6px; font-size: 11px; }
.rd-uni-dim { color: var(--c-text-dim); }
.rd-uni-list { margin-top: 4px; color: var(--c-text-dim); line-height: 1.6; word-break: break-all; }
.rd-uni-hint { color: #4dabf7; cursor: pointer; white-space: nowrap; margin-left: 4px; }
details.rd-uni > summary { cursor: pointer; list-style: none; outline: none; }
details.rd-uni > summary::-webkit-details-marker { display: none; }
details.rd-uni > summary::marker { content: ''; }
details.rd-uni[open] > summary .rd-uni-hint, details.rd-uni[open] > summary .rd-uni-preview { display: none; }
/* --- 搜参历史 modal --- */
.sh-row { border-bottom: 1px solid var(--c-input-border); }
.sh-top { display: flex; align-items: center; gap: 8px; padding: 6px 4px; }
.sh-main { flex: 1; min-width: 0; }
.sh-l1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-meta { color: var(--c-text-dim); font-size: 11px; }
.sh-detail { padding: 4px 10px 10px; background: rgba(150, 150, 150, 0.05); }
.sh-act { cursor: pointer; color: var(--c-btn); padding: 0 3px; white-space: nowrap; }
.sh-act:hover { text-decoration: underline; }
.sh-cur { color: var(--c-btn); font-size: 9px; }
.sh-detail-panel { flex-shrink: 0; max-height: 44%; overflow: auto; border-top: 2px solid var(--c-border); margin-top: 4px; }

/* Modal */
.modal-overlay {
  /* z-index 1500: 必须在所有 drawer 之上 — 否则从 drawer 里弹的 confirmDialog /
     inputDialog 会被 drawer-mask 遮住, 用户点不到按钮.
     已知 drawer 高水位:
       - components/Drawer.js .drawer (通用): 300
       - widgets/styles.js .wg-editor-drawer (caller-specific): 999  ← 必须高过它
     popups/popovers (color picker, chipFilter, toast 等) 走 9999+, 比 modal 高,
     这是 desired — modal 里弹的小弹层应该浮在 modal 之上. */
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1500;
  align-items: center; justify-content: center;
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 8px;
  padding: 20px 24px; min-width: 320px; max-width: 480px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3);
  display: flex; flex-direction: column; font-size: 13px;
}
.modal-lg {
  width: 60vw; max-width: 60vw; height: 60vh; max-height: 60vh;
}
.modal h3 { font-size: 15px; font-weight: 700; margin: 0 0 14px 0; color: var(--c-body-text); }
.modal .modal-body { flex: 1; min-height: 0; overflow: auto; }
.modal .modal-footer {
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: auto; padding-top: 12px; flex-shrink: 0;
}
.modal .form-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.modal .form-row label { font-size: 13px; color: var(--c-label); min-width: 64px; text-align: right; }
.modal .form-row select, .modal .form-row input {
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  padding: 5px 10px; border-radius: 3px; font-size: 13px; font-family: inherit; flex: 1;
}
.modal .form-row input[type="number"] { width: 80px; flex: none; }

/* ============ 仓位配置 modal — grid 布局 ============ */
.pos-modal { overflow-y: auto; padding: 18px 20px; }
.pos-modal .pos-section { margin-bottom: 14px; }
.pos-modal .pos-section:last-of-type { margin-bottom: 0; }
/* subgroup 小标题 */
.pos-modal .pos-subhdr {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--c-text-dim); margin: 0 0 6px; padding: 0 0 3px;
  border-bottom: 1px solid var(--c-border);
}
/* grid: auto-fill, 数字 input 短一点 (140-180px), 多余空间走右侧空白而不是把
   单个 input 撑成 600px. 这是数字字段的合理宽度 (4-6 字符 + 单位 + spinner).
   244px 上限是 header symbol-picker 的标准, 不适用于这里的窄 numeric input. */
.pos-modal .pos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 180px));
  gap: 8px 12px;
}
/* 单 field: label 上 input 下, 等宽 */
.pos-modal .pos-field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* pos-full 例外: mode dropdown 等"全宽" 字段上限 244px, 跟设计语言一致 */
.pos-modal .pos-field.pos-full { grid-column: 1 / -1; max-width: 244px; }
.pos-modal .pos-field label {
  font-size: 10px; color: var(--c-label); min-width: 0; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pos-modal .pos-field input,
.pos-modal .pos-field select,
.pos-modal .pos-field .cdd {
  width: 100%; min-width: 0; flex: none;
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  padding: 5px 8px; border-radius: 3px; font-size: 12px; font-family: inherit;
  box-sizing: border-box;
}
.pos-modal .pos-field .cdd { padding: 0; border: none; background: transparent; }
.pos-modal .pos-field .cdd-trigger { padding: 5px 8px; font-size: 12px; }
.pos-modal .pos-legend {
  font-size: 10px; color: var(--c-text-dim); margin: 0 0 8px 2px;
}
/* 分段切换器 (tgl) — 对齐 tfund3 财务页 `.chip-select`: 透明底 + 一圈细边 + 选中项淡色块。
   选中态**不用实心深色**: 二选一切换器的视觉重量必须小于它切换的内容 (createToggle) */
.tgl {
  display: inline-flex; align-items: center; gap: 0; padding: 1px; width: fit-content;
  border: 1px solid color-mix(in srgb, var(--c-border) 70%, transparent);
  border-radius: 6px; background: transparent;
}
.tgl-item {
  border: none; background: transparent; cursor: pointer; font-family: inherit;
  color: var(--c-text-dim); border-radius: 4px; line-height: 1; white-space: nowrap;
  transition: background .12s, color .12s;
}
.tgl--sm .tgl-item { height: 20px; padding: 0 10px; font-size: 11px; font-weight: 500; }
.tgl--xs .tgl-item { height: 17px; padding: 0 8px; font-size: 10px; font-weight: 500; }
.tgl-item:hover:not([data-active]) { color: var(--c-text); }
.tgl-item[data-active] {
  color: var(--c-accent, #3b82f6); font-weight: 600;
  background: color-mix(in srgb, var(--c-accent, #3b82f6) 14%, transparent);
}
.tgl-item:disabled { cursor: not-allowed; opacity: .45; }

/* 改过还没保存的输入格 — 黄色描边 + 淡黄底, 一眼定位"我动了哪几项" */
.is-edited, .cdd.is-edited .cdd-trigger {
  border-color: var(--c-warn, #d97706) !important;
  background: color-mix(in srgb, var(--c-warn, #d97706) 9%, transparent) !important;
}

/* Custom dropdown (cdd) — replaces native <select>.
   max-width 卡 288px, 防止 flex 行空时撑满整行 (Grafana / 控制台风); 需要更宽走 width 选项 */
.cdd { position:relative; flex:1 1 auto; min-width:0; max-width:var(--dd-max-w); }
.cdd[style*="width"] { max-width:none; }  /* 显式 width 覆盖 cap */
/* cdd-trigger 走 --form-* 变量, 与 input/select 同尺寸同配色. */
.cdd-trigger {
  display:flex; align-items:center; justify-content:space-between; gap:6px;
  box-sizing:border-box; height:var(--form-h);
  background:var(--c-input-bg); border:1px solid var(--c-input-border); color:var(--c-input-text);
  padding:var(--form-pad-y) var(--form-pad-x); border-radius:var(--form-radius);
  font-size:var(--form-fs); line-height:1.4; cursor:pointer; font-family:inherit;
}
.cdd-trigger:hover { border-color:var(--c-btn); }
.cdd.cdd-open .cdd-trigger { border-color:var(--c-btn); }
.cdd-text { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.cdd-arrow { font-size:10px; color:var(--c-text-dim); flex-shrink:0; }
.cdd-sub { font-size:10px; color:var(--c-text-dim); margin-left:6px; }
.cdd-menu {
  /* 菜单**宽度随内容自适应, 左对齐** (不再被 trigger 窄宽裁掉长选项), 下限=trigger 宽, 上限防溢出。系统级统一。 */
  display:none; position:absolute; top:100%; left:0; right:auto; margin-top:2px;
  min-width:100%; width:max-content; max-width:min(460px, 92vw);
  background:var(--c-surface); border:1px solid var(--c-border); border-radius:4px;
  box-shadow:0 4px 16px rgba(0,0,0,0.35); z-index:300; max-height:260px; overflow-y:auto;
  padding:4px 0;
}
.cdd-menu.open { display:block; }
.cdd-item {
  display:flex; align-items:center; gap:6px; padding:5px 10px; cursor:pointer;
  font-size:12px; color:var(--c-body-text); white-space:nowrap;
}
.cdd-item:hover { background:rgba(37,99,235,0.12); }
.cdd-item.active { background:rgba(37,99,235,0.18); font-weight:600; }
.cdd-item .cdd-range { font-size:10px; color:var(--c-text-dim); margin-left:auto; }
.cdd-item.focus { background:rgba(37,99,235,0.22); }
.cdd-item.disabled { opacity:0.45; cursor:not-allowed; }
/* 表格式下拉菜单 (createDropdown columns): 复用 .dt, 列上下对齐 + 点表头排序 + 行选中高亮 */
.cdd-menu-table { max-width:min(680px, 96vw); }   /* 表格菜单默认更宽 (多列: 场次/交易量等); menuMaxWidth 可再覆盖 */
.cdd-menu .dt { width:auto; min-width:100%; font-size:12px; border-collapse:collapse; }
.cdd-menu .dt thead th { padding:3px 10px 4px; font-size:10px; color:var(--c-text-dim); font-weight:600; white-space:nowrap; border-bottom:1px solid var(--c-border); }
.cdd-menu .dt thead th.sortable { cursor:pointer; user-select:none; }
.cdd-menu .dt thead th.sortable:hover { color:var(--c-body-text); }
.cdd-menu .dt tbody td { padding:4px 10px; white-space:nowrap; }
.cdd-menu .dt tbody tr { cursor:pointer; }
.cdd-menu .dt tbody tr:hover { background:rgba(37,99,235,0.12); }
.cdd-menu .dt tbody tr.cdd-tr-active { background:rgba(37,99,235,0.18); font-weight:600; }
/* 多选下拉: 勾选标记 + 顶部 全选/清空 条 */
.cdd-item-multi .cdd-check { width:12px; flex-shrink:0; color:var(--c-long,#16a34a); font-weight:700; text-align:center; }
.cdd-item-multi.active { font-weight:500; }
.cdd-multi-bar { display:flex; align-items:center; gap:10px; padding:5px 10px; border-bottom:1px solid var(--c-border); font-size:11px; }
.cdd-multi-act { cursor:pointer; color:var(--c-btn,#2563eb); user-select:none; }
.cdd-multi-act:hover { text-decoration:underline; }
.cdd-multi-cnt { margin-left:auto; color:var(--c-text-dim); }
.cdd-search {
  position:sticky; top:0; z-index:1; width:calc(100% - 8px); margin:4px;
  padding:4px 8px; font-size:12px;
  background:var(--c-input-bg); border:1px solid var(--c-input-border);
  color:var(--c-input-text); border-radius:3px; outline:none; box-sizing:border-box;
}
.cdd-search:focus { border-color:var(--c-btn); }
.cdd-empty, .cdd-loading {
  padding:12px; text-align:center; font-size:11px; color:var(--c-text-dim);
}
.cdd-group-title {
  padding:6px 10px 2px; font-size:10px; text-transform:uppercase;
  color:var(--c-text-dim); letter-spacing:0.3px;
}
.cdd-clear {
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; margin-right:2px; border-radius:2px;
  color:var(--c-text-dim); font-size:14px; line-height:1; cursor:pointer;
}
.cdd-clear:hover { background:var(--c-short); color:#fff; }
.cdd-compact .cdd-trigger { background:transparent; border-color:transparent; padding:2px 6px; }
.cdd-compact .cdd-trigger:hover { background:var(--c-input-bg); border-color:var(--c-input-border); }
/* 因子文件 tab */
.ff-upload-zone {
  border: 1.5px dashed var(--c-border); border-radius: 6px;
  padding: 18px 12px; text-align: center;
  transition: all 0.15s; margin-bottom: 10px;
  background: var(--c-input-bg);
}
.ff-upload-zone.drag { border-color: var(--c-btn); background: rgba(37,99,235,0.08); }
.ff-upload-hint { color: var(--c-text-dim); font-size: 12px; }
.ff-upload-hint a { color: var(--c-btn); text-decoration: none; }
.ff-msg { padding: 6px 10px; border-radius: 4px; font-size: 11px; margin-bottom: 8px; }
.ff-msg.ok { background: rgba(34,197,94,0.12); color: #22c55e; }
.ff-msg.err { background: rgba(239,68,68,0.12); color: #ef4444; }
.ff-list { margin-bottom: 10px; }
/* Chips 布局: 每个因子文件一个 chip, 右侧 X 删除, 点 label 打开编辑 modal */
/* 颜色由 JS 注入 --chip-bg (chipColor.js: name 哈希 → 暗调色板), 白字, 无边线 */
.ff-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ff-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 3px 3px 8px;
  background: var(--chip-bg, var(--c-input-bg));
  border: none; color: #fff;
  border-radius: 14px; font-size: 11px; max-width: 100%;
  transition: filter .12s;
}
.ff-chip:hover { filter: brightness(1.12); }
/* 选中态: 外圈高亮环 + 上抬阴影, 颜色取自当前 chip 自己, 视觉上和下面 ff-mapping 顶 accent 串成一线 */
.ff-chip.selected {
  filter: brightness(1.18);
  box-shadow:
    0 0 0 2px var(--c-bg),
    0 0 0 4px var(--chip-bg, var(--c-btn)),
    0 4px 8px rgba(0,0,0,0.25);
  z-index: 1;
}
.ff-chip-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 0 1px rgba(0,0,0,0.25); }
.ff-chip-dot.ok { background: #22c55e; }
.ff-chip-dot.warn { background: #eab308; }
.ff-chip-label {
  cursor: pointer; color: #fff; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px;
}
.ff-chip-mode {
  font-size: 9px; padding: 1px 4px; border-radius: 2px;
  background: rgba(255,255,255,0.22); color: #fff; margin-left: 4px;
}
.ff-chip-size { color: rgba(255,255,255,0.72); font-size: 10px; }
.ff-chip-x {
  width: 16px; height: 16px; line-height: 14px; text-align: center;
  border-radius: 50%; color: rgba(255,255,255,0.7); cursor: pointer;
  font-size: 14px; user-select: none; transition: all 0.12s;
}
.ff-chip-x:hover { background: rgba(0,0,0,0.35); color: #fff; }
.ff-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border: 1px solid var(--c-input-border);
  border-radius: 4px; margin-bottom: 4px; cursor: pointer;
  background: var(--c-surface);
}
.ff-item:hover { border-color: var(--c-btn); }
.ff-item.active { border-color: var(--c-btn); background: rgba(37,99,235,0.08); }
.ff-item-name { flex: 1; font-size: 12px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ff-item-tag { font-size: 10px; padding: 1px 6px; border-radius: 2px; }
.ff-item-tag.ok { background: rgba(34,197,94,0.18); color: #22c55e; }
.ff-item-tag.warn { background: rgba(234,179,8,0.18); color: #eab308; }
.ff-item-size { font-size: 10px; color: var(--c-text-dim); }
/* Inline 映射面板 (替代原 modal). 整圈 1px 细 border 读 --chip-bg, 与选中 chip 视觉串联. */
.ff-mapping {
  margin-top: 12px; padding: 12px 14px;
  background: var(--c-surface);
  border: 1px solid var(--chip-bg, var(--c-border));
  border-radius: 6px;
  position: relative;
}
.ff-mapping-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ff-mapping-close {
  margin-left: auto; background: transparent; border: none; color: var(--c-text-dim);
  cursor: pointer; width: 22px; height: 22px; line-height: 18px; text-align: center;
  border-radius: 50%; font-size: var(--ui-icon-lg); padding: 0;
}
.ff-mapping-close:hover { background: var(--c-short); color: #fff; }
/* 映射三列同行 — select 不拉满整宽, 保持紧凑 */
.ff-map-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.ff-map-field { flex: 0 0 150px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ff-map-field label { font-size: 11px; color: var(--c-label); }
.ff-map-field select,
.ff-map-field input { width: 100%; font-size: 11px; padding: 3px 6px; }
/* 品种 / 粒度 跟映射三列并排, 用额外 margin-left 视觉上归另一组 */
.ff-map-field.ff-map-gap { margin-left: 8px; }
/* Preview 区 */
.ff-preview {
  margin-top: 12px; border: 1px solid var(--c-input-border); border-radius: 4px;
  background: var(--c-bg); padding: 6px 8px 8px; position: relative;
}
.ff-preview-header {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 11px; color: var(--c-body-text); margin-bottom: 4px;
  padding-bottom: 4px; border-bottom: 1px dashed var(--c-border);
}
.ff-preview-title { font-weight: 600; flex-shrink: 0; }
.ff-preview-chart { height: 140px; width: 100%; }
.ff-preview-chart + .ff-preview-chart { margin-top: 4px; border-top: 1px dashed var(--c-border); padding-top: 4px; }
/* Preview 表/图 tab (小号, header 内用) */
.ff-preview-tabs {
  display: inline-flex; gap: 1px; padding: 1px;
  background: var(--c-input-bg); border-radius: 3px;
}
.ff-preview-tab {
  border: none; border-radius: 2px; padding: 1px 8px;
  background: transparent; color: var(--c-text-dim); cursor: pointer;
  font-size: 10px; height: auto; font-weight: 500;
}
.ff-preview-tab:hover { color: var(--c-body-text); }
.ff-preview-tab.active {
  background: var(--c-surface); color: var(--c-body-text); font-weight: 600;
}
/* 放大尺寸, 与映射三列同行使用 */
.ff-preview-tabs-big { padding: 3px; gap: 2px; align-self: flex-end; }
.ff-preview-tabs-big .ff-preview-tab {
  padding: 5px 14px; font-size: 12px; border-radius: 3px; min-width: 48px;
}
.ff-preview-table {
  width: 100%; border-collapse: collapse; font-size: 10px; font-family: SF Mono, monospace;
}
.ff-preview-table th {
  position: sticky; top: 0; background: var(--c-surface);
  color: var(--c-text-dim); font-weight: 500; text-align: right;
  padding: 3px 8px; border-bottom: 1px solid var(--c-border);
}
.ff-preview-table th:first-child { text-align: left; }
.ff-preview-table td {
  padding: 2px 8px; text-align: right; color: var(--c-body-text);
  border-bottom: 1px solid var(--c-input-border);
}
.ff-preview-table td:first-child { text-align: left; color: var(--c-text-dim); }
.ff-preview-table tr:hover td { background: rgba(128,128,128,0.06); }
.ff-preview-empty {
  position: absolute; inset: 28px 0 0 0; display: flex; align-items: center; justify-content: center;
  color: var(--c-text-dim); font-size: 11px; pointer-events: none;
}
/* KPI 横排指标 pill — 全项目通用 (factor preview / live dashboard / 任何 summary).
   .kpi-row 是容器 (flex-wrap), .kpi 是单 pill (label + value). */
.kpi-row {
  display: flex; flex-wrap: wrap; gap: 4px 8px;
  font-size: 10px; align-items: baseline;
}
.kpi-row:empty { display: none; }
.kpi {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 1px 6px; border-radius: 3px; background: var(--c-surface);
}
.kpi .l { color: var(--c-text-dim); font-size: 9px; }
.kpi .v { color: var(--c-body-text); font-weight: 600; }
.kpi .v .pos, .kpi .v.pos { color: var(--c-long); }
.kpi .v .neg, .kpi .v.neg { color: var(--c-short); }
/* BC: 老 .ff-preview-kpi 还能用 */
.ff-preview-kpi { display: flex; flex-wrap: wrap; gap: 4px 8px; font-size: 10px; margin-left: auto; }
.ff-preview-kpi:empty { display: none; }
/* .kpi-lg modifier — 大尺寸 KPI 条 [a | b | c | d] 无 margin, 共享分隔线 */
.kpi-row.kpi-lg {
  gap: 0;
  /* 容器整圈无 border (上层 panel 有 border-bottom 即可) */
}
.kpi-row.kpi-lg .kpi {
  flex-direction: column; align-items: flex-start; justify-content: center; gap: 0;
  padding: 2px 10px; min-width: 76px;
  border: none; border-radius: 0; background: transparent;
  border-right: 1px solid var(--c-border);
}
.kpi-row.kpi-lg .kpi:last-child { border-right: none; }
/* 早期 active tab 显示 — inline script 读 LS 设 html[data-init-tab=X], 让对应
   nav 高亮 + tab 容器立刻显, 防 init() async 期间 SaaS 默认 first tab 闪一下 */
html[data-init-tab="data"]      .nav-tab[data-tab="data"],
html[data-init-tab="analysis"]  .nav-tab[data-tab="analysis"],
html[data-init-tab="backtest"]  .nav-tab[data-tab="backtest"],
html[data-init-tab="portfolio"] .nav-tab[data-tab="portfolio"],
html[data-init-tab="strategy"]  .nav-tab[data-tab="strategy"],
html[data-init-tab="live"]      .nav-tab[data-tab="live"] {
  /* 老 fallback #fff 在 dark theme 下让 active nav-tab 变白方块 — 用户反馈
     "暗色背景下实盘复盘按钮是白色的". 改 transparent (与 nav-tabs 同色),
     active 仅靠 .nav-tab.active 的 color + border-bottom 区分 */
  border-bottom: 2px solid var(--c-btn, #4dabf7);
  color: var(--c-body-text);
  font-weight: 600;
}
/* 让 saved tab 容器立刻显, 别的全保持 display:none (HTML 里已这样).
   注: backtest 是默认 tab, 也必须在这里显; 之前漏写导致 F5 落 backtest 时容器
   永远 hidden 直到 JS 层 switchTab 跑完. 修. */
html[data-init-tab="data"]      #tab-data,
html[data-init-tab="analysis"]  #tab-analysis,
html[data-init-tab="backtest"]  #tab-backtest,
html[data-init-tab="live"]      #tab-live { display: block !important; }
/* 引擎下拉不再占单独一行: 塞进各引擎工具栏左侧的 [data-role="engine-slot"] (见 app.js registerFeature('strategy')) */
/* 策略 / 组合 tab 外层用 flex column (toolbar + body 撑满高度), 早显也得用 flex 不能 block —
   portfolio 曾误列进上面的 block 组 → switchTab 每次设 data-init-tab 后这条 !important 盖过
   inline flex → #portfolio-body flex:1 失效 → 整个分屏塌成 72px 空白 (2026-07-03 修) */
html[data-init-tab="strategy"]  #tab-strategy,
html[data-init-tab="portfolio"] #tab-portfolio { display: flex !important; }
/* 实盘复盘全屏: 只隐项目级 .nav-tabs (顶 tab 栏), 持仓/trades 保留 */
body.live-fullscreen .nav-tabs { display: none !important; }
body.live-fullscreen #tab-live { height: 100vh !important; }
.kpi-row.kpi-lg .kpi .l { font-size: 9px; }
.kpi-row.kpi-lg .kpi .v { font-size: 13px; font-variant-numeric: tabular-nums; }
/* live chart 浮层 — 都 abs 在 chart 顶部; 右侧控件必须停在 y 轴左边. */
.lc-legend {
  position: absolute; top: 4px; left: 6px; z-index: 10;
  background: var(--c-legend-bg); padding: 1px 6px; border-radius: 3px;
  font-size: 10px; font-family: 'SF Mono', monospace;
  color: var(--c-body-text); pointer-events: none;
  /* 允许折行 (2026-08-06): 原来 nowrap + max-width:60% + ellipsis, K线 hover 那行
     "O H L C 涨幅 振幅 Vol" 一定超宽 → **振幅被省略号吃掉**, 正是最该看的那一项。
     折行后全部可见; 只在 hover 时有内容, 多占一行可接受。右侧 .lc-right 留 34% 净空。 */
  white-space: normal; max-width: calc(66% - 12px); overflow: hidden;
}
.lc-right {
  position: absolute; top: 4px; right: 6px; z-index: 10;
  background: var(--c-legend-bg); padding: 1px 4px; border-radius: 3px;
  display: flex; align-items: center; gap: 4px;
  font-size: 10px; font-family: 'SF Mono', monospace;
}
.lc-right:empty { display: none; }
.chart-box.live-chart-box {
  --live-price-scale-width: 70px;
  --live-chart-action-size: 26px;
  --live-chart-action-gap: 4px;
}
/* live chart 不显 per-chart ↔ fit / ⛶ 全屏 — dashboard toolbar 已有全局 ↔ 复位 + ⛶ 全屏,
   每 chart 各自再放一组按钮反而冗余 (用户反馈 "<-> 全屏 kline的删除") */
.chart-box.live-chart-box .chart-fs-btn,
.chart-box.live-chart-box .chart-fit-btn { display: none !important; }
/* chart 透明 — 让 dashboard 主题色透过来 (用户反馈"chart 透明以便适应 ui 主题") */
.chart-box.live-chart-box { background: transparent; }
.chart-box.live-chart-box .chart-fs-btn-NULL {
  top: 30px;
  right: var(--live-price-scale-width);
}
.chart-box.live-chart-box .chart-fit-btn-NULL {
  top: 30px;
  right: calc(var(--live-price-scale-width) + var(--live-chart-action-size) + var(--live-chart-action-gap));
  width: 26px; height: 26px; border-radius: 4px; font-size: var(--ui-icon-lg);
}
.chart-box.live-chart-box .lc-right {
  right: var(--live-price-scale-width);
  padding-right: 0;
  max-width: calc(100% - var(--live-price-scale-width) - 12px);
  overflow: hidden;
}
.lc-right .btn {
  font-size: 9px; padding: 1px 7px; border-radius: 0;
  height: auto; line-height: 1.6;
}
.lc-right .series-toggles {
  position: static; padding: 0; background: transparent; border-radius: 0;
  display: flex; gap: 4px; min-width: 0; max-width: 100%; overflow-x: auto;
}
.lc-right .chart-seg {
  position: static; padding: 0; background: transparent; border-radius: 0;
  display: flex; min-width: 0; max-width: 100%; overflow-x: auto;
}
/* Preview crosshair tooltip (price chart 和 value chart 共享) */
.ff-preview-tip {
  position: absolute; z-index: 50; pointer-events: none;
  background: var(--c-legend-bg); color: var(--c-body-text);
  padding: 4px 8px; border-radius: 4px; font-size: 10px;
  border: 1px solid var(--c-border);
  box-shadow: 0 2px 8px rgba(0,0,0,0.18);
  line-height: 1.5; white-space: nowrap;
}
.ff-preview-tip .tv-t { color: var(--c-text-dim); }
.ff-preview-tip .tv-p { color: var(--c-pnl); font-weight: 600; }
.ff-preview-tip .tv-v { color: var(--c-factor); font-weight: 600; }

/* Modal 顶部 tab: [数据因子 | 因子文件] — 小尺寸, 左上角 */
.cfg-tabs {
  display:inline-flex; gap:1px; margin:-4px 0 8px;
  padding:1px; background:var(--c-input-bg); border-radius:4px;
}
/* Tab 外的全局控件行 (样本内外等, 两个 tab 都用) */
.cfg-global-row {
  display: flex; flex-wrap: wrap; gap: 4px; align-items: center;
  padding: 6px 8px; margin-bottom: 10px;
  background: var(--c-surface); border: 1px solid var(--c-input-border); border-radius: 4px;
}
.cfg-global-row > label:first-child {
  font-size: 11px; color: var(--c-label); margin-right: 6px; white-space: nowrap;
}
/* 行内所有控件等高 26px, 日期输入也和按钮一致 (避免 native date 矮一档) */
.cfg-global-row > button,
.cfg-global-row > input[type="date"] {
  height: 26px; box-sizing: border-box; line-height: 24px;
  font-size: 11px;
}
.cfg-global-row > input[type="date"] {
  width: 140px; padding: 0 8px;
}
.cfg-tab {
  border:none; border-radius:3px; padding:3px 10px;
  background:transparent; color:var(--c-text-dim); cursor:pointer;
  font-size:11px; font-weight:500;
  transition: all 0.15s ease;
}
.cfg-tab:hover { color:var(--c-body-text); }
.cfg-tab.active {
  background:var(--c-surface); color:var(--c-body-text); font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,0.15);
}

/* 因子 tab 内部次级 subtab: 数据→因子 / 因子文件 */
.cfg-subtabs {
  display: flex; gap: 0;
  border-bottom: 1px solid var(--c-border);
  margin: 0 0 10px;
}
.cfg-subtab {
  border: none; background: transparent;
  color: var(--c-text-dim); cursor: pointer;
  font-size: 11px; padding: 5px 14px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all 0.15s;
}
.cfg-subtab:hover { color: var(--c-body-text); }
.cfg-subtab.active {
  color: var(--c-body-text); font-weight: 600;
  border-bottom-color: var(--c-btn);
}

/* 数据+因子合并 modal: 90% 宽高 */
#modal-cfg > .modal {
  width: 90vw; max-width: 90vw;
  height: 90vh; max-height: 90vh;
  overflow: hidden;
}
#modal-cfg > .modal > .cfg-tab-panel { overflow-y: auto; flex: 1; min-height: 0; }
/* CodeMirror 用显式高度 — 嵌套 details 里 flex chain 会 break, 用 height 更稳 */
#factor-code-wrap { height: 340px; min-height: 260px; display: flex; flex-direction: column; }
#factor-code-wrap .CodeMirror { flex: 1; height: 100%; min-height: 260px; }
#cfg-fold-code[open] #factor-code-wrap { height: 340px; }

/* 因子参数网格对齐: 2-3 列自适应 */
#factor-params {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px 12px;
  margin-bottom: 10px;
}
#factor-params .form-row { margin-bottom: 0; }
#factor-params .form-row label { min-width: 60px; }
#factor-params .form-row input[type="number"] { flex: 1; min-width: 0; width: auto; }
/* 折叠区 */
.cfg-fold { border-top: 1px solid var(--c-input-border); margin-top: 8px; padding-top: 4px; }
.cfg-fold > summary {
  cursor: pointer; font-size: 11px; color: var(--c-label);
  padding: 4px 2px; user-select: none; list-style: none;
}
.cfg-fold > summary::before { content: '▸ '; display: inline-block; width: 10px; transition: transform 0.15s; }
.cfg-fold[open] > summary::before { content: '▾ '; }
.cfg-fold > summary:hover { color: var(--c-body-text); }
#cfg-fold-code[open] { display: flex; flex-direction: column; min-height: 300px; }
/* 版本历史 */
.ver-bar { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--c-label); margin-top: 4px; }
.ver-bar select { background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text); padding: 2px 6px; border-radius: 3px; font-size: 11px; font-family: inherit; }
.ver-hash { font-family: 'SF Mono', monospace; font-size: 10px; color: var(--c-label); opacity: 0.7; }

/* 图表高度 — 由 JS layoutCharts() 动态设置，这里给 fallback */
#hist-chart { height: 200px; }
#ic-chart { height: 200px; }
#quantile-chart { height: 120px; }
/* 寻优内联工具栏 */
#scan-toolbar {
  display: flex; flex-direction: column; gap: 0; padding: 0;
  border-bottom: 1px solid var(--c-border); flex-shrink: 0;
}
.scan-toolbar-row {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 4px;
  padding: 0 6px; height: 36px;
}
.scan-toolbar-row + .scan-toolbar-row { border-top: 1px solid var(--c-border); }
#scan-param-rows { display: flex; flex-direction: column; gap: 6px; }
.scan-param-row {
  display: flex; align-items: center; gap: 6px; font-size: 12px;
}
.scan-param-row select, .scan-param-row input {
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  padding: 4px 6px; border-radius: 3px; font-size: 12px; font-family: inherit; height: 26px; box-sizing: border-box;
  font-weight: normal;
}
/* scan 参数行: key/scale 已迁到 createDropdown, 原 select.scan-key-sel / scan-scale 规则删掉,
   createDropdown 自己读 width option 决定宽度. */
.scan-param-row input.scan-from, .scan-param-row input.scan-to { width: 68px; }
.scan-param-row .scan-tilde { color: var(--c-text-dim); font-size: 12px; }
.scan-param-row .scan-remove-btn { background: none; border: none; color: var(--c-text-dim); cursor: pointer; padding: 0 4px; font-size: 13px; }
.scan-param-row .scan-remove-btn:hover { color: var(--c-short); }
#scan-toolbar button { white-space: nowrap; }
#backtest-body { display: flex; align-items: stretch; height: calc(100vh - 72px); }
#scan-left { width: 40%; flex-shrink: 0; overflow: hidden; display: flex; flex-direction: column; background: var(--c-table-bg); }
#scan-left > .scan-table-wrap { height: 50%; flex-shrink: 0; overflow: auto; }
#scan-left > .scan-chart-wrap { flex: 1; min-height: 0; }
#backtest-main { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
#scan-left + #backtest-main { border-left: 1px solid var(--c-border); }
.scan-chart-wrap { overflow: hidden; }
.scan-table-wrap {
  font-size: 11px;
}
.scan-table-wrap table { width: 100%; border-collapse: collapse; }
.scan-table-wrap th {
  position: sticky; top: 0; background: var(--c-table-bg);
  padding: 3px 6px; text-align: right; font-weight: 500;
  color: var(--c-text-dim); border-bottom: 1px solid var(--c-border);
  cursor: pointer; user-select: none; white-space: nowrap; font-size: 10px;
}
.scan-table-wrap th:first-child { text-align: left; }
.scan-table-wrap td {
  padding: 2px 6px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--c-input-border); cursor: pointer;
}
.scan-table-wrap td:first-child { text-align: left; }
.scan-table-wrap tbody tr { transition: background 0.1s; }
.scan-table-wrap tbody tr:hover { background: rgba(155,155,155,0.2); }
.scan-table-wrap tbody tr.ctx-active { background: rgba(155,155,155,0.3) !important; }
.yearly-row { transition: filter 0.1s; }
.yearly-row:hover { filter: brightness(1.3); outline: 1px solid var(--c-text-dim); }
.scan-table-wrap tr.active { background: rgba(155,155,155,0.4); }
#scan-hist-body table { width: 100%; border-collapse: collapse; }
#scan-hist-body th { position: sticky; top: 0; background: var(--c-table-bg); padding: 4px 6px; text-align: left; font-weight: 500; color: var(--c-text-dim); border-bottom: 1px solid var(--c-border); white-space: nowrap; }
#scan-hist-body td { padding: 3px 6px; cursor: pointer; white-space: nowrap; color: var(--c-text-dim); border-bottom: 1px solid var(--c-input-border); }
#scan-hist-body tr:hover td { background: var(--c-input-bg); color: var(--c-body-text); }
#scan-hist-body tr.active td { background: rgba(37,99,235,0.12); color: var(--c-body-text); }
#scan-hist-body .sh-del { opacity: 0; cursor: pointer; color: var(--c-text-dim); }
#scan-hist-body tr:hover .sh-del { opacity: 0.5; }
#scan-hist-body .sh-del:hover { opacity: 1; color: var(--c-short); }
#scan-hist-body .sh-method { font-size: 9px; padding: 1px 4px; border-radius: 3px; color: #fff; margin-right: 4px; }
.scan-legend {
  display: flex; gap: 6px; font-size: 10px;
  padding: 2px 6px; background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
  flex-shrink: 0; align-items: center;
}
.scan-legend span {
  cursor: pointer; padding: 1px 4px; border-radius: 2px;
  color: var(--c-text-dim); transition: all 0.15s; user-select: none;
}
.scan-legend span:hover { color: var(--c-body-text); }
.scan-legend span.active {
  color: var(--c-body-text); font-weight: 600;
  border-bottom: 2px solid var(--c-btn);
}

/* Depth Modal */
.depth-modal {
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 6px;
  width: 90vw; height: 90vh; display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3);
}
.depth-modal .depth-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; border-bottom: 1px solid var(--c-border); flex-shrink: 0;
}
.depth-modal .depth-header h3 { font-size: 13px; font-weight: 600; color: var(--c-body-text); margin: 0; }
.depth-modal .depth-header .close-btn {
  background: none; border: none; color: var(--c-text-dim); font-size: var(--ui-icon-lg); cursor: pointer; padding: 0 4px;
}
.depth-modal .depth-header .close-btn:hover { color: var(--c-body-text); }
#depth-status { padding: 4px 16px; font-size: 11px; color: var(--c-text-dim); flex-shrink: 0; }
#depth-status:empty { display: none; }
.progress-bar {
  height: 4px; background: var(--c-input-border); border-radius: 2px; margin: 4px 0; overflow: hidden;
}
.progress-bar-fill {
  height: 100%; background: var(--c-btn); border-radius: 2px; transition: width 0.3s ease;
}
/* 统一: 三个面板同 border/radius, 相等 margin, 整齐 gap.
   kline 固定 200px (够看 1 天 1m 轮廓), heatmap flex:1 撑, imb 固定 120px */
.depth-chart-container {
  flex: 1; min-height: 0; margin: 10px 12px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.depth-chart-container > * {
  background: var(--c-bg); border: 1px solid var(--c-border); border-radius: 4px;
  overflow: hidden; position: relative;
}
#depth-kline-chart { flex: 0 0 200px; min-height: 160px; }
#depth-heatmap-panel {
  flex: 1 1 auto; min-height: 240px;
  display: flex; flex-direction: column;
}
/* 顶部 tab 切换: 热力图 / 列表 */
.depth-view-tabs {
  display: flex; align-items: center; gap: 2px;
  padding: 4px 8px; border-bottom: 1px solid var(--c-border);
  background: var(--c-surface); flex-shrink: 0;
}
.depth-view-tab {
  background: transparent; color: var(--c-text-dim); border: none;
  font-size: 11px; padding: 3px 10px; border-radius: 3px; cursor: pointer;
  height: auto;
}
.depth-view-tab:hover { color: var(--c-body-text); }
.depth-view-tab.active { background: var(--c-btn); color: #fff; font-weight: 600; }
.depth-err {
  color: var(--c-short); font-size: 11px; margin-left: 8px;
  font-family: 'SF Mono', monospace;
  padding: 2px 6px; border-radius: 3px;
  background: rgba(239,68,68,0.08); border: 1px solid rgba(239,68,68,0.3);
  max-width: 500px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* GL / 2D 渲染器切换 — segmented 小开关, 仅在 heatmap 面板使用 */
.depth-renderer-toggle {
  display: inline-flex; border: none; border-radius: var(--ui-btn-radius); overflow: hidden;
  background: color-mix(in srgb, var(--c-btn-sec) 35%, transparent);
}
.depth-renderer-toggle .rtog-btn {
  background: transparent; color: var(--c-text-dim); border: none;
  font-size: 10px; padding: 2px 10px; cursor: pointer; font-family: 'SF Mono', monospace;
  height: auto;
}
.depth-renderer-toggle .rtog-btn:hover { color: var(--c-body-text); background: rgba(255,255,255,0.06); }
.depth-renderer-toggle .rtog-btn.active {
  background: var(--c-btn); color: #fff; font-weight: 600;
}
/* GL canvas 与 2D canvas 叠在同一 view 里, 绝对定位.
   pointer-events:none 保证 mouse 事件穿透给上层 2D canvas, 复用 hit test / tooltip 逻辑. */
#depth-heatmap-gl-canvas {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: block;
  pointer-events: none;
}
.depth-view-body { flex: 1; min-height: 0; position: relative; }
/* Imbalance 子图 — 20% 高, X 轴和 heatmap 对齐 */
.depth-imb-view { flex: 0 0 20%; border-top: 1px solid var(--c-border); position: relative; }
/* imb tooltip — 跟 .depth-stats 同套, 左上角固定, 不跟鼠标飘 */
.depth-imb-tip {
  position: absolute; top: 4px; left: 60px; z-index: 25;
  pointer-events: none; display: none;
  background: var(--c-legend-bg); color: var(--c-body-text);
  border: 1px solid var(--c-border); border-radius: 3px;
  padding: 3px 8px;
  font-size: 10px; font-family: 'SF Mono', monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.depth-imb-tip.show { display: block; }
#depth-imb-canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
#depth-heatmap-canvas {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  display: block;
}
#depth-heatmap-empty {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--c-text-dim); font-size: 11px; pointer-events: none;
}
/* 列表视图 */
.depth-rects-table {
  width: 100%; border-collapse: collapse; font-size: 11px; font-family: 'SF Mono', monospace;
}
.depth-rects-table th {
  position: sticky; top: 0; background: var(--c-surface); color: var(--c-label);
  padding: 4px 8px; text-align: right; font-weight: 500; border-bottom: 1px solid var(--c-border);
}
.depth-rects-table th:first-child, .depth-rects-table th:nth-child(3) { text-align: left; }
.depth-rects-table td {
  padding: 2px 8px; text-align: right; border-bottom: 1px solid var(--c-input-border);
  white-space: nowrap;
}
.depth-rects-table td:first-child, .depth-rects-table td:nth-child(3) { text-align: left; }
.depth-rects-table tr.bid td:nth-child(3) { color: var(--c-long); }
.depth-rects-table tr.ask td:nth-child(3) { color: var(--c-short); }
.depth-rects-table tr:hover { background: rgba(128,128,128,0.08); }
/* 因子文件 服务端文件浏览器 item */
.ff-browse-item {
  display: flex; align-items: center; padding: 4px 8px; border-radius: 3px;
  cursor: pointer; user-select: none; font-family: SF Mono, monospace;
}
.ff-browse-item:hover { background: rgba(77,171,247,0.12); }
.ff-browse-dir { color: var(--c-body-text); }
.ff-browse-file { color: var(--c-text-dim); }
.ff-browse-file:hover { color: var(--c-body-text); }
/* 左上指标 overlay — 横排, 每格固定宽度, 数字 tabular-nums 对齐, hover 值变化不抖动 */
.depth-stats {
  position: absolute; top: 6px; left: 64px; z-index: 25;
  pointer-events: none;
  background: var(--c-legend-bg); color: var(--c-body-text);
  border: 1px solid var(--c-border); border-radius: 3px;
  font-size: 10px; font-family: 'SF Mono', monospace;
  line-height: 1.6;
  display: none;
  max-width: calc(100% - 140px);
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}
.depth-stats.show { display: flex; flex-wrap: nowrap; align-items: center; }
.depth-stats .stc {
  display: inline-flex; align-items: baseline; gap: 3px;
  padding: 0 8px;
  border-right: 1px solid var(--c-border);
  white-space: nowrap;
  box-sizing: border-box;
  overflow: hidden; text-overflow: ellipsis;
}
.depth-stats .stc:last-child { border-right: none; }
.depth-stats .stc i { font-style: normal; color: var(--c-text-dim); }
.depth-stats .stc b { font-weight: normal; }
.depth-stats .stc.empty { visibility: hidden; }
/* 每类 cell 固定宽度 — monospace + tabular-nums 下能精准预留 */
.depth-stats .stc-bid,
.depth-stats .stc-ask     { width: 92px; }
.depth-stats .stc-imb     { width: 92px; }
.depth-stats .stc-imbpct  { width: 80px; }
.depth-stats .stc-mid     { width: 100px; }
.depth-stats .stc-sp      { width: 126px; }
.depth-stats .stc-lvl     { width: 66px; }
.depth-stats .stc-dmid    { width: 96px; }
.depth-stats .stc-px      { width: 88px; }
/* 实盘盘口下钻直接复用 depth-stats；这里只补充该视图特有字段的固定宽度。 */
.live-book-depth-stats { max-width: calc(100% - 84px); }
.live-book-order-stats { top: 32px; }
.live-book-signal-stats { top: 4px; }
.depth-stats .stc-live-symbol      { width: 148px; }
.depth-stats .stc-live-src         { width: 172px; }
.depth-stats .stc-live-level       { width: 174px; }
.depth-stats .stc-live-time        { width: 112px; }
.depth-stats .stc-live-order-state { width: 118px; }
.depth-stats .stc-live-order-px    { width: 128px; }
.depth-stats .stc-live-order-qty,
.depth-stats .stc-live-order-fill  { width: 108px; }
.depth-stats .stc-live-order-life  { width: 90px; }
.depth-stats .stc-live-order-id    { width: 232px; }
.depth-stats .stc-live-order-time  { width: 112px; }
.depth-stats .stc-live-order-action { width: 148px; }
.depth-stats .stc-live-signal       { width: 92px; }
.depth-stats .stc-live-vol          { width: 154px; }
.depth-stats .stc-live-vol-part     { width: 116px; }
.depth-stats .stc-live-horizon      { width: 76px; }
.depth-stats .stc-live-position     { width: 148px; }
/* 右键菜单 */
#scan-ctx-menu {
  display: none; position: fixed; z-index: 300;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 4px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.3); padding: 4px 0; min-width: 120px;
}
#scan-ctx-menu .ctx-item {
  padding: 5px 14px; font-size: 12px; cursor: pointer; color: var(--c-body-text); white-space: nowrap;
}
#scan-ctx-menu .ctx-item:hover { background: rgba(37,99,235,0.15); }
#scan-ctx-menu .ctx-sep {
  border-top: 1px solid var(--c-border); margin: 2px 0; padding: 2px 14px;
  font-size: 9px; color: var(--c-text-dim); pointer-events: none;
}
#scan-ctx-menu .ctx-hint { padding: 2px 14px; font-size: 9px; color: var(--c-text-dim); pointer-events: none; }
/* 数据管理 Tab */
.path-seg { cursor: pointer; padding: 0 1px; border-radius: 2px; color: var(--c-btn); transition: background 0.1s; }
.path-seg:hover { background: rgba(37,99,235,0.15); text-decoration: underline; }
#tab-data table tbody tr { transition: background 0.1s; }
#tab-data table tbody tr:hover { background: rgba(155,155,155,0.15); }
#tab-data table tbody tr.active { background: rgba(37,99,235,0.12); }
#tab-data table tbody td { padding: 5px 8px; border-bottom: 1px solid var(--c-input-border); }
.data-del-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; vertical-align:middle;
  cursor:pointer; color:var(--c-text-dim); font-size:12px;
}
.data-del-btn:hover { color: var(--c-short); }
/* Local status: hover toggles check -> delete */
.local-status .data-del-btn { display:none; }
.local-status .local-check { display:inline; }
#tab-data table tbody tr:hover .local-status .data-del-btn { display:inline; }
#tab-data table tbody tr:hover .local-status .local-check { display:none; }
/* Source badges */
.source-badge {
  display: inline-block; padding: 1px 6px; border-radius: 3px; font-size: 10px; font-weight: 600; white-space: nowrap;
}
.source-badge.local { background: rgba(34,197,94,0.15); color: #22c55e; }
.source-badge.server { background: rgba(59,130,246,0.15); color: #3b82f6; }
.source-badge.binance { background: rgba(234,179,8,0.15); color: #eab308; }
/* Search bar */
#data-search-input {
  flex: 1; min-width: 200px; padding: 6px 12px; font-size: 13px;
  background: var(--c-input-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  border-radius: 4px; font-family: inherit; outline: none;
}
#data-search-input:focus { border-color: var(--c-btn); }
#data-search-input::placeholder { color: var(--c-text-dim); }
/* Dir breadcrumb */
.dir-crumb { cursor: pointer; color: var(--c-btn); }
.dir-crumb:hover { text-decoration: underline; }
/* Data chip colors — now set via inline style per-instance */
/* dl-icon (download button) — hidden by default, shown on row hover.
   尺寸对齐 .data-copy-btn (16×16 flex / 12px glyph), 视觉统一. */
.dl-icon {
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; vertical-align:middle;
  cursor:pointer; font-size:12px; font-weight:700;
  color:transparent; transition:color 0.15s;
}
#tab-data table tbody tr:hover .dl-icon { color:var(--c-btn); }
.dl-icon:hover { color:var(--c-btn-hover) !important; }
/* data-copy-btn — 品种行右侧复制按钮, 默认隐藏, 行 hover 时显示 */
.data-copy-btn {
  display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer; color:transparent; transition:color 0.15s;
  width:16px; height:16px; vertical-align:middle;
}
#tab-data table tbody tr:hover .data-copy-btn { color:var(--c-text-dim); }
.data-copy-btn:hover { color:var(--c-btn) !important; }
.data-copy-btn.copied { color:#22c55e !important; }
/* Source dot (compact location indicator) */
.source-dot {
  display:inline-block; width:6px; height:6px; border-radius:50%;
}
.source-dot.local { background:#22c55e; }
.source-dot.server { background:#3b82f6; }
.source-dot.binance { background:#eab308; }
/* Global: "不可用 / disabled" 视觉规范 — 任何 element 加 .is-disabled 即降透明 + 去饱和.
   不阻断 pointer-events (用户仍可点 × 移除等子元素), 视觉示意 "当前不可用".
   chip / button / table row / nav-item / form field 都能用. */
.is-disabled { opacity: 0.42; filter: grayscale(0.4); transition: opacity 0.15s, filter 0.15s; }
.is-disabled:hover { opacity: 0.72; }

/* 品种 dashboard: tag dropdown + mode + sort + threshold + iv 全保留.
   vol/OI/OI-vol 排序通过后端 heatmap response 的 median_vol_usd /
   median_oi_usd array 喂 coin_meta 实现, 不再隐藏. */

/* Loading 视觉提示 — layout 不变, 只让"数据态"内容 (KPI 值 / perf timing /
   yearly table 行) 变 skeleton. 按钮 / 名字 / 标签 / chart toolbar 不动. */
.is-loading { transition: opacity 0.12s; }

/* KPI 值卡 + perf timing 文字: color 透明 + 灰底 + pulse, 保持原 layout 尺寸 */
#metrics-bar.is-loading .mc .v,
#metrics-bar.is-loading .perf-tip,
#factor-stats-bar.is-loading .mc .v {
  color: transparent !important;
  background: var(--c-input-border);
  border-radius: 2px;
  animation: pulse 1.2s ease-in-out infinite;
}
/* 因子卡和 perf-tip 内的 .perf-detail (hover 才显的明细) 也一并清掉 */
#metrics-bar.is-loading .perf-tip .perf-detail { display: none; }

/* yearly-table: 行视觉清空 + 居中 "Loading..." pulse, 维持容器高度 */
#yearly-table.is-loading { position: relative; min-height: 60px; }
#yearly-table.is-loading > * { visibility: hidden; }
#yearly-table.is-loading::after {
  content: "Loading...";
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  color: var(--c-text-dim); font-size: 11px; letter-spacing: 1px;
  animation: pulse 1.2s ease-in-out infinite;
  visibility: visible;
}
/* Legacy alias — 走全局 (保留 dashed border 表示 "未配置") */
.data-chip.unconfigured { opacity: 0.42; filter: grayscale(0.4); border-style: dashed; }
/* Download inline row */
.dl-inline-row {
  background: var(--c-input-bg); border-top: 1px dashed var(--c-border);
}
.dl-inline-row td { padding: 6px 8px !important; }
.dl-inline-row input, .dl-inline-row select {
  background: var(--c-bg); border: 1px solid var(--c-input-border); color: var(--c-input-text);
  padding: 3px 6px; border-radius: 3px; font-size: 11px; font-family: inherit;
}
/* Data source chips — 深色底白字, 无边线; 颜色从 JS 注入 --chip-bg (源色 palette) */
.data-chip {
  display: inline-flex; align-items: center; gap: 0;
  padding: 4px 8px 4px 14px; border-radius: 12px; font-size: 11px; cursor: pointer;
  border: none; background: var(--chip-bg, var(--c-input-bg)); color: #fff;
  transition: filter 0.15s; white-space: nowrap;
  filter: saturate(1.25) brightness(1.08);   /* 提色 — 原 palette 偏沉 */
  line-height: 16px;
}
.data-chip:hover { filter: saturate(1.25) brightness(1.18); }
/* label 高 16 跟 ↻/× 同行高, 三者 baseline 完全对齐 */
.data-chip .chip-label {
  height: 16px; line-height: 16px; display: inline-flex; align-items: center;
}
/* ↻ / × 字符 16px box; 跟 label 一起靠 chip 的 align-items:center 居中 */
.data-chip .chip-refresh,
.data-chip .chip-x {
  width: 16px; height: 16px;
  font-size: 16px !important;
  line-height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  color: rgba(255,255,255,0.85);
  padding: 0 !important;
}
/* ↻ 与 label 之间留 6px (label 后一点空气); ↻ 和 × 紧贴, 视觉成对 */
.data-chip .chip-refresh { cursor: pointer; opacity: 1 !important; margin-left: 6px; }
.data-chip .chip-refresh:hover { color: #fff; }
.data-chip .chip-x { cursor: pointer; margin-left: 0; }
.data-chip .chip-x:hover { color: var(--c-short); }

/* 刷新中状态: ↻ 持续旋转 + chip 微闪 (脉冲), 让用户清楚后台还在等. OSS list_objects
   实测 30-60s, 一次性 600ms transform 看着像没反应. */
@keyframes chip-refresh-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes chip-refresh-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
.data-chip.is-refreshing {
  animation: chip-refresh-pulse 1.4s ease-in-out infinite;
  cursor: wait;
}
.data-chip.is-refreshing .chip-refresh {
  display: inline-block;
  animation: chip-refresh-spin 0.9s linear infinite;
  pointer-events: none;   /* 刷新中再点 ↻ 没用, 视觉上也禁掉 */
}
.data-chip.is-refreshing .chip-x { pointer-events: none; opacity: 0.5; }
/* 刚完成短暂态: ↻ 已被替换为 ✓, 套绿色让"真去查了"看得见 */
.data-chip.is-just-refreshed .chip-refresh { color: #22c55e; animation: none; }

/* ===================== Palette selector + editor ===================== */
.palette-selector .cdd-trigger { padding: 2px 6px; }
.palette-selector .palette-bar { box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08); }
.palette-editor-drawer .drawer__body { padding: 0; overflow-y: auto; }
.palette-editor-drawer input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.palette-editor-drawer input[type="color"]::-webkit-color-swatch { border: none; border-radius: 2px; }

.data-chip-add {
  display: inline-flex; align-items: center; padding: 4px 8px; border-radius: 12px;
  font-size: 11px; cursor: pointer; border: none; color: var(--c-text-dim);
  background: color-mix(in srgb, var(--c-text-dim) 14%, transparent);
  transition: all 0.15s; position: relative;
}
.data-chip-add:hover {
  background: color-mix(in srgb, var(--c-btn) 28%, transparent);
  color: var(--c-btn);
}

/* "管理 →" 链 — chip 区只读模式下的 drawer 入口, 视觉跟 add 同套但无虚线 */
.data-chip-manage {
  display: inline-flex; align-items: center; padding: 4px 8px;
  font-size: 11px; cursor: pointer; color: var(--c-text-dim);
  background: transparent; transition: color 0.15s;
}
.data-chip-manage:hover { color: var(--c-btn); }
.chip-add-menu {
  display: none; position: absolute; top: 100%; left: 0; margin-top: 4px;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3); z-index: 200; min-width: 220px; padding: 4px 0;
}
.chip-add-menu.open { display: block; }
/* 分组标题 (预设 / 自定义) */
.chip-add-menu .chip-add-group {
  padding: 4px 12px 2px; font-size: 10px; color: var(--c-text-dim);
  text-transform: uppercase; letter-spacing: 0.5px;
  border-top: 1px solid var(--c-border);
}
.chip-add-menu .chip-add-group:first-child { border-top: none; }
/* 类型选项 */
.chip-add-menu .chip-add-type {
  padding: 5px 12px; font-size: 11px; cursor: pointer; color: var(--c-body-text); white-space: nowrap;
}
.chip-add-menu .chip-add-type:hover { background: rgba(37,99,235,0.15); }
/* Preview 区 — 选类型后展开, 默认不展开 */
.chip-add-menu .chip-add-preview {
  border-top: 1px solid var(--c-border); margin-top: 4px;
}
/* Data file path chip: 极简图标+"路径"标签, 完整 path 走 hover tooltip */
.data-path-chip {
  font-size: 10px; color: var(--c-text-dim); cursor: pointer;
  white-space: nowrap;
  padding: 1px 6px; border-radius: 3px; background: var(--c-surface);
  border: 1px solid var(--c-input-border);
}
.data-path-chip:hover { border-color: var(--c-btn); color: var(--c-body-text); }
/* Filter chip row (cell-click 加的 where col=val 过滤). 紧凑, badge 风格. */
.flt-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; line-height: 1; height: 18px;
  padding: 0 4px 0 6px; border-radius: 3px;
  background: var(--c-bg); color: var(--c-body-text);
  border: 1px solid var(--c-btn);
  font-family: ui-monospace, monospace;
}
.flt-chip > .k { color: var(--c-text-dim); }
.flt-chip > .op { color: var(--c-btn); margin: 0 1px; }
.flt-chip > .v { color: var(--c-body-text); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.flt-chip > .x {
  cursor: pointer; color: var(--c-text-dim);
  width: 14px; height: 14px; line-height: 14px; text-align: center;
  border-radius: 2px; font-size: 11px;
}
.flt-chip > .x:hover { background: var(--c-input-border); color: var(--c-short); }
.flt-chip-clear {
  font-size: 10px; cursor: pointer; color: var(--c-text-dim);
  padding: 0 4px; border-radius: 2px;
}
.flt-chip-clear:hover { color: var(--c-short); }
/* preview cell-click filter: 仅 .dt-filter-text 文字本身可点 (cell padding 不触发).
   hover 文字出虚下划线提示可点 — 用户必须主动点文字才加 chip, 不再误触. */
td[data-cell-clickable] .dt-filter-text {
  cursor: pointer;
  text-decoration: underline dotted transparent;
  text-underline-offset: 2px;
  transition: text-decoration-color 0.12s;
}
td[data-cell-clickable] .dt-filter-text:hover {
  text-decoration-color: var(--c-text-dim);
  color: var(--c-body-text);
}
/* 数组 cell (tags 等) — 每元素一个小 pill chip, 取代 'a, b, c' 文字. */
.dt-pill {
  display: inline-block;
  padding: 0 5px;
  margin: 1px 2px 1px 0;
  font-size: 10px;
  line-height: 14px;
  background: var(--c-input-bg);
  border: 1px solid var(--c-input-border);
  border-radius: 8px;
  color: var(--c-text-dim);
  white-space: nowrap;
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
td[data-cell-clickable] .dt-pill:hover {
  background: var(--c-bg);
  color: var(--c-body-text);
  border-color: var(--c-text-dim);
  text-decoration: none;   /* 复用 dt-filter-text 时撤虚线下划线 */
}
.dt-pill-more {
  display: inline-block;
  padding: 0 4px;
  font-size: 9px;
  line-height: 14px;
  color: var(--c-text-dim);
  font-style: italic;
  vertical-align: middle;
}
/* Data detail panel */
#data-detail { background: var(--c-bg); }
#data-detail-table {
  font-size: 11px; width: 100%; border-collapse: collapse;
}
#data-detail-table th {
  position: sticky; top: 0; background: var(--c-surface);
  padding: 5px 6px; text-align: left; font-weight: 700;
  color: var(--c-body-text); border-bottom: 1px solid var(--c-border);
  font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#data-detail-table td {
  padding: 3px 6px; border-bottom: 1px solid var(--c-input-border);
  white-space: nowrap; font-size: 11px;
}
/* Custom tooltip for data-tip (legacy, DataTable 列头在用) */
[data-tip] { position: relative; }
[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute; right: 0; top: 100%; z-index: 9000;
  background: var(--c-surface); color: var(--c-body-text);
  border: 1px solid var(--c-border); border-radius: 4px;
  padding: 3px 8px; font-size: 11px; font-weight: 400;
  white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,0.25);
  pointer-events: none;
}

/* 统一 hover tooltip (替代原生 title=), 配合 components/tooltip.js */
#app-tooltip {
  position: fixed; z-index: 100000; display: none;
  background: var(--c-surface); color: var(--c-body-text);
  border: 1px solid var(--c-border); border-radius: 4px;
  padding: 4px 8px; font-size: 11px; line-height: 1.45;
  max-width: 560px; word-break: break-all; white-space: pre-wrap;
  box-shadow: 0 4px 12px rgba(0,0,0,0.35); pointer-events: none;
  font-family: -apple-system, BlinkMacSystemFont, 'SF Mono', monospace;
}
/* DataTable component */
.dt { width:100%; border-collapse:collapse; font-size:11px; }
.dt th {
  position:sticky; top:0; z-index:10; background:var(--c-surface);
  padding:4px 6px; text-align:left; font-weight:600;
  color:var(--c-body-text); border-bottom:1px solid var(--c-border);
  white-space:nowrap; font-size:12px; user-select:none;
  overflow:hidden; text-overflow:ellipsis; height:24px; line-height:16px;
}
.dt th[data-sort-key] { cursor:pointer; }
.dt th[data-sort-key]:hover { color:var(--c-btn); }
.dt td { padding:3px 6px; border-bottom:1px solid var(--c-input-border); white-space:nowrap; position:relative; }
.dt tbody tr:hover { background:rgba(255,255,255,0.03); }
.dt tbody tr.active { background:rgba(37,99,235,0.12); }
.dt tbody tr.fb-row-active { background:rgba(74,158,255,0.18); box-shadow:inset 3px 0 0 #4dabf7; }
/* 行可点表格 (strategy per_symbol 等): 指针 + 更明显 hover, 提示可点 */
.dt-rows-clickable .dt tbody tr { cursor:pointer; }
.dt-rows-clickable .dt tbody tr:hover { background:rgba(74,158,255,0.12); box-shadow:inset 2px 0 0 #4dabf7; }

/* Glassnode browser widget */
.gn-cat-h:hover { background:var(--c-surface) !important; }
.gn-m:hover { background:rgba(255,255,255,0.04); }
.gn-m.active { background:rgba(37,99,235,0.18); box-shadow:inset 2px 0 0 #4dabf7; }

/* Analyze tabs (segmented control) */
.analyze-tabs {
  display:inline-flex; gap:1px; padding:1px; border-radius:4px; background:var(--c-input-bg);
}
.analyze-tabs .analyze-tab {
  border:none; border-radius:3px;
  font-size:10px; padding:1px 8px; background:transparent; color:var(--c-text-dim); cursor:pointer;
  transition: all 0.15s ease; line-height:14px;
}
.analyze-tabs .analyze-tab:hover { color:var(--c-body-text); }
.analyze-tabs .analyze-tab.active {
  background:var(--c-surface); color:var(--c-body-text); font-weight:600;
  box-shadow:0 1px 3px rgba(0,0,0,0.15);
}

/* Pager component */
.pager {
  display:flex; align-items:center; justify-content:flex-end; flex:1;
  gap:4px; padding:3px 8px; font-size:10px; color:var(--c-text-dim);
}
.pager [data-page-action] { cursor:pointer; padding:0 3px; }
.pager [data-page-action]:hover { color:var(--c-btn); }
.pager .pg-active {
  background:var(--c-btn); color:#fff; border-radius:2px;
  padding:0 4px; min-width:16px; text-align:center;
}
.pager .pg-disabled { opacity:0.3; pointer-events:none; }

/* Downloader cards */
.dl-card {
  padding:10px 12px; border:1px solid var(--c-border); border-radius:6px;
  background:var(--c-input-bg); transition:border-color 0.15s;
  font-size:12px; font-weight:500;  /* 统一 label / tag / desc 字号, 和 tag 一样 */
}
.dl-card:hover { border-color:var(--c-btn); }
.dl-tag {
  /* 字号跟 dl-card 继承 (12px), tag 视觉仍靠底色 + padding 区分, 不再独立 font-size */
  display:inline-block; padding:1px 6px; border-radius:3px; font-weight:500;
}
.dl-tag.type { background:rgba(139,92,246,0.12); color:#8b5cf6; }
.dl-tag.interval { background:rgba(59,130,246,0.12); color:#3b82f6; }
/* Spinner */
.data-spinner {
  display: inline-block; width: 14px; height: 14px; border: 2px solid var(--c-border);
  border-top-color: var(--c-btn); border-radius: 50%; animation: tree-spin 0.6s linear infinite;
  vertical-align: middle; margin-left: 6px;
}
/* Detail tab buttons */
.data-dtab.active { background:var(--c-btn) !important; color:#fff !important; border-color:var(--c-btn) !important; }
/* Heatmap */
.heatmap-wrap { padding:12px 16px; }
.heatmap-table { border-collapse:collapse; font-size:9px; }
.heatmap-table th { padding:1px 2px; font-weight:500; color:var(--c-text-dim); white-space:nowrap; text-align:center; font-size:8px; }
.heatmap-table td { width:14px; height:13px; text-align:center; font-size:8px; border:1px solid var(--c-surface); border-radius:1px; padding:0; }
.heatmap-table td.hm-0 { background:var(--c-input-bg); color:transparent; }
.heatmap-table .ym-label { text-align:right; padding-right:4px; color:var(--c-text-dim); font-size:9px; font-weight:600; width:auto; }
/* Missing table */
.missing-table { border-collapse:collapse; font-size:11px; width:100%; }
.missing-table th { text-align:left; padding:3px 8px; border-bottom:1px solid var(--c-border); color:var(--c-text-dim); font-weight:600; }
.missing-table td { padding:3px 8px; border-bottom:1px solid var(--c-input-border); }
.missing-bar { height:8px; border-radius:2px; background:var(--c-short); opacity:0.7; }
/* Fast tooltip */
#fast-tip {
  position:fixed; z-index:9999; pointer-events:none; display:none;
  background:var(--c-surface); color:var(--c-body-text); border:1px solid var(--c-border);
  border-radius:4px; padding:3px 8px; font-size:11px; white-space:nowrap;
  box-shadow:0 2px 8px rgba(0,0,0,0.25); max-width:400px; overflow:hidden; text-overflow:ellipsis;
}

/* Popover (Depth 合并参数面板等通用弹出) */
.popover {
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 300;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  padding: 10px 12px; font-size: 11px; min-width: 260px;
}
.popover .agg-sec { display: flex; align-items: center; gap: 6px; margin: 5px 0; }
.popover .agg-label { width: 68px; color: var(--c-text-dim); font-size: 11px; flex-shrink: 0; }
.popover .agg-unit { color: var(--c-text-dim); font-size: 10px; }
.popover .agg-hr { border: none; border-top: 1px solid var(--c-border); margin: 8px 0; }
.popover .agg-footer { display: flex; align-items: center; gap: 6px; margin-top: 10px; }
.popover .agg-footer > span { flex: 1; }
.popover .agg-footer button { font-size: 11px; padding: 3px 12px; }
.popover input[type="number"], .popover select { font-size: 11px; padding: 2px 4px; }

/* Depth toolbar — pill 群组美学 (对齐 .btn 系统: 无 1px border, 用 --c-btn-sec 翻译填色)
   每个 .dt-group 是一颗 pill (35% --c-btn-sec 底), 内部 lbl/input/btn/cdd 全透明无边线,
   靠 hover 0.07 白叠加做交互反馈; 单 child 的 group (映射 / 聚合) 走 .btn--sec 自身底色. */
.depth-toolbar {
  margin-left: auto; display: flex; gap: 6px; align-items: center;
}
.depth-toolbar .dt-group {
  display: inline-flex; align-items: center; gap: 0; height: 24px;
  background: color-mix(in srgb, var(--c-btn-sec) 35%, transparent);
  border-radius: var(--ui-btn-radius); overflow: hidden;
}
/* 含 cdd dropdown 的 group 必须 overflow visible, 否则 cdd-menu 被裁剪 (1min 视窗下拉看不到) */
.depth-toolbar .dt-group:has(.cdd) { overflow: visible; }

.depth-toolbar .dt-lbl {
  font-size: 11px; color: var(--c-text-dim); height: 24px;
  display: inline-flex; align-items: center; padding: 0 6px;
  background: transparent; border: none; box-sizing: border-box;
}
.depth-toolbar .dt-num, .depth-toolbar .dt-sel, .depth-toolbar .dt-btn {
  height: 24px; font-size: 11px; padding: 0 6px; box-sizing: border-box;
  line-height: 22px; background: transparent; border: none; color: var(--c-input-text);
  outline: none; font-family: inherit; border-radius: 0;
}
.depth-toolbar .dt-num:focus { background: rgba(255,255,255,0.06); }
.depth-toolbar .dt-num.w52 { width: 52px; }
.depth-toolbar .dt-num.w60 { width: 60px; }
/* btn 重写: dt-btn 在 group 内透明 ghost. !important 是为了压过 .btn--sec 的 background */
.depth-toolbar .dt-group .dt-btn,
.depth-toolbar .dt-group .btn.dt-btn {
  background: transparent !important; border: none !important;
  color: var(--c-body-text); padding: 0 8px; min-width: 24px;
  border-radius: 0; cursor: pointer;
}
.depth-toolbar .dt-group .dt-btn:hover { background: rgba(255,255,255,0.07) !important; filter: none; }
/* icon 按钮 (⇔ ⇕ ‹ ›) 字号变大 */
.depth-toolbar .dt-btn.dt-icon { font-size: 16px; padding: 0 8px; min-width: 26px; }
/* 单 child 的 dt-group (映射 / 聚合): 让 .btn--sec 自己的底显出来, group pill 底变透 */
.depth-toolbar .dt-group:has(> .btn:only-child) { background: transparent; overflow: visible; }
/* cdd-trigger 在 toolbar 中: 跟 dt-btn 一样透明无边 */
.depth-toolbar .cdd { max-width: none; min-width: 0; flex: 0 0 auto; }
.depth-toolbar .cdd-trigger {
  background: transparent; border: none; padding: 0 8px;
  height: 24px; border-radius: 0;
}
.depth-toolbar .cdd-trigger:hover { background: rgba(255,255,255,0.07); border-color: transparent; }
.depth-toolbar .cdd.cdd-open .cdd-trigger { background: rgba(255,255,255,0.1); border-color: transparent; }
/* 聚合按钮内嵌 × (激活时出现) */
#depth-agg-btn .agg-x {
  display: inline-block; margin-left: 4px; padding: 0 4px;
  color: var(--c-text-dim); font-size: 13px; line-height: 1; font-weight: normal;
  border-radius: 2px; cursor: pointer;
}
#depth-agg-btn .agg-x:hover { color: var(--c-short); background: rgba(239,68,68,0.15); }
/* 累计 / 柱图 — heatmap 右上角浮层 segmented 切换 */
.depth-bar-toggle {
  position: absolute; top: 6px; right: 8px; z-index: 26;
  display: inline-flex; border: 1px solid var(--c-border); border-radius: 3px;
  background: var(--c-legend-bg); overflow: hidden;
  font-family: 'SF Mono', monospace;
}
.depth-bar-toggle .dbt-btn {
  background: transparent; color: var(--c-text-dim); border: none;
  font-size: 10px; padding: 2px 8px; cursor: pointer; height: auto;
}
.depth-bar-toggle .dbt-btn:hover { color: var(--c-body-text); }
.depth-bar-toggle .dbt-btn.active {
  background: var(--c-btn); color: #fff; font-weight: 600;
}
.depth-toolbar .depth-renderer-toggle { height: 24px; }
.depth-toolbar .depth-renderer-toggle .rtog-btn { height: 24px; box-sizing: border-box; }
/* 颜色点 (bid/ask 颜色编辑器入口) — 棋盘格底 + 颜色叠加, 透明度可见 */
.dt-color-dot {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid var(--c-border); cursor: pointer; flex-shrink: 0;
  transition: transform 0.1s;
  background-image:
    linear-gradient(45deg, #555 25%, transparent 25%),
    linear-gradient(-45deg, #555 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #555 75%),
    linear-gradient(-45deg, transparent 75%, #555 75%);
  background-size: 4px 4px;
  background-position: 0 0, 0 2px, 2px -2px, -2px 0;
  background-color: #2a2a2a;
  position: relative;
  overflow: hidden;
}
.dt-color-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
}
.dt-color-dot:hover { transform: scale(1.3); }
.dt-color-dot.bid::after { background: var(--c-depth-bid, #22c55e); }
.dt-color-dot.ask::after { background: var(--c-depth-ask, #ef4444); }

/* ============ 数据分析 Tab (.an-*) ============ */
#tab-analysis { flex-direction: column; }
.an-root {
  display: flex; flex: 1 1 auto;
  width: 100%; height: 100%;
  min-width: 0; min-height: 0;
}
.an-leftbar {
  width: 200px; flex-shrink: 0; overflow: hidden;
  background: var(--c-surface); border-right: 1px solid var(--c-border);
  display: flex; flex-direction: column;
}
.an-group { margin-bottom: 10px; }

/* ===== leftbar 顶部搜索框 (常驻, 不随 tree 重建) ===== */
.an-leftbar-search { flex-shrink: 0; padding: 6px 8px; border-bottom: 1px solid var(--c-border); }
.an-leftbar-search-input {
  width: 100%; box-sizing: border-box;
  font-size: 11px; padding: 4px 8px; line-height: 1.4;
  background: var(--c-input-bg); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: 4px; outline: none;
}
.an-leftbar-search-input::placeholder { color: var(--c-text-dim); }
.an-leftbar-search-input:focus { border-color: var(--c-btn); }
/* tree body — 滚动交给它, 搜索框/toolbar 保持固定 */
.an-leftbar-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 6px 0; }
.an-leftbar-search-count { padding: 4px 10px 2px; font-size: 10px; color: var(--c-text-dim); }
.an-leftbar-search-empty { padding: 12px 10px; font-size: 11px; color: var(--c-text-dim); }
.an-leftbar .an-search-namewrap { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.an-leftbar .an-search-sub {
  font-size: 9px; color: var(--c-text-dim);
  font-family: ui-monospace, Menlo, monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.an-leftbar .an-search-item { align-items: center; }

/* ===== leftbar 文件夹 (用户自建, 后端持久化, v2 支持嵌套) ===== */

/* 底部 + 文件夹 toolbar — 常驻显示 (淡), hover 变明显. 放最下方贴底.
   drag 中加亮 (拖 folder/file 到这里拔回根). */
.an-leftbar-toolbar {
  padding: 6px 10px 8px;
  display: flex; align-items: center; gap: 6px;
  opacity: 0.45;
  transition: opacity .15s ease;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface);
  margin-top: auto;   /* 把 toolbar 推到 flex 容器最底 */
}
.an-leftbar-toolbar:hover,
.an-leftbar:has(.is-dragging) .an-leftbar-toolbar {
  opacity: 1;
}
.an-leftbar-toolbar.is-drop-over {
  background: rgba(77,171,247,0.12);
  outline: 1px dashed var(--c-btn); border-radius: 3px;
  opacity: 1;
}
.an-leftbar-newfolder.btn { width: 100%; justify-content: center; }

/* leftbar fav-pick-* 复用 (跟数据 tab 远程目录浏览同一套, mac-folder 蓝
   文件夹 + 三角 + hover actions). 字号小一点对齐 leftbar 风格. */
.an-leftbar .fav-pick-node {
  font-size: 12px; padding: 3px 6px;
  border-radius: 3px; gap: 2px;
}
.an-leftbar .fav-pick-name {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.an-leftbar .fav-pick-date {
  font-size: 10px; color: var(--c-text-dim);
  flex-shrink: 0; font-variant-numeric: tabular-nums; margin-left: 6px;
}
.an-leftbar .fav-pick-count {
  font-size: 10px; color: var(--c-text-dim); font-weight: normal;
  background: var(--c-input-bg); padding: 0 5px; border-radius: 8px;
  min-width: 14px; text-align: center; margin-left: 4px; flex-shrink: 0;
}
.an-leftbar .an-folder-head { font-weight: 600; }
.an-leftbar .an-folder-empty {
  font-size: 10px; color: var(--c-text-dim); padding: 4px 8px;
  font-style: italic;
}
.an-leftbar .fav-pick-node.is-dragging { opacity: 0.4; }
.an-leftbar .fav-pick-node.is-draggable { cursor: grab; }
.an-leftbar .fav-pick-node.is-draggable:active { cursor: grabbing; }
.an-leftbar .fav-pick-node.is-drop-over {
  background: rgba(77,171,247,0.18);
  outline: 1px dashed var(--c-btn);
}

/* item 拖拽插入指示线 — 上半区前 / 下半区后 (用 box-shadow 不抖) */
.an-leftbar .fav-pick-node.is-drop-before { box-shadow: inset 0 2px 0 0 var(--c-btn); }
.an-leftbar .fav-pick-node.is-drop-after  { box-shadow: inset 0 -2px 0 0 var(--c-btn); }

/* 折叠 body — wrapper, 子节点自己 indent (padding-left 内联控制 depth) */
.an-leftbar .an-folder-body { /* nothing — children carry their own indent */ }

/* default group title 是 drop target — 用作 "拔出文件夹" */
.an-group[data-default-bucket="1"].is-drop-over .an-group-title {
  background: rgba(77,171,247,0.1); color: var(--c-text);
  outline: 1px dashed var(--c-border); border-radius: 3px;
}

/* ===================== 报告 (Reports) 渲染 — Typora 风 =====================
   排版目标 (跟 Typora "GitHub Light" / "Newsprint" 主题对齐):
   - 中英文混排专用字体栈: PingFang / Helvetica Neue / system-ui
   - 行高 1.75, 段间距宽松
   - H1 / H2 大号 + 底边线; H3+ 仅 weight 区分
   - max-width ~760px 居中阅读, 不让长行刺眼
   - 代码块用 var(--c-input-bg), 系统等宽字体
*/
.report-host {
  padding: 20px 32px 40px;     /* 紧凑版 — 字体大小不动, 仅压外边距 */
  height: 100%; overflow: auto; box-sizing: border-box;
  position: relative;
  /* Typora 默认字体栈, 中英混排佳 */
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue",
               "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
               "Source Han Sans CN", sans-serif;
}
/* 报告操作栏 — 悬浮右上, 不占 header 视觉空间 */
.report-actions {
  position: absolute; top: 16px; right: 24px; z-index: 10;
  display: inline-flex; align-items: center; gap: 6px;
}
.report-download-btn { white-space: nowrap; }
.report-rerun-fab {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--c-surface); border: 1px solid var(--c-border);
  color: var(--c-text-dim); cursor: pointer; font-size: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.report-rerun-fab:hover { background: var(--c-btn); color: white; border-color: var(--c-btn); }
.report-rerun-fab:disabled { opacity: 0.5; cursor: wait; }
/* 报告底部 meta 脚注 — 框架信息(date/tags/id), 不抢主内容视觉 */
.report-footer-meta {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 11px; color: var(--c-text-dim);
  padding-top: 8px; max-width: 760px; margin: 0 auto;
}
.report-footer-meta .report-id {
  font-family: 'SF Mono', monospace; font-size: 10px; opacity: 0.7;
}
/* 可点 inline code (sql/py 文件) — hover 高亮提示能点 */
.md-code-clickable {
  border-color: var(--c-btn) !important;
  color: var(--c-btn) !important;
  transition: background 0.12s;
}
.md-code-clickable:hover {
  background: color-mix(in srgb, var(--c-btn) 18%, var(--c-input-bg)) !important;
}
/* H1 下方血缘行 (series + parent) — 紧贴标题, 同 family 报告一眼看出 */
.report-lineage-row {
  display: flex; gap: 8px; flex-wrap: wrap; margin: 2px 0 6px;
  max-width: 760px; font-size: 11px; color: var(--c-text-dim);
}
.report-lineage-row .report-series {
  padding: 1px 8px; border-radius: 3px;
  background: color-mix(in srgb, var(--c-btn) 12%, transparent);
  color: var(--c-btn); font-weight: 500; letter-spacing: 0.3px;
}
.report-lineage-row .report-parent {
  padding: 1px 6px; color: var(--c-text-dim); font-family: 'SF Mono', monospace;
}
.report-lineage-row .report-parent::before { content: ''; }

/* details 折叠块 — 长报告里"方法/讨论"段默认收起, 点开展开 */
.md-details {
  margin: 10px 0; padding: 0; border: 1px solid var(--c-border);
  border-radius: 4px; background: color-mix(in srgb, var(--c-surface) 50%, transparent);
}
/* 报告 ## 问题/假设/方法 自动 fold-section: 标题区视觉跟普通 H2 对齐
   (大字+下划线), 但点 summary 折叠. 不带 .md-details 默认的 box border. */
.md-section-fold {
  margin: 14px 0 6px;
  border: none; background: transparent;
}
.md-section-fold > .md-details-sum {
  padding: 0 0 4px 0; font-size: 22px; font-weight: 600;
  line-height: 1.35; color: var(--c-text);
  border-bottom: 1px solid var(--c-border);
}
.md-section-fold > .md-details-sum:hover {
  background: transparent; color: var(--c-text);
  border-bottom-color: var(--c-text-dim);
}
.md-section-fold > .md-details-sum::before {
  content: '▸'; display: inline-block; margin-right: 8px;
  font-size: 14px; transition: transform 0.15s; color: var(--c-text-dim);
}
.md-section-fold[open] > .md-details-sum::before { transform: rotate(90deg); }
.md-section-fold > .md-details-body {
  padding: 8px 0 4px 0; border-top: none;
}
.md-details > .md-details-sum {
  padding: 6px 12px; cursor: pointer; user-select: none;
  font-weight: 500; font-size: 12px; color: var(--c-body-text);
  list-style: none;
}
.md-details > .md-details-sum::-webkit-details-marker { display: none; }
.md-details > .md-details-sum::before {
  content: '▸'; display: inline-block; margin-right: 6px;
  font-size: 10px; transition: transform 0.15s; color: var(--c-text-dim);
}
.md-details[open] > .md-details-sum::before { transform: rotate(90deg); }
.md-details > .md-details-sum:hover { background: color-mix(in srgb, var(--c-btn) 6%, transparent); }
.md-details > .md-details-body { padding: 4px 14px 10px; border-top: 1px solid var(--c-border); }

/* 报告 H1 下方 tag chip 列 (主题分类, 中文) */
.report-tags-row {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 2px 0 6px; max-width: 760px;
}
.report-tags-row .report-tag {
  padding: 2px 10px; border-radius: 12px; font-size: 11px;
  background: color-mix(in srgb, var(--c-btn) 14%, transparent);
  color: var(--c-btn); border: 1px solid color-mix(in srgb, var(--c-btn) 25%, transparent);
}
/* 报告 H1 下方 data sources chip 列 */
.report-data-sources {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin: 0 0 10px; max-width: 760px;
}
.report-ds-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 4px;
  background: color-mix(in srgb, var(--c-btn) 8%, var(--c-surface));
  border: 1px solid var(--c-border);
  font-size: 11px; cursor: help;
}
.report-ds-kind {
  font-size: 9px; font-weight: 600; text-transform: uppercase;
  color: var(--c-text-dim); letter-spacing: 0.5px;
}
.report-ds-label {
  font-family: 'SF Mono', monospace; font-size: 11px;
  color: var(--c-body-text);
}
.report-meta-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; margin: 0 auto 16px; max-width: 760px;
  font-size: 12px; background: var(--c-surface); border-radius: 6px;
  border: 1px solid var(--c-border);
}
.report-status {
  padding: 2px 10px; border-radius: 12px; font-weight: 500;
  text-transform: uppercase; font-size: 10px; letter-spacing: 0.4px;
}
.report-date { color: var(--c-text-dim); }
.report-tags { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.report-tag {
  padding: 2px 8px; border-radius: 10px; font-size: 10px;
  background: color-mix(in srgb, var(--c-btn) 14%, transparent);
  color: var(--c-btn);
}
.report-id { color: var(--c-text-dim); font-family: 'SF Mono', monospace; font-size: 10px; }
.report-headline {
  padding: 8px 14px; margin: 0 0 12px;
  background: color-mix(in srgb, var(--c-btn) 8%, transparent);
  border-left: 4px solid var(--c-btn); border-radius: 4px;
  font-size: 14px; color: var(--c-body-text); line-height: 1.5;
  display: flex; gap: 10px; align-items: flex-start;
}
.report-headline-icon { flex-shrink: 0; line-height: 1.6; }
.report-headline-rows {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.report-headline-row { /* 平齐左缘, 无 bullet, 无 padding */ }

/* —— markdown article 主体 ——
   全宽布局 (用户要 100%): 段落 / 标题 / 列表 / 图表都用满父容器宽,
   max-width 1400 给极宽屏一个上限免长行刺眼太离谱.
   紧凑版 — 字体大小不变, 仅压外边距 + 行高让信息密度更高. */
.md-article {
  max-width: 1400px; margin: 0 auto;
  line-height: 1.55; color: var(--c-body-text);
  font-size: 15px;
  letter-spacing: 0.01em;
  word-wrap: break-word;
}
.md-article > *:first-child { margin-top: 0; }
.md-article > *:last-child { margin-bottom: 0; }

/* —— headings —— */
.md-h1 {
  font-size: 30px; font-weight: 700; line-height: 1.3;
  margin: 18px 0 10px; padding-bottom: 6px;
  border-bottom: 2px solid var(--c-border);
  color: var(--c-text);
}
.md-h2 {
  font-size: 22px; font-weight: 600; line-height: 1.35;
  margin: 18px 0 8px; padding-bottom: 4px;
  border-bottom: 1px solid var(--c-border);
  color: var(--c-text);
}
.md-h3 {
  font-size: 18px; font-weight: 600; line-height: 1.4;
  margin: 14px 0 6px; color: var(--c-text);
}
.md-h4 { font-size: 16px; font-weight: 600; margin: 12px 0 4px; color: var(--c-text); }
.md-h5 { font-size: 15px; font-weight: 600; margin: 10px 0 3px; color: var(--c-text); }
.md-h6 { font-size: 14px; font-weight: 600; margin: 8px 0 3px; color: var(--c-text-dim); }

/* —— paragraphs / lists —— */
.md-p { margin: 8px 0; font-size: 15px; }
.md-ul, .md-ol { margin: 8px 0; padding-left: 24px; font-size: 15px; }
.md-ul li, .md-ol li { margin: 3px 0; }
.md-ul li::marker { color: var(--c-text-dim); }

/* —— images: 居中 + 阴影 —— */
.md-img {
  display: block; max-width: 100%; margin: 12px auto;
  border-radius: 4px; box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}

/* —— inline code —— */
.md-code {
  background: var(--c-input-bg); padding: 2px 6px; border-radius: 3px;
  font-family: 'SF Mono', Menlo, Monaco, 'Courier New', monospace;
  font-size: 0.9em;     /* 跟正文相对放大 */
  color: var(--c-body-text);
  border: 1px solid color-mix(in srgb, var(--c-border) 60%, transparent);
}

/* —— code blocks —— */
.md-pre {
  background: var(--c-input-bg); padding: 10px 14px; margin: 12px 0;
  border-radius: 6px; overflow-x: auto;
  font-family: 'SF Mono', Menlo, Monaco, 'Courier New', monospace;
  font-size: 13px; line-height: 1.5;
  border: 1px solid color-mix(in srgb, var(--c-border) 50%, transparent);
}
.md-pre code { background: transparent; padding: 0; border: none; font-size: inherit; }

/* —— links —— */
.md-link { color: var(--c-btn); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--c-btn) 40%, transparent); }
.md-link:hover { border-bottom-color: var(--c-btn); }

/* —— tables —— */
.md-table {
  border-collapse: collapse; margin: 10px 0; font-size: 14px;
  display: block; overflow-x: auto; max-width: 100%;
}
.md-table th, .md-table td {
  border: 1px solid var(--c-border);
  padding: 5px 10px; text-align: left;
}
.md-table th { background: var(--c-surface); font-weight: 600; }
.md-table tr:nth-child(2n) td { background: color-mix(in srgb, var(--c-surface) 50%, transparent); }

/* —— block quotes —— */
.md-bq {
  border-left: 4px solid var(--c-text-dim);
  padding: 10px 18px; margin: 16px 0;
  color: var(--c-text-dim);
  background: color-mix(in srgb, var(--c-text-dim) 5%, transparent);
  border-radius: 0 4px 4px 0;
}
.md-bq .md-p { margin: 4px 0; }

/* —— horizontal rule —— */
.md-hr {
  border: none; height: 1px;
  background: var(--c-border); margin: 32px auto; max-width: 50%;
}

/* —— ⭐ 块收藏 —— */
/* 每个 ### section 渲染后被 wrapBlocks 包成 .report-block, 顶角放收藏按钮.
   position:relative 让 ⭐ 按钮 absolute 定位; padding-right 给按钮让位防覆盖标题. */
.report-block {
  position: relative;
  padding-right: 28px;
}
.report-block-star {
  position: absolute;
  top: 14px;
  right: 0;
  width: 22px; height: 22px;
  padding: 0; border: none; background: transparent;
  color: var(--c-text-dim);
  cursor: pointer; opacity: 0.45;
  transition: opacity 0.15s, color 0.15s, transform 0.1s;
  display: flex; align-items: center; justify-content: center;
}
.report-block:hover .report-block-star { opacity: 1; }
.report-block-star:hover { color: #f59e0b; transform: scale(1.1); }
.report-block-star.is-favorited {
  color: #f59e0b; opacity: 1;
}

/* —— 📑 收藏夹卡 —— */
.draft-block-card {
  margin: 0 0 18px;
  border: 1px solid var(--c-border);
  border-radius: 6px;
  background: var(--c-surface);
  overflow: hidden;
}
.draft-block-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; gap: 10px;
  background: color-mix(in srgb, var(--c-surface) 60%, var(--c-body));
  border-bottom: 1px solid var(--c-border);
  font-size: 12px;
}
.draft-block-source { color: var(--c-text-dim); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.draft-block-name {
  font-weight: 600; color: var(--c-text); font-size: 13px;
  cursor: pointer; padding: 1px 4px; border-radius: 3px;
}
.draft-block-name:hover { background: color-mix(in srgb, var(--c-btn) 12%, transparent); }
.draft-block-orig {
  font-size: 10px; color: var(--c-text-dim); font-style: italic;
  font-family: 'SF Mono', Menlo, monospace;
}
.draft-block-exp {
  font-family: 'SF Mono', Menlo, monospace;
  color: var(--c-body-text);
}
.draft-block-time { margin-left: 4px; }
.draft-block-stale {
  color: #ef4444; margin-left: 6px;
}
.draft-block-stale-body {
  padding: 16px; font-size: 12px; color: var(--c-text-dim);
  background: color-mix(in srgb, #ef4444 6%, transparent);
}
.draft-block-actions { display: flex; gap: 6px; }
.draft-block-body {
  padding: 4px 16px 12px;
}
.draft-block-body .report-block {
  padding-right: 0;          /* 收藏夹里不显 ⭐, 已经在卡头有"取消"了 */
}
.draft-block-body .report-block-star { display: none; }

/* —— mini btn (收藏夹用, 可全局复用) —— */
.btn-mini {
  font-size: 11px; padding: 3px 9px; border-radius: 3px;
  border: 1px solid var(--c-border);
  background: var(--c-bg, var(--c-surface));
  color: var(--c-body-text);
  cursor: pointer; font-family: inherit;
  transition: background 0.12s, border-color 0.12s;
}
.btn-mini:hover { background: var(--c-input-bg); border-color: var(--c-btn); }
.btn-mini:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-mini-ghost { background: transparent; }
.btn-mini-danger { color: #ef4444; }
.btn-mini-danger:hover { background: color-mix(in srgb, #ef4444 12%, transparent); border-color: #ef4444; }
.an-group-title {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--c-text-dim); padding: 8px 14px 4px;
}
/* 老 .an-item 已退役, leftbar item 走 .fav-pick-node (跟 TreeBrowser 同套) */
.an-host {
  flex: 1; min-width: 0; overflow: auto;
  background: var(--c-body);
  display: flex; flex-direction: column;
}
.an-section-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: 10px 14px 8px; gap: 12px; flex-shrink: 0;
  border-bottom: 1px solid var(--c-border); background: var(--c-surface);
}
.an-section-title { font-size: 14px; font-weight: 600; color: var(--c-text); }
.an-section-subtitle { font-size: 11px; color: var(--c-text-dim); margin-top: 2px; }
.an-section-toolbar { display: flex; gap: 8px; align-items: center; }
.an-section-body { flex: 1; min-height: 0; overflow: auto; }

/* ==== DIY dashboard: widget host (Grafana 风) ====
   无界设计: 0 padding / 0 gap, toolbar 与 grid 全靠 background 色对比分界, 不画线 */
.an-dashboard-section {
  padding: 0; display: flex; flex-direction: column;
  overflow-y: auto; overflow-x: hidden;
}
.an-widget-toolbar { display: flex; align-items: center; gap: 8px; flex-shrink: 0; padding: 0 2px; }
.an-widget-add-wrap { position: relative; }
.an-widget-add-btn {
  background: var(--c-btn); color: #fff; border: none;
  padding: 4px 12px; border-radius: 3px; cursor: pointer;
  font-size: 12px; font-weight: 500; height: 26px;
}
.an-widget-add-btn:hover { filter: brightness(1.1); }
.an-widget-add-menu {
  position: absolute; top: 100%; left: 0; margin-top: 2px;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 4px; box-shadow: 0 6px 16px rgba(0,0,0,0.4);
  z-index: 100; min-width: 180px; padding: 4px 0;
}
.an-widget-add-item { padding: 6px 12px; font-size: 12px; cursor: pointer; color: var(--c-body-text); white-space: nowrap; }
.an-widget-add-item:hover { background: var(--c-bg); color: var(--c-btn); }

/* Panel 列表: 纵向堆叠, 每 widget 100% 宽度, 与父区对齐边距 */
.an-widget-list { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; width: 100%; }
.an-widget {
  display: flex; flex-direction: column; width: 100%;
  background: var(--c-bg); border: 1px solid var(--c-border); border-radius: 3px;
  overflow: hidden; position: relative;
  transition: border-color 0.12s, box-shadow 0.12s;
}
/* hover: 细蓝包边 + 轻微发光 (Grafana 风格) */
.an-widget:hover {
  border-color: var(--c-btn);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-btn) 35%, transparent);
}
.an-widget-header {
  display: flex; align-items: center; gap: 6px;
  padding: 0 10px; height: 30px;
  background: var(--c-surface); border-bottom: 1px solid var(--c-border); flex-shrink: 0;
}
.an-widget-title { font-size: 12px; font-weight: 600; color: var(--c-body-text); letter-spacing: 0.2px; }
.an-widget-type-hint {
  font-size: 10px; color: var(--c-text-dim); font-family: 'SF Mono', monospace;
  opacity: 0; transition: opacity 0.12s;
}
.an-widget:hover .an-widget-type-hint { opacity: 0.6; }
.an-widget-x {
  margin-left: auto; width: 22px; height: 22px; line-height: 1; text-align: center;
  background: transparent; border: none; color: var(--c-text-dim); cursor: pointer;
  border-radius: 3px; font-size: var(--ui-icon-lg); padding: 0; opacity: 0;
  transition: opacity 0.12s, background 0.12s, color 0.12s;
}
.an-widget:hover .an-widget-x { opacity: 0.9; }
.an-widget-x:hover { background: var(--c-short); color: #fff; opacity: 1; }
.an-widget-body { flex: 1; min-height: 0; overflow: auto; position: relative; }

/* Resize handle: 默认仅显一条短线, hover 时加抓手 + 蓝色 */
.an-widget-resize {
  height: 6px; cursor: ns-resize; flex-shrink: 0; background: transparent;
  position: relative; transition: background 0.12s;
}
.an-widget-resize::before {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 24px; height: 2px; transform: translate(-50%, -50%);
  background: var(--c-border); border-radius: 1px;
  transition: background 0.12s, width 0.12s;
}
.an-widget:hover .an-widget-resize::before { background: var(--c-text-dim); }
.an-widget-resize:hover { background: color-mix(in srgb, var(--c-btn) 18%, transparent); }
.an-widget-resize:hover::before { background: var(--c-btn); width: 40px; }

/* ============ Drawer 组件基础 (components/Drawer.js — 通用) ============
   .wg-editor-drawer / .settings-drawer 等 caller-specific 类追加微调. */
/* mask 只捕捉点击关闭, **不视觉变暗** — 让 kline 上的 region/标线之类
   的视觉信息在 drawer 开着时保持清晰 (Grafana 风, 用 drawer 自己的
   box-shadow 做层次, 不靠遮罩). */
.drawer-mask {
  position: fixed; inset: 0; background: transparent;
  z-index: 290; opacity: 0; pointer-events: none;
  transition: opacity 0.18s ease;
}
.drawer-mask.open { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; bottom: 0;
  background: var(--c-surface); border-left: 1px solid var(--c-border);
  box-shadow: -4px 0 16px rgba(0,0,0,0.25);
  transition: transform 0.2s ease;
  z-index: 300;
  display: flex; flex-direction: column;
  font-size: 12px;
}
.drawer--right { right: 0; transform: translateX(100%); }
.drawer--right.open { transform: translateX(0); }
.drawer--left { left: 0; transform: translateX(-100%); }
.drawer--left.open { transform: translateX(0); }
.drawer__head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-bottom: 1px solid var(--c-border);
  flex-shrink: 0; background: var(--c-surface);
}
.drawer__title { font-weight: 600; font-size: 13px; flex: 1; }
.drawer__close { margin-left: auto; }
.drawer__body {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 4px 0;
}
.drawer__foot {
  padding: 8px 12px; border-top: 1px solid var(--c-border);
  display: flex; gap: 6px; justify-content: flex-end; flex-shrink: 0;
}

/* ============ Theme 编辑器 modal ============ */
.theme-section {
  border: 1px solid var(--c-border); border-radius: 4px; margin-bottom: 6px;
  background: var(--c-bg);
}
.theme-section[open] { background: var(--c-surface); }
.theme-section__head {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; cursor: pointer; user-select: none;
  font-size: 12px; font-weight: 500;
  list-style: none;
}
.theme-section__head::-webkit-details-marker { display: none; }
.theme-section__head::before {
  content: '▸'; font-size: 10px; color: var(--c-text-dim);
  transition: transform 0.15s;
}
.theme-section[open] .theme-section__head::before { transform: rotate(90deg); }
.theme-section__icon { font-size: 14px; line-height: 1; }
.theme-section__title { color: var(--c-body-text); }
.theme-section__count { font-size: 10px; margin-left: auto; }
.theme-section__fields {
  padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 6px;
  border-top: 1px solid var(--c-border);
}
.theme-field {
  display: grid; grid-template-columns: 1fr 180px auto;
  align-items: center; gap: 8px; font-size: 11px;
}
.theme-field > label {
  color: var(--c-text-dim); font-size: 10px; font-family: 'SF Mono', monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.theme-field input[type="text"] {
  height: var(--form-h); padding: 0 var(--form-pad-x); font-size: var(--form-fs);
  font-family: 'SF Mono', monospace;
}
.theme-field__swatch {
  display: inline-block; width: 22px; height: 22px;
  border-radius: 3px; border: 1px solid var(--c-border);
  background: transparent;
}
/* 原生 color picker: 把 chrome 全干掉, 只留 22x22 色块, 风格跟 swatch 一致 */
.theme-field__picker {
  width: 22px; height: 22px; padding: 0;
  border: 1px solid var(--c-border); border-radius: 3px;
  background: transparent; cursor: pointer;
  appearance: none; -webkit-appearance: none;
}
.theme-field__picker::-webkit-color-swatch-wrapper { padding: 0; }
.theme-field__picker::-webkit-color-swatch { border: none; border-radius: 2px; }
.theme-field__picker::-moz-color-swatch { border: none; border-radius: 2px; }
/* 当文本不是 hex (rgba / RGB-数字) 时, picker 加斜纹提示无法精确反映 */
.theme-field__picker[data-fallback="1"]::-webkit-color-swatch {
  background: repeating-linear-gradient(45deg,
    var(--c-text-dim) 0 3px, var(--c-bg) 3px 6px) !important;
}
.theme-field__picker[data-fallback="1"]::-moz-color-swatch {
  background: repeating-linear-gradient(45deg,
    var(--c-text-dim) 0 3px, var(--c-bg) 3px 6px) !important;
}
#theme-dirty-flag { color: var(--c-ic); }

/* ============ 右侧设置 drawer (Grafana 风) ============ */
/* settings-overlay 是 drawer-mask 的别名 (兼容老 id), 同样保持透明. */
.settings-overlay {
  position: fixed; inset: 0; background: transparent;
  z-index: 290; opacity: 0; pointer-events: none;
  transition: opacity 0.18s ease;
}
.settings-overlay.open { opacity: 1; pointer-events: auto; }

/* settings 容器 — modal 风格 (居中, 不再侧拉 drawer)
   保留 .settings-drawer class 名兼容选择器, 实际定位是 centered modal. */
.settings-drawer {
  position: fixed;
  top: 50%; left: 50%;
  height: auto; max-height: 82vh; width: min(720px, 88vw);
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
  /* 跟 drawer.js 用的 .open class 协作: 关 = 缩小淡出, 开 = 实尺寸. */
  transform: translate(-50%, -50%) scale(0.96);
  opacity: 0; pointer-events: none;
  transition: transform 0.18s ease, opacity 0.18s ease;
  z-index: 300;
  display: flex; flex-direction: column;
  font-size: 12px;
}
.settings-drawer.open {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1; pointer-events: auto;
}

.settings-drawer__header {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-bottom: 1px solid var(--c-border);
  flex-shrink: 0; background: var(--c-surface);
  position: sticky; top: 0; z-index: 1;
}
.settings-drawer__title {
  font-weight: 600; font-size: 13px; white-space: nowrap;
}
.settings-drawer__search {
  flex: 1; min-width: 0; padding: 3px 8px; font-size: 12px;
  background: var(--c-table-bg); border: 1px solid var(--c-border);
  border-radius: 4px; color: var(--c-text);
}
.settings-drawer__search:focus {
  outline: none; border-color: var(--c-btn);
}
.settings-drawer__close {
  background: none; border: none; color: var(--c-text-dim);
  cursor: pointer; font-size: 18px; padding: 0 4px;
  line-height: 1; border-radius: 4px; width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
}
.settings-drawer__close:hover {
  background: var(--c-table-bg); color: var(--c-text);
}

.settings-drawer__body {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 4px 0 16px;
}

.settings-section {
  border-bottom: 1px solid var(--c-border);
}
.settings-section__header {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 12px; cursor: pointer;
  user-select: none;
  background: var(--c-surface);
  position: sticky; top: 0; z-index: 1;
}
.settings-section__header:hover { background: var(--c-table-bg); }
.settings-section__caret {
  font-size: 10px; color: var(--c-text-dim);
  transition: transform 0.15s ease;
  display: inline-block; width: 10px;
  transform: rotate(90deg);
}
.settings-section.is-collapsed .settings-section__caret { transform: rotate(0deg); }
.settings-section__icon {
  font-size: 14px; line-height: 1;
}
.settings-section__title {
  font-weight: 600; font-size: 12px; color: var(--c-text);
}
.settings-section__body {
  padding: 6px 12px 12px;
  display: block;
}
.settings-section.is-collapsed .settings-section__body { display: none; }

.settings-section__body mark {
  background: rgba(234,179,8,0.35); color: inherit;
  border-radius: 2px; padding: 0 1px;
}

.settings-section__placeholder {
  color: var(--c-text-dim); font-size: 11px; font-style: italic;
  padding: 4px 0;
}

/* ==== 数据源管理 (右 drawer 板块) ==== */
.ds-manager { display: flex; flex-direction: column; gap: 8px; }
.ds-manager__header { display: flex; align-items: center; gap: 8px; }
.ds-manager__add-menu {
  display: none; position: absolute; top: 100%; left: 0; margin-top: 4px;
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3); z-index: 50; min-width: 160px; padding: 4px 0;
}
.ds-manager__add-menu.open { display: block; }
.ds-manager__add-item {
  padding: 5px 10px; font-size: 11px; cursor: pointer; color: var(--c-body-text);
  display: flex; align-items: center; gap: 6px;
}
.ds-manager__add-item:hover { background: var(--c-bg); }
.ds-manager__add-item .ds-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}

.ds-manager__list { display: flex; flex-direction: column; gap: 4px; }
.ds-manager__empty {
  padding: 12px; color: var(--c-text-dim); font-size: 11px; text-align: center;
  border: 1px dashed var(--c-border); border-radius: 4px;
}
.ds-manager__row {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 6px; border-radius: 3px; font-size: 11px;
  background: var(--c-bg);
}
.ds-manager__row:hover { background: color-mix(in srgb, var(--c-btn) 8%, var(--c-bg)); }

.ds-manager__chip {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 10px;
  background: var(--chip-bg); color: #fff; font-size: 10px;
  filter: saturate(1.25) brightness(1.08);
  flex-shrink: 0;
}
.ds-manager__chip-label { cursor: pointer; user-select: none; }

.ds-manager__type {
  font-size: 10px; color: var(--c-text-dim); flex-shrink: 0;
}
.ds-manager__meta {
  font-size: 10px; color: var(--c-text-dim);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: 'SF Mono', monospace;
}
.ds-manager__actions { display: inline-flex; gap: 4px; flex-shrink: 0; }
.ds-manager .ds-act {
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; cursor: pointer; user-select: none;
  color: var(--c-text-dim); border-radius: 3px;
}
.ds-manager .ds-act:hover { background: var(--c-input-bg); color: var(--c-body-text); }
.ds-manager .ds-act--del:hover { color: var(--c-short); }
/* refresh 按钮持续转直到 fetch 完成 (manager_ui 加 .is-loading) */
.ds-manager .ds-act.is-loading { animation: ds-act-spin 0.8s linear infinite; pointer-events: none; opacity: 0.85; }
@keyframes ds-act-spin { to { transform: rotate(360deg); } }

/* nav 上的 ⚙️ 按钮 */
#settings-btn {
  padding: 2px 8px; display: inline-flex;
  align-items: center; justify-content: center;
}

/* ===================== 远端任务面板 (rr-*) ===================== */
.rr-panel { padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.rr-submit {
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px; background: var(--c-input-bg); border-radius: 4px;
  border: 1px solid var(--c-input-border);
}
.rr-submit-row { display: flex; align-items: center; gap: 6px; }
.rr-submit-label { font-size: 10px; color: var(--c-text-dim); width: 28px; flex-shrink: 0; }
.rr-submit-desc { font-size: 10px; color: var(--c-text-dim); padding: 0 4px; }
.rr-submit-btn { align-self: flex-end; }

.rr-section-header {
  font-size: 10px; color: var(--c-text-dim); text-transform: uppercase;
  letter-spacing: 0.5px; padding: 6px 4px 2px; font-weight: 600;
}

.rr-empty {
  color: var(--c-text-dim); text-align: center; padding: 12px;
  font-style: italic; font-size: 11px;
}

.rr-card {
  display: flex; flex-direction: column; gap: 4px;
  padding: 8px; margin-bottom: 6px;
  background: var(--c-surface); border: 1px solid var(--c-input-border);
  border-radius: 4px;
}
.rr-card-head { display: flex; align-items: center; gap: 6px; font-size: 11px; }
.rr-card-label { font-weight: 600; color: var(--c-btn); }
.rr-card-rid { color: var(--c-text-dim); font-size: 9px; font-family: monospace; }
.rr-card-status { margin-left: auto; font-size: 10px; font-weight: 600; }
.rr-card-body {
  display: flex; gap: 10px; font-size: 10px; color: var(--c-text-dim);
  flex-wrap: wrap;
}
.rr-card-lastline {
  font-size: 10px; font-family: monospace; color: var(--c-text-dim);
  background: var(--c-input-bg); padding: 4px 6px; border-radius: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rr-card-actions { display: flex; gap: 4px; justify-content: flex-end; }

.rr-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.rr-dot--alive { background: #22c55e; animation: pulse 1s ease-in-out infinite; }
.rr-dot--ok    { background: var(--c-text-dim); }
.rr-dot--err   { background: var(--c-short); }

/* ===================== 远端任务 tail modal ===================== */
.rr-tail-modal { padding: 14px 16px; }
.rr-tail-head { padding-bottom: 10px; border-bottom: 1px solid var(--c-input-border); margin-bottom: 8px; }
.rr-tail-title { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.rr-tail-label { font-weight: 700; color: var(--c-btn); }
.rr-tail-rid { font-family: monospace; font-size: 10px; color: var(--c-text-dim); }
.rr-tail-mode {
  margin-left: auto; font-size: 10px; padding: 1px 6px;
  background: var(--c-input-bg); border-radius: 3px; color: var(--c-text-dim);
}
.rr-tail-log {
  flex: 1; min-height: 0; overflow: auto;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 11px; line-height: 1.5;
  padding: 8px; background: var(--c-input-bg);
  border-radius: 4px; white-space: pre-wrap; word-break: break-all;
  color: var(--c-input-text);
}
.rr-autoscroll-chip {
  margin-right: auto; font-size: 10px; padding: 2px 8px; border-radius: 3px;
  background: var(--c-input-bg); color: var(--c-text-dim);
  border: 1px solid var(--c-input-border);
}
.rr-autoscroll-chip[data-on="1"] { color: #22c55e; border-color: #22c55e; }

/* ===================== 远端模板编辑器 (rr-editor-*) ===================== */
.rr-editor-modal { padding: 14px 18px; }
.rr-editor-modal h3 { margin: 0 0 10px 0; font-size: 14px; }
.rr-editor-body { display: flex; flex-direction: column; gap: 6px; }
.rr-ed-row.form-field--inline { display: flex; align-items: center; gap: 8px; margin: 0; }
.rr-ed-row.form-field--inline > label {
  width: 140px; flex-shrink: 0; font-size: 11px;
  color: var(--c-label); text-align: right;
}
.rr-ed-row.form-field--inline > input,
.rr-ed-row.form-field--inline > textarea {
  flex: 1; padding: 4px 8px; font-size: 11px;
  background: var(--c-input-bg); border: 1px solid var(--c-input-border);
  color: var(--c-input-text); border-radius: 3px; font-family: inherit;
}
.rr-ed-sep {
  margin: 8px 0 4px; padding-bottom: 4px;
  border-bottom: 1px solid var(--c-input-border);
  font-size: 10px; color: var(--c-text-dim); text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* ===================== 远端产物预览 (rr-art-*) ===================== */
.rr-art-modal { padding: 12px 14px; }
.rr-art-head { padding-bottom: 8px; border-bottom: 1px solid var(--c-input-border); margin-bottom: 8px; }
.rr-art-title { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.rr-art-label { font-weight: 700; color: var(--c-btn); }
.rr-art-rid { font-family: monospace; font-size: 10px; color: var(--c-text-dim); }
.rr-art-mode {
  margin-left: auto; font-size: 10px; padding: 1px 6px;
  background: var(--c-input-bg); border-radius: 3px; color: var(--c-text-dim);
}

.rr-art-body {
  flex: 1; min-height: 0; display: grid;
  grid-template-columns: 220px 1fr; gap: 8px;
}
.rr-art-list {
  overflow: auto; border: 1px solid var(--c-input-border);
  border-radius: 4px; padding: 4px;
}
.rr-art-preview {
  overflow: auto; border: 1px solid var(--c-input-border);
  border-radius: 4px; padding: 8px; display: flex;
  flex-direction: column; gap: 6px;
}

.rr-art-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: 6px 8px; cursor: pointer; border-radius: 3px;
  font-size: 11px; line-height: 1.4;
}
.rr-art-item:hover { background: var(--c-input-bg); }
.rr-art-item--active { background: var(--c-input-bg); }
.rr-art-item-loc {
  font-size: 9px; padding: 1px 5px; border-radius: 3px;
  align-self: flex-start; text-transform: uppercase; letter-spacing: 0.5px;
}
.rr-art-loc--fetch-on-finish { background: rgba(34,197,94,0.15); color: #22c55e; }
.rr-art-loc--fetch-on-demand { background: rgba(245,158,11,0.15); color: #f59e0b; }
.rr-art-loc--physic-only     { background: rgba(148,163,184,0.15); color: var(--c-text-dim); }
.rr-art-item-path {
  font-family: monospace; word-break: break-all;
  color: var(--c-input-text);
}

.rr-art-crumb {
  font-size: 10px; font-family: monospace; color: var(--c-text-dim);
  padding-bottom: 4px; border-bottom: 1px solid var(--c-input-border);
}
.rr-art-crumb-seg { cursor: pointer; padding: 0 3px; }
.rr-art-crumb-seg:hover { color: var(--c-btn); text-decoration: underline; }

.rr-art-meta {
  font-size: 10px; color: var(--c-text-dim);
  font-family: monospace;
}

.rr-art-pre {
  margin: 0; flex: 1; overflow: auto;
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 11px; line-height: 1.5;
  padding: 8px; background: var(--c-input-bg);
  border-radius: 4px; white-space: pre-wrap; word-break: break-all;
  color: var(--c-input-text);
}

.rr-art-table {
  flex: 1; overflow: auto; font-size: 11px;
}

.rr-art-dir { display: flex; flex-direction: column; gap: 2px; }
.rr-art-diritem {
  display: grid; grid-template-columns: 18px 1fr auto;
  gap: 6px; padding: 4px 8px; cursor: pointer; border-radius: 3px;
  font-size: 11px;
}
.rr-art-diritem:hover { background: var(--c-input-bg); }
.rr-art-diritem-name { font-family: monospace; }
.rr-art-diritem-size { font-size: 10px; color: var(--c-text-dim); font-family: monospace; }

.rr-art-notfetched {
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; padding: 24px;
}
.rr-art-binary { padding: 24px; text-align: center; }

/* ===================== tasks panel rows ===================== */
.tasks-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px; border-bottom: 1px solid var(--c-input-border);
}
.tasks-row--routine { padding: 8px 4px; }
.tasks-row-label {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tasks-row-type { color: var(--c-btn); font-weight: 600; }
.tasks-row-details { color: var(--c-text-dim); font-size: 9px; }
.tasks-row-elapsed { color: var(--c-text-dim); white-space: nowrap; font-size: 10px; }
.tasks-row-result { white-space: nowrap; font-size: 10px; }
.tasks-row-result--ok { color: var(--c-long); }
.tasks-row-result--err { color: var(--c-short); }
.tasks-row-result--neutral { color: var(--c-text-dim); }
.tasks-row-main { flex: 1; min-width: 0; }
.tasks-row-name { font-weight: 600; margin-bottom: 2px; }
.tasks-row-desc { font-size: 10px; color: var(--c-text-dim); }
.tasks-row-meta { font-size: 10px; margin-top: 2px; color: var(--c-text-dim); }

/* ===================== 数据字典 view (dd-*) ===================== */
.dd-toolbar {
  display: flex; gap: 8px; align-items: center;
  padding: 8px 14px; border-bottom: 1px solid var(--c-border);
  flex-shrink: 0; font-size: 12px;
}
.dd-meta { color: var(--c-text-dim); }
.dd-q {
  margin-left: auto; width: 200px;
  font-size: 12px; padding: 3px 6px;
  background: var(--c-input-bg); border: 1px solid var(--c-input-border);
  color: var(--c-input-text); border-radius: 3px;
}
.dd-body {
  flex: 1; min-height: 0; overflow: auto;
  padding: 8px 14px; display: flex; flex-direction: column; gap: 6px;
}
.dd-empty {
  text-align: center; padding: 20px;
  color: var(--c-text-dim); font-style: italic; font-size: 11px;
}

.dd-type {
  border: 1px solid var(--c-input-border);
  border-radius: 4px; background: var(--c-surface);
}
.dd-type--empty { opacity: 0.7; }
.dd-type-summary {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; cursor: pointer; font-size: 12px;
  list-style: none; user-select: none;
}
.dd-type-summary::-webkit-details-marker { display: none; }
.dd-type-summary::before {
  content: '▶'; font-size: 9px; color: var(--c-text-dim);
  transition: transform 0.15s; display: inline-block; flex-shrink: 0;
}
.dd-type[open] .dd-type-summary::before { transform: rotate(90deg); }
.dd-type-name { font-family: monospace; font-weight: 600; color: var(--c-btn); }
.dd-type-label { color: var(--c-text-dim); font-size: 11px; }
.dd-type-stats { margin-left: auto; font-size: 10px; }
.dd-stats-ok { color: var(--c-long); }
.dd-stats-empty { color: var(--c-text-dim); font-style: italic; }
.dd-stats-err { color: var(--c-short); }

.dd-type-detail {
  border-top: 1px solid var(--c-input-border);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 10px;
  font-size: 11px;
}

.dd-cols {
  width: 100%; border-collapse: collapse; font-size: 10px;
}
.dd-cols thead th {
  text-align: left; padding: 4px 8px;
  background: var(--c-input-bg); color: var(--c-text-dim);
  font-weight: 500; border-bottom: 1px solid var(--c-input-border);
}
.dd-cols tbody td {
  padding: 4px 8px; border-bottom: 1px solid var(--c-input-border);
}
.dd-cols code {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10px; background: transparent;
}
.dd-col-type { color: var(--c-text-dim); }
.dd-col-sample { color: var(--c-text-dim); font-style: italic; }

.dd-meta-grid {
  display: grid; grid-template-columns: 90px 1fr; gap: 4px 10px;
}
.dd-meta-row { display: contents; }
.dd-meta-k { color: var(--c-text-dim); font-size: 10px; }
.dd-meta-v { color: var(--c-input-text); font-size: 11px; }
.dd-meta-v.mono { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 10px; }

.dd-notes {
  margin: 0; padding-left: 18px; font-size: 11px;
  color: var(--c-text-dim);
}
.dd-notes li { margin: 2px 0; }

/* ===================== 数据预览 modal (dp-*) ===================== */
.dp-modal { padding: 12px 14px; }
.dp-head { padding-bottom: 8px; border-bottom: 1px solid var(--c-input-border); margin-bottom: 8px; }
.dp-title { display: flex; align-items: center; gap: 8px; font-size: 12px; flex-wrap: wrap; }
.dp-type { font-family: monospace; font-weight: 600; color: var(--c-btn); }
.dp-symbol { font-weight: 600; }
.dp-interval { color: var(--c-text-dim); font-size: 11px; }
.dp-path {
  margin-left: auto; font-family: monospace; font-size: 10px;
  color: var(--c-text-dim); max-width: 60%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dp-body {
  flex: 1; min-height: 0; overflow: auto;
  display: flex; flex-direction: column; gap: 6px;
}
.dp-meta { font-size: 10px; color: var(--c-text-dim); font-family: monospace; }
.dp-table { flex: 1; overflow: auto; font-size: 11px; }
.dp-loading { padding: 24px; text-align: center; color: var(--c-text-dim); font-size: 11px; }
.dp-error { padding: 24px; color: var(--c-short); font-size: 11px; font-family: monospace; }

/* hover 高亮 */
.inv-row:hover { background: var(--c-input-bg); }

/* ===================== chip drift 角标 ===================== */
.chip-drift {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 14px; height: 14px; padding: 0 4px;
  font-size: 9px; font-weight: 700; line-height: 1;
  border-radius: 7px; cursor: help; user-select: none;
}
.chip-drift--warn { background: var(--c-short); color: #fff; }
.chip-drift--info { background: var(--c-text-dim); color: var(--c-surface); }

/* ===================== 数据字典 drift banner / type 标 ===================== */
.dd-banner-slot { padding: 0 14px; }
.dd-banner {
  display: flex; align-items: center; gap: 8px;
  margin: 8px 0; padding: 8px 12px;
  background: rgba(255, 107, 107, 0.12);
  border: 1px solid var(--c-short); border-radius: 4px;
  font-size: 11px;
}
.dd-banner-icon { font-size: 14px; color: var(--c-short); }
.dd-banner-text { flex: 1; color: var(--c-input-text); }
.dd-banner-time { color: var(--c-text-dim); font-size: 10px; margin-left: 6px; }

.dd-type--drift { border-color: var(--c-short); }
.dd-type-drift {
  font-size: 10px; padding: 1px 5px; border-radius: 3px;
  background: var(--c-short); color: #fff; font-weight: 600;
}

.dd-drift {
  display: flex; flex-direction: column; gap: 8px;
  padding: 8px 10px; background: rgba(255, 107, 107, 0.08);
  border-left: 3px solid var(--c-short); border-radius: 3px;
  font-size: 11px;
}
.dd-drift-sec-h { font-weight: 600; color: var(--c-short); margin-bottom: 4px; font-size: 10px; }
.dd-drift-list {
  margin: 0; padding-left: 18px; font-size: 10px;
  color: var(--c-input-text);
}
.dd-drift-list li { margin: 2px 0; }
.dd-drift-list code {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 10px; color: var(--c-input-text);
}

/* ===================== 例行 tab schedule 控制 ===================== */
.tasks-sched {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10px; margin-top: 2px;
  color: var(--c-text-dim);
}
.tasks-sched-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.tasks-sched-dot--on { background: var(--c-long); }
.tasks-sched-dot--off { background: var(--c-text-dim); opacity: 0.5; }
.tasks-sched-int {
  cursor: pointer; padding: 1px 4px; border-radius: 2px;
  font-family: monospace;
}
.tasks-sched-int:hover { background: var(--c-input-bg); color: var(--c-body-text); }
.tasks-sched-next { font-family: monospace; font-size: 9px; }
.tasks-sched-actions { display: flex; gap: 4px; align-items: center; }

/* ===================== glassnode uniformity outlier ===================== */
.dd-uniformity { padding: 6px 0; }
.dd-uniformity > summary { color: var(--c-short); }
.dd-uniformity-list {
  margin-top: 6px; max-height: 280px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px;
}
.dd-uniformity-item {
  padding: 4px 6px; border-left: 2px solid var(--c-short);
  background: rgba(255, 107, 107, 0.04); border-radius: 2px;
}
.dd-um-name { font-size: 10px; }
.dd-um-name code { color: var(--c-input-text); }
.dd-um-diff { font-size: 9px; margin-top: 2px; line-height: 1.6; }
.dd-um-miss { color: var(--c-short); padding-right: 2px; }
.dd-um-extra { color: var(--c-long); padding-right: 2px; }
.dd-um-more { font-size: 10px; color: var(--c-text-dim); padding: 4px; font-style: italic; }

/* conform stat chips */
.dd-um-tally { color: var(--c-text-dim); font-weight: 400; margin-right: 6px; }
.dd-um-stat {
  display: inline-block; padding: 1px 6px; border-radius: 8px;
  font-size: 9px; font-weight: 600; margin-right: 4px;
}
.dd-um-stat--ok { background: rgba(34,197,94,0.15); color: var(--c-long); }
.dd-um-stat--info { background: rgba(99,102,241,0.15); color: #818cf8; }
.dd-um-stat--dim { background: var(--c-input-bg); color: var(--c-text-dim); }
.dd-um-stat--warn { background: rgba(255,107,107,0.15); color: var(--c-short); }
.dd-um-summary-ok {
  font-size: 10px; color: var(--c-text-dim);
  font-weight: 600; padding: 2px 0;
}
.dd-um-allgood {
  padding: 6px 8px; font-size: 10px; color: var(--c-long);
  font-style: italic;
}
.dd-uniformity--warn { background: rgba(255,107,107,0.06); }

/* sparkline + healthy banner */
.dd-banner--ok {
  background: rgba(34, 197, 94, 0.06);
  border-color: var(--c-long);
}
.dd-spark { display: inline-block; line-height: 0; margin: 0 4px; }

/* schema modal (outlier 跳转) */
.ts-modal { padding: 14px 16px; }
.ts-head { padding-bottom: 8px; border-bottom: 1px solid var(--c-input-border); margin-bottom: 8px; }
.ts-title { display: flex; align-items: baseline; gap: 8px; font-size: 12px; }
.ts-table-name { font-family: monospace; color: var(--c-btn); font-weight: 600; }
.ts-source { color: var(--c-text-dim); font-size: 10px; }
.ts-body { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 6px; }
.ts-meta { font-size: 10px; color: var(--c-text-dim); font-family: monospace; }
.ts-cols { width: 100%; border-collapse: collapse; font-size: 11px; }
.ts-cols thead th {
  text-align: left; padding: 4px 8px; background: var(--c-input-bg);
  color: var(--c-text-dim); font-weight: 500;
  border-bottom: 1px solid var(--c-input-border); font-size: 10px;
}
.ts-cols tbody td { padding: 3px 8px; border-bottom: 1px solid var(--c-input-border); }
.ts-cols code { font-family: ui-monospace, monospace; font-size: 10px; }
.ts-idx { color: var(--c-text-dim); width: 24px; text-align: right; font-family: monospace; }
.ts-col-type { color: var(--c-text-dim); }
.ts-comment { color: var(--c-text-dim); font-size: 10px; }
.ts-error { padding: 24px; color: var(--c-short); font-size: 11px; font-family: monospace; }
/* Stats grouping 表的 val cell — 可点复制 */
.ts-grouping-val { cursor: pointer; padding: 1px 3px; border-radius: 2px; transition: background 0.1s; }
.ts-grouping-val:hover { background: var(--c-input-bg); color: var(--c-btn); }

.dd-uniformity-item--clickable { cursor: pointer; transition: background 0.1s; }
.dd-uniformity-item--clickable:hover { background: rgba(255,107,107,0.12); }
