Files
tamabox/static/css/themes/_scaffold.css
T
tamakyi 27856dd4a2 字号阶梯收尾 + 主色补到 WCAG AA(新增 --tb-on-primary)
一号事项(剩余令牌化):
- 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 全过。
2026-10-21 18:39:08 +08:00

178 lines
11 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================================
主题底稿(scaffold)—— 复制本文件改名为 <slug>.css 即可新增一套主题。
不想手写 CSS 的话,用 dev/theme-builder/index.html 可视化生成(选图 / 拖位置 / 导出 zip)。
文件名即 slug:只允许小写字母、数字、连字符(如 sakura / ocean-mist)。
新增后需在 conf/app.ini 登记:
[theme]
default = default
available = default,sakura,ocean-mist
⚠️ 硬规则(违反会导致深色模式错乱或整页错位):
1. 两个块都必须写:浅色「html[data-theme-style="SLUG"]」
与深色「html[data-theme="dark"][data-theme-style="SLUG"]」。
只写浅色块会连深色模式一起覆盖(同特异性 + 本文件在 base.css 之后加载)。
2. 只改令牌(下方变量)与「组件微调」段。不要改布局:宽高、margin、padding、
display / flex / grid、position 一律不动 —— 主题不是换皮模板。
3. 本文件不参与构建,仅作参考;真正生效的是同目录下的 <slug>.css。
── 可用的 30 个令牌 ──────────────────────────────────────────────
底色层 --tb-bg 页面底色(html/body)
--tb-surface 卡片、输入框等前景面板
--tb-surface-2 次级面(标签底、进度条轨道、代码块)
--tb-surface-hover 悬停底(列表行、下拉项)
--tb-navbar 顶栏底色(不写则同 --tb-surface;
页面底色不是白时建议覆盖成 bg 或它的同色,否则顶栏会成为一条白带)
线条 --tb-border 边框、分隔线
文字 --tb-text 正文
--tb-text-secondary 次要文字(说明、meta、顶栏链接)
--tb-text-muted 弱化文字(占位、时间戳)
⚠️ 这三个都要满足 WCAG AA 的 4.5:1(对 --tb-bg 与压平后的 --tb-surface 都算)。
往浅调很容易掉到 3:1 以下(旧的 #8a919c 是 3.18:1),肉眼"淡一点"其实已经看不清了。
强调 --tb-primary 主色:链接、主按钮、进度条
--tb-primary-weak 主色 10% 左右的浅底(选中态、标签)
--tb-on-primary 主色作背景时的文字色(默认白字;深色块一般是深字)
主色同时是 14px 链接色,要 ≥4.5:1;但主色越深,
白字压在按钮上越清楚 —— 所以深色模式反而不该用白字。
形状 --tb-radius 卡片 12px / --tb-radius-sm 8px / --tb-radius-xs 6px
阴影 --tb-shadow 卡片默认 / --tb-shadow-hover 悬停
字体 --tb-font 字体栈(一般不改)
--tb-fs-xs 12px 标签、脚注、meta
--tb-fs-md 14px 正文、列表、按钮
--tb-fs-lg 16px 区块小标题、卡片标题
--tb-fs-xl 24px 页面标题、大数字
--tb-fs-hero 28px 首页主标题
这套阶梯 base.css 已统一定义,主题一般不要覆盖:
改一档会连带挤坏所有页面的排版,且与主题要解决的问题无关。
页面背景 --tb-page-image 整页背景图(cover,fixed)
--tb-page-pattern 整页图案(平铺,可叠加在背景图之上)
--tb-page-pattern-size 图案平铺尺寸(默认 auto)
--tb-page-position 背景焦点(cover 裁切时保留哪一侧,默认 center center)
装饰 --tb-deco 装饰图层,固定 10 个槽位(必须写满 10 个,缺的填 none);
适合放人物/摆件/光斑。默认 none。
值可以是图片,也可以是 linear-gradient / radial-gradient(纯"光")。
--tb-deco-size 对应每层的尺寸,如 auto 400px, 100% 100%, auto, …(10 个)
想随视口缩就用 clamp,不要写死 px:
人物/竖幅 auto clamp(min(calc(100vh - 24px), 231px), 46.67vh, 420px)
横幅/场景 clamp(min(calc(100vw - 24px), 587px), 70.57vw, 1067px) auto
内层 min() 是兜底:屏幕小到连下限都放不下时让位给视口。
background-size 的百分比是相对「容器 − 图片」,和 position 不同,
所以用 clamp 比用 % 好推理。
--tb-deco-position 对应每层的位置,如 calc(50% - 524px) calc(100% - 36px), …(10 个)
两值形式(水平 垂直);别用 left/bottom 关键字混搭成三值,
非法时整条声明作废,图层会静默掉回左上角。
── 素材规格(放 R2,不需要重新编译) ─────────────────────────────
页面背景图 2400×1600(3:2)或 2560×1440,WebP q80,≤300KB;明暗各一张:
https://r2.337845818.best/tamabox/themes/<slug>/bg-light.webp
https://r2.337845818.best/tamabox/themes/<slug>/bg-dark.webp
注意:背景图上还要叠卡片和文字,主题要保证「--tb-surface 不透明」
或足够对比;照片类背景建议配 10%~20% 的同色半透明遮罩。
平铺图案 200×200 或 400×400 可无缝平铺,PNG/WebP,≤40KB;
建议透明度 ≤15%,否则会和正文抢注意力。
设置页色块 由本文件浅色块的 --tb-bg 与 --tb-primary 自动生成,无需额外素材。
============================================================================ */
/* 1) 浅色(必须)—— 选择器里的 SLUG 换成文件名 */
html[data-theme-style="SLUG"] {
--tb-bg: #f7f8fa;
--tb-surface: #ffffff;
--tb-surface-2: #f4f6f8;
--tb-surface-hover: #f3f7ff;
--tb-navbar: var(--tb-surface); /* 顶栏底色,需要时改成 var(--tb-bg) */
--tb-border: #e8eaee;
--tb-text: #1f2329;
--tb-text-secondary: #5c6370;
--tb-text-muted: #6b7280; /* AA 下限:白底 4.83:1。别再往浅调 */
--tb-primary: #0e6fd0; /* AA:白底 4.70:1。再浅就只够大号字了 */
--tb-primary-weak: rgba(14, 111, 208, 0.10);
--tb-on-primary: #ffffff;
--tb-radius: 12px;
--tb-radius-sm: 8px;
--tb-radius-xs: 6px;
--tb-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 12px 28px -18px rgba(16, 24, 40, 0.20);
--tb-shadow-hover: 0 1px 2px rgba(16, 24, 40, 0.05), 0 18px 40px -20px rgba(16, 24, 40, 0.28);
--tb-font: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif;
/* 整页背景:两者可同时用,图案叠在图片之上;不需要就保持 none */
--tb-page-image: none;
--tb-page-pattern: none;
--tb-page-pattern-size: auto;
--tb-page-position: center center; /* cover 裁切时保留哪一侧 */
/* 装饰层(放人物/摆件/光)。固定 10 个槽位,必须写满,缺的填 none——
值一多一少,多背景各列表就错位(会出现整页重复同一张图)。
尺寸用「auto <高度>」;位置统一写 calc:
calc(0% + 40px) 左对齐 + 40px
calc(50% + 0px) 居中
calc(100% - 36px) 右/下对齐 - 36px(百分比是相对「容器 − 图片」的剩余空间)
不要用 left / bottom 关键字混搭 —— 「水平居中 + 垂直贴底」会变成三值语法,
一旦写法不合规范整条声明作废,图层静默掉到左上角。 */
--tb-deco: none, none, none, none, none, none, none, none, none, none;
--tb-deco-size: auto, auto, auto, auto, auto, auto, auto, auto, auto, auto;
--tb-deco-position: left top, left top, left top, left top, left top,
left top, left top, left top, left top, left top;
}
/* 2) 深色(必须)—— 深浅两套必须成对,缺一段会让深色用户看到「浅色的深色主题」 */
html[data-theme="dark"][data-theme-style="SLUG"] {
--tb-bg: #1a1d23;
--tb-surface: #242830;
--tb-surface-2: #2d323c;
--tb-surface-hover: rgba(92, 141, 255, 0.12);
--tb-border: #3a404c;
--tb-text: #d8dce4;
--tb-text-secondary: #a8b0bd;
--tb-text-muted: #8b93a1;
--tb-primary: #5c8dff;
--tb-primary-weak: rgba(92, 141, 255, 0.14);
--tb-on-primary: #0b1016; /* 深色主色偏亮,白字只有 3.13:1 */
--tb-shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 12px 28px -18px rgba(0, 0, 0, 0.55);
--tb-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.35), 0 18px 40px -20px rgba(0, 0, 0, 0.65);
--tb-page-image: none;
--tb-page-pattern: none;
--tb-page-pattern-size: auto;
--tb-page-position: center center; /* cover 裁切时保留哪一侧 */
}
/* 3) 按页面作用域覆盖(可选)
服务端会按请求路径给 <html> 打 data-page-scope,取值:
(无属性 = 全局)/ box(箱主页) / question(单题页) / admin(/user/questions)
/ profile(设置页等 /user/* ) / vote(投票页)
典型用法:「问题页正文长,人物退场;题目列表字更密,只留一点光」。
html[data-theme-style="SLUG"][data-page-scope="question"] {
--tb-page-image: none;
--tb-deco: none, none, none, none, none, none, none, none, none, none;
--tb-deco-size: auto, auto, auto, auto, auto, auto, auto, auto, auto, auto;
--tb-deco-position: left top, left top, left top, left top, left top,
left top, left top, left top, left top, left top;
}
⚠️ 覆盖块里同样要写满 10 个槽位。
⚠️ 深色要再写一条三重选择器,否则深色下会被浅色覆盖块污染:
html[data-theme="dark"][data-theme-style="SLUG"][data-page-scope="question"] { … }
⚠️ 没写覆盖块的页面自动沿用全局,不会出现「某页装饰消失」。
首页 / 与 /explore 不加载主题 css,配了也不会生效。 */
/* 4) 组件微调(可选,默认整段注释掉)
只允许「外观」层面的补充:边框、阴影、封面遮罩浓度等。
禁止改尺寸/间距/定位 —— 那属于布局,主题不管。 */
/*
html[data-theme-style="SLUG"] .uk-card-default {
border-color: transparent;
}
html[data-theme-style="SLUG"] .tb-pcard {
box-shadow: var(--tb-shadow);
}
*/