/* ============================================================
   tj-quant 共享设计令牌（assets/css/app.css）
   来源：index.html / report.html 内联 <style> 的 :root 与
   html[data-theme="dark"] 变量声明块（两文件一致，抽此共享）。
   规则：此处仅允许「变量声明」，禁止选择器规则——组件样式仍留在
   各页面内联 <style>，避免共享文件破坏页面内联的级联顺序。
   修改令牌只改本文件，并在 index/report 页面保持相同引用语义。
   ============================================================ */
:root {
  --background: 210 20% 97%;
  --foreground: 215 25% 22%;
  --card: 0 0% 100%;
  --card-foreground: 215 25% 22%;
  --popover: 0 0% 100%;
  --popover-foreground: 215 25% 22%;
  --primary: 210 58% 45%;
  --primary-foreground: 0 0% 100%;
  --secondary: 210 20% 96%;
  --secondary-foreground: 215 25% 30%;
  --muted: 210 18% 95%;
  --muted-foreground: 215 12% 48%;
  --accent: 210 45% 95%;
  --accent-foreground: 210 58% 38%;
  --destructive: 0 68% 52%;
  --destructive-foreground: 0 0% 100%;
  --success: 168 66% 44%;
  --warning: 38 90% 48%;
  --border: 214 15% 90%;
  --input: 214 14% 84%;
  --ring: 210 58% 45%;
  --radius: 0.6rem;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .06);
  --shadow: 0 1px 3px rgba(16, 24, 40, .07), 0 4px 14px rgba(16, 24, 40, .05);
  --shadow-lg: 0 8px 30px rgba(16, 24, 40, .16);
  --font-sans: "Helvetica Neue", Roboto, Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
  --font-mono: Menlo, Consolas, monospace;
  /* 间距（4px 网格）/ 字号（5 级）/ 圆角（4 档）—— 规范 02，供组件样式统一引用 */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-6: 24px; --space-8: 32px; --space-12: 48px; --space-16: 64px;
  --text-xs: 12px; --text-sm: 14px; --text-base: 16px; --text-lg: 18px; --text-xl: 20px;
  --radius-sm: 4px; --radius-md: 6px; --radius-lg: 8px; --radius-xl: 12px;
  /* —— 设计令牌（规范 02 对齐命名；值 = 现有代码实际用色，等值收敛）——
     brand：品牌青绿（tj-quant 主色，= 现行 #1abb9c 系）
     surface：灰阶面 / ink：蓝灰文字；语义色仅用于状态徽标。
     规范要求禁止 hardcode 裸色值：页面组件样式一律引用 var(--x)。 */
  --brand-50:  #E4F6F1;   /* 品牌浅底：icon hover 底 / 选中浅底 */
  --brand-600: #1abb9c;   /* 主按钮 / 激活 / 链接 / 图标主色 */
  --brand-700: #169f85;   /* hover / 深一档 / 边框强调 */
  --brand-800: #12806c;   /* 更深边框 / 按下 */
  --brand-900: #0E6B57;   /* 品牌深字（浅底上文字） */
  --surface-0: #FFFFFF;   /* 卡片 / 面板 / 弹层底 */
  --surface-2: #F5F7FA;   /* 页面背景 / 内容区 */
  --ink-900: #2A3F54;     /* 标题 / 主文字 */
  --ink-700: #5E6E80;     /* 正文 */
  --ink-500: #8292A4;     /* 次级文字 / 描述 / 图标静默 */
  --ink-400: #B7C6D4;     /* 占位 / 弱化 / 时间戳 */
  /* 语义色（现有代码用色等值；仅状态用） */
  --danger: #E74C3C;  --danger-deep: #C9302C;  --danger-bg: #FDECEC;  --danger-fg: #A52A1F;
  --success-bg: #E4F6F1; --success-fg: #0E6B57;
  /* 边框/分隔线（现有代码高频浅灰） */
  --line-1: #ECEEF1;  --line-2: #EEF0F2;  --line-3: #E4E8ED;  --line-4: #D4D9DF;
  --bg-input: #F5F5F5; --row-hover-lite: #F5F8FB;
  /* 品牌色半透明（聚焦环 / hover 底） */
  --brand-soft: rgba(26, 187, 156, .12);
}

/* —— 主题色（规范 03 双轴：data-brand 主题色 × data-theme=dark 明暗）——
   默认 emerald = 现有品牌青绿（决策 2：不强迁 indigo）；
   页面组件只用 var(--brand-*) / var(--brand-soft)，切换仅覆盖本组变量。 */
html[data-brand="indigo"] {
  --brand-50: #EEF2FF; --brand-600: #4F46E5; --brand-700: #4338CA;
  --brand-800: #3730A3; --brand-900: #312E81; --brand-soft: rgba(79, 70, 229, .12);
}
html[data-brand="emerald"] {
  --brand-50: #E4F6F1; --brand-600: #1abb9c; --brand-700: #169f85;
  --brand-800: #12806c; --brand-900: #0E6B57; --brand-soft: rgba(26, 187, 156, .12);
}
html[data-brand="rose"] {
  --brand-50: #FFF1F2; --brand-600: #E11D48; --brand-700: #BE123C;
  --brand-800: #9F1239; --brand-900: #881337; --brand-soft: rgba(225, 29, 72, .12);
}
html[data-brand="amber"] {
  --brand-50: #FFFBEB; --brand-600: #D97706; --brand-700: #B45309;
  --brand-800: #92400E; --brand-900: #78350F; --brand-soft: rgba(217, 119, 6, .12);
}
html[data-brand="slate"] {
  --brand-50: #F8FAFC; --brand-600: #475569; --brand-700: #334155;
  --brand-800: #1E293B; --brand-900: #0F172A; --brand-soft: rgba(71, 85, 105, .12);
}

/* —— 右下角悬浮按钮组（规范 7.16）——
   形态：单主按钮，鼠标悬浮展开子按钮组（主题色/明暗/退出登录），
   展开/折叠带缩放+位移动画；主题色气泡在按钮组左侧展开（不被遮挡）。
   交互：hover / focus-within 展开；点外部或 Esc 收起。纯 SVG、无文字按钮。 */
.fab-wrap {
  position: fixed; right: 24px; bottom: 24px; z-index: 950;
  display: flex; flex-direction: column; align-items: flex-end;
}
.fab-wrap .fab-btn {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line-1);
  background: var(--surface-0); color: var(--ink-700);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: var(--shadow, 0 2px 10px rgba(16, 24, 40, .12));
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease, color .15s ease, opacity .15s ease;
  position: relative;
}
html[data-theme="dark"] .fab-wrap .fab-btn { background: var(--bg-panel); color: var(--fg-body); border-color: var(--line); }
.fab-wrap .fab-btn svg { width: 19px; height: 19px; }
.fab-wrap .fab-btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.fab-wrap .fab-btn:active { transform: scale(.94); }
.fab-wrap .fab-btn:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }
/* 主按钮：品牌色实底 + 悬浮时旋转，标识"可展开" */
.fab-wrap .fab-main {
  background: var(--brand-600); border-color: var(--brand-700); color: var(--surface-0);
}
html[data-theme="dark"] .fab-wrap .fab-main { background: var(--brand-600); border-color: var(--brand-700); color: var(--surface-0); }
.fab-wrap .fab-main:hover { background: var(--brand-700); color: var(--surface-0); }
.fab-wrap .fab-main svg { transition: transform .2s ease; }
.fab-wrap.open .fab-main svg { transform: rotate(45deg); }
/* 子按钮组：主按钮上方垂直排列；折叠 = 透明 + 下沉 + 不可点 */
.fab-wrap .fab-panel {
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  margin-bottom: 12px;
  opacity: 0; visibility: hidden; transform: translateY(8px) scale(.92);
  transform-origin: bottom right;
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
}
.fab-wrap.open .fab-panel {
  opacity: 1; visibility: visible; transform: translateY(0) scale(1);
  transition: opacity .18s ease, transform .18s ease;
}
.fab-wrap .fab-logout { color: var(--danger); border-color: rgba(231, 76, 60, .35); }
html[data-theme="dark"] .fab-wrap .fab-logout { color: var(--danger); border-color: rgba(231, 76, 60, .4); }
.fab-wrap .fab-logout:hover { background: var(--danger-bg); color: var(--danger-deep); }
/* 主题色气泡：相对按钮组容器，在左侧展开（水平 + 垂直居中于 palette 按钮） */
.fab-wrap .fab-pop {
  position: absolute; right: calc(100% + 12px); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface-0); border: 1px solid var(--line-1); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg); padding: 12px 14px; white-space: nowrap;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
}
html[data-theme="dark"] .fab-wrap .fab-pop { background: var(--bg-panel); border-color: var(--line); }
.fab-wrap .fab-theme.open .fab-pop {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity .18s ease, transform .18s ease;
}
.fab-wrap .fab-pop .fp-label { font-size: 11px; color: var(--ink-500); font-weight: 600; letter-spacing: .03em; }
.fab-wrap .fab-swatches { display: flex; gap: 8px; }
.fab-wrap .fab-swatch { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; padding: 0; transition: transform .12s ease; }
.fab-wrap .fab-swatch:hover { transform: scale(1.12); }
.fab-wrap .fab-swatch.active { border-color: var(--ink-900); box-shadow: 0 0 0 2px var(--surface-0); }
html[data-theme="dark"] .fab-wrap .fab-swatch.active { border-color: var(--fg-strong); }

/* —— 组件结构变量亮色值（与 dark 块同名，双态单源）——
   组件样式统一引用 var(--bg-panel)/var(--fg-body) 等即可自动亮暗切换，
   暗色覆盖块逐步删除；值 = 现有亮色组件用色，等值收敛。 */
:root {
  --bg-page: #F5F7FA;      /* 页面露底 / 登录背景（亮=surface-2） */
  --bg-canvas: #F5F7FA;    /* 内容区 right_col */
  --bg-top: #FFFFFF;       /* 顶栏（已无顶栏，兼容保留） */
  --bg-panel: #FFFFFF;     /* 卡片/面板/表格/弹层 */
  --bg-panel2: #FFFFFF;    /* 次级浮起面（亮=白）：tabs 选中 / btn-normal / 分页钮 */
  --bg-soft: #EEF1F4;      /* hover/轨道面（亮=tabs 轨道 #EEF1F4 等值）：tabs 轨道 / 次级 hover */
  --bg-field: #FFFFFF;     /* 输入框 */
  --fg-strong: #2A3F54;    /* 标题文字（亮=ink-900） */
  --fg-body: #5E6E80;      /* 正文（亮=ink-700） */
  --fg-sub: #8292A4;       /* 次级文字（亮=ink-500） */
  --fg-weak: #A4AEB9;      /* 弱/禁用文字（亮=占位符 #A4AEB9 等值） */
  --line: #ECEEF1;         /* 常规边框（亮=line-1） */
  --line-strong: #D4D9DF;  /* 输入 / 分页边框（亮=line-4） */
  --row-hover: rgba(16, 24, 40, .04);
  --teal-soft: rgba(26, 187, 156, .12);
  /* 图表（Plotly）专用：亮暗双态单源。JS P 助手与暗色 CSS 兜底共同引用，改色只动本文件 */
  --plot-paper: #FFFFFF;     /* 图纸底色（亮=面板白；暗=深图板） */
  --plot-ink: #2A3F54;       /* 图表标题（=fg-strong） */
  --plot-axis: #5E6E80;      /* 轴刻度文字（=fg-body） */
  --plot-grid: #E6E9ED;      /* 网格线 */
  --plot-hover-bg: #FFFFFF;  /* hover 提示底 */
  --plot-hover-bd: #DDDDDD;  /* hover 提示边框 */
}

html[data-theme="dark"] {
  --background: 213 18% 9%;
  --foreground: 214 22% 91%;
  --card: 213 24% 15%;
  --card-foreground: 214 22% 91%;
  --popover: 213 24% 15%;
  --popover-foreground: 214 22% 91%;
  --primary: 168 58% 52%;
  --primary-foreground: 0 0% 100%;
  --secondary: 214 18% 13%;
  --secondary-foreground: 214 18% 84%;
  --muted: 214 18% 13%;
  --muted-foreground: 213 13% 66%;
  --accent: 214 18% 14%;
  --accent-foreground: 168 60% 55%;
  --border: 214 15% 20%;
  --input: 214 15% 22%;
  --ring: 168 60% 48%;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow: 0 1px 3px rgba(0, 0, 0, .42), 0 4px 14px rgba(0, 0, 0, .28);
  --shadow-lg: 0 10px 34px rgba(0, 0, 0, .5);
  /* 组件结构色（与 :root 语义令牌平行，供写死色组件覆盖用） */
  --bg-page: #0B1119;      /* 页面露底 / 登录背景 */
  --bg-canvas: #131C27;    /* 内容区 right_col */
  --bg-top: #192330;       /* 顶栏 */
  --bg-panel: #1B2634;     /* 卡片/面板/表格/弹层 */
  --bg-panel2: #202C3A;    /* 次级面：tabs 选中 / 分页钮 / btn-default */
  --bg-soft: #253141;      /* 表头 / hover / tabs 轨道 */
  --bg-field: #101A24;     /* 输入框 */
  --fg-strong: #E6EDF4;    /* 标题文字 */
  --fg-body: #B9C7D4;      /* 正文 */
  --fg-sub: #90A3B6;       /* 次级文字 */
  --fg-weak: #66798D;      /* 弱/禁用文字 */
  --line: #293949;         /* 常规边框 */
  --line-strong: #3A4B5E;  /* 输入 / 分页边框 */
  --row-hover: rgba(255, 255, 255, .05);
  --teal-soft: rgba(26, 187, 156, .15);
  --plot-paper: #131B26;
  --plot-ink: #E6EDF4;
  --plot-axis: #B9C7D4;
  --plot-grid: #8FA5BC;
  --plot-hover-bg: #253141;
  --plot-hover-bd: #45576C;
}

/* ================= 按钮组件（规范 7.1） =================
   Primary(.btn-primary) / Secondary(.btn-default) / Danger(.btn-danger) / Icon(.btn-icon)
   / Ghost(.btn-ghost 行内文字钮)。
   一次书写：底色/边框/文字全走双态变量自切亮暗；hover 纯色变（无浮起、无阴影叠加）。
   变体限 4 + Icon + Ghost，禁止新增。 */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4);                  /* Default = 8px 16px */
  border: 1px solid transparent; border-radius: var(--radius-lg);   /* rounded-lg 8px */
  font-size: var(--text-sm); font-weight: 500; font-family: var(--font-sans); line-height: 1.4;
  color: var(--fg-body); background: transparent; cursor: pointer; white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.btn svg { width: var(--space-4); height: var(--space-4); flex-shrink: 0; }
.btn:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; pointer-events: none; }
.btn:active:not(:disabled) { transform: scale(.97); }
.btn.btn-sm { padding: 6px var(--space-3); font-size: var(--text-xs); }
.btn.btn-primary { background: var(--brand-600); color: var(--surface-0); }
.btn.btn-primary:hover:not(:disabled) { background: var(--brand-700); color: var(--surface-0); }
.btn.btn-default { background: var(--bg-panel); border-color: var(--line); color: var(--fg-body); }
.btn.btn-default:hover:not(:disabled) { background: var(--bg-soft); color: var(--fg-strong); }
.btn.btn-danger { background: var(--danger); color: var(--surface-0); }
.btn.btn-danger:hover:not(:disabled) { background: var(--danger-deep); color: var(--surface-0); }
/* 选中态（按钮组当前项，如快捷段按钮）——视觉同 Primary 实底 */
.btn.active, .btn.active:hover:not(:disabled) {
  background: var(--brand-600); border-color: var(--brand-700); color: var(--surface-0);
}
/* Icon 型：纯图标按钮（须配 aria-label）；中性色可叠加变体色 */
.btn.btn-icon { width: 36px; height: 36px; padding: 0; color: var(--fg-body); }
.btn.btn-icon svg { width: 20px; height: 20px; flex-shrink: 0; }
.btn.btn-icon:hover:not(:disabled) { background: var(--bg-soft); color: var(--fg-strong); }
/* 变体色图标钮 = Ghost 语义：无底无框，仅着色（Primary 品牌色 / Danger 危险色） */
.btn.btn-icon.btn-primary { background: transparent; border-color: transparent; color: var(--brand-600); }
.btn.btn-icon.btn-primary:hover:not(:disabled) { background: transparent; color: var(--brand-700); }
.btn.btn-icon.btn-danger { background: transparent; border-color: transparent; color: var(--danger); }
.btn.btn-icon.btn-danger:hover:not(:disabled) { background: transparent; color: var(--danger-deep); }
/* Ghost（规范 7.1）：行内文字钮（查看/编辑链接、行内操作）——无底无框、品牌字 */
.btn.btn-ghost { background: transparent; border-color: transparent; color: var(--brand-600); padding: var(--space-1) var(--space-2); }
.btn.btn-ghost:hover:not(:disabled) { background: transparent; color: var(--brand-700); }
.btn.btn-ghost:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }
/* 按钮 loading（规范 7.1）：Loader2 旋转 + disabled 防重复；图标占位不挤压宽度 */
.btn .btn-spinner { display: inline-flex; }
.btn .btn-spinner svg { width: var(--space-4); height: var(--space-4); animation: tj-spin .8s linear infinite; }
@keyframes tj-spin { to { transform: rotate(360deg); } }

/* 控件加载失败态（规范 08 错误处理）：友好提示 + 重试按钮，不向用户裸显状态码。
   errRow（表格行内）/ errBlock（块级容器）共用；亮暗自切由 --fg-sub/按钮体系驱动。 */
.load-err {
  display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap;
  padding: 18px 14px; color: var(--fg-sub); font-size: var(--text-sm); text-align: center;
}
.load-err .btn-retry { flex-shrink: 0; }
