一号事项(剩余令牌化):
- templates/user/profile.html 20 处、base.css 9 处 font-size 全部落到 --tb-fs-*
- base.css 导航四档(0.95/0.88/0.82/0.78)合并成「桌面 md → ≤1000 xs」;logo 三档统一 lg
- 有理由保留的:.tb-pin-flag / .md-body code 的 0.9em(相对父级)、验证码 1.4/1.2rem(等宽字形)、
chat 关闭按钮 40px、password 页 3em、mail/*(邮件客户端不保证 var());行内 12px/0.75rem 等值顺手换掉
二号事项(主色对比度):
- base/default #1e87f0(3.42) → #0e6fd0(4.70);shiroko #4a7fc1(3.69) → #3b6dac(4.74);
sakura #e5678f(2.80) → #ba3e66(4.70,饱和度压到 .5 保持柔和)。同色相只压亮度,目标 4.7 留余量
- 深色块 muted 之前只对 --tb-bg 算(4.7 以为过了),对压平后的卡片其实 4.31/4.17 → 提到 #a18790 / #7f8ea1
- 新增 --tb-on-primary(亮 #ffffff / 暗 #0b1016):深色模式主色偏亮,白字只有 2.2~3.1:1,
用同一个令牌兼顾「链接色要深」和「按钮底要深」是矛盾的。.uk-button-primary 与
.uk-label:not(语义色) 改吃它 → 深色按钮变成浅底深字(6.10 / 8.65 / 7.27)
- 顺手封掉几处主色泄漏:header 验证码 focus、profile .feat-day.is-on、explore 随机投票的 JS outline、
vote-results 行内色,全部改成令牌(否则换主题时不跟着变)
生成器同步:paletteVars 导出 --tb-on-primary(白字/深字择优);?dump=palette 增加
onPrimaryCr / onPrimaryPickedBest / warnings —— 主色卡中间调时只警告不判失败;
配色面板给橙色提示。_scaffold 令牌 29 → 30。StaticVersion → 20261021c。
验证:TestSwatch 断言同步为 #ba3e66;8 种组合(base 亮暗 + 三主题亮暗)对比度全部 ≥4.5;
go test internal/{theme,templates,conf,i18n} 全绿;生成器 validate/fit/quality/palette/layers/fx/fxpipe 全过。
55 lines
5.8 KiB
Markdown
55 lines
5.8 KiB
Markdown
# 主题(箱主个性化)(长版明细)
|
||
|
||
## 主题(箱主个性化)
|
||
|
||
- 三个注入点:`/_/{domain}/*` → `question.Pager` 按 `pageUser.Theme`;`/user/*` → `internal/context`
|
||
Contexter 按 `c.User.Theme`(`isThemeScope()` 只认 `/user` 与 `/user/`);`/vote/{token}` → `route/vote.Page`
|
||
按发布者 `owner.Theme`。都看箱主/发布者,不看访客。全站页(`/`、`/explore`、`/login`)不主题化。
|
||
- 投票页**语言**也跟发布者:`applyOwnerLocale(data, owner)`(与主题同一函数),必须在任何 i18n 取词之前调用。
|
||
- 一套主题 = `static/css/themes/<slug>.css`,**只覆盖令牌**,不碰布局。`static/fs.go` 已嵌整个 `themes/` 目录。
|
||
- 主题显示名:模板用 `{{ themeName .LangCode .Slug }}` → `theme.DisplayName`,i18n 没登记
|
||
`theme.name.<slug>` 时**回退成 slug**。⚠️ 别在模板里直接 `{{t .LangCode (printf "theme.name.%s" .Slug)}}`:
|
||
`i18n.T` 缺词条返回 key 本身,设置页就会显示 `theme.name.test01`(用户报过)。
|
||
- ⚠️ **`[theme] available` 是硬白名单,启动时读一次**:css 发布了但没登记,设置页看不到,现象同「部署没生效」。
|
||
排查:`curl /static/css/themes/<slug>.css` 200 = 文件在(没登记);404 = 旧二进制。
|
||
- ⚠️ 主题 css **必须成对写**:`html[data-theme-style="x"]`(0,1,1) + `html[data-theme="dark"][data-theme-style="x"]`(0,2,1)。
|
||
`TestThemeCSSComplete` 查两个选择器 + 10 个颜色令牌。
|
||
- ⚠️ **按页面作用域**:`internal/context.pageScope()` → `<html data-page-scope>`,取值
|
||
`box`/`question`/`admin`(/user/questions,/user/votes*)/`profile`/`vote`。深色作用域覆盖必须**三重选择器**,
|
||
否则被浅色作用域块(同特异性、写在后面)盖掉。
|
||
- ⚠️ **装饰层固定 10 槽**(base.css 12 层 = pattern1 + deco10 + image1),三组 `--tb-deco/-size/-position`
|
||
必须等长。`TestDecoSlotCount` 逐文件逐声明检查(只扫 embed 到的文件)。
|
||
- 位置一律两值 `calc(0%|50%|100% ± N)`(百分比相对「容器 − 图片」)。**别用 left/bottom 关键字混搭**:
|
||
三值语法非法时整条声明作废 → 图层静默回左上。
|
||
- 尺寸想随视口缩用 `clamp`,**不要写死 px**:`auto clamp(min(calc(100vh - 24px), 231px), 46.67vh, 420px)`。
|
||
内层 `min()` 是兜底 —— 屏幕小到连下限都放不下时让位给视口。宽幅素材只能按宽度缩(`vw`),
|
||
按高度缩的话宽度按比例涨,窄屏照样裁。
|
||
- ⚠️ **UIkit 3.3.3 主色是编译期常量 `#1e87f0`**,令牌注入不进去。base.css 末尾按组件映射(a/uk-link、
|
||
uk-button-primary、checkbox/radio、input:focus、uk-tab active、`.uk-progress`、`.uk-label:not(...)`)。
|
||
- 令牌 `--tb-navbar`(顶栏底色,默认 `var(--tb-surface)`):页面底色偏彩时主题必须覆盖。
|
||
- 静态资源版本号统一 `conf.StaticVersion`;**图片不走这个缓存键**(`max-age=86400`),换图要给 URL 带 `?v=`。
|
||
- 整页背景 `--tb-page-image`(cover)/ `--tb-page-pattern`(平铺,`-size` 控尺寸)/ `--tb-page-position`
|
||
(焦点,默认 `var(--tb-page-position, center center)`,旧主题不写也不坏)。底色用**纯色**别用渐变;
|
||
图案 ≥24px、透明度 ≤0.06。
|
||
- ⚠️ **多背景层不能塞变量列表**:变量自身是逗号列表会让层数与 size/position 错位。多张装饰用固定槽位。
|
||
- 装饰摆位:**贴边、成组、避开页脚**;四角各摆一个会读成贴纸墙纸;页脚文案右对齐 → 右下角不能放人物。
|
||
`--tb-deco` 是 fixed 视口层,贴边插画别放进 `cover` 背景图(必裁边)。
|
||
- 主题视觉的**结构**比摆位重要:通行做法是「整屏场景插画 + UI 悬浮其上」(蔚蓝档案 JP)。
|
||
白底留白里摆人物,无论多大都读成贴纸;卡片/顶栏配半透明白 + `backdrop-filter` 才有"浮在画面上"的关系。
|
||
- 素材放 `static/images/themes/<slug>/`(embed 已含 `images/themes`,子目录自动覆盖)。整页图 16:9 + 竖版两张。
|
||
- 人物素材:**图生图 + 抠白底**(`image1` 给立绘、`input_fidelity: high`、`flat vector illustration, no outlines`)。
|
||
⚠️ 正面立绘直接贴进空场景像贴纸:改**侧后方视角**(不直视访客),RGB **压白 12~16%** 与压白 38% 的场景对齐雾度。
|
||
- ⚠️ **抠白底容差 16**:背景 253、白袜子 237 只差 16,容差 22 以上会把袜子吃穿。手内侧/两腿之间是
|
||
**闭合**白区,四边 floodfill 进不去,得按连通域单独掏(面积 ≥24),再 1px 收边。
|
||
- ⚠️ `ruleBody` 取令牌前要剥 `/* */`:注释会和后面的令牌粘成一个键,色块预览静默失效。
|
||
- ⚠️ **主题会覆盖 base.css 的同名令牌 —— 基座改配色必须同步改主题**。改 `--tb-text-muted` 时
|
||
sakura `#a08c94`(2.8:1)、shiroko `#8794a7`(2.76:1) 都还没跟上,"修了但主题页没变"就是这么来的。
|
||
现已调到 `#78696e`(4.61) / `#656e7a`(4.63),深色块 `#a18790` / `#7f8ea1`(对压平后的卡片 4.62)。
|
||
主色也已修(`#0e6fd0` / `#3b6dac` / `#ba3e66`)+ 新增 `--tb-on-primary`,见 topics/style.md。
|
||
量对比度时半透明 `--tb-surface` 要**压平到 --tb-bg** 再算,别当纯白。
|
||
- 主题选择页的色块由浅色块的 `--tb-bg` + `--tb-primary` 生成(`swatchOf`),注释里别写令牌名。
|
||
- `test01` 是用户 2026-10-21 自建又删掉的验证主题(css + 2 张 webp 已移除,未提交)。
|
||
删主题只需删文件:`build()` 读不到 css 会打 warning 并忽略,已选该主题的用户静默回退站点默认。
|
||
`static/images/shiroko-cutout.png` 也一并删除(2026-10-21):它从不进 embed,只是 docs 里的图生图参考图,
|
||
仓库不存这类大图。
|