Files
tamabox/docs/theme-new-sakura.md
T
tamakyi 48a1938fb2 新增 new-sakura 主题:纯 CSS 樱花,每个页面位置不同
樱花不依赖任何图片素材:整朵花、带缺口的花瓣、带枝的花朵树都是内联 SVG 的
data URI,写在主题 CSS 里。好处是零请求、任意缩放不糊、换花色只改一个色值;
代价是 CSS 约 50KB(gzip 约 12KB),走 StaticVersion 缓存。

- 六个页面作用域各一套 --tb-deco 位置(global / box / question / admin /
  profile / vote),10 槽三组等长;位置一律「关键字 + 偏移」两值写法。
- 窄屏(≤640px)装饰层全关、底纹缩到 200px:卡片占满宽度后枝条会糊在字上。
- 深色换亮一档的粉、关掉底纹(浅粉压在深底上会变噪点)、背景用渐变避免死黑。
- 亮色 primary 从候选 #c14a72(4.39:1)压深到 #b8436a(4.87:1),
  muted 5.27:1,都踩住 AA;深色对应 8.17:1 / 5.82:1。
- 生成脚本 dev/theme-tools/gen_new_sakura.py(花形、位置表、配色都在里面),
  CSS 是产物,不手改。
- 四份词典加 theme.name.new-sakura;conf/app.sample.ini 的 available 登记。

为什么不用生成器:生成器的装饰层只认图片素材,没有内联 SVG 图层,
见 docs/theme-new-sakura.md「为什么不用主题生成器出图」。
2026-10-22 10:45:39 +08:00

4.7 KiB
Raw Blame History

new-sakura(新·樱花):纯 CSS 樱花主题

和已有的 sakura 的区别:sakura 是「粉底 + 网点」的静态配色;new-sakura 把樱花本身 做成了可摆放的装饰层 —— 整朵花、带缺口的花瓣、带枝的花朵树,全部是内联 SVG 的 data:image/svg+xml URI,写在主题 CSS 里。

因此这个主题:

  • 不需要任何图片素材,也不依赖对象存储(static/images/themes/new-sakura/ 是空的);
  • 任意视口缩放都不糊(矢量),DPI 无关;
  • 换花色只改 dev/theme-tools/gen_new_sakura.py 里的一个色值,重跑即得;
  • 没有额外 HTTP 请求 —— SVG 就在 CSS 里。

代价是 CSS 有 40~50KB(gzip 后约 12KB)。主题 CSS 走 StaticVersion 缓存,一次性开销。

结构

static/css/themes/new-sakura.css      ← 生成产物,别手改
dev/theme-tools/gen_new_sakura.py     ← 改这里,重跑
python dev/theme-tools/gen_new_sakura.py

生成器脚本里有三样东西:花形(blossom / petal / branch / pattern)、 每个页面作用域的位置表(SCOPES)、以及配色(LIGHT / DARK)。

每个页面的樱花位置

--tb-deco / --tb-deco-size / --tb-deco-position 三组各 10 槽,必须等长 (TestDecoSlotCount 会逐文件逐声明检查)。

作用域 选择器 构图
global html[data-theme-style="new-sakura"] 右下花枝 + 左上大花 + 两片落瓣
box …[data-page-scope="box"] 右上花枝垂下(细端在外、粗端朝内)+ 左下花与落瓣
question …[data-page-scope="question"] 左下花枝斜穿 + 右上大花 + 落瓣
admin …[data-page-scope="admin"] 左上花枝 + 左侧底部小花(卡片占满宽度,右侧会被盖住)
profile …[data-page-scope="profile"] 右下花枝 + 左侧竖排小花与落瓣
vote …[data-page-scope="vote"] 左上花枝 + 右侧花与落瓣

位置一律「关键字 + 偏移」两值写法(right -24px top -16px)。三值语法里混用 left / bottom 关键字是非法的,整条声明会作废、花瓣静默回到左上角。

窄屏(≤640px)

装饰层全部置 none:卡片占满宽度后,留白只剩顶栏上下两条,枝条会直接糊在文字上。 樱花改由底纹承担 —— @media 里把 --tb-page-pattern-size 从 300px 收到 200px,密度上来才看得见。

深色

  • 花瓣换成更亮一档的粉(#f0a0b8),枝条提亮到能看见;
  • 底纹 --tb-page-pattern: none:浅粉花瓣压在深底上会变成一层噪点;
  • 整页背景改深色渐变(不用纯色,避免大面积死黑)。

深色块必须写成 html[data-theme="dark"][data-theme-style="new-sakura"](三重选择器), 只写浅色块会被同特异性的作用域块盖掉。

配色与对比度

令牌 亮色 深色 说明
--tb-bg #fdf6f8 #221a1e 纯色,不用渐变(整页色感一致)
--tb-surface #ffffff #2c2227 卡片
--tb-text #3a2c31 (12.4:1) #f3e6ea (14.0:1)
--tb-text-secondary #6d555d (6.3:1) #c9aeb8 (8.3:1)
--tb-text-muted #77626a (5.3:1) #ab9099 (5.8:1) 踩 AA 下限
--tb-primary #b8436a (4.9:1) #ff93b4 (8.2:1) 原候选 #c14a72 只有 4.39:1,压深
--tb-on-primary #ffffff (5.2:1) #1b1014 (8.9:1) 主色按钮上的字

为什么不用主题生成器出图

生成器的装饰层只支持「图片素材」(导出时打进 zip 或传对象存储),没有内联 SVG 图层。 要把樱花做成可摆放的图层,只能在设计上二选一:

  1. 生成图片素材(花瓣 PNG/WebP)→ 可以用生成器、可以放 S3,但会有位图缩放、额外请求;
  2. 内联 SVG 写进 CSS → 零素材、任意缩放不糊,但生成器管不到。

new-sakura 选 2,因为「用 CSS 做樱花」本身就是这个主题的诉求。 生成器仍然可以用来预览它:?demo=1&fresh=1 起画板,把 new-sakura.css 注入即可。

怎么验证

go test ./internal/theme          # 10 槽等长、深浅块成对、必需令牌齐全

视觉自检用项目真实页面快照:

TEST_PREVIEW=1 go test ./templates -run TestGenPreview
python dev/theme-builder/serve.py
# 打开 outputs/preview-box-light.html,DevTools 里给 <html> 加
#   data-theme-style="new-sakura"  data-page-scope="box"

上线

  1. conf/app.ini 的 [theme] available 加上 new-sakura(不改就「设置页看不到」,现象和部署没生效一样);
  2. 重新 go build —— 主题 CSS 是编译期 embed,只重启不重编不会变;
  3. 箱主设置页 → 账号 → 外观,选择「新·樱花」。