:root {
  --bg: #0e1117;
  --bg-elev: #161b24;
  --bg-elev2: #1c2230;
  --border: #262d3b;
  --border-soft: #1f2532;
  --text: #e6eaf2;
  --text-dim: #9aa4b8;
  --text-mute: #6b7488;
  --accent: #4c8dff;
  --accent-soft: rgba(76, 141, 255, .14);
  --up: #f6465d;
  --down: #2ebd85;
  --shadow: 0 8px 24px rgba(0, 0, 0, .35);
  --radius: 12px;
  /* 别名：各板块卡片直接引用这些名字。以前它们只在个别内联样式的 var(…, 回退值)
     里出现、没有定义，**浅色主题下会退化成硬编码的深色**（深底 + 深字 = 数字看不见），
     所以这里补齐两套主题的值，别名与主变量保持同步。 */
  --card: #1a2029;
  --text-1: #e6eaf2;
  --text-2: #c9d1e0;
  --line: #262d3b;
  --muted: #9aa4b8;
  --warn: #f5a623;
  --warn-soft: rgba(245, 166, 35, .16);
  --mono: "JetBrains Mono", Consolas, "Courier New", monospace;
  /* 图表（ECharts canvas 不吃 CSS 变量，由 _shared.js planTheme/colors() 读取后代入）。
     深色值刻意等于历史硬编码（#262d3b 轴、rgba(22,27,36) tooltip 底等），
     保证注入层在深色主题下是恒等变换（Phase 2 方案：默认主题像素级不变）。 */
  --chart-split: rgba(255, 255, 255, .05);
  --chart-tooltip-rgb: 22, 27, 36;
  --chart-endlabel-bg: rgba(22, 27, 36, .88);
}

[data-theme="light"] {
  --bg: #f4f6fa;
  --bg-elev: #ffffff;
  --bg-elev2: #f7f9fc;
  --border: #e2e7f0;
  --border-soft: #edf1f7;
  --text: #1b2233;
  --text-dim: #5a6478;
  --text-mute: #8b94a8;
  --shadow: 0 8px 24px rgba(20, 30, 60, .10);
  /* 别名同样跟随浅色主题（否则卡片会退回深色底 + 深色字） */
  --card: #ffffff;
  --text-1: #1b2233;
  --text-2: #3d475c;
  --line: #e2e7f0;
  --muted: #7d879c;
  --warn: #b5730a;
  --warn-soft: rgba(181, 115, 10, .12);
  --chart-split: rgba(20, 30, 60, .07);
  --chart-tooltip-rgb: 255, 255, 255;
  --chart-endlabel-bg: rgba(255, 255, 255, .88);
}

/* 护眼主题 · 浅绿（《数据看板主题配色规范》Theme 1，Chris 2026-09-24 拍板）。
   派生 token（--bg-elev2/--border-soft/--text-mute/--shadow/--text-2）规范未给出，
   按「低饱和、与给定 token 同色系」补齐；涨跌保持平台「红涨绿跌」默认（Chris 拍板）：
   规范 color-down 绿 → --down，color-up 红 → --up，绿涨组合交给 [data-up="green"] 开关。
   本块必须排在 [data-up="green"] 交换规则**之前**，绿涨红跌开关才能继续生效。 */
[data-theme="green"] {
  --bg: #F2F7F2;
  --bg-elev: #FFFFFF;
  --bg-elev2: #EAF2EA;
  --border: #E2EAE3;
  --border-soft: #EDF3ED;
  --text: #2D3730;
  --text-dim: #607065;
  --text-mute: #8A978D;
  --accent: #4A9668;
  --accent-soft: rgba(74, 150, 104, .14);
  --up: #C26565;
  --down: #57A878;
  --chart-1: #73A888;
  --chart-2: #B4D2C0;
  --shadow: 0 8px 24px rgba(45, 55, 48, .10);
  /* 别名同步（教训同 app.css:16-26：缺了会退化成深色底 + 深色字） */
  --card: #FFFFFF;
  --text-1: #2D3730;
  --text-2: #46534A;
  --line: #E2EAE3;
  --muted: #607065;
  --warn: #B5730A;
  --warn-soft: rgba(181, 115, 10, .12);
  --chart-split: rgba(45, 55, 48, .08);
  --chart-tooltip-rgb: 255, 255, 255;
  --chart-endlabel-bg: rgba(255, 255, 255, .88);
}

/* 护眼主题 · 沙色（《数据看板主题配色规范》Theme 2）。涨跌方向同浅绿主题：红涨 #B86058 / 绿跌 #639977。 */
[data-theme="sand"] {
  --bg: #F7F3EB;
  --bg-elev: #FFFFFF;
  --bg-elev2: #F0EADD;
  --border: #E9E2D6;
  --border-soft: #F2EDE3;
  --text: #38342E;
  --text-dim: #746E63;
  --text-mute: #9C948A;
  --accent: #A67C52;
  --accent-soft: rgba(166, 124, 82, .14);
  --up: #B86058;
  --down: #639977;
  --chart-1: #C4A887;
  --chart-2: #D9C8B4;
  --shadow: 0 8px 24px rgba(56, 52, 46, .10);
  --card: #FFFFFF;
  --text-1: #38342E;
  --text-2: #524C42;
  --line: #E9E2D6;
  --muted: #746E63;
  --warn: #B5730A;
  --warn-soft: rgba(181, 115, 10, .12);
  --chart-split: rgba(56, 52, 46, .08);
  --chart-tooltip-rgb: 255, 255, 255;
  --chart-endlabel-bg: rgba(255, 255, 255, .88);
}

[data-up="green"] { --up: #2ebd85; --down: #f6465d; }

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
}

.boot { padding: 60px; text-align: center; color: var(--text-mute); }

/* 站点页脚：备案号——固定于视口底部（position:fixed），任何分辨率不滚动即可见。
   z-index 50：压过普通内容，但被板块最大化(60)/抽屉(70)/弹窗(80)等浮层自然盖住。
   body 预留 28px 高度，滚到底时最后一行内容不被底栏遮挡。 */
body { padding-bottom: 28px; }
#app { min-height: calc(100vh - 28px); }
.site-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  height: 28px; line-height: 27px; padding: 0 12px; box-sizing: border-box;
  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 11.5px; color: var(--text-mute);
  border-top: 1px solid var(--border); background: var(--bg);
}
.site-foot a { color: var(--text-mute); text-decoration: none; }
.site-foot a:hover { color: var(--accent); }
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.up { color: var(--up); }
.down { color: var(--down); }
.flat { color: var(--text-dim); }
.muted { color: var(--text-mute); }
.dim { color: var(--text-dim); }

/* ---------------------------------------------------------------- 按钮 / 表单 */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-elev2); color: var(--text);
  font-size: 12.5px; cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { filter: brightness(1.1); color: #fff; }
.btn.analysis { background: #e5484d; border-color: #e5484d; color: #fff; }
.btn.analysis:hover { filter: brightness(1.1); color: #fff; }
.btn.mining { background: #12a594; border-color: #12a594; color: #fff; }
.btn.mining:hover { filter: brightness(1.1); color: #fff; }
.btn.ghost { background: transparent; }
.btn.icon { width: 28px; padding: 0; justify-content: center; }
.btn.danger:hover { border-color: var(--up); color: var(--up); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

input, select {
  height: 30px; padding: 0 10px;
  background: var(--bg-elev2); border: 1px solid var(--border); border-radius: 8px;
  color: var(--text); font-size: 12.5px; outline: none;
}
input:focus, select:focus { border-color: var(--accent); }
input::placeholder { color: var(--text-mute); }
label.field { display: flex; flex-direction: column; gap: 6px; font-size: 12px; color: var(--text-dim); }

/* 密码框 + 显示/隐藏按钮 */
.pw-wrap { position: relative; display: block; }
.pw-wrap > input { width: 100%; padding-right: 54px; box-sizing: border-box; }
.pw-wrap > button[data-eye] {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  height: 22px; padding: 0 8px; font-size: 11px; line-height: 1;
  color: var(--text-dim); background: transparent; border: 1px solid transparent;
  border-radius: 6px; cursor: pointer;
}
.pw-wrap > button[data-eye]:hover { color: var(--text); border-color: var(--border); }
.pw-wrap > button[data-eye].on { color: var(--accent); }

/* ---------------------------------------------------------------- 登录 / 注册 */
.auth-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(1200px 500px at 50% -10%, rgba(76, 141, 255, .12), transparent 60%);
}
.auth-col { display: flex; flex-direction: column; align-items: center; }
/* 登录框正下方外部的「使用指南」入口 */
.auth-guide { margin-top: 14px; font-size: 12.5px; }
.auth-guide a { color: var(--accent); text-decoration: none; }
.auth-guide a:hover { text-decoration: underline; }
.auth-card {
  width: 380px; padding: 32px; border-radius: 16px;
  background: var(--bg-elev); border: 1px solid var(--border); box-shadow: var(--shadow);
}
.auth-card h1 { margin: 0 0 4px; font-size: 20px; }
.auth-card .sub { margin: 0 0 24px; color: var(--text-mute); font-size: 12.5px; }
.auth-card .stack { display: flex; flex-direction: column; gap: 14px; }
.auth-card .row { display: flex; gap: 10px; }
.auth-card .row > * { flex: 1; }
.auth-err { color: var(--up); font-size: 12px; min-height: 16px; }
.auth-err.auth-tip { color: var(--text-mute); } /* 非错误的普通提示 */
.auth-remember {
  display: flex; align-items: center; gap: 8px; margin-top: -4px;
  font-size: 12.5px; color: var(--text-mute); cursor: pointer; user-select: none;
}
.auth-remember input { width: 14px; height: 14px; accent-color: var(--accent); cursor: pointer; }
.auth-foot { margin-top: 18px; font-size: 12px; color: var(--text-mute); text-align: center; }
.auth-foot a { color: var(--accent); cursor: pointer; text-decoration: none; }
/* 登录页演示账号提示框 */
.auth-demo {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 10px; border: 1px dashed var(--border); border-radius: 9px;
  background: var(--bg-elev2, rgba(127, 127, 127, .06)); font-size: 12.5px; color: var(--text-mute);
}
.auth-demo .t { color: var(--text-mute); }
.auth-demo code { color: var(--text); font-family: var(--mono, ui-monospace, monospace); font-size: 12px; }
.auth-demo .sep { opacity: .6; }
.auth-demo a { color: var(--accent); cursor: pointer; margin-left: 4px; }
.auth-demo[hidden] { display: none; } /* display:flex 会盖过 hidden 属性，需显式还原 */

/* 站点级 /login 与看板内登录页共用：窄屏时 380px 固定宽会溢出 */
@media (max-width: 480px) {
  .auth-card { width: calc(100vw - 32px); padding: 24px; }
  .auth-col > .auth-demo { width: calc(100vw - 32px); }
}
/* 登录框外部的演示账号提示：位于登录框与「使用指南」之间，宽度与登录框对齐 */
.auth-col > .auth-demo { margin-top: 14px; width: 380px; max-width: 92vw; }

/* ---------------------------------------------------------------- 顶栏 */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  height: 50px; padding: 0 16px;
  background: var(--bg-elev); border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 600; }
.brand .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.topbar .spacer { flex: 1; }
.tabs { display: flex; gap: 4px; overflow-x: auto; }
.tab {
  padding: 5px 12px; border-radius: 8px; cursor: pointer; color: var(--text-dim);
  font-size: 12.5px; white-space: nowrap; border: 1px solid transparent;
}
.tab:hover { background: var(--bg-elev2); }
.tab.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-soft); }
/* 板块标题栏的数据时效提示 */
.meta { font-size: 11.5px; color: var(--text-mute); }
.meta.stale {
  color: var(--warn, #d99a2b); background: var(--warn-soft, rgba(217,154,43,.12));
  border-radius: 6px; padding: 1px 6px;
}

/* 看板标签拖拽排序 */
.tab[draggable="true"] { cursor: grab; }
.tab.dragging { opacity: .45; cursor: grabbing; }
.tab.drop-hint { border-color: var(--accent); box-shadow: inset 2px 0 0 var(--accent); }
.tab {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 12px 5px 10px;
}
.tab-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.tab-del {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 3px; font-size: 11px;
  color: var(--text-mute, #6b7488); opacity: 0; transition: opacity .15s, background .15s, color .15s;
  flex: none; line-height: 1; cursor: pointer;
}
.tab:hover .tab-del { opacity: 1; }
.tab-del:hover { background: rgba(229,72,77,.15); color: #e5484d; }

/* 偏好设置中的城市多选 chip */
.city-chips {
  display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 0 10px;
}
.city-chip {
  display: inline-flex; align-items: center;
  padding: 3px 10px; border-radius: 14px; font-size: 12px;
  cursor: pointer; user-select: none;
  background: var(--bg-elev2); border: 1px solid var(--border-soft);
  color: var(--text-dim); transition: all .15s;
}
.city-chip:hover { color: var(--text-1, inherit); border-color: var(--border); }
.city-chip.on {
  background: var(--accent-soft, rgba(76,141,255,.12));
  border-color: var(--accent); color: var(--accent);
}
/* 自定义城市 pill：名字 + 右侧 × 删除 */
.city-chip.custom { gap: 5px; }
.city-chip.custom .x {
  font-style: normal; font-size: 13px; line-height: 1;
  margin-right: -3px; opacity: .55; transition: opacity .15s;
}
.city-chip.custom:hover .x { opacity: 1; }
/* 自定义城市搜索框 + 下拉候选 */
.city-search { position: relative; }
.city-search input {
  width: 100%; box-sizing: border-box;
  padding: 6px 10px; font-size: 12.5px;
  background: var(--bg-elev2); color: var(--text-1, inherit);
  border: 1px solid var(--border-soft); border-radius: 8px; outline: none;
}
.city-search input:focus { border-color: var(--accent); }
.city-search-drop {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  z-index: 60; max-height: 240px; overflow-y: auto;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,.18);
}
.city-search-item {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 7px 10px; font-size: 12.5px; cursor: pointer;
}
.city-search-item:hover { background: var(--accent-soft, rgba(76,141,255,.10)); }
.city-search-item b { font-weight: 500; }
.city-search-item .muted { font-size: 11px; white-space: nowrap; }

/* ---------------------------------------------------------------- 世界时钟条 */
.clockbar {
  display: flex; align-items: center; gap: 10px; overflow-x: auto;
  padding: 7px 14px; background: var(--bg-elev2);
  border-bottom: 1px solid var(--border-soft); font-size: 12px;
}
.clockbar .clock {
  display: flex; align-items: baseline; gap: 6px; white-space: nowrap;
  padding: 3px 10px; border: 1px solid var(--border-soft); border-radius: 8px;
  background: var(--bg-elev);
}
.clockbar .city { color: var(--text-mute); }
.clockbar .t { font-family: var(--mono, "JetBrains Mono", Consolas, monospace); font-size: 13px; font-weight: 600; }
.clockbar .muted { font-size: 11px; }
/* 行尾的账户「上次登录」提示：margin-left:auto 把它顶到这一行结尾；窄屏时钟条横向
   滚动时它就在滚动内容的末尾。不用 display:none 藏起来——藏了等于小窗口丢掉功能。 */
.clockbar .clock-last {
  margin-left: auto; color: var(--text-mute); font-weight: 400; border-style: dashed;
}

/* ---------------------------------------------------------------- 管理页签（邀请码 / 用户 / 板块） */
.admin-tabs {
  display: flex; gap: 4px; padding: 0 16px; border-bottom: 1px solid var(--border-soft);
  background: var(--bg-elev2); overflow-x: auto;
}
.admin-tab {
  padding: 9px 14px; font-size: 13px; color: var(--text-mute); text-decoration: none;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.admin-tab:hover { color: var(--text-1, #e6eaf2); }
.admin-tab.on { color: var(--accent, #4c8dff); border-bottom-color: var(--accent, #4c8dff); font-weight: 600; }

/* ---------------------------------------------------------------- 天气条（时钟条下一行） */
.weatherbar {
  display: flex; align-items: center; gap: 8px; overflow-x: auto;
  padding: 6px 14px; background: var(--bg-elev2);
  border-bottom: 1px solid var(--border-soft); font-size: 12px;
}
.weatherbar .wcard {
  display: flex; align-items: baseline; gap: 6px; white-space: nowrap;
  padding: 3px 10px; border: 1px solid var(--border-soft); border-radius: 8px;
  background: var(--bg-elev);
}
.weatherbar .city { color: var(--text-mute); }
/* 当地天气（按 IP 定位）：加一点高亮，一眼区分「当前所在」与固定四城 */
.weatherbar .wcard.local { border-color: var(--accent, #4c8dff); background: var(--bg-elev2); }
.weatherbar .city.local { color: var(--text-1, #e6eaf2); font-weight: 600; }
.weatherbar .city.local i {
  font-style: normal; font-size: 10px; margin-left: 4px; padding: 0 4px;
  border-radius: 999px; background: rgba(76, 141, 255, .18); color: var(--accent, #4c8dff);
}
.weatherbar .w { display: inline-flex; align-items: center; gap: 4px; }
.weatherbar .wicon { display: inline-flex; width: 16px; height: 16px; }
.weatherbar .wicon svg { width: 16px; height: 16px; display: block; }
.weatherbar .w b { font-size: 13px; }
.weatherbar .muted { font-size: 11px; }
.weatherbar .upd { margin-left: auto; flex: none; }

/* ---------------------------------------------------------------- 「+分析」板块通用样式 */
.an-frame { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.an-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; padding: 8px 10px 0; }
.an-body > .chart { flex: 1; min-height: 90px; width: 100%; }

/* 结论卡：主结论突出展示，候选结论可展开 */
.an-verdict {
  margin: 8px 10px 0; padding: 8px 12px; border-radius: 8px;
  border: 1px solid var(--border, #262d3b); background: var(--bg-elev, #1a2029);
}
.an-verdict .top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.an-verdict .tag {
  color: #fff; font-size: 11px; padding: 1px 7px; border-radius: 999px; flex: none;
}
.an-verdict .text { font-size: 13px; font-weight: 600; }
.an-verdict .more {
  margin-left: auto; font-size: 11px; color: var(--text-mute); cursor: pointer;
  border-bottom: 1px dashed currentColor;
}
.an-verdict .advice { font-size: 12px; color: var(--text-2, #c9d1e0); margin-top: 4px; }
.an-verdict .evidence { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; }
.an-verdict .an-ev { font-size: 11px; color: var(--text-mute); }
.an-verdict .an-ev i { font-style: normal; opacity: .8; margin-right: 4px; }
.an-verdict .an-ev b { color: var(--text-1, #e6eaf2); font-weight: 600; }
.an-verdict .cands { list-style: none; margin: 8px 0 0; padding: 8px 0 0; border-top: 1px dashed var(--border-soft, #262d3b); }
.an-verdict .cands li { display: flex; gap: 6px; align-items: baseline; font-size: 12px; padding: 2px 0; }
.an-verdict .cands li.active { background: rgba(76, 141, 255, .08); border-radius: 4px; }
.an-verdict .cands .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; margin-top: 5px; }
.an-verdict .cands .adv { color: var(--text-mute); font-size: 11px; }

/* 因子打分条 */
.an-factor { border: 1px solid var(--border-soft, #262d3b); border-radius: 8px; padding: 6px 10px; }
.an-factor .row { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; }
.an-factor .track { position: relative; height: 4px; background: var(--bg-elev2, #11161d); border-radius: 2px; margin: 5px 0; }
.an-factor .track i { position: absolute; top: 0; height: 100%; border-radius: 2px; }
.an-factor .sub { font-size: 11px; color: var(--text-mute); line-height: 1.5; }

/* 指标卡网格 */
.an-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 6px; }
.an-card {
  border: 1px solid var(--border-soft, #262d3b); border-radius: 8px; padding: 5px 8px;
  display: flex; flex-direction: column; gap: 2px; background: var(--bg-elev, #1a2029);
}
.an-card .name { font-size: 11px; color: var(--text-mute); }
.an-card .value { font-size: 14px; font-weight: 600; font-family: var(--mono, monospace); }
.an-card .delta { font-size: 11px; }

/* 注入到既有分析板块的结论卡（dashboard.js applyConclusion） */
.an-verdict-inject { padding: 8px 10px 0; }
.an-verdict-inject .an-verdict { margin: 0; }
.an-meta-inline { margin-top: 6px; font-size: 11px; color: var(--text-mute); line-height: 1.6; }
.an-meta-inline .sep { font-style: normal; opacity: .5; margin: 0 4px; }

/* 口径缺口 & 脚注 */
.an-gaps { font-size: 11px; color: var(--text-mute); line-height: 1.6; }
.an-gaps b { color: var(--text-2, #c9d1e0); }
.an-gaps ul { margin: 2px 0 0; padding-left: 16px; }
/* 脚注默认一行：超出部分省略号，完整内容在 title 里；长说明收进可展开的 detail */
.an-foot { flex-direction: column; align-items: stretch; gap: 3px; padding: 5px 10px; }
.an-foot-line {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  white-space: nowrap; overflow: hidden;
}
.an-foot-line > span {
  overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.an-foot-line .an-meta-fw { color: var(--text-2, #c9d1e0); flex: none; }
.an-foot .sep { font-style: normal; opacity: .5; margin: 0 2px; flex: none; }
.an-foot .badge { flex: none; }
.an-foot-more {
  margin-left: auto; flex: none; font-size: 11px; color: var(--accent, #4c8dff);
  cursor: pointer; border-bottom: 1px dashed currentColor;
}
.an-foot-detail {
  max-height: 84px; overflow: auto; font-size: 11px; line-height: 1.6;
  color: var(--text-mute); padding-top: 2px;
}
/* 最大化时放宽说明区上限：小板块里 84px 合适，但保持 84px 会出现
   「板块放大了、说明还是只露一小截」的观感 */
.grid-stack-item.maximized .an-foot-detail { max-height: 40vh; }
.an-foot .an-note { line-height: 1.6; }

/* 非分析板块的脚注同样收成一行，避免说明把图挤小 */
.widget-foot {
  flex-wrap: nowrap; overflow: hidden;
}
.widget-foot > span, .widget-foot > div {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}

/* ---------------------------------------------------------------- 「+挖掘」板块通用零件 */
.mg-tag { color:#fff; font-size:11px; padding:1px 7px; border-radius:999px; white-space:nowrap; }
.mg-bars { display:flex; flex-direction:column; gap:3px; }
.mg-bar { display:flex; align-items:center; gap:6px; font-size:11.5px; }
.mg-bar .nm { width:34%; color:var(--text-2,#c9d1e0); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mg-bar .track { flex:1; height:5px; background:var(--bg-elev2,#11161d); border-radius:3px; overflow:hidden; }
.mg-bar .track i { display:block; height:100%; border-radius:3px; }
.mg-bar .vl { width:64px; text-align:right; font-family:var(--mono,monospace); }
.mg-bar .rt { font-size:10.5px; max-width:30%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mg-pctl { display:flex; align-items:center; gap:8px; font-size:11.5px; }
.mg-pctl .lb { color:var(--text-mute); width:78px; }
.mg-pctl .tk { position:relative; flex:1; height:6px; background:var(--bg-elev2,#11161d); border-radius:3px; }
.mg-pctl .tk i { position:absolute; top:-2px; width:8px; height:10px; border-radius:2px; transform:translateX(-4px); }
.mg-pctl .tk em { position:absolute; top:0; width:1px; height:6px; background:var(--border-soft,#262d3b); opacity:.7; }
.mg-pctl .vl { width:52px; text-align:right; font-family:var(--mono,monospace); }
.mg-pctl .hint { max-width:34%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mg-table { width:100%; border-collapse:collapse; font-size:11.5px; }
.mg-table th, .mg-table td { text-align:right; padding:3px 6px; border-bottom:1px solid var(--border-soft,#262d3b); white-space:nowrap; }
.mg-table th:first-child, .mg-table td:first-child { text-align:left; }
.mg-table th { color:var(--text-mute); font-weight:600; }
.mg-scroll { overflow:auto; min-height:0; }

/* 标的代码清单（＋挖掘 · A股 板块的统一出口：复制 / 导出） */
.mg-codes { margin: 6px 10px 0; padding: 6px 8px; border: 1px solid var(--border-soft, #262d3b);
  border-radius: 8px; background: var(--bg-elev, #1a2029); }
.mg-codes .hd { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mg-codes .hd .ttl { font-size: 11.5px; color: var(--text-2, #c9d1e0); margin-right: auto; }
.mg-codes .hd .ttl b { color: var(--accent, #4c8dff); }
.mg-codes .hd .btn { font-size: 11px; padding: 2px 8px; }
.mg-codes .chips { display: flex; flex-wrap: wrap; gap: 4px 6px; margin-top: 5px; max-height: 66px; overflow: auto; }
.mg-codes .chip { font-size: 11px; color: var(--text-2, #c9d1e0); border: 1px solid var(--border-soft, #262d3b);
  border-radius: 5px; padding: 1px 6px; white-space: nowrap; }
.mg-codes .chip i { font-style: normal; color: var(--text-mute); margin-left: 5px; font-family: var(--mono, monospace); }

/* ---------------------------------------------------------------- 看板 */
.dash-wrap { padding: 14px 12px 60px; }
.grid-stack { min-height: 200px; }
.grid-stack-item-content {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius);
}
.widget {
  display: flex; flex-direction: column; height: 100%; min-height: 0;
}
.widget-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 8px 12px; border-bottom: 1px solid var(--border-soft);
  cursor: move; user-select: none;
}
.widget-head .title { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 标题旁的重命名按钮（✎）：样式与操作区按钮一致，尺寸更紧凑 */
.rename-btn {
  flex: none; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--text-mute); border-radius: 6px;
  cursor: pointer; font-size: 11px; line-height: 1; opacity: .55; transition: opacity .15s;
}
.grid-stack-item:hover .rename-btn { opacity: 1; }
.rename-btn:hover { background: var(--bg-elev2); color: var(--accent); }
.rename-input {
  height: 24px; min-width: 0; width: 170px; padding: 0 8px;
  font-size: 12.5px; font-weight: 600; border-radius: 6px;
}
.widget-head .spacer { flex: 1; }
.widget-head .meta { font-size: 11px; color: var(--text-mute); }
.widget-actions { display: flex; gap: 2px; opacity: .55; transition: opacity .15s; }
.grid-stack-item:hover .widget-actions { opacity: 1; }
.widget-actions button {
  width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--text-dim); border-radius: 6px; cursor: pointer;
  font-size: 13px; line-height: 1;
}
.widget-actions button:hover { background: var(--bg-elev2); color: var(--accent); }
.widget-actions button.del:hover { color: var(--up); }
.widget-body { flex: 1; min-height: 0; position: relative; overflow: auto; padding: 8px 10px 10px; }
.widget-body.pad0 { padding: 0; }
/* 内联设置条：设置项少的板块把常用参数直接平铺在标题栏下方（无需打开设置抽屉） */
.widget-settings {
  display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: center;
  padding: 5px 10px; border-bottom: 1px solid var(--border-soft);
  background: rgba(127, 127, 127, .04); font-size: 11.5px; flex: none;
}
.widget-settings .section-title {
  display: inline; margin: 0; font-size: 11px; color: var(--text-mute); white-space: nowrap;
}
.widget-settings select, .widget-settings input {
  height: 24px; padding: 0 6px; font-size: 11.5px; border-radius: 6px; width: auto; max-width: 150px;
}
.widget-settings .ws-explain { display: none !important; } /* 纯说明文字内联模式隐藏，抽屉里仍可见 */
/* 已内联展示设置的板块：隐藏板块工具栏里的「设置」按钮，避免重复入口 */
.widget.inline-settings [data-role="set"] { display: none !important; }
.widget-foot {
  padding: 6px 12px; border-top: 1px solid var(--border-soft);
  font-size: 11px; color: var(--text-mute); display: flex; gap: 10px; align-items: center;
}
/* 放大：板块浮到最上层 + 底部遮罩层，避免与背后内容重叠难以辨认。
   注意 .grid-stack-item-content 带 z-index:0 会形成层叠上下文，
   只给 .widget 设 z-index 无效，必须同时抬高所在的 grid-stack-item。 */
.grid-stack-item.maximized { z-index: 60 !important; }
.widget.maximized {
  position: fixed !important; inset: 56px 16px 16px; z-index: 60; width: auto !important; height: auto !important;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.widget-max-backdrop {
  position: fixed; inset: 0; z-index: 55; display: none;
  background: rgba(6, 9, 14, .62);
}
/* 拖拽缩放手柄：右下角（se）、左下角（sw）拐角的抓手图标默认隐藏，
   只有鼠标移到该拐角上才淡入显示——避免常驻图标干扰阅读，同时保留可缩放的热区。
   （opacity:0 仍接收 hover/pointer，故悬停即现、可直接拖拽缩放） */
.grid-stack-item > .ui-resizable-se,
.grid-stack-item > .ui-resizable-sw { width: 20px; height: 20px; opacity: 0; transition: opacity .12s ease; }
.grid-stack-item > .ui-resizable-se:hover,
.grid-stack-item > .ui-resizable-sw:hover { opacity: .9; }
.widget-body .state {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--text-mute); font-size: 12.5px;
}
.skeleton { padding: 10px 0; }
.skeleton .bar { height: 12px; border-radius: 6px; background: var(--bg-elev2); margin-bottom: 10px; animation: pulse 1.2s infinite; }
@keyframes pulse { 0%,100% { opacity: .5; } 50% { opacity: 1; } }

.toolbar { display: flex; gap: 6px; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--border-soft); flex-wrap: wrap; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button { border: none; background: transparent; color: var(--text-dim); padding: 4px 10px; cursor: pointer; font-size: 12px; }
.seg button.on { background: var(--accent-soft); color: var(--accent); }

/* ---------------------------------------------------------------- 表格 */
table.data { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.data th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-elev); color: var(--text-dim); font-weight: 500; text-align: right;
  padding: 7px 8px; border-bottom: 1px solid var(--border); cursor: pointer; white-space: nowrap;
  user-select: none;
}
/* 点击表头排序的升降指示（util.js 全站委托排序） */
table.data th[data-sort] { color: var(--accent); }
table.data th[data-sort="asc"]::after { content: " ▴"; }
table.data th[data-sort="desc"]::after { content: " ▾"; }
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data td { padding: 6px 8px; border-bottom: 1px solid var(--border-soft); text-align: right; white-space: nowrap; }
table.data tbody tr:hover { background: var(--bg-elev2); }
table.data td.name { color: var(--text); }
/* 键值表（账户信息）：左侧为字段名 */
table.data.kv th {
  position: static; text-align: left; cursor: default; color: var(--text-mute);
  font-weight: 500; white-space: nowrap;
}
table.data.kv td { text-align: left; white-space: normal; }

.badge { display: inline-block; padding: 1px 6px; border-radius: 6px; font-size: 11px; border: 1px solid var(--border); color: var(--text-dim); }
.badge.open { color: var(--up); border-color: rgba(246, 70, 93, .35); background: rgba(246, 70, 93, .10); }
.badge.closed { color: var(--text-mute); }
.badge.pre, .badge.post, .badge.lunch { color: var(--accent); border-color: var(--accent-soft); }
.badge.mock { color: var(--text-mute); }
.badge.tushare { color: var(--down); border-color: rgba(46, 189, 133, .35); }
.badge.tencent, .badge.eastmoney, .badge.sina, .badge.mixed, .badge.gate, .badge.coinex, .badge.chinabond, .badge.worldbank, .badge.datayes, .badge.amap, .badge.openmeteo, .badge.wttr { color: var(--down); border-color: rgba(46, 189, 133, .35); background: rgba(46, 189, 133, .10); }
.badge.unavailable { color: var(--warn, #d89614); border-color: rgba(216, 150, 20, .35); }

/* ---------- 核心指数百分位：分位条 + PE 温度徽标 ---------- */
.val-pct { display: flex; justify-content: flex-end; }
.val-bar { position: relative; width: 120px; height: 20px; border-radius: 5px; overflow: hidden;
  border: 1px solid var(--border); background: var(--bg-elev2); }
.val-bar i { position: absolute; inset: 0 auto 0 0; display: block; opacity: .28; }
.val-bar b { position: relative; z-index: 1; display: block; line-height: 18px; padding-left: 6px;
  font-size: 11px; font-weight: 500; text-align: left; }
.val-bar.low i, .val-bar.low b { color: var(--down); background: var(--down); }
.val-bar.low b { background: none; }
.val-bar.mid i, .val-bar.mid b { color: var(--accent); background: var(--accent); }
.val-bar.mid b { background: none; }
.val-bar.high i, .val-bar.high b { color: var(--up); background: var(--up); }
.val-bar.high b { background: none; }
.val-temp { display: inline-block; padding: 1px 10px; border-radius: 10px; font-size: 11.5px;
  border: 1px solid var(--border); color: var(--text-dim); }
.val-temp.cool { color: var(--down); border-color: rgba(46, 189, 133, .35); background: rgba(46, 189, 133, .10); }
.val-temp.ok { color: var(--text-dim); }
.val-temp.warm { color: var(--warn, #d89614); border-color: rgba(216, 150, 20, .35); background: rgba(216, 150, 20, .10); }
.val-temp.hot { color: var(--up); border-color: rgba(246, 70, 93, .35); background: rgba(246, 70, 93, .10); }
.val-temp.na { color: var(--text-mute); }

.chart { width: 100%; height: 100%; min-height: 160px; }

/* ---------------------------------------------------------------- 抽屉 / 弹窗 */
/* 图层锁（R7）：任何抽屉/弹窗打开期间，底层页面整体禁止交互 ——
   被遮罩挡住的按钮彻底不可点（util.js 用 MutationObserver 同步此状态） */
body.overlay-open #app { pointer-events: none; user-select: none; }
.drawer-mask { position: fixed; inset: 0; background: rgba(0, 0, 0, .45); z-index: 70; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 380px; z-index: 71;
  background: var(--bg-elev); border-left: 1px solid var(--border); box-shadow: var(--shadow);
  display: flex; flex-direction: column;
}
.drawer header { display: flex; align-items: center; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.drawer header .spacer { flex: 1; }
.drawer .content { flex: 1; overflow: auto; padding: 16px; }
.drawer.wide { width: 640px; }
.section-title { font-size: 12px; color: var(--text-mute); margin: 14px 0 8px; }
.opt-list { display: flex; flex-direction: column; gap: 6px; max-height: 320px; overflow: auto; padding-right: 4px; }
.opt {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--border-soft); background: var(--bg-elev2); cursor: pointer;
}
.opt:hover { border-color: var(--accent); }
.opt.on { border-color: var(--accent); background: var(--accent-soft); }
.opt .nm { flex: 1; }
.opt .code { color: var(--text-mute); font-size: 11.5px; }
.switch-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; }
.switch { width: 38px; height: 20px; border-radius: 12px; background: var(--border); position: relative; cursor: pointer; transition: background .15s; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .15s; }
.switch.on { background: var(--accent); }
.switch.on::after { left: 20px; }

/* 偏好抽屉的主题选择器：四块色卡代替原「深色主题」开关（护眼双主题上线后） */
.theme-chips { display: flex; gap: 6px; }
.theme-chip {
  width: 34px; height: 22px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border); position: relative;
}
.theme-chip i { position: absolute; left: 4px; bottom: 3px; width: 10px; height: 4px; border-radius: 2px; }
.theme-chip.on { box-shadow: 0 0 0 2px var(--accent); }

.modal-mask { position: fixed; inset: 0; background: rgba(0, 0, 0, .5); z-index: 80; display: flex; align-items: center; justify-content: center; }
.modal { position: relative; z-index: 81; width: 520px; max-width: 92vw; max-height: 82vh; overflow: auto; background: var(--bg-elev); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); }
.modal.wide { width: 680px; }
.modal header { position: relative; padding: 16px 46px 16px 16px; border-bottom: 1px solid var(--border); font-weight: 600; }
.modal-x {
  position: absolute; right: 10px; top: 9px; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--text-dim);
  border-radius: 7px; cursor: pointer; font-size: 13px; line-height: 1;
}
.modal-x:hover { background: var(--bg-elev2); color: var(--up); }
.modal .content { padding: 16px; }
.modal footer { padding: 12px 16px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }
/* 添加板块菜单：分类组按两列瀑布排布，避免板块多时菜单过长 */
.modal:has(.tpl-panel) { width: 880px; }
.tpl-panel { columns: 2; column-gap: 16px; }
.tpl-panel .tpl-group { break-inside: avoid; }
/* 单分类平铺模式（如「+分析」菜单）：条目直接是 .tpl-panel 的子元素，
   标题通栏跨两列，条目才能被 columns 拆成两列瀑布 */
.tpl-panel > .tpl { break-inside: avoid; }
.tpl-panel > .group-head { column-span: all; }
.tpl-group { margin-bottom: 18px; }
.tpl-group .group-head {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px;
  font-weight: 600; font-size: 13px;
}
.tpl-group .group-head .muted { font-weight: 400; font-size: 11.5px; }

.tpl {
  display: flex; gap: 10px; align-items: flex-start; padding: 12px; border-radius: 10px;
  border: 1px solid var(--border-soft); background: var(--bg-elev2); cursor: pointer; margin-bottom: 10px;
}
.tpl:hover { border-color: var(--accent); }
.tpl .t { font-weight: 600; margin-bottom: 3px; }
.tpl .d { color: var(--text-mute); font-size: 12px; }
.tpl .cat { align-self: center; color: var(--accent); font-size: 11px; border: 1px solid var(--accent-soft); border-radius: 6px; padding: 2px 6px; }
/* 「已添加」标注：仅提示，仍可点击重复添加（同一板块开两个实例是常见需求） */
.tpl.has { border-color: var(--accent-soft); }
.tpl .tag-added {
  margin-left: 6px; padding: 1px 6px; border-radius: 999px; font-size: 10.5px; font-weight: 400;
  background: rgba(76, 141, 255, .16); color: var(--accent); vertical-align: 1px;
}
/* 管理员视角里被下架的板块：灰显但仍可添加（便于自查） */
.tpl.off { opacity: .6; }
.tpl .tag-off {
  margin-left: 6px; padding: 1px 6px; border-radius: 999px; font-size: 10.5px; font-weight: 400;
  background: rgba(229, 72, 77, .16); color: var(--down, #2ebd85);
}

.toast {
  position: fixed; left: 50%; bottom: 32px; transform: translateX(-50%);
  padding: 9px 16px; border-radius: 10px; background: var(--bg-elev2);
  border: 1px solid var(--border); box-shadow: var(--shadow); z-index: 90; font-size: 12.5px;
}
.toast.ok { border-color: rgba(46, 189, 133, .5); }
.toast.err { border-color: var(--up); color: var(--up); }

.empty-tip { padding: 40px 20px; text-align: center; color: var(--text-mute); }

/* ---------------------------------------------------------------- 左侧栏布局（仅看板 tabs 下沉侧栏，功能按钮留顶栏） */
/* flex 嵌套而非 CSS Grid：sidebar 的固定高度绝不参与内容列任何行高计算 */
.body-row { display: flex; align-items: flex-start; }
.sidebar {
  flex: none; width: 172px;
  display: flex; flex-direction: column;
  padding: 10px 8px; gap: 4px;
  background: var(--bg-elev); border-right: 1px solid var(--border);
  position: sticky; top: 50px; height: calc(100vh - 50px); overflow-y: auto;
  z-index: 30;
}
.main-col { flex: 1; min-width: 0; }
.sidebar-label {
  font-size: 11px; color: var(--text-mute); text-transform: uppercase;
  letter-spacing: .06em; padding: 4px 8px;
}
.sidebar .tabs {
  flex-direction: column; gap: 2px; overflow: visible;
}
.sidebar .tab {
  justify-content: flex-start; width: 100%; padding: 6px 10px;
  font-size: 12px;
}
.sidebar .tab-name { max-width: 136px; }
.sidebar .tab-del { opacity: .4; }
.sidebar .tab:hover .tab-del { opacity: 1; }

@media (max-width: 900px) {
  .drawer { width: 100%; }
  .topbar { height: auto; flex-wrap: wrap; padding: 8px 12px; }
}

/* ---------- 新用户引导（tour.js） ----------
   聚光框靠超大 box-shadow 压暗全屏其余区域；pointer-events:none 让用户
   能直接点中正在讲解的按钮当场试用。层级盖过抽屉(71)/弹窗(81)/toast(90)。 */
.tour-spot {
  position: fixed; z-index: 120; pointer-events: none;
  border: 1.5px solid var(--accent); border-radius: 10px;
  box-shadow: 0 0 0 9999px rgba(8, 11, 16, .62);
  transition: left .18s ease, top .18s ease, width .18s ease, height .18s ease;
}
.tour-bubble {
  position: fixed; z-index: 121; width: 320px; max-width: 92vw;
  background: var(--bg-elev2); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow); padding: 12px 14px;
}
.tour-head { display: flex; align-items: center; justify-content: space-between; }
.tour-step { font-size: 11.5px; color: var(--text-mute); }
.tour-x {
  background: none; border: none; color: var(--text-mute); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 0 2px;
}
.tour-x:hover { color: var(--text); }
.tour-title { font-size: 14px; font-weight: 600; color: var(--text); margin: 4px 0 6px; }
.tour-body { font-size: 12.5px; line-height: 1.7; color: var(--text-dim); }
.tour-foot { display: flex; align-items: center; margin-top: 12px; }
.tour-foot .btn + .btn { margin-left: 8px; }
.tour-skip {
  margin-right: auto; background: none; border: none; cursor: pointer;
  font-size: 12px; color: var(--text-mute); padding: 4px 2px;
}
.tour-skip:hover { color: var(--text); }

/* 分析板块「说明」按钮：文字两字所以宽度自适应，字号压到 11px 与图标按钮等高 */
.widget-actions button.doc-btn { width: auto; padding: 0 6px; font-size: 11.5px; }

/* ---------- 小下拉 → 分段按钮（util.segmentize） ---------- */
.seg {
  display: inline-flex; vertical-align: middle; overflow: hidden;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg-elev2);
}
.seg .seg-btn {
  border: none; background: transparent; color: var(--text-dim); cursor: pointer;
  font-size: 12px; padding: 5px 12px; line-height: 1.3; white-space: nowrap;
}
.seg .seg-btn + .seg-btn { border-left: 1px solid var(--border); }
.seg .seg-btn:hover { color: var(--text); }
.seg .seg-btn.on { background: var(--accent); color: #fff; }
.seg.dis { opacity: .5; pointer-events: none; }

/* ---------- 指南站内弹窗（app.openGuideModal）宽窄两档 ---------- */
.modal.guide-modal { width: min(900px, 94vw); max-width: none; max-height: 88vh; height: 88vh;
  display: flex; flex-direction: column; padding: 0; overflow: hidden;
  transition: width .18s ease; }
.guide-modal.guide-wide { width: min(1280px, 96vw); }  /* 宽屏：方法论页表格/手机横屏更舒展 */
.guide-modal header .guide-w {
  position: absolute; right: 44px; top: 8px; height: 26px; padding: 0 10px;
  font-size: 11.5px; font-weight: 400;
}
.guide-modal > header { flex: 0 0 auto; }
.guide-modal > .content { flex: 1; min-height: 0; padding: 0; }
.guide-modal iframe { width: 100%; height: 100%; border: 0; background: var(--bg); }
/* 指南页被嵌时（guide.js 打 in-frame 标记）收紧外边距，弹窗里不需要固定关闭件 */
html.in-frame .guide-wrap { padding-top: 12px; }

/* 指南主题跟随（guide-theme.js）：取偏好回来前不闪默认深色，超时/失败自动放行 */
html.theme-pending body { visibility: hidden; }
