diff --git a/assets/admin/src/schema/sections/global/layout.js b/assets/admin/src/schema/sections/global/layout.js
index 2a35fa0e..6be77a22 100644
--- a/assets/admin/src/schema/sections/global/layout.js
+++ b/assets/admin/src/schema/sections/global/layout.js
@@ -1,3 +1,52 @@
+const bgDefault = {
+ color: '',
+ image: '',
+ position: 'center top',
+ repeat: 'no-repeat',
+ attachment: 'fixed',
+ size: '100%',
+ origin: '',
+}
+
+const opts = (pairs) => pairs.map(([value, label]) => ({ label, value }))
+
+// 与 Settings ThemeSearch::background_css() 的白名单一致。
+const bgField = (key, label, help) => ({
+ key,
+ label,
+ type: 'fieldset',
+ default: { ...bgDefault },
+ help,
+ fields: [
+ { key: 'color', label: '背景颜色', type: 'color', default: '' },
+ { key: 'image', label: '背景图片', type: 'media', default: '' },
+ { key: 'position', label: '背景位置', type: 'select', default: 'center top', options: opts([
+ ['', '默认'], ['left top', '左上'], ['left center', '左中'], ['left bottom', '左下'],
+ ['center top', '中上'], ['center center', '居中'], ['center bottom', '中下'],
+ ['right top', '右上'], ['right center', '右中'], ['right bottom', '右下'],
+ ]) },
+ { key: 'repeat', label: '背景重复', type: 'select', default: 'no-repeat', options: opts([
+ ['', '默认'], ['repeat', '重复'], ['no-repeat', '不重复'], ['repeat-x', '水平重复'], ['repeat-y', '垂直重复'],
+ ]) },
+ { key: 'attachment', label: '背景附着', type: 'select', default: 'fixed', options: opts([
+ ['', '默认'], ['scroll', '滚动'], ['fixed', '固定'],
+ ]) },
+ { key: 'size', label: '背景尺寸', type: 'select', default: '100%', options: opts([
+ ['', '默认'], ['100%', '100%'], ['cover', '覆盖 (cover)'], ['contain', '包含 (contain)'], ['auto', '自动 (auto)'],
+ ]) },
+ { key: 'origin', label: '背景原点', type: 'select', default: '', options: opts([
+ ['', '默认'], ['padding-box', 'Padding Box'], ['border-box', 'Border Box'], ['content-box', 'Content Box'],
+ ]) },
+ ],
+})
+
+// palette 的 label 即色块背景色;ff1856 的色块沿用参考主题的 #fd2760。
+const SKIN_PALETTE = [
+ ['ff1856', '#fd2760'], ['f04494', '#f04494'], ['ae53f3', '#ae53f3'], ['627bf5', '#627bf5'],
+ ['00a2e3', '#00a2e3'], ['16b597', '#16b597'], ['36af18', '#36af18'], ['8fb107', '#8fb107'],
+ ['b18c07', '#b18c07'], ['e06711', '#e06711'], ['f74735', '#f74735'],
+].map(([value, label]) => ({ label, value }))
+
export const layoutSchema = {
key: 'global.layout',
title: '显示 & 布局',
@@ -6,10 +55,12 @@ export const layoutSchema = {
defaults: {
theme_mode: 'time-auto',
theme_mode_button: ['pc_nav', 'm_menu'],
- primary_color: '#1890ff',
+ theme_img_bg: { ...bgDefault },
+ dark_theme_img_bg: { ...bgDefault },
+ theme_skin_custom: '',
theme_skin: 'f04494',
- dark_primary_color: '',
- border_radius: 8,
+ dark_theme_skin_custom: '',
+ close_backdrop: false,
theme_main_radius: 12,
container_max_width: 1200,
sidebar_enabled: true,
@@ -22,6 +73,7 @@ export const layoutSchema = {
sidebar_page_enabled: true,
sidebar_search_enabled: true,
font_family: 'system',
+ font_family_custom: '',
qj_loading: false,
qj_dh_xs: 'no1',
},
@@ -61,50 +113,41 @@ export const layoutSchema = {
fields: [
{
key: 'theme_mode',
- label: '默认主题模式',
+ label: '主题模式',
type: 'radio',
default: 'time-auto',
options: [
- { label: '浅色', value: 'white-theme' },
- { label: '深色', value: 'dark-theme' },
- { label: '跟随系统', value: 'time-auto' },
+ { label: '日间亮色主题', value: 'white-theme' },
+ { label: '夜间深色主题', value: 'dark-theme' },
+ { label: '早晚8点自动切换', value: 'time-auto' },
],
+ help: '此处设置为默认风格,实际显示风格以用户设置优先。如需固定风格,则关闭还需下方主题切换按钮',
},
{
key: 'theme_mode_button',
- label: '主题切换按钮位置',
+ label: '主题切换按钮',
type: 'checkbox',
default: ['pc_nav', 'm_menu'],
options: [
- { label: 'PC 顶部导航', value: 'pc_nav' },
- { label: '移动端菜单', value: 'm_menu' },
+ { label: 'PC端顶部导航', value: 'pc_nav' },
+ { label: '移动端弹出菜单', value: 'm_menu' },
],
- help: '控制主题切换按钮在哪些位置显示',
+ help: '如果关闭此功能,则前端不会显示切换按钮',
},
- { key: 'primary_color', label: '主题色', type: 'color', default: '#f04494', help: '按钮、链接和强调元素的主色调' },
+ bgField('theme_img_bg', '全局背景图', '注意:要达到良好的效果需要图片与参数配合,同时需注意颜色搭配!配合不好容易降低显示美感'),
+ bgField('dark_theme_img_bg', '夜间模式背景图', '如未设置夜间模式背景图,则夜间模式也显示上方背景图'),
+ { key: 'theme_skin_custom', label: '全局主题色', type: 'color', default: '', help: '默认主题高亮颜色。如需选择下方预置颜色,请先清空上方颜色' },
{
key: 'theme_skin',
- label: '预设主题色',
+ label: ' ',
type: 'palette',
default: 'f04494',
- options: [
- { label: '玫红', value: 'ff1856' },
- { label: '粉色', value: 'f04494' },
- { label: '紫色', value: 'ae53f3' },
- { label: '靛蓝', value: '627bf5' },
- { label: '天蓝', value: '00a2e3' },
- { label: '青绿', value: '16b597' },
- { label: '翠绿', value: '36af18' },
- { label: '黄绿', value: '8fb107' },
- { label: '棕金', value: 'b18c07' },
- { label: '橘橙', value: 'e06711' },
- { label: '朱红', value: 'f74735' },
- ],
- help: '选择预设主题色,将覆盖上方自定义主题色',
+ dependsOn: { key: 'theme_skin_custom', operator: 'empty' },
+ options: SKIN_PALETTE,
},
- { key: 'dark_primary_color', label: '暗色模式主题色', type: 'color', default: '', help: '暗色模式下独立的主题色,留空则跟随浅色模式' },
- { key: 'border_radius', label: '全局圆角 (px)', type: 'slider', min: 0, max: 20, step: 1, default: 8 },
- { key: 'theme_main_radius', label: '卡片圆角 (px)', type: 'number', min: 0, max: 30, default: 12, help: '独立卡片圆角,留空则使用全局圆角 +4' },
+ { key: 'dark_theme_skin_custom', label: '夜间模式主题色', type: 'color', default: '', help: '在此可单独设置夜间模式的高亮色,清空此处则使用上方默认高亮色' },
+ { key: 'close_backdrop', label: '全局关闭背景高斯模糊', type: 'switch', default: false, help: '在支持的浏览器上部分UI(例如导航栏)会显示背景高斯模糊的特效,但此功能比较消耗浏览器性能。同时系统会自动检测用户浏览器性能情况,如果性能较差,将自动关闭此特效,以提供更流畅的体验' },
+ { key: 'theme_main_radius', label: '卡片圆角', type: 'spinner', default: 12, min: 0, max: 30, step: 1, unit: 'PX', description: '页面卡片的圆角尺寸' },
],
},
{
@@ -112,16 +155,7 @@ export const layoutSchema = {
title: '布局设置',
icon: 'fa fas fa-columns',
fields: [
- { key: 'container_max_width', label: '内容最大宽度 (px)', type: 'select', default: 1200, options: [
- { label: '1200px', value: 1200 },
- { label: '1320px', value: 1320 },
- { label: '1440px', value: 1440 },
- { label: '1600px', value: 1600 },
- { label: '1800px', value: 1800 },
- { label: '2000px', value: 2000 },
- { label: '2200px', value: 2200 },
- { label: '全宽', value: 0 },
- ]},
+ { key: 'container_max_width', label: '内容最大宽度', type: 'number', default: 1200, min: 1200, max: 2200, step: 50, unit: 'PX', help: '页面布局的最大宽度,可设置 1200–2200PX。宽度过大会造成显示不协调,非特殊需求请勿调整。' },
{ key: 'sidebar_enabled', label: '开启侧边栏', type: 'switch', default: true },
{ key: 'sidebar_position', label: '侧边栏位置', type: 'radio', default: 'right', dependsOn: { key: 'sidebar_enabled', value: true }, options: [
{ label: '左侧', value: 'left' },
@@ -153,7 +187,8 @@ export const layoutSchema = {
{ label: '思源黑体', value: 'noto-sans-sc' },
{ label: '思源宋体', value: 'noto-serif-sc' },
{ label: '自定义', value: 'custom' },
- ]},
+ ], help: '思源字体不会远程加载,访客设备未安装时回退到系统字体。' },
+ { key: 'font_family_custom', label: '自定义字体', type: 'input', default: '', placeholder: '例如:"LXGW WenKai", "PingFang SC", sans-serif', dependsOn: { key: 'font_family', value: 'custom' }, help: 'CSS font-family 字体栈,多个字体用英文逗号分隔;留空使用系统字体。' },
],
},
],
diff --git a/src/Admin/Schema/GlobalSchema.php b/src/Admin/Schema/GlobalSchema.php
index b2912999..cc1fa3cf 100644
--- a/src/Admin/Schema/GlobalSchema.php
+++ b/src/Admin/Schema/GlobalSchema.php
@@ -101,38 +101,26 @@ class GlobalSchema {
'option_key' => 'aksrt_settings',
'groups' => [
['key' => 'color', 'title' => '色彩方案', 'fields' => [
- ['key' => 'theme_mode', 'label' => '默认主题模式', 'type' => 'radio', 'default' => 'time-auto', 'options' => [
- ['label' => '浅色', 'value' => 'white-theme'],
- ['label' => '深色', 'value' => 'dark-theme'],
- ['label' => '跟随系统', 'value' => 'time-auto'],
+ ['key' => 'theme_mode', 'label' => '主题模式', 'type' => 'radio', 'default' => 'time-auto', 'help' => '此处设置为默认风格,实际显示风格以用户设置优先。如需固定风格,则关闭还需下方主题切换按钮', 'options' => [
+ ['label' => '日间亮色主题', 'value' => 'white-theme'],
+ ['label' => '夜间深色主题', 'value' => 'dark-theme'],
+ ['label' => '早晚8点自动切换', 'value' => 'time-auto'],
]],
- ['key' => 'theme_mode_button', 'label' => '主题切换按钮位置', 'type' => 'checkbox', 'default' => ['pc_nav', 'm_menu'], 'options' => [
- ['label' => 'PC 顶部导航', 'value' => 'pc_nav'],
- ['label' => '移动端菜单', 'value' => 'm_menu'],
+ ['key' => 'theme_mode_button', 'label' => '主题切换按钮', 'type' => 'checkbox', 'default' => ['pc_nav', 'm_menu'], 'help' => '如果关闭此功能,则前端不会显示切换按钮', 'options' => [
+ ['label' => 'PC端顶部导航', 'value' => 'pc_nav'],
+ ['label' => '移动端弹出菜单', 'value' => 'm_menu'],
]],
- ['key' => 'theme_skin', 'label' => '预设主题色', 'type' => 'palette', 'default' => 'f04494', 'options' => [
- ['label' => '玫红', 'value' => 'ff1856'],
- ['label' => '粉色', 'value' => 'f04494'],
- ['label' => '紫色', 'value' => 'ae53f3'],
- ['label' => '靛蓝', 'value' => '627bf5'],
- ['label' => '天蓝', 'value' => '00a2e3'],
- ['label' => '青绿', 'value' => '16b597'],
- ['label' => '翠绿', 'value' => '36af18'],
- ['label' => '黄绿', 'value' => '8fb107'],
- ['label' => '棕金', 'value' => 'b18c07'],
- ['label' => '橘橙', 'value' => 'e06711'],
- ['label' => '朱红', 'value' => 'f74735'],
- ]],
- ['key' => 'primary_color', 'label' => '自定义主题色', 'type' => 'color', 'default' => '#f04494'],
- ['key' => 'dark_primary_color', 'label' => '暗色模式主题色', 'type' => 'color', 'default' => '#f04494'],
- ['key' => 'border_radius', 'label' => '全局圆角', 'type' => 'slider', 'default' => 8, 'min' => 0, 'max' => 20],
- ['key' => 'theme_main_radius', 'label' => '卡片圆角 (px)', 'type' => 'number', 'default' => 12, 'min' => 0, 'max' => 30, 'help' => '独立卡片圆角,不填则使用全局圆角 +4'],
- ['key' => 'close_backdrop', 'label' => '关闭毛玻璃效果', 'type' => 'switch', 'default' => false],
+ self::background_field('theme_img_bg', '全局背景图', '注意:要达到良好的效果需要图片与参数配合,同时需注意颜色搭配!配合不好容易降低显示美感'),
+ self::background_field('dark_theme_img_bg', '夜间模式背景图', '如未设置夜间模式背景图,则夜间模式也显示上方背景图'),
+ ['key' => 'theme_skin_custom', 'label' => '全局主题色', 'type' => 'color', 'default' => '', 'help' => '默认主题高亮颜色。如需选择下方预置颜色,请先清空上方颜色'],
+ ['key' => 'theme_skin', 'label' => ' ', 'type' => 'palette', 'default' => 'f04494', 'dependsOn' => ['key' => 'theme_skin_custom', 'operator' => 'empty'], 'options' => self::skin_palette()],
+ ['key' => 'dark_theme_skin_custom', 'label' => '夜间模式主题色', 'type' => 'color', 'default' => '', 'help' => '在此可单独设置夜间模式的高亮色,清空此处则使用上方默认高亮色'],
+ ['key' => 'close_backdrop', 'label' => '全局关闭背景高斯模糊', 'type' => 'switch', 'default' => false, 'help' => '在支持的浏览器上部分UI(例如导航栏)会显示背景高斯模糊的特效,但此功能比较消耗浏览器性能。同时系统会自动检测用户浏览器性能情况,如果性能较差,将自动关闭此特效,以提供更流畅的体验'],
+ ['key' => 'theme_main_radius', 'label' => '卡片圆角', 'type' => 'spinner', 'default' => 12, 'min' => 0, 'max' => 30, 'step' => 1, 'unit' => 'PX', 'description' => '页面卡片的圆角尺寸'],
]],
['key' => 'layout', 'title' => '布局设置', 'fields' => [
- // 0(全宽)与 1200–2200 与设置页下拉选项、Settings::container_max_width() 归一化区间一致;
- // 上限低于 UI 可选项会让后台保存被校验拒绝,页面宽度卡在旧值。
- ['key' => 'container_max_width', 'label' => '内容最大宽度', 'type' => 'number', 'default' => 1200, 'min' => 0, 'max' => 2200],
+ // 1200–2200 与 Settings::container_max_width() 归一化区间一致。
+ ['key' => 'container_max_width', 'label' => '内容最大宽度', 'type' => 'number', 'default' => 1200, 'min' => 1200, 'max' => 2200, 'step' => 50, 'unit' => 'PX'],
['key' => 'sidebar_enabled', 'label' => '开启侧边栏', 'type' => 'switch', 'default' => true],
['key' => 'sidebar_position', 'label' => '侧边栏位置', 'type' => 'radio', 'default' => 'right', 'options' => [
['label' => '左侧', 'value' => 'left'],
@@ -153,6 +141,7 @@ class GlobalSchema {
['label' => '思源宋体', 'value' => 'noto-serif-sc'],
['label' => '自定义', 'value' => 'custom'],
]],
+ ['key' => 'font_family_custom', 'label' => '自定义字体', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'font_family', 'value' => 'custom']],
]],
['key' => 'performance', 'title' => '性能优化', 'fields' => [
['key' => 'qj_loading', 'label' => '全站加载动画', 'type' => 'switch', 'default' => false],
@@ -458,4 +447,57 @@ class GlobalSchema {
],
];
}
+ /** 与 assets/admin/src/schema/sections/global/layout.js 的 skinPalette 保持一致;label 即色块颜色。 */
+ private static function skin_palette(): array {
+ $map = [
+ 'ff1856' => '#fd2760', 'f04494' => '#f04494', 'ae53f3' => '#ae53f3', '627bf5' => '#627bf5',
+ '00a2e3' => '#00a2e3', '16b597' => '#16b597', '36af18' => '#36af18', '8fb107' => '#8fb107',
+ 'b18c07' => '#b18c07', 'e06711' => '#e06711', 'f74735' => '#f74735',
+ ];
+ $options = [];
+ foreach ($map as $value => $label) {
+ $options[] = ['label' => $label, 'value' => (string) $value];
+ }
+ return $options;
+ }
+
+ /** 背景图配置(对齐参考主题 background 字段:颜色/图片/位置/重复/附着/尺寸/原点)。 */
+ private static function background_field(string $key, string $label, string $help): array {
+ $opts = static function (array $map): array {
+ $out = [['label' => '默认', 'value' => '']];
+ foreach ($map as $value => $text) {
+ $out[] = ['label' => $text, 'value' => $value];
+ }
+ return $out;
+ };
+ return [
+ 'key' => $key, 'label' => $label, 'type' => 'fieldset', 'help' => $help,
+ // 子键与 layout.js bgField 及 ThemeSearch::background_css() 白名单一致。
+ 'default' => [
+ 'color' => '', 'image' => '', 'position' => 'center top',
+ 'repeat' => 'no-repeat', 'attachment' => 'fixed', 'size' => '100%', 'origin' => '',
+ ],
+ 'fields' => [
+ ['key' => 'color', 'label' => '背景颜色', 'type' => 'color', 'default' => ''],
+ ['key' => 'image', 'label' => '背景图片', 'type' => 'media', 'default' => ''],
+ ['key' => 'position', 'label' => '背景位置', 'type' => 'select', 'default' => 'center top', 'options' => $opts([
+ 'left top' => '左上', 'left center' => '左中', 'left bottom' => '左下',
+ 'center top' => '中上', 'center center' => '居中', 'center bottom' => '中下',
+ 'right top' => '右上', 'right center' => '右中', 'right bottom' => '右下',
+ ])],
+ ['key' => 'repeat', 'label' => '背景重复', 'type' => 'select', 'default' => 'no-repeat', 'options' => $opts([
+ 'repeat' => '重复', 'no-repeat' => '不重复', 'repeat-x' => '水平重复', 'repeat-y' => '垂直重复',
+ ])],
+ ['key' => 'attachment', 'label' => '背景附着', 'type' => 'select', 'default' => 'fixed', 'options' => $opts([
+ 'scroll' => '滚动', 'fixed' => '固定',
+ ])],
+ ['key' => 'size', 'label' => '背景尺寸', 'type' => 'select', 'default' => '100%', 'options' => $opts([
+ '100%' => '100%', 'cover' => '覆盖 (cover)', 'contain' => '包含 (contain)', 'auto' => '自动 (auto)',
+ ])],
+ ['key' => 'origin', 'label' => '背景原点', 'type' => 'select', 'default' => '', 'options' => $opts([
+ 'padding-box' => 'Padding Box', 'border-box' => 'Border Box', 'content-box' => 'Content Box',
+ ])],
+ ],
+ ];
+ }
}
diff --git a/src/Core/ScriptsPart2.php b/src/Core/ScriptsPart2.php
index 60ad71a1..dee1a085 100644
--- a/src/Core/ScriptsPart2.php
+++ b/src/Core/ScriptsPart2.php
@@ -112,6 +112,11 @@ trait ScriptsPart2 {
$classes[] = 'auth-page';
}
+ // 对齐参考主题 close_backdrop:fps-accelerat 由 main.css 统一关闭 backdrop-filter。
+ if (class_exists('\AKSRT\Settings\Settings') && \AKSRT\Settings\Settings::close_backdrop()) {
+ $classes[] = 'fps-accelerat';
+ }
+
// legacy site-layout-1/2/3 (no sidebar / right / left).
if (function_exists('aksrt_body_layout_classes')) {
foreach (aksrt_body_layout_classes() as $layout_class) {
diff --git a/src/Frontend/InlineStyleBuilder.php b/src/Frontend/InlineStyleBuilder.php
index b968f406..4e67c934 100644
--- a/src/Frontend/InlineStyleBuilder.php
+++ b/src/Frontend/InlineStyleBuilder.php
@@ -13,28 +13,18 @@ class InlineStyleBuilder {
$logo_url = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::logo_url() : (string) aksrt_get_setting('logo_url', '');
$dark_logo_url = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::logo_dark_url() : (string) aksrt_get_setting('site_logo_dark', '');
$favicon = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::favicon_url() : (string) aksrt_get_setting('favicon_url', '');
- $primary_color = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::resolved_primary_color() : '#f04494';
- $dark_primary = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::dark_primary_color() : '#f04494';
- $border_radius = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::border_radius() : 8;
- $card_radius = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::card_radius() : ($border_radius + 4);
+ $primary_color = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::theme_color() : '#f04494';
+ $dark_primary = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::dark_theme_color() : '';
+ $main_radius = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::main_radius() : 12;
$container_max = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::container_max_width() : 1200;
$font_family = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::font_family() : 'system';
$logo_width = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::logo_width() : 150;
$sidebar_cfg = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_sidebar_config() : ['width' => 311, 'enabled' => true, 'position' => 'right'];
- $content_width = $container_max === 0 ? '100%' : $container_max . 'px';
- $container_wide = $container_max === 0 ? '100%' : max(1280, $container_max + 160) . 'px';
- $radius_sm = max(0, $border_radius - 2);
- $radius_lg = $border_radius + 4;
- $radius_xl = $border_radius + 10;
- $rgb = $this->hex_to_rgb($primary_color);
- $primary_hover = $this->adjust_hex_color($primary_color, -0.12);
- $primary_active = $this->adjust_hex_color($primary_color, -0.22);
- $font_stacks = $this->resolve_font_stacks($font_family);
-
- $dark_rgb = $this->hex_to_rgb($dark_primary);
- $dark_hover = $this->adjust_hex_color($dark_primary, -0.12);
- $dark_active = $this->adjust_hex_color($dark_primary, -0.22);
+ $content_width = $container_max . 'px';
+ $container_wide = max(1280, $container_max + 160) . 'px';
+ $font_custom = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::font_family_custom() : '';
+ $font_stacks = $this->resolve_font_stacks($font_family, $font_custom);
// legacy hard-codes 311px dual-column math; keep runtime width aligned to that
// baseline when settings still hold the old 300 default (or empty).
@@ -49,22 +39,7 @@ class InlineStyleBuilder {
'--container-wide' => $container_wide,
'--mian-max-width' => $content_width, // legacy typo token
'--sidebar-width' => $sidebar_width . 'px',
- '--color-primary' => $primary_color,
- '--color-primary-hover' => $primary_hover,
- '--color-primary-active' => $primary_active,
- '--color-primary-soft' => sprintf('rgba(%d, %d, %d, 0.12)', $rgb[0], $rgb[1], $rgb[2]),
- '--color-primary-softer' => sprintf('rgba(%d, %d, %d, 0.06)', $rgb[0], $rgb[1], $rgb[2]),
- '--color-primary-rgb' => implode(', ', $rgb),
- '--focus-color' => $primary_color,
- '--radius-sm' => $radius_sm . 'px',
- '--radius' => $border_radius . 'px',
- '--radius-card' => $card_radius . 'px',
- // legacy --main-radius tracks the base radius (8), not the larger card radius.
- '--main-radius' => $border_radius . 'px',
- '--radius-btn' => $border_radius . 'px',
- '--radius-code' => $border_radius . 'px',
- '--radius-lg' => $radius_lg . 'px',
- '--radius-xl' => $radius_xl . 'px',
+ '--radius-card' => $main_radius . 'px',
'--shadow-md' => '0 8px 24px rgba(20, 28, 48, 0.10)',
'--main-shadow' => 'rgba(116, 116, 116, 0.08)',
'--font-body' => $font_stacks['body'],
@@ -79,7 +54,9 @@ class InlineStyleBuilder {
echo '' . "\n";
+ // 对齐参考主题 zib_head_css():主题色变量与 --main-radius 挂在 body(main.css 的定义层级),
+ // 夜间主题色仅在单独设置时覆盖 body.dark-theme。
+ echo '' . "\n";
+
if (class_exists('\AKSRT\Settings\Settings')) {
$list_settings = \AKSRT\Settings\Settings::get_post_list_style_settings();
$mobile_meta = sanitize_key((string) ($list_settings['list_meta_show'] ?? 'like'));
@@ -130,9 +115,6 @@ class InlineStyleBuilder {
}
}
- if (class_exists('\AKSRT\Settings\Settings') && !empty(\AKSRT\Settings\Settings::get_value('close_backdrop', false))) {
- echo '' . "\n";
- }
echo '' . "\n";
}
- private function resolve_font_stacks(string $family): array {
+ private function resolve_font_stacks(string $family, string $custom = ''): array {
+ // Same system stack as tokens.css; "system" must not swap in a serif face.
+ $system = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif';
switch ($family) {
case 'noto-sans-sc':
- return [
- 'body' => '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
- 'display' => '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
- 'ui' => 'Inter, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
- ];
+ $stack = '"Noto Sans SC", "Source Han Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif';
+ break;
case 'noto-serif-sc':
- return [
- 'body' => '"Noto Serif SC", Georgia, "Songti SC", serif',
- 'display' => '"Noto Serif SC", Georgia, "Songti SC", serif',
- 'ui' => 'Inter, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
- ];
+ $stack = '"Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", SimSun, serif';
+ break;
+ case 'custom':
+ $stack = $custom !== '' ? $custom . ', ' . $system : $system;
+ break;
default:
- return [
- 'body' => '"Source Serif 4", "Noto Serif SC", Georgia, "Songti SC", "STSong", serif',
- 'display' => '"Source Serif 4", "Noto Serif SC", Georgia, "Songti SC", "STSong", serif',
- 'ui' => 'Inter, Manrope, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
- ];
+ $stack = $system;
}
+ return ['body' => $stack, 'display' => $stack, 'ui' => $stack];
+ }
+
+ /** 参考主题色变量族(--theme-color / --focus-* 透明度)+ AKSRT --color-primary* 族;$hex 已由 Settings 校验。 */
+ private function theme_color_vars(string $hex): string {
+ $rgb = $this->hex_to_rgb($hex);
+ $rgba = static function (float $alpha) use ($rgb): string {
+ return sprintf('rgba(%d,%d,%d,%s)', $rgb[0], $rgb[1], $rgb[2], $alpha);
+ };
+ $vars = [
+ '--theme-color' => $hex,
+ '--focus-color' => $hex,
+ '--focus-shadow-color' => $rgba(0.4),
+ '--focus-color-opacity1' => $rgba(0.1),
+ '--focus-color-opacity05' => $rgba(0.05),
+ '--focus-color-opacity3' => $rgba(0.3),
+ '--focus-color-opacity6' => $rgba(0.6),
+ '--color-primary' => $hex,
+ '--color-primary-hover' => $this->adjust_hex_color($hex, -0.12),
+ '--color-primary-active' => $this->adjust_hex_color($hex, -0.22),
+ '--color-primary-soft' => $rgba(0.12),
+ '--color-primary-softer' => $rgba(0.06),
+ '--color-primary-rgb' => implode(', ', $rgb),
+ ];
+ $css = '';
+ foreach ($vars as $name => $value) {
+ $css .= $name . ':' . $this->css_value($value) . ';';
+ }
+ return $css;
+ }
+
+ /** CSS-context escape for custom property values inside a