Files
tamabox/.workbuddy/memory/topics/theme.md
T
2026-10-21 12:09:28 +08:00

4.7 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 取令牌前要剥 /* */:注释会和后面的令牌粘成一个键,色块预览静默失效。