Files
GarminHealthLab/client/src/theme.css
ericwyuan 9e5e77755e [阶段7.2] 隐藏 AI 模块;剩余页面迁移到设计令牌
AI 模块暂时下线(待重新设计),加 FEATURES 开关集中控制:
- 导航不显示"建议",路由也不注册 —— 只隐藏入口而保留可访问的
  URL 等于没隐藏
- 设置页的模型清单区块一并隐藏,且不再请求 /analysis/models
- 页面与后端端点都保留,重新打开是一行改动

登录/同步/建议/设置四个页面此前仍在用旧样式(共 101 处硬编码颜色),
深色模式下全部失效。已改写为设计令牌。

fix(a11y): 主按钮白字对比度不足
- 白字在 --accent 上实测 4.42:1(浅)/ 3.64:1(深),均低于正文
  所需的 4.5:1
- 新增 --accent-solid 专用于填充面(按钮、选中标签),取同一蓝色阶
  更深的一步:5.39:1 / 6.63:1;--accent 继续用于文字、边框和标记

fix(viz): 一年档柱形图不可读
- 365 根柱子在 607px 宽度下每根仅 1.66px,既看不清也远低于
  ~24px 的悬停命中下限
- 超过 90 个点时柱形自动改为面积图,并在副标题里说明原因。
  折线/面积的十字准星吸附最近点,本就不依赖逐标记命中区

其他:
- 统计数值精度按量级取(11,013.99 既是虚假精度,又长到把单位挤到
  第二行)
- 设置页隐私说明更正:改用 OAuth 令牌后同步已不需要每次输密码

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-23 22:05:28 +08:00

110 lines
3.1 KiB
CSS

/*
* Design tokens.
*
* The series colours are the validated categorical palette, in its documented
* slot order — the ordering is the colour-blind-safety mechanism, not a
* cosmetic choice, so slots are assigned in order and never cycled.
* Verified with the palette validator in both modes:
* light worst adjacent CVD ΔE 9.1, normal-vision ΔE 22.9
* dark worst adjacent CVD ΔE 8.4, normal-vision ΔE 19.8
* On the light surface aqua (2.74:1) and yellow (2.11:1) fall below 3:1, so
* every chart using them ships visible labels plus a table view.
*/
:root {
color-scheme: light;
/* surfaces & ink */
--surface-0: #f4f4f2;
--surface-1: #fcfcfb;
--surface-2: #ffffff;
--border: #e4e3df;
--border-strong: #d3d2cd;
--text-primary: #0b0b0b;
--text-secondary: #52514e;
--text-muted: #86847e;
/* categorical series — assign in order */
--series-1: #2a78d6; /* blue */
--series-2: #eb6834; /* orange */
--series-3: #1baf7a; /* aqua */
--series-4: #eda100; /* yellow */
--series-5: #e87ba4; /* magenta */
--series-6: #008300; /* green */
/* status — reserved, never reused as a series */
--status-good: #0ca30c;
--status-warning: #fab219;
--status-serious: #ec835a;
--status-critical: #d03b3b;
--grid: #eceae5;
/* Separate token for filled surfaces (buttons, active tabs). White text on
--accent measures only 4.42:1 light / 3.64:1 dark — under the 4.5:1 body
floor — so fills use a darker step from the same blue ramp: 5.39:1 light,
6.63:1 dark. --accent stays for text, borders and marks. */
--accent: #2a78d6;
--accent-solid: #256abf;
--accent-soft: #eef4fd;
--radius: 10px;
--shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 8px rgba(0, 0, 0, 0.03);
}
/* Dark steps are the same hues re-stepped for the dark surface — selected and
validated as a set, not an automatic inversion. Declared under both the OS
media query and the explicit toggle so either can win. */
@media (prefers-color-scheme: dark) {
:root:where(:not([data-theme='light'])) {
color-scheme: dark;
--surface-0: #131312;
--surface-1: #1a1a19;
--surface-2: #232322;
--border: #34342f;
--border-strong: #45443e;
--text-primary: #ffffff;
--text-secondary: #c3c2b7;
--text-muted: #8f8e85;
--series-1: #3987e5;
--series-2: #d95926;
--series-3: #199e70;
--series-4: #c98500;
--series-5: #d55181;
--series-6: #008300;
--grid: #2c2c28;
--accent: #3987e5;
--accent-solid: #1c5cab;
--accent-soft: #1d2938;
--shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
}
:root[data-theme='dark'] {
color-scheme: dark;
--surface-0: #131312;
--surface-1: #1a1a19;
--surface-2: #232322;
--border: #34342f;
--border-strong: #45443e;
--text-primary: #ffffff;
--text-secondary: #c3c2b7;
--text-muted: #8f8e85;
--series-1: #3987e5;
--series-2: #d95926;
--series-3: #199e70;
--series-4: #c98500;
--series-5: #d55181;
--series-6: #008300;
--grid: #2c2c28;
--accent: #3987e5;
--accent-solid: #1c5cab;
--accent-soft: #1d2938;
--shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}