跳转至

OneTHU UI/UX 体验改造方案(下一个大版本)v2

状态:草案 v2.1(对接需求用;已融合外部咨询《建议.md》并根据项目实际情况修订;§1 现状描述已逐项对照代码核实,2026-09-25) 分支:next/ui-ux-overhaul 目标读者:参与本大版本的全部开发 / 设计 / 文案同学 服务对象:清华学生(本科生与研究生需求基本一致,不做身份区分与分层;研究生收入等少数专属模块作为普通补充功能对待)


0. 背景与问题定义

0.1 用户画像(唯一画像,不再拆分)

  • 清华学生(本科生与研究生,需求基本一致,统一对待),Android 移动端为主,无计算机背景;
  • 现状反馈:功能极其丰富,但"太极客、无从下手、眼花缭乱";视觉"太朴素、太专业"。

0.2 不可动摇的约束(本方案红线)

约束 说明
原子收藏机制不改 收藏(state/favorites.ts / favs.tsx / Collect.tsx / FavAtomPicker.tsx / 小组件绑定)是产品立身之本,交互与数据结构原样保留。本方案只在收藏之外新增系统推荐,二者并存(见 §2.5)
不做身份分层 全部按"清华学生"统一设计:首启不问学历、界面不区分身份;研究生收入等少数专属模块按普通补充功能归组,不做特殊处理
不做功能减法 借用外部建议的话:"能力做加法,界面做减法"。所有功能保留入口,只重排可见性
零 UI 组件库 不引入 MUI / Fluent / antd。手写令牌 + 手写组件的架构保持
不动数据层 @onethu/core / @onethu/info-lib 业务逻辑不变;本方案只动 UI/UX/文案层

0.3 三个核心问题与改造主线

# 问题 主线 章节
P1 按系统/模块组织入口,不按学生任务组织;首屏眼花缭乱 任务导向的信息架构 §2
P2 视觉朴素专业、密度过高 MD3 视觉改造 + 动态色调 + 降密度 §3
P3 业务入口藏在设置里;首启过载;文案技术化 入口场景化 + 渐进首启 + 文案口语化 §4

0.4 成功标准(验收指标,融合外部建议 §7)

  1. 新用户 5 分钟可用:新装 → 登录统一认证 → 看到带真实课表的「今日」页,全程不接触外部账号配置;
  2. 任务测试(5–10 名非计算机背景学生):查明日作业、交雨课堂作业、查校园卡余额、交电费、看洗衣机状态、亲友报备入校——每项点击 ≤ 3 次、10 秒级完成,记录完成率/求助率/走错入口次数;
  3. 首屏克制:默认「今日」页卡片 ≤ 6 张,底部导航 5 项;
  4. 文案 lint 全绿(新词表,§4.5);
  5. 性能不回退:Android 冷启动 / 首帧不劣于现版 ±10%;
  6. 收藏功能回归通过:收藏、桌面小组件绑定在改版后行为与现版完全一致(专门回归项)。

1. 现状盘点(代码地图 + 完整功能清单)

1.1 改动涉及的代码

区域 路径 角色
设计令牌 packages/ui/src/tokens.css、base.css 重写为 MD3 令牌层(§3.1)
全局样式 apps/desktop/src/styles/global.css(≈5000 行)、motion.css(≈850 行) 分期迁移(§3.5、§3.6)
主题 state/theme.ts 扩展动态色调(§3.4)
外壳 components/Layout.tsx(现状:PC 侧栏 + 移动端抽屉,尚无底部栏)、TabManageModal.tsx(聚合页栏目管理:勾选显隐+排序,LifePage/ReservePage/收藏夹等共用) IA 重排主战场(§2.2)
页面 pages/*、聚合页:info/InfoPage.tsx(8 tab:成绩/体测/考试/评估/校历/新闻/个人信息/课程信息)、info/LifePage.tsx(8 tab:宿舍/洗衣机/卫生成绩/校园卡/发票/银行代发/研究生收入/校园网)、info/ReservePage.tsx(6 tab:图书馆座位/研讨间/空教室/体育/公共空间/更多场馆)、pages/zhjwxk/Courses.tsx(选课工作台)、pages/learn/* 按 §1.2 清单重排入口
首页卡片 pages/Today.tsx + lib/homeCards.ts(卡片注册表)+ components/HomeWidgets.tsx:今日页已是全量卡片化(可编辑列位/顺序/折叠,localStorage 持久化) 在现有注册表上升级(§2.3)
使用统计 lib/usage.ts(原子使用计数)、lib/suggest.ts(suggestAtoms 推荐)——已存在 常用推荐区直接复用(§2.5)
原子/收藏 state/atoms.tsx、favorites.ts、favs.tsx、Collect.tsx、FavAtomPicker.tsx、收藏夹页 FolderPage.tsx(瀑布流+瓦片块) 保留不动,仅入口换位
首启 components/OnboardingTour.tsx(现状 10 步:含预设选卡、账号接入第 5–8 步、小组件末步)、state/onboarding.ts 重做(§4.2)
外部账号 state/accountSetup.ts、state/exthw.ts、ExtHwLoginModal.tsx 场景化绑定(§4.3)
文案 tools/ui-copy-lint.mjs 扩展口语化规则(§4.5)
AI OneTHU Harness 面板 作为万能兜底入口(§2.7)
Native src-tauri/plugins/onethu-mobile 新增动态取色命令(§3.4)

1.2 完整功能清单与初始可见性分级(M0 评审定稿)

分级定义:core = 底部导航直达 / 「今日」卡片;group = 服务页分组内;buried = 仅「全部功能」目录 + 搜索可达。

学习类 | 功能 | 代码位置 | 分级 | 备注 | |------|----------|------|------| | 网络学堂课程/文件/讨论区 | pages/learn/* | group(学习组) | | | 全部作业(网络学堂+外部源合并) | pages/Learn.tsx、AssignmentsPage.tsx | core | 今日卡直接聚合 DDL | | 雨课堂作业/主观题作答 | exthw/、YktAssignmentDetailPage.tsx | core 内嵌 | 绑定入口场景化(§4.3) | | 外部 OJ 作业(TUOJ/Tyche/DSA) | state/exthw.ts | core 内嵌 | 同上 | | 成绩 / 中英文成绩单 / 学年汇总 | info/ReportTab.tsx(InfoPage「成绩」tab) | group(学习组) | | | 课程信息 / 考试安排 | CourseInfoTab / ExamsTab | group | 考试周可在今日卡加权(P2) | | 选课(NextTHUxk 同源工作台) | pages/zhjwxk/Courses.tsx(单屏两栏:课程列表 + 学分统计/课表预览) | group(选课季提升) | 时间敏感:选课期间临时升 group→今日推荐 | | 教学评估 | EvaluationTab | buried | 评估季同理 |

日程与提醒 | 功能 | 分级 | 备注 | |------|------|------| | 课表 / 日程时间轴(Schedule.tsx、ScheduleAgenda.tsx) | core | 今日页"下一节课"卡 | | 云日历 / 系统日历 / 提醒通知 | group(我的→日历与账号) | |

生活与财务(除校历/新闻外,宿主均为 info/LifePage.tsx 聚合页) | 功能 | 代码位置 | 分级 | |------|----------|------| | 校园卡流水/充值 | info/CardTab.tsx(LifePage「校园卡」tab) | core(今日余额条) | | 宿舍电费/充值 | info/DormTab.tsx(LifePage「宿舍」tab) | core(今日余额条) | | 洗衣机状态 | info/WasherTab.tsx(LifePage「洗衣机」tab) | group(生活组);宿舍楼填写后可上今日卡(P2) | | 校园网 | info/NetworkTab.tsx(LifePage「校园网」tab) | group | | 电子发票 / 银行代发 / 研究生收入 | info/InvoiceTab / PayrollTab / GradIncomeTab(LifePage 对应 tab) | group(行政组;研究生收入在描述中注明适用人群,不做入口屏蔽) | | 校历 | info/CalendarTab.tsx(InfoPage tab) | group | | 新闻 | info/NewsTab.tsx(InfoPage tab) | group(今日取前 3 条) |

预约与场馆(宿主 info/ReservePage.tsx,6 tab) | 功能 | 分级 | |------|------| | 图书馆座位 / 研讨间 / 空教室 / 体育 / 公共空间 / 更多场馆(LibraryTab LibRoomTab ClassroomTab VenueSportsTab KongjianTab SportsTab) | group(预约组) |

行政与账号 | 功能 | 代码位置 | 分级 | |------|----------|------| | 邮箱(MailPage.tsx) | group(行政组) | | 云盘(CloudPage.tsx,seafile) | group | | 在线服务 / THOS 服务大厅(含进行中/待办任务、亲友入校报备) | info/ThosPage.tsx | group(行政组;报备假期前置顶——P2 时间敏感项) | | 其他 Info 应用导航(门户应用目录,点击走系统浏览器) | pages/OtherInfoPage.tsx + lib/infoApps.ts | buried | | 个人信息 / 体测(ProfileTab FitnessTab,InfoPage tab;卫生成绩在 LifePage) | group(我的/行政) | | Thubook(ThubookPage.tsx) | group |

高级能力(标准模式不可见) | 功能 | 分级 | |------|------| | 插件系统 / 插件市场(Plugins.tsx) | 高级模式 | | OneTHU Harness(AI 面板) | 常驻但降调(§2.7) | | Trace(Trace.tsx)、开发者面板(DevPanel.tsx) | 高级模式 | | 桌面小组件配置(widget*.ts 全家) | 保留,入口在"我的",不做首启教学 |


2. 主线一:任务导向的信息架构(P1)

2.1 核心原则(吸收自外部建议,逐条修订)

  • 按学生任务组织,不按接入系统组织:学生想的是"看作业、交电费、查洗衣机",不是"打开雨课堂、进 info";
  • 能力做加法,界面做减法:默认极简,长尾进目录 + 搜索 + AI 兜底;
  • 业务入口放业务场景,设置只做管理:绑定动作发生在用户第一次碰到相关功能时(§4.3);
  • 系统推荐与用户收藏并存(修订外部建议 4.3):收藏机制一字不动;新增"常用推荐"作为并排补充,见 §2.5。

2.2 新 IA:底部 5 Tab

┌─────────┬─────────┬─────────┬─────────┬─────────┐
│  今日    │  待办    │  服务    │  收藏    │  我的    │
│  Today  │  Tasks  │Services │  Favs   │   Me    │
└─────────┴─────────┴─────────┴─────────┴─────────┘

今日:问候语 → 下一节课卡 → 今日作业 DDL 卡 → 余额速览条(校园卡+电费)
      → 最近通知(≤3 条)→ 常用推荐区(§2.5)
待办:全部作业(现有合并视图升级为独立 tab,含外部作业源与忽略逻辑)
服务:分组目录(学习 / 日程 / 生活 / 预约 / 行政)+ 顶部搜索框
收藏:现有收藏页原样迁入(原子收藏立身之本,一级直达反而强化)
我的:个人信息、账号与绑定、通知设置、外观、日历、高级模式开关、帮助、关于

与外部建议的差异说明:外部建议 5 Tab 为 首页/待办/消息/服务/我的,未给收藏留位置——这违背项目约束。本方案把"消息"并入「今日」通知卡与「待办」,腾出一级位置给收藏。

2.3 实施步骤

  1. [ ] 新增 state/navigation.ts:功能注册表(见 §2.6 metadata 结构),声明 §1.2 的全量清单、分级、关键词、绑定依赖。页面 ID 沿用现有值,不改路由实现;
  2. [ ] 改造 Layout.tsx:现状为"PC 侧栏 + 移动端抽屉(<860px),无底部栏"(global.css v2 块接管),本步为移动端新增固定底部导航(§2.8.1 三断点);TabManageModal.tsx 是聚合页栏目管理(LifePage/ReservePage/收藏夹共用),机制原样保留继续服务各聚合页,不承担底部导航职责;
  3. [ ] 「今日」页已是全量卡片化(lib/homeCards.ts 注册表 + HomeWidgets.tsx,支持编辑列位/顺序/折叠):本步不改架构,只调整注册表内容——按 §2.2 定义收缩默认卡片集、新增余额速览条与常用推荐卡、更新默认布局(restoreDefaultTodayCards 现有机制可复用);
  4. [ ] AssignmentsPage 升级为「待办」tab 直达页;
  5. [ ] 新增「服务」分组目录页(复用 InfoPage.tsx 的 tab 骨架)+ 新增「收藏」tab(迁移现有收藏视图);
  6. [ ] 入口映射表核对:§1.2 每项功能在 PR 中逐条勾选"新入口路径",不允许出现找不到入口的功能。

2.4 时间敏感的动态提升(P2,可选做)

选课季、考试周、评估季、假期报备期间,把对应功能从 group 提升到「今日」推荐卡。机制:navigation.ts 中声明 boostWindow(日期区间),Today.tsx 按日期渲染。首版可不做,但注册表字段预留。

2.5 常用推荐区(与收藏并存,不替代)

  • 「今日」页底部新增"常用"横滑区:排序数据直接复用现有 lib/usage.ts(原子使用计数 onethu.usage.counts.v1)与 lib/suggest.ts(suggestAtoms),无需新建埋点;
  • 收藏功能完全不动:一级「收藏」tab、长按收藏、桌面小组件绑定全部原样;推荐区只是"没收藏过的同学也能快速到达"的兜底;
  • 长按推荐项可"固定到推荐位"(本地持久化),与收藏是两套数据、互不影响;
  • 空状态不空白:无历史数据时按 §1.2 的 core 顺序展示默认推荐。

2.6 功能注册表 metadata(吸收外部建议 §5,前端单文件实现)

// state/navigation.ts 中每项:
{
  id: "yuketang_homework",        // 沿用现有页面/原子 ID
  name: "雨课堂作业",
  category: "学习",               // 学习|日程|生活|预约|行政
  visibility: "core",             // core|group|buried|advanced
  needBind?: "yuketang",          // 绑定依赖键,供 ConnectGate 使用
  keywords: ["雨课堂", "作业", "课件"],   // 供搜索与 AI
  boostWindow?: { from: "0915", to: "0925" }, // 时间敏感提升(P2)
}

搜索(复用现有原子搜索与 lib/suggest.ts 索引,lib/infoApps.ts 已有"名称/分类即打即筛"先例)、服务页分组、常用推荐、AI 意图匹配、ConnectGate 绑定引导全部消费这一份数据——这是本方案的技术枢纽,M0 必须先定稿。

2.7 搜索与 AI 兜底

  • [ ] 「服务」页与「今日」顶部提供全局搜索:支持功能名、关键词(消费 metadata)、以及自然语言透传给 Harness; — 服务页与 PC 命令面板已能全局搜;「今日」顶部仍没有入口——只剩今日这一处。
  • [ ] Harness 面板保持左下角常驻但视觉降调(小按钮),未主动使用过的用户不教学、不弹窗; — 按钮已降调(40px,移动 34px);「未主动使用过的用户」那半句未核对。
  • [ ] P2:AI 支持执行型意图("绑定雨课堂""交电费"直达),消费同一份注册表。 — P2,未做。

2.8 双端布局规范(移动端 ≠ 窄桌面端)

原则:一套数据、一套令牌、两套壳与布局。PC 不是"拉宽的手机",移动端不是"缩小的 PC"。 底部导航是移动端的正确答案;PC 沿用并升级现有侧边栏。断点处切换,不做中间妥协态。

2.8.1 断点与壳

断点 宽度 壳 备注
compact < 600px(手机竖屏) 底部 5 Tab(§2.2) 当前主力场景,最高优先级打磨
medium 600–840px(手机横屏/平板竖屏/小窗) 底部 Tab 保持,内容单列 + 最大宽度 600px 居中 过渡态,保证不破即可
expanded ≥ 840px(PC/平板横屏) 侧边栏(升级版,见下) 沿用现有侧边栏结构,不迁移到底栏
  • [x] 断点判定用 CSS 容器/视口媒体查询(Layout.tsx 现有逻辑基础上改),JS 侧只读一份 usePlatformLayout() 结果,禁止组件各自写断点; — 复核 2026-09-28:global.css 里 24 处媒体查询,全仓只 5 处 window.innerWidth——断点确实主要交给 CSS 了。
  • [x] PC 侧边栏升级(不推倒重来):保持现有位置与结构,套用 B4 批次的 MD3 navigation rail 样式——active 项胶囊指示器、分区小标题(对应 §1.2 的 category 分组)、底部收纳 Harness 入口与折叠按钮;宽度收窄至 ≤ 240px(折叠后 72px 图标态); — 复核 2026-09-28:侧栏折叠(is-collapsed)、B4 批次组件、注册表驱动导航均已落地。
  • [x] 移动端"服务"目录页与 PC 侧边栏消费同一份 navigation.ts:PC 上 group 级功能在侧栏以分组小标题直接展开,不再需要目录页。 — 复核 2026-09-28:侧栏与「服务」页都取 NAV_REGISTRY,搜索同走 state/searchAll.ts。

2.8.2 内容布局分端设计(逐页)

页面 移动端(compact) PC(expanded)
今日 单列卡片流,问候语大标题 左侧卡片流(≤ 640px)+ 右侧"时间轴/下一节课"常驻面板;问候语缩为顶栏欢迎语
待办(作业) 单列列表,底部 sheet 看详情 列表-详情双栏:左列表右详情(复用现有 AssignmentDetailPage 路由,PC 上主区域分栏渲染,不跳页)
课表 现有两种模式保留:周视图网格(compact 下横向滚动)+ 列表模式(ScheduleAgenda,竖向按日)。改造点仅两处:① compact 默认落在列表模式(周网格横滚在手机上是已知的糟糕体验,用户手动切网格的保留);② 两模式套 B2 新令牌 PC 默认周视图网格(现有布局),套新令牌;列表模式作为次要视图保留
服务 分组目录页 + 搜索框 侧栏已直达,此页仅移动端存在(PC 访问则重定向到分组首个功能)
收藏 现状 FolderPage.tsx 已是瀑布流(原子长卡全宽 + 方卡瓦片聚块),移动端保持该形态 沿用瓦片网格(现状即网格语义),拖拽排序为 PC 增强项(P2)
成绩/信息类 tab(info/) 单列 tab 滚动 单列但最大宽度 720px 居中,表格类(成绩单、学年汇总)用完整宽度横向表格
设置 单列分组列表 + 二级页签 单列 ≤ 720px 居中;二级为页签(与信息页/生活页同形态。规范原写「右侧推入面板」,未采用;2026-02 经用户确认保持页签)
邮件(MailPage) 单列,列表→详情推入 双栏:左邮件列表右阅读 pane(邮件类应用的标准形态)
文件预览(FilePreview) 全屏 sheet 居中大窗 + 侧边附件信息栏
  • [ ] 每行的"PC 布局"都标注了复用策略:双栏页只改容器渲染,不改数据流与子组件——AssignmentDetailPage、邮件 pane 等作为子组件被两个壳复用;
  • [ ] M1 交付时本表逐行实现核对;M3 各批次截图必须双端各一张(§3.5 已要求,此处为落点)。 §2.8.2 逐行核对(2026-02,用户逐项确认;护栏 tools/pc-layout-test.mjs)
页面 代码现状 本轮处置
今日 已落地:useExpanded 分端,右栏是用户可自组的卡片列(onethu.home.layout,main/rail/off),「下一节课」卡 + 问候语缩顶栏 用户裁定保持现状,不加常驻「时间轴」卡
待办(作业) 已落地:tasks-body.is-wide 双栏 + detailRef 详情槽位(lib/detailSlots.ts) 无需改动
课表 已落地:tier === "expanded" ? "timetable" : "agenda",手动切过的模式保留 无需改动
服务 已落地:PC 重定向到分组首个功能,带回退(beta) 无需改动
收藏 现状即瓦片网格 拖拽排序按 P2 保留,不做
成绩/信息类 tab 已落地::has(> .page-anim[data-page=info life]) 限宽 720 + :has(table) 放开
设置 限宽 720 已落地;二级实际是页签 用户裁定保持页签,规范行已同步改写
邮件 已落地:.mail-layout = 340px minmax(0,1fr),窄屏收单列,复用同一阅读 pane 无需改动(曾被误判为“未做”)
文件预览 PC 居中大窗已有;缺侧边附件信息栏 本轮补上:.fp-info 右栏(名称/类型/大小/格式 + 平台提示),窄屏不渲染

定位方式提醒:邮件页两个 pane 的类名是 .mail-layout / .mail-list / .mail-detail——按 mail-pane 之类猜的名字搜索会搜空。查分端状态请直接用护栏的断言表。

2.8.3 组件形态分端映射

组件 移动端 PC
ConnectGate / TabManageModal 等所有弹层 bottom sheet(B3 样式) 居中 modal(≤ 480px)或右推面板
搜索(复用原子搜索/usage 索引) 顶部下拉结果 ⌘/Ctrl+K 唤起的居中命令面板——已落地(见下方注)
涟漪反馈(Ripple) 启用 禁用(指针设备用 hover state layer 代替,§3.9-5)
刷新/重试 下拉刷新 工具栏刷新按钮 + r 键快捷(P2)
日期/时间选择 系统风格滚轮/日历 sheet 日历弹出面板
  • [x] 实现方式:组件内部按 usePlatformLayout() 分支渲染形态,对外 API 不变——调用方无感知; — 复核 2026-09-28:意图已达成,但没有引入 usePlatformLayout 这个 API——双端形态全交给 CSS 媒体查询(840px),比计划更省 JS。
  • [ ] PC 端 hover 态在 M3 走查中单列检查项(移动端验收覆盖不到的盲区)。

2.8.4 双端验收补充

  • [x] 三断点(375px / 768px / 1440px)全页面截图走查纳入 M5; — 霖人工走查通过 2026-09-28。
  • [x] PC 端专项:hover/focus 态、窗口缩放拖拽不破版、命令面板(⌘/Ctrl+K)、侧栏折叠态; — 霖人工走查通过 2026-09-28(含命令面板 Ctrl+K)。
  • [x] 移动端专项在 §0.4 任务测试中不变(主力场景,权重最高)。 — 霖人工走查通过 2026-09-28。

2.8.4 命令面板(2026-09-28 落地)

components/CommandPalette.tsx:⌘/Ctrl+K 唤起的居中搜索,输入即搜、↑↓ 选择、回车直达、Esc 关闭; 侧栏顶部同时留了可点击入口(旁边写着当前平台的键位)。

  • 键位:(e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k"。本项目只出 Windows exe 与 Android APK,实际按的是 Ctrl+K; 两个都认是为了将来出 Mac 版不返工。提示文案按平台走(Mac 显 ⌘K,其它显 Ctrl K)——在 Windows 上印 ⌘K 就是错的。
  • 同源:结果只经 state/searchAll.ts 取(注册表命中 + 原子命中 + 设置页签),服务页的顶部搜索也改走这一份, 避免两处各写一套(ADR 第 6 条);设置页签清单也随之挪到 state/settingsMode.ts 作为唯一一处定义。
  • 点得动:功能行走 pageAtomRef/ resolveAtom 的 open(使用统计照记),无同名原子的按注册表 page/params 跳。
  • 护栏:tools/palette-test.mjs 盯四件事——双键位与平台提示、结果同源、跳转走注册表、点击入口与挂载(面板挂 body,不被滚动容器裁掉)。

3. 主线二:MD3 视觉改造(P2)

策略:令牌层激进重构,组件层渐进迁移。零新依赖(动态取色的 material-color-utilities 结果固化为 CSS)。

3.1 令牌层重写(packages/ui/src/tokens.css)

  1. [ ] MD3 三层令牌:Reference(tonal palette)→ System(--md-sys-color-* 亮暗两套)→ Compat 层保留全部旧变量名(--bg、--surface、--primary、--accent、--text-1/2/3、--red…)映射到 System 层,≈5000 行 global.css 零改动换肤;
  2. [ ] 关键映射:--bg/--surface→surface;--bg-soft/--surface-2→surface-container-low;--surface-3→surface-container;--border*→outline-variant;--primary→primary(黑改品牌色);--accent→primary/tertiary;--text-1/2/3→on-surface/on-surface-variant;
  3. [ ] 新增形状令牌(8/12/16px/full)、五档字阶、--elev-1..3 阴影;
  4. [ ] PR 附完整新旧变量对照表。

3.2 品牌色

  • [x] "清华紫"为 seed 生成 tonal palette,结果固化为 CSS(构建期跑 material-color-utilities,产物入 git),零运行时依赖; — 复核 2026-09-28:tools/gen-tokens.mjs 构建期用 @material/material-color-utilities 从种子 #660874 生成,产物已固化。
  • [x] 主按钮黑 → 品牌色。 — 复核 2026-09-28:.btn-primary 取 --md-sys-color-primary。

3.3 暗色模式

  • [x] System 层亮暗双套,prefers-color-scheme + state/theme.ts 手动覆盖双通道;保留现有骨架屏流光 --skeleton-shine 暗色覆盖的教训注释。 — 复核 2026-09-28:theme.ts 双通道(data-theme 手动 + data-scheme 跟随系统)已实现。

3.4 动态取色(Android 12+)

  • [x] plugins/onethu-mobile 新增 getDynamicColor() 命令(Rust: src-tauri/src/lib.rs dynamic_color → run_mobile_plugin_async("getDynamicColor"),supported=false 时返回 None 走降级),读取系统 monet 取色返回 seed/tone;
  • [x] 前端注入 Reference 层变量,Compat 层自动生效(src/lib/dynamicColor.ts:注入