Files
tamabox/.workbuddy/memory/topics/theme.md
T
tamakyi db4b3fa095 主题体系跟上设计令牌化:派生文字色按对比度下限、主题 muted 补到 AA
生成器(dev/theme-builder):
- paletteVars 的 text-secondary/text-muted 从「往底色混 36%/55%」改成 mixToContrast(5.5/4.5):二分找最淡且达标的位置,文字本身不达标就原样返回
- 半透明卡片先 flatten 压平到底色再算对比度;参考背景取「页面底色 + 压平后的卡片」中更不利的
- 配色面板加读数(正文/次要/淡文字/主色),低于 4.5 变橙;默认 primary #4a7fc1(3.69) → #3d6fac(4.63)
- 新增 ?dump=palette 四种配色回归;README 补配色一节

主题/base(含用户本轮 base.css 改动):
- sakura muted #a08c94(2.8:1) → #78696e(4.61)、shiroko #8794a7(2.76:1) → #656e7a(4.63):主题覆盖令牌,基座的 AA 修复到不了主题页
- 深色顶栏链接补 secondary 覆盖:亮色块已是次要文字色,深色块原来 !important 定成正文色,同一顶栏权重跳一档
- _scaffold.css 令牌清单 23 → 29(补 fs 阶梯与 page-position),muted 说明 AA 下限
- StaticVersion 20261021a → 20261021b
2026-10-21 17:42:43 +08:00

5.6 KiB
Raw Blame History

主题(箱主个性化)(长版明细)

主题(箱主个性化)

  • 三个注入点:/_/{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),同色相只压深。主色仍不达标(见 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 只是 docs/theme-shiroko.md 的生成参考图,不进 embed。