311, 'enabled' => true, 'position' => 'right'];
$list_settings = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_post_list_style_settings() : [];
$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).
$sidebar_width = (int) ($sidebar_cfg['width'] ?? 311);
if ($sidebar_width <= 0 || $sidebar_width === 300) {
$sidebar_width = 311;
}
$sidebar_width = max(200, min(400, $sidebar_width));
$layout_vars = [
'--container' => $content_width,
'--container-wide' => $container_wide,
'--mian-max-width' => $content_width, // legacy typo token
'--sidebar-width' => $sidebar_width . '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'],
'--font-display' => $font_stacks['display'],
'--font-ui' => $font_stacks['ui'],
'--font-heading' => $font_stacks['ui'],
'--aksrt-logo-width' => $logo_width . 'px',
'--nav-height' => '60px',
];
echo '' . "\n";
// 对齐参考主题 zib_head_css():主题色变量与 --main-radius 挂在 body(main.css 的定义层级),
// 夜间主题色仅在单独设置时覆盖 body.dark-theme。
// main.css declares these defaults on body; :root values cannot override them by inheritance.
echo '' . "\n";
if (class_exists('\AKSRT\Settings\Settings')) {
$mobile_meta = sanitize_key((string) ($list_settings['list_meta_show'] ?? 'like'));
if (!in_array($mobile_meta, ['view', 'like', 'comm'], true)) {
$mobile_meta = 'like';
}
echo '' . "\n";
}
// legacy header_theme_custom → --header-bg / --header-color on .header.
if (class_exists('\AKSRT\Settings\Settings')) {
$ht = \AKSRT\Settings\Settings::get_header_theme_config();
if (!empty($ht['custom'])) {
$h_bg = $ht['bg_custom'] !== '' ? $ht['bg_custom'] : ($ht['bg'] ?? '');
$h_fg = $ht['color_custom'] ?? '';
if ($h_bg !== '' || $h_fg !== '') {
echo '' . "\n";
}
}
}
echo '' . "\n";
}
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':
$stack = '"Noto Sans SC", "Source Han Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif';
break;
case 'noto-serif-sc':
$stack = '"Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", SimSun, serif';
break;
case 'custom':
$stack = $custom !== '' ? $custom . ', ' . $system : $system;
break;
default:
$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