feat(theme): 主题支持按页面分别配装饰,生成器改用真实页面画布

原来的生成器只能配「背景 + 人物 + 道具」三件套,预览还是自己画的仿制页面 ——
跟真实页面不像,也没法给不同页面配不同内容。

机制层:
- internal/context.pageScope() 按路径归类,输出 <html data-page-scope>:
  box / question / admin / profile / vote(首页与 /explore 不加载主题,不列)
- /user/questions 单独归为 admin:题目列表信息密,和设置表单的装饰诉求不同
- base.css 装饰槽位 6 -> 10,背景 8 层 -> 12 层;主题按作用域覆盖时同样写满 10 个
- 新增 TestDecoSlotCount:逐文件逐声明检查 10 个值。少写一个不报错,
  只会让图层与 size/position 错位(整页重复同一张图 / 人物跑到左上角),注释守不住

生成器:
- 画板改成 iframe 加载 outputs/preview-*.html(真实模板渲染),配 serve.py 起本地服务
  解决 file:// 下父页面读不到 iframe DOM 的问题
- 八个页面作用域(去掉不生效的首页/探索),每个可独立配背景与最多 10 层装饰
- 图层类型:图片 / 径向光斑 / 线性光;9 宫格锚点 + 像素偏移,可在画板上直接拖
- 位置统一写 calc(0%|50%|100% ± Npx):百分比是相对 (容器-图片),
  不用 left/bottom 关键字混搭,避免三值语法非法导致整条声明作废
- 配色只填 6 个基础色,其余 4 个必需令牌按方向派生(surface-2 往 text 靠,
  浅色变深、深色变亮,方向自动正确)

配套:
- zz_preview_test.go 增加单题页 / 题目列表 / 投票页预览,作为生成器画板
- docs/theme-page-scope.md 记录作用域取值、选择器特异性与 10 槽位约束
- StaticVersion 20261020e(base.css 变了)

验证:生成器导出的 CSS 通过 TestThemeCSSComplete + TestDecoSlotCount;
真实箱主页计算样式为 12 层对齐;临时主题验证「question 覆盖为 none」生效、
未覆盖时回退全局。
This commit is contained in:
tamakyi
2026-10-20 10:53:44 +08:00
parent feb5b1f78d
commit ddee221de2
14 changed files with 1748 additions and 796 deletions
+4 -1
View File
@@ -31,7 +31,10 @@ available = default,sakura,shiroko
| 中层 | 卡片与顶栏:半透明白 + `backdrop-filter` 磨砂 | `--tb-surface: rgba(255,255,255,.86)` / `--tb-navbar` |
| 上层 | 人物站在场景左侧地面(400px 高)+ 椭圆接触阴影 | `--tb-deco` 前两个槽位 |
| 道具 | 她的自行车(车头朝右、与人同向)斜靠一把步枪 | `--tb-deco` 第 3 槽位 |
| 空气层 | 左窗光柱 / 右侧暖散景 / 脚下地面光斑 / 底部压深 | `--tb-deco` 后四个槽位(全是渐变) |
| 空气层 | 左窗光柱 / 右侧暖散景 / 脚下地面光斑 / 底部压深 | `--tb-deco` 第 4~7 槽位(全是渐变) |
> 装饰层共 10 个槽位(见 `internal/theme/slots_test.go`),本主题用前 7 个,其余留空。
> 想给某一页换装饰(例如问题页让人物退场),见 [theme-page-scope.md](theme-page-scope.md)。
| 深色 | 不用场景(白天教室压在深底上会脏),回到深色渐变 + 极淡纹样 | 深色块单独覆盖 |
摆位经验(都是踩过的):