原来的生成器只能配「背景 + 人物 + 道具」三件套,预览还是自己画的仿制页面 —— 跟真实页面不像,也没法给不同页面配不同内容。 机制层: - internal/context.pageScope() 按路径归类,输出 <html data-page-scope>: box / question / admin / profile / vote(首页与 /explore 不加载主题,不列) - /user/questions 单独归为 admin:题目列表信息密,和设置表单的装饰诉求不同 - base.css 装饰槽位 6 -> 10,背景 8 层 -> 12 层;主题按作用域覆盖时同样写满 10 个 - 新增 TestDecoSlotCount:逐文件逐声明检查 10 个值。少写一个不报错, 只会让图层与 size/position 错位(整页重复同一张图 / 人物跑到左上角),注释守不住 生成器: - 画板改成 iframe 加载 outputs/preview-*.html(真实模板渲染),配 serve.py 起本地服务 解决 file:// 下父页面读不到 iframe DOM 的问题 - 八个页面作用域(去掉不生效的首页/探索),每个可独立配背景与最多 10 层装饰 - 图层类型:图片 / 径向光斑 / 线性光;9 宫格锚点 + 像素偏移,可在画板上直接拖 - 位置统一写 calc(0%|50%|100% ± Npx):百分比是相对 (容器-图片), 不用 left/bottom 关键字混搭,避免三值语法非法导致整条声明作废 - 配色只填 6 个基础色,其余 4 个必需令牌按方向派生(surface-2 往 text 靠, 浅色变深、深色变亮,方向自动正确) 配套: - zz_preview_test.go 增加单题页 / 题目列表 / 投票页预览,作为生成器画板 - docs/theme-page-scope.md 记录作用域取值、选择器特异性与 10 槽位约束 - StaticVersion 20261020e(base.css 变了) 验证:生成器导出的 CSS 通过 TestThemeCSSComplete + TestDecoSlotCount; 真实箱主页计算样式为 12 层对齐;临时主题验证「question 覆盖为 none」生效、 未覆盖时回退全局。
136 lines
6.7 KiB
CSS
136 lines
6.7 KiB
CSS
/* 砂狼白子(shiroko):阿拜多斯学园的灰蓝/银白配色。
|
|
只覆盖令牌与外观层面的组件微调,不改任何布局。
|
|
|
|
做法参考二次元官网(蔚蓝档案 JP 首页)的构图:**整个视口是一张场景插画,UI 浮在场景之上**,
|
|
而不是"白底 + 留白里贴几个人"。这里用一张教室场景(压白 38%)当整页背景,
|
|
卡片与顶栏改成磨砂半透明,人物站在场景左侧地面 —— 人物有环境,才不像贴纸。
|
|
|
|
素材(static/images/themes/shiroko/):
|
|
- scene-desktop.webp / scene-mobile.webp 教室场景(16:9 / 9:16,已压白与轻度虚化)
|
|
- chibi/window.webp 人物(侧后方视角、双手背在身后,已抠白底并压白 16%)
|
|
- pattern.svg / pattern-dark.svg 雪花 + 光环的极淡平铺纹样(深色模式用)
|
|
来源、提示词与处理参数见 docs/theme-shiroko.md。 */
|
|
html[data-theme-style="shiroko"] {
|
|
--tb-bg: #eef3f9;
|
|
/* 磨砂卡片:半透明白 + backdrop-filter,让场景的颜色透上来一点点 */
|
|
--tb-surface: rgba(255, 255, 255, 0.86);
|
|
--tb-surface-2: rgba(229, 236, 245, 0.92);
|
|
--tb-surface-hover: rgba(234, 241, 249, 0.92);
|
|
--tb-navbar: rgba(255, 255, 255, 0.52);
|
|
--tb-border: #d6e0ec;
|
|
|
|
--tb-text: #222d3b;
|
|
--tb-text-secondary: #51607a;
|
|
--tb-text-muted: #8794a7;
|
|
|
|
--tb-primary: #4a7fc1;
|
|
--tb-primary-weak: rgba(74, 127, 193, 0.11);
|
|
|
|
--tb-shadow: 0 1px 2px rgba(38, 56, 82, 0.05), 0 18px 44px -22px rgba(38, 56, 82, 0.30);
|
|
--tb-shadow-hover: 0 1px 2px rgba(38, 56, 82, 0.07), 0 24px 56px -24px rgba(38, 56, 82, 0.38);
|
|
|
|
/* 整页场景:一张教室插画,cover 铺满;不再叠纹样(纹样压在实景上会变成噪点) */
|
|
--tb-page-image: url("/static/images/themes/shiroko/scene-desktop.webp?v=20261020d");
|
|
--tb-page-pattern: none;
|
|
|
|
/* 人物:侧后方视角、双手背在身后望向箱内(不是正面盯着访客),
|
|
站在场景左侧地面,离底边 36px,配一层椭圆接触阴影,避免悬空。
|
|
图已压白 12%,与压白 38% 的场景同一"雾度",避免变成高对比贴纸。
|
|
|
|
槽位 3 是她的自行车(车头朝右,与人同向,斜靠着一把步枪,自带接触阴影)。
|
|
它必须和人物用**同一套定位公式**,否则视口一变两件东西就分家了——
|
|
所以不能烘焙进背景图里。
|
|
|
|
其余 3 个槽位是"空气"(纯渐变):4 左窗光柱 / 5 地面光斑 / 6 底部轻压深。 */
|
|
--tb-deco: url("/static/images/themes/shiroko/chibi/window.webp?v=20261020d"),
|
|
radial-gradient(ellipse at center, rgba(63, 96, 138, 0.18) 0%, rgba(63, 96, 138, 0) 72%),
|
|
url("/static/images/themes/shiroko/props/bike.webp?v=20261020d"),
|
|
linear-gradient(112deg, rgba(255, 250, 236, 0.50) 0%, rgba(255, 250, 236, 0.22) 20%, rgba(255, 250, 236, 0) 44%),
|
|
radial-gradient(ellipse 560px 170px at 28% 94%, rgba(255, 248, 228, 0.80) 0%, rgba(255, 248, 228, 0) 72%),
|
|
linear-gradient(0deg, rgba(110, 128, 156, 0.10) 0%, rgba(110, 128, 156, 0) 24%),
|
|
none, none, none, none;
|
|
--tb-deco-size: auto 400px, 96px 13px, auto 259px, 100% 100%, 100% 100%, 100% 100%,
|
|
auto, auto, auto, auto;
|
|
--tb-deco-position: left max(10px, calc(50% - 524px)) bottom 36px,
|
|
left max(22px, calc(50% - 512px)) bottom 29px,
|
|
left calc(50% - 612px) bottom 20px,
|
|
left top, left top, left top,
|
|
left top, left top, left top, left top;
|
|
}
|
|
|
|
html[data-theme="dark"][data-theme-style="shiroko"] {
|
|
--tb-bg: #141a22;
|
|
--tb-surface: #1d2530;
|
|
--tb-surface-2: #273140;
|
|
--tb-surface-hover: rgba(111, 163, 224, 0.12);
|
|
--tb-navbar: #141a22;
|
|
--tb-border: #334052;
|
|
|
|
--tb-text: #e3eaf4;
|
|
--tb-text-secondary: #a6b4c8;
|
|
--tb-text-muted: #77869b;
|
|
|
|
--tb-primary: #6fa3e0;
|
|
--tb-primary-weak: rgba(111, 163, 224, 0.16);
|
|
|
|
--tb-shadow: 0 1px 2px rgba(0, 0, 0, 0.34), 0 12px 28px -18px rgba(0, 0, 0, 0.58);
|
|
--tb-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.40), 0 18px 40px -20px rgba(0, 0, 0, 0.68);
|
|
|
|
/* 深色不用浅色场景(白天教室压在深底上会很脏),回到纯色渐变 + 极淡纹样 */
|
|
--tb-page-image: linear-gradient(180deg, #161d26 0%, #141a22 60%, #11161d 100%);
|
|
--tb-page-pattern: url("/static/images/themes/shiroko/pattern-dark.svg?v=20261020d");
|
|
--tb-page-pattern-size: 340px 340px;
|
|
--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;
|
|
}
|
|
|
|
/* 窄屏:卡片占满宽度,两侧没有视觉空间 —— 换成竖版场景,人物退场 */
|
|
@media (max-width: 900px) {
|
|
html[data-theme-style="shiroko"] {
|
|
--tb-page-image: url("/static/images/themes/shiroko/scene-mobile.webp?v=20261020d");
|
|
--tb-surface: rgba(255, 255, 255, 0.92);
|
|
--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;
|
|
}
|
|
}
|
|
|
|
/* 组件微调(仅外观) */
|
|
|
|
/* 磨砂:卡片与顶栏让场景透上来,才像"UI 浮在画面上"而不是压在照片上 */
|
|
html[data-theme-style="shiroko"] .uk-card-default {
|
|
backdrop-filter: blur(16px) saturate(1.05);
|
|
-webkit-backdrop-filter: blur(16px) saturate(1.05);
|
|
box-shadow: 0 0 0 1px rgba(74, 127, 193, 0.12), var(--tb-shadow);
|
|
}
|
|
html[data-theme-style="shiroko"] .uk-card-default.uk-card-hover:hover {
|
|
box-shadow: 0 0 0 1px rgba(74, 127, 193, 0.18), var(--tb-shadow-hover);
|
|
}
|
|
html[data-theme-style="shiroko"] .uk-navbar-container:not(.uk-navbar-transparent) {
|
|
background-color: var(--tb-navbar);
|
|
backdrop-filter: blur(14px) saturate(1.1);
|
|
-webkit-backdrop-filter: blur(14px) saturate(1.1);
|
|
}
|
|
|
|
/* 深色不用半透明(背后没有场景,半透明只会让层次变浑),也不加模糊 */
|
|
html[data-theme="dark"][data-theme-style="shiroko"] .uk-card-default {
|
|
backdrop-filter: none;
|
|
-webkit-backdrop-filter: none;
|
|
box-shadow: 0 0 0 1px rgba(111, 163, 224, 0.14), var(--tb-shadow);
|
|
}
|
|
html[data-theme="dark"][data-theme-style="shiroko"] .uk-navbar-container:not(.uk-navbar-transparent) {
|
|
backdrop-filter: none;
|
|
-webkit-backdrop-filter: none;
|
|
}
|
|
|
|
/* 顶栏融进场景后,UIkit 默认的 #999 偏淡,提到次要文字色 */
|
|
html[data-theme-style="shiroko"] .uk-navbar-nav > li > a {
|
|
color: var(--tb-text-secondary);
|
|
}
|
|
html[data-theme-style="shiroko"] .uk-navbar-nav > li > a:hover {
|
|
color: var(--tb-primary);
|
|
}
|