/**
 * tokens.css — 设计 token（全站唯一允许出现色值/字号原始量的文件）
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * 规矩
 * ═══════════════════════════════════════════════════════════════════════════
 * shell.css 与各页面样式**只能引用 var(--…)**，不得写死颜色、字号、间距。
 * tools/verify/frontend-shell.js 会静态扫描：除本文件外出现 #rgb / rgb() / hsl()
 * 一律判失败。这样换配色、加浅色主题、改涨跌习惯都只动这一处。
 *
 * ═══════════════════════════════════════════════════════════════════════════
 * 分层
 * ═══════════════════════════════════════════════════════════════════════════
 *   ① 基础色阶   --c-*      只是颜色本身，不带含义
 *   ② 界面语义   --ui-*     背景/描边/文字层级
 *   ③ 品牌       --brand-*  强调色，**不参与涨跌与状态表达**
 *   ④ 语义状态   --sem-*    警告/危险/提示/成功，与品牌色分离
 *   ⑤ 涨跌       --mkt-rise / --mkt-fall，跟随用户习惯可换（红涨绿跌 / 绿涨红跌）
 *   ⑥ §23 状态   --state-*  八种状态 + 参数未配置的边框/底色/底纹
 *   ⑦ 评分五档   --band-*   单色系强度阶梯，**刻意不用红绿、不配箭头**
 *   ⑧ 排版/间距/圆角/层级/触控尺寸
 *
 * 为什么评分五档不用绿色 + 上箭头：
 * §11.4 明确「机会分高不等于买入建议」。绿色配向上箭头在行情产品里就是「买入」的
 * 视觉惯例，用户不会去读旁边那行免责声明。所以五档走一条中性的紫—青强度阶梯，
 * 只表达「强弱」，不表达「方向」，更不表达「该不该下单」。
 */

:root {
  /* ── ① 基础色阶（GitHub Dark 系，延续 workbench.css 的观感）────────────── */
  --c-gray-950: #0d1117;
  --c-gray-900: #161b22;
  --c-gray-800: #21262d;
  --c-gray-700: #30363d;
  --c-gray-500: #6e7681;
  --c-gray-400: #8b949e;
  --c-gray-100: #f0f6fc;

  --c-green: #3fb950;
  --c-red: #f85149;
  --c-amber: #d29922;
  --c-blue: #58a6ff;
  --c-purple: #bc8cff;
  --c-teal: #39c5cf;
  --c-orange: #f78166;

  /* 半透明底色统一在这里配，避免各处自己调 alpha 调出十几种黄 */
  --c-amber-a08: rgba(210, 153, 34, 0.08);
  --c-amber-a12: rgba(210, 153, 34, 0.12);
  --c-amber-a20: rgba(210, 153, 34, 0.20);
  --c-red-a08: rgba(248, 81, 73, 0.08);
  --c-red-a16: rgba(248, 81, 73, 0.16);
  --c-red-a20: rgba(248, 81, 73, 0.20);
  --c-blue-a10: rgba(88, 166, 255, 0.10);
  --c-purple-a10: rgba(188, 140, 255, 0.10);
  --c-orange-a10: rgba(247, 129, 102, 0.10);
  --c-green-a10: rgba(63, 185, 80, 0.10);
  --c-teal-a10: rgba(57, 197, 207, 0.10);
  --c-shadow: rgba(1, 4, 9, 0.55);

  /* ── ② 界面语义 ──────────────────────────────────────────────────────── */
  --ui-bg: var(--c-gray-950);
  --ui-surface: var(--c-gray-900);
  --ui-surface-2: var(--c-gray-800);
  --ui-line: var(--c-gray-700);
  --ui-line-soft: var(--c-gray-800);
  --ui-text: var(--c-gray-100);
  --ui-text-2: var(--c-gray-400);
  --ui-text-3: var(--c-gray-500);
  --ui-overlay: var(--c-shadow);

  /* ── ③ 品牌（只用于强调与选中态，绝不表达涨跌或风险）──────────────── */
  --brand: var(--c-orange);
  --brand-soft: var(--c-orange-a10);

  /* ── ④ 语义状态色 ────────────────────────────────────────────────────── */
  --sem-info: var(--c-blue);
  --sem-warn: var(--c-amber);
  --sem-danger: var(--c-red);
  --sem-ok: var(--c-green);
  --sem-locked: var(--c-purple);
  --sem-neutral: var(--c-gray-400);

  /* ── ⑤ 涨跌方向：缺省红涨绿跌，与 K 线工作台的 red_up 缺省一致 ──────── */
  --mkt-rise: var(--c-red);
  --mkt-fall: var(--c-green);
  --mkt-flat: var(--ui-text-3);

  /* ── ⑥ §23 八种状态 + 参数未配置 ──────────────────────────────────────
     四种最容易被混为一谈的状态在**边框形态**上也拉开，不只靠颜色：
       数据不足   实线黄框 + 浅黄底
       参数未配置 点线黄框 + 更浅底
       服务异常   实线红框 + 斜纹底
       空数据     虚线灰框 + 透明底
     色觉障碍用户靠边框形态与底纹同样能分辨。 */
  --state-empty-line: var(--ui-line);
  --state-empty-bg: transparent;
  --state-empty-fg: var(--ui-text-2);

  --state-insufficient-line: var(--sem-warn);
  --state-insufficient-bg: var(--c-amber-a12);
  --state-insufficient-fg: var(--sem-warn);

  --state-unconfigured-line: var(--sem-warn);
  --state-unconfigured-bg: var(--c-amber-a08);
  --state-unconfigured-fg: var(--sem-warn);

  --state-fault-line: var(--sem-danger);
  --state-fault-bg: var(--c-red-a08);
  --state-fault-fg: var(--sem-danger);
  --state-fault-stripe: var(--c-red-a16);

  --state-locked-line: var(--sem-locked);
  --state-locked-bg: var(--c-purple-a10);
  --state-locked-fg: var(--sem-locked);

  --state-gated-line: var(--brand);
  --state-gated-bg: var(--brand-soft);
  --state-gated-fg: var(--brand);

  --state-stale-line: var(--sem-info);
  --state-stale-bg: var(--c-blue-a10);
  --state-stale-fg: var(--sem-info);

  --state-loading-line: var(--ui-line);
  --state-loading-bg: var(--ui-surface);
  --state-loading-fg: var(--ui-text-2);

  /* ── ⑦ 评分五档（§11.4：只表达强弱，不表达方向与操作）──────────────
     0-44 弱 / 45-54 观察 / 55-74 机会 / 75-79 强机会 / 80-100 极强机会 */
  --band-weak: var(--c-gray-500);
  --band-watch: var(--c-gray-400);
  --band-opportunity: var(--c-blue);
  --band-strong-opportunity: var(--c-teal);
  --band-very-strong-opportunity: var(--c-purple);
  --band-weak-bg: transparent;
  --band-watch-bg: transparent;
  --band-opportunity-bg: var(--c-blue-a10);
  --band-strong-opportunity-bg: var(--c-teal-a10);
  --band-very-strong-opportunity-bg: var(--c-purple-a10);

  /* ── ⑧ 排版 ───────────────────────────────────────────────────────────
     字号一律 clamp()：小屏不至于挤成一团，宽屏不至于稀疏。 */
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans TC', 'Noto Sans KR', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --fs-xs: clamp(0.6875rem, 0.66rem + 0.12vw, 0.75rem);
  --fs-sm: clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --fs-md: clamp(0.8125rem, 0.78rem + 0.18vw, 0.875rem);
  --fs-lg: clamp(0.9375rem, 0.90rem + 0.22vw, 1.0625rem);
  --fs-xl: clamp(1.0625rem, 1.00rem + 0.35vw, 1.25rem);
  /* 关键数字（价格、涨跌幅、评分）比正文重一档，盯盘时先看到它们 */
  --fs-metric: clamp(1.375rem, 1.15rem + 1.05vw, 2rem);

  --fw-normal: 400;
  --fw-medium: 500;
  --fw-bold: 600;

  --lh-tight: 1.25;
  --lh-base: 1.5;

  /* ── 间距 / 圆角 / 阴影 ───────────────────────────────────────────────── */
  --sp-1: 0.25rem;
  --sp-2: 0.375rem;
  --sp-3: 0.5rem;
  --sp-4: 0.625rem;
  --sp-5: 0.875rem;
  --sp-6: 1rem;
  --sp-7: 1.25rem;
  --sp-8: 1.75rem;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-pill: 999px;
  --border-hair: 1px;
  --shadow-card: 0 1px 2px var(--c-shadow);

  /* ── 布局与触控 ───────────────────────────────────────────────────────
     断点（媒体查询不能用变量，这里是唯一书面口径，改了要同步 shell.css）：
       >= 1280px  桌面宽屏：侧栏常驻 + 多栏内容 + 大图表
       >  1200px  桌面：侧栏常驻 + 主内容
       901–1200   平板：侧栏收窄，卡片列数收敛
       <=  900px  手机：抽屉导航 + 单栏 + 宽表格降级为卡片

     为什么手机档取 900 而不是常见的 768：
     统一优先于「标准值」。批次 8 的信号/预警/资金/消息各页
     （pages/signal/tokens.css、pages/alert/alert.css、pages/signal/runtime.js
     的 BREAKPOINTS）都已按 900 / 1200 落地并写进了各自的验收。
     外壳若单独改用 768，就会出现「导航已经折成抽屉、内容还按桌面两列排」
     的错位——这正是响应式最难查的一类 bug。故全站统一到 900 / 1200。 */
  --bp-wide: 1280px;
  --bp-desktop: 1200px;
  --bp-tablet: 900px;

  --nav-w: clamp(9.5rem, 14vw, 13rem);
  --content-max: 120rem;
  /* 点击目标下限：WCAG 2.5.8 给的是 24px，移动端实操公认 44px */
  --tap-min: 44px;
  --tap-compact: 2rem;
  --chart-min-h: clamp(18rem, 46vh, 34rem);

  --z-nav: 30;
  --z-drawer: 40;
  --z-scrim: 35;
}

/* 绿涨红跌（欧美习惯）：只换这两个 token，全站跟着变 */
:root[data-updown='green_up'] {
  --mkt-rise: var(--c-green);
  --mkt-fall: var(--c-red);
}

/* 数字必须等宽：价格与百分比逐秒跳动时不能左右抖动 */
.ms-num,
.ms-metric-value,
.ms-table td.ms-r,
.ms-table th.ms-r {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.ms-rise { color: var(--mkt-rise); }
.ms-fall { color: var(--mkt-fall); }
.ms-flat { color: var(--mkt-flat); }

/* 评分五档的统一视觉映射：色块 + 档位名，没有箭头、没有红绿 */
.ms-band {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 0 var(--sp-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  border: var(--border-hair) solid currentColor;
}
.ms-band[data-band='weak'] { color: var(--band-weak); background: var(--band-weak-bg); }
.ms-band[data-band='watch'] { color: var(--band-watch); background: var(--band-watch-bg); }
.ms-band[data-band='opportunity'] { color: var(--band-opportunity); background: var(--band-opportunity-bg); }
.ms-band[data-band='strong_opportunity'] { color: var(--band-strong-opportunity); background: var(--band-strong-opportunity-bg); }
.ms-band[data-band='very_strong_opportunity'] { color: var(--band-very-strong-opportunity); background: var(--band-very-strong-opportunity-bg); }
