Files
tamabox/.workbuddy/memory/topics/builder.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

4.0 KiB
Raw Blame History

主题生成器 dev/theme-builder/(长版明细)

主题生成器 dev/theme-builder/

  • serve.py 起静态服务(8777),iframe 加载 outputs/preview-*.html。file:// 下父页读不到 iframe DOM,必须走 HTTP。 8777 常由用户自己起着,改完直接刷新。
  • 单文件 index.html(约 2900 行)。图片处理非破坏:orig 存原始字节 + fx 存参数,每次从 orig 重算; 参数没变则跳过重编码。画质(S.export.quality/maxSide)同理 —— 改完 rebakeAll() 从 orig 重来,不叠加压缩。
  • 尺寸单位 4 档:fit(按视口高,人物)/ fitw(按视口宽,横幅)/ px / vh。 layerSize() 出 CSS、unitGeom() 出预览框,两处必须共用同一函数,否则「框没超、图已裁」。 ⚠️ 下拉的 value 用 l.unit,不能用 unitOf(l)(后者把 fit 归一成 vh → 选了 fit 却显示 vh)。
  • 溢出检测 layerMetrics(l, a, VW, VH):算 left/top/overL/R/T/B,编辑器里显示「显示 131×420,完整可见」或 「⚠ 左右各 88px 越界」,并给「按当前视口修好」按钮(切 px + 算刚好放下的尺寸)。导出前 overflowReport() 再扫一遍。
  • 视口预设带高度(1512×900 / 1280×800 / 1024×768 / 820×1180 / 390×844):裁切几乎全由高度决定, 只改宽度模拟不出来。fitStage() 按预设高渲染 iframe。
  • 窄屏:全局 hideDeco(急停)> 每层 mob(inherit/scale/hide)> 尺寸单位(fit/fitw 自己就缩)。 ⚠️ hideDeco 会把 @media 里 10 槽全写 none —— 桌面完全正常、手机上素材全没了, 这是「素材在窄屏消失」的头号来源(test01 就是这么中招的)。UI 已在勾选时给橙色警告、 图层行标「窄屏隐藏」、加层/导出再提醒;?narrow=hide 可一键复现。 ⚠️ @media 里每个独立配置的 scope 都要写一条 [data-page-scope="x"]:页面覆盖块特异性 (0,2,1), 只写 html[data-theme-style](0,1,1) 的话独立配置页在手机上完全不生效。 ⚠️ 竖版图只替换本来有背景图的页面(cfg.bg 非空),否则等于给纯色页塞了张图。
  • ⚠️ 派生文字色必须走对比度下限,不能按固定比例混:paletteVars 里 text-secondary = mixToContrast(text, backdrops, 5.5)、text-muted = 4.5(WCAG AA)。 旧的 mix(text,bg,0.55) 在浅底只有 2.9:1 —— 每导一次主题就把 base.css 的 AA 修复覆盖回去。
    • 半透明卡片(--tb-surface: rgba(255,255,255,0.86))必须 flatten() 压到底色再算,否则按纯白算偏低;
    • 参考背景取「页面底色 + 压平后的卡片」两者更不利的那个;
    • 手填正文本身不达标时原样返回(宁可不够淡,不能产出看不见的字)。
    • 配色面板有读数(正文/次要/淡文字/主色),<4.5 变橙;默认 primary 已压到 #3d6fac(4.63)。
  • 自检钩子:?dump=css|zip|validate|install|fx|fxpipe|fxkey|layers|fit|quality|palette,?demo=1&fresh=1&rows=N&scope=&loadurl= (?demo=1 已含 fit 层 + 竖版背景,@media 才会生成)。用法: chrome --headless=old --virtual-time-budget=12000 --dump-dom "http://127.0.0.1:8777/dev/theme-builder/index.html?demo=1&fresh=1&dump=fit" 抓 <pre id="dump">(正则要带属性:<pre id="dump"[^>]*>)。
  • ⚠️ canvas toDataURL('image/webp', 1) 不能用:Skia 在 q=1 切无损,输出反常(噪声图 q=1 只 52KB, q=0.95 是 440KB)。canvasAsset 夹到 0.95,滑块上限也是 0.95。
  • ⚠️ 平涂/线稿降 q 可能变大(有损引入噪点)。压体积先砍长边,再降 q。缩小走 imageSmoothingQuality='high'。
  • ⚠️ 面板只有 ~240px:input[type=range] 有固有宽度,必须 flex:1 1 0;width:0;min-width:0, 且数值放进 label 里(第三个小 flex 项会被顶出可视区)。
  • ?dump=css 的产物要过 Go 侧校验:临时存成 static/css/themes/<非下划线名>.css 再 go test ./internal/theme, 跑完删掉。