Sync multi-theme optimizations from dev (exclude Bento/Style C)
- Magazine (A) + Swiss (B) template updates: ?slide=N, ESC thumbnail fix, reduced-motion, spacing fixes - Swiss validator: Playwright M1/M2 rendered measurement (overflow/whitespace/nav-safe/title-gap) - SKILL.md: Step 0 upstream-update check, image-mixing decision tree, measure-before-edit ladder - checklist.md: image-role guidance, quiet-zone rule, post-render measurement section - Remove author-local golden-source absolute paths; point to in-repo template-swiss.html snapshot - Add ppt-skill-showcase.png and A/B-only unification-plan.md - Exclude all Bento/Style C assets, references, validator, and design-research docs Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
82fe5ae129
commit
ba12c5c9ad
11 files changed
+429
-95
No files matched your search
@@ -0,0 +1,96 @@
|
||||
# 多主题统一管理整合方案
|
||||
|
||||
> 基于对 template.html / template-swiss.html 两份模板与全部 references 的逐行对比分析(2026-07)。
|
||||
> 本文档是**方案建议**,尚未实施;按阶段推进,每个阶段独立可交付、可回滚。
|
||||
|
||||
## 现状诊断
|
||||
|
||||
两个主题是"复制粘贴后各自演化"的关系,同一份基础设施存在多份副本,并已实际漂移:
|
||||
|
||||
### 运行时 JS 漂移(约 250 行 × 每主题一份)
|
||||
|
||||
| 模块 | A 杂志风 | B 瑞士风 |
|
||||
|---|---|---|
|
||||
| 低功耗事件名 | `ppt-low-power-change` | `swiss-low-power-change` |
|
||||
| localStorage key | `guizang-ppt-low-power`(共用!) | 同左 |
|
||||
| ESC 索引缩略图可见性修复 | ✅(本次补齐) | ✅ |
|
||||
| `?slide=N` 直达参数 | ✅(本次补齐) | ✅ |
|
||||
| Windows 字重补偿 `is-win` | 缺失 | ✅ |
|
||||
| prefers-reduced-motion 自动降级 | ✅(本次补齐) | ✅ |
|
||||
| 翻页/滚轮/触屏/键盘核心 | 两份逐字符几乎相同 | 同左 |
|
||||
|
||||
### Token 体系成熟度不一
|
||||
|
||||
- **B 最成熟**:主题色 + Carbon 文字角色 token + `--sp-3~13` 8px 间距阶梯 + motion token + `--nav-safe-bottom`
|
||||
- **A 最简陋**:只有 6 个颜色变量,层级靠 opacity 表达,存在 10-11px 小字(投屏不可读),`.lead/.chrome/.foot` 在模板内部重复定义(v1 与 v2 API 叠加)
|
||||
|
||||
### 已知具体坏味道(可立即修的小项)
|
||||
|
||||
1. B 模板 `#hint` 引用了未定义变量 `--ink-tint`(靠 fallback 兜底)
|
||||
2. B 模板 pipeline 死代码:`__pipeAdvance` 恒返 false,但 43 行 pipeline CSS 和动效 CSS 还在
|
||||
3. B 的 motion token 双维护:CSS 定义了 `--ease-prod`,JS 里又硬编码 `EASE_PROD=[.2,0,.38,.9]`
|
||||
4. A 是唯一没有校验器的主题,但 validate-swiss-deck.mjs 的标题选择器已经包含 A 的类名(`.display/.h1-zh` 等),说明测量层本来就通用
|
||||
|
||||
## 整合原则
|
||||
|
||||
**不建议**把两个模板合并成一个"大一统模板"——两种风格的美学规则互斥(直角 vs 圆角、衬线 vs 无衬线),强行合并会让类名前缀和条件分支爆炸,也违背"每份 deck 单文件交付"的定位。
|
||||
|
||||
**建议**的整合层次:**共享的是"基建"和"契约",不共享"皮肤"**。
|
||||
|
||||
## 分阶段方案
|
||||
|
||||
### Phase 1 · 共享运行时(收益最大)
|
||||
|
||||
把各主题漂移的 JS 收敛为一份 `assets/runtime.js`(构建时内联进各模板,保持单文件交付):
|
||||
|
||||
- 翻页核心 go() / 键盘 / 滚轮 / 触屏 / nav 圆点 / ESC 索引(含缩略图可见性修复)
|
||||
- 低功耗 IIFE:统一事件名为 `deck-low-power-change`,统一 localStorage key,保留各主题旧事件名一个版本作为 alias
|
||||
- `?slide=N`、prefers-reduced-motion、Motion One 加载器
|
||||
- 主题差异通过配置对象注入:`initDeck({ darkClass:'dark', onSlideChange(){...} })`
|
||||
|
||||
实施方式二选一:
|
||||
- **a. 构建脚本**(推荐):`scripts/build-templates.mjs` 把 `src/runtime.js` + 各主题 `src/style-*.css` + 皮肤 HTML 组装成各 template*.html。模板仍是完整单文件,但源头唯一。
|
||||
- **b. 文档约定**:不引入构建,把 runtime 段落用 `<!-- SHARED-RUNTIME v3 -->` 注释标记,改动时用脚本校验各份一致。成本低但漂移风险仍在。
|
||||
|
||||
### Phase 2 · 公共 Token 契约
|
||||
|
||||
在各模板间统一**命名和语义**(值可以不同):
|
||||
|
||||
- 间距:全部采用 B 的 `--sp-*` 8px 阶梯(A 补齐)
|
||||
- 文字角色:`--text-primary/secondary/helper/on-color` + `--border-subtle/strong` 各主题同名(A 需要从 opacity 方案迁移)
|
||||
- 安全区:`--nav-safe-bottom` + `.nav-safe-bottom(-tight)` 各主题同名(已完成:B 有,A 待补)
|
||||
- Motion:`--ease-*/--dur-*` 统一命名,JS 从 CSS var 读取,消除双维护
|
||||
- 最小字号地板:A 对齐 B 的"正文 ≥16px、caption ≥14px"投屏标准(A 现存 10-11px 小字需要清理)
|
||||
|
||||
### Phase 3 · 校验器公共核
|
||||
|
||||
抽 `scripts/lib/validate-core.mjs`:
|
||||
|
||||
- slide 解析、Playwright 加载(双根解析 + try/finally + swiftshader)、isMeaningful 过滤器、M1 溢出/底部空白/nav 安全线、M2 标题间距、overflowFix 分级建议
|
||||
- 各主题瘦身为 config + 专属静态规则:`validate-swiss-deck.mjs`(版式锁定)、**新增 `validate-magazine-deck.mjs`**(A 目前裸奔,公共核直接就能给它 M1/M2 测量)
|
||||
|
||||
### Phase 4 · References 去重
|
||||
|
||||
- `themes*.md` 各份结构完全同构 → 统一"主题卡片 schema",每主题只留数据
|
||||
- 图片规则目前散在 4+ 处且 A/B 规则有分叉(A:信息图必须 fit-contain;B:重生成图禁止 fit-contain)→ 合并为单一来源 `references/images.md`,分叉处显式按主题参数化
|
||||
- 动效说明多处重复 → 收敛到各 layouts 文件,组件文档只放链接
|
||||
- 清理 golden source 绝对路径:改为相对于 `<SKILL_ROOT>` 的路径或删除
|
||||
|
||||
### 顺手修复清单(可与任一阶段同批)
|
||||
|
||||
- [ ] A:`.lead/.chrome/.foot` 双定义合并
|
||||
- [ ] A:补齐 `--nav-safe-bottom` 安全区 token
|
||||
- [ ] B:删 pipeline 死 CSS 或恢复 `__pipeAdvance`
|
||||
- [ ] B:`--ink-tint` 未定义引用
|
||||
- [ ] B:JS 缓动改读 CSS var
|
||||
- [ ] 文档:去除 `/Users/guohao/...` 绝对路径(已完成)
|
||||
- [ ] 各模板共有:`file://` 直开时 module 动态 import 本地 `./assets/motion.min.js` 被 Chrome CORS 拦截,实际总是走 jsDelivr CDN;离线 + 直开的组合只能拿到静态降级。共享 runtime 时考虑把 motion 关键函数直接内联进模板,或文档明确"离线演示请起本地 server"
|
||||
|
||||
## 建议排序
|
||||
|
||||
1. **Phase 1a(构建脚本 + 共享 runtime)** —— 一次性消灭最大的漂移面
|
||||
2. **顺手修复清单** —— 全部是小改动,跟 Phase 1 同一个 PR
|
||||
3. **Phase 3(校验器公共核 + A 校验器)** —— A 从此也有质量护栏
|
||||
4. Phase 2、4 可以慢慢来,不阻塞新主题
|
||||
|
||||
完成 Phase 1+3 后,再增加"新主题"的边际成本会从"复制 2000 行再改"降到"写一份皮肤 CSS + 一份 layouts 文档 + 一个 validator config"。
|
||||
Reference in new issue
Block a user