<?php
/**
 * 模板变异引擎 (Template Variation Engine)
 * 同一模板套件在不同域名下生成结构差异化的 HTML，提升 SEO 独立性。
 *
 * 变异维度：
 *   1. CSS 色彩方案（主色/辅色/强调色/背景）
 *   2. 字体组合（标题字体 + 正文字体）
 *   3. 间距节奏（紧凑/标准/宽松）
 *   4. 圆角风格（直角/小圆角/大圆角/药丸）
 *   5. CSS 类名前缀（每域名唯一前缀）
 *   6. 首页模块顺序重排
 *   7. 语义标签变体（section/div/article 等）
 *   8. 文章页布局变异（侧栏位置/正文字号/行高/段间距/标题样式）
 *
 * 所有变异基于 domain_id 确定性哈希，同域名始终产出相同结果。
 */

// ──────────────────────────────────────────────
// 1. 预设色彩方案（12 组）
// ──────────────────────────────────────────────
function variation_color_schemes()
{
    return array(
        array('--v-primary' => '#2563eb', '--v-primary-dark' => '#1d4ed8', '--v-primary-light' => '#dbeafe', '--v-accent' => '#f59e0b', '--v-bg-subtle' => '#f8fafc', '--v-dark-bg' => '#0a1628'),
        array('--v-primary' => '#059669', '--v-primary-dark' => '#047857', '--v-primary-light' => '#d1fae5', '--v-accent' => '#8b5cf6', '--v-bg-subtle' => '#f0fdf4', '--v-dark-bg' => '#0a1a0f'),
        array('--v-primary' => '#dc2626', '--v-primary-dark' => '#b91c1c', '--v-primary-light' => '#fee2e2', '--v-accent' => '#0ea5e9', '--v-bg-subtle' => '#fef2f2', '--v-dark-bg' => '#1a0a0a'),
        array('--v-primary' => '#7c3aed', '--v-primary-dark' => '#6d28d9', '--v-primary-light' => '#ede9fe', '--v-accent' => '#10b981', '--v-bg-subtle' => '#faf5ff', '--v-dark-bg' => '#0f0a1a'),
        array('--v-primary' => '#0891b2', '--v-primary-dark' => '#0e7490', '--v-primary-light' => '#cffafe', '--v-accent' => '#e11d48', '--v-bg-subtle' => '#ecfeff', '--v-dark-bg' => '#0a1a1f'),
        array('--v-primary' => '#ea580c', '--v-primary-dark' => '#c2410c', '--v-primary-light' => '#ffedd5', '--v-accent' => '#2563eb', '--v-bg-subtle' => '#fff7ed', '--v-dark-bg' => '#1a100a'),
        array('--v-primary' => '#4f46e5', '--v-primary-dark' => '#4338ca', '--v-primary-light' => '#e0e7ff', '--v-accent' => '#f97316', '--v-bg-subtle' => '#eef2ff', '--v-dark-bg' => '#0a0a1f'),
        array('--v-primary' => '#0d9488', '--v-primary-dark' => '#0f766e', '--v-primary-light' => '#ccfbf1', '--v-accent' => '#d946ef', '--v-bg-subtle' => '#f0fdfa', '--v-dark-bg' => '#0a1a18'),
        array('--v-primary' => '#be185d', '--v-primary-dark' => '#9d174d', '--v-primary-light' => '#fce7f3', '--v-accent' => '#14b8a6', '--v-bg-subtle' => '#fdf2f8', '--v-dark-bg' => '#1a0a14'),
        array('--v-primary' => '#1e40af', '--v-primary-dark' => '#1e3a8a', '--v-primary-light' => '#dbeafe', '--v-accent' => '#ca8a04', '--v-bg-subtle' => '#eff6ff', '--v-dark-bg' => '#0a1228'),
        array('--v-primary' => '#15803d', '--v-primary-dark' => '#166534', '--v-primary-light' => '#dcfce7', '--v-accent' => '#e11d48', '--v-bg-subtle' => '#f0fdf4', '--v-dark-bg' => '#0a1a0d'),
        array('--v-primary' => '#9333ea', '--v-primary-dark' => '#7e22ce', '--v-primary-light' => '#f3e8ff', '--v-accent' => '#06b6d4', '--v-bg-subtle' => '#faf5ff', '--v-dark-bg' => '#100a1a'),
    );
}

// ──────────────────────────────────────────────
// 2. 预设字体组合（8 组）
// ──────────────────────────────────────────────
function variation_font_pairs()
{
    return array(
        array(
            'heading' => '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
            'body'    => '"Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
            'import'  => '',
        ),
        array(
            'heading' => '"Noto Serif SC", "SimSun", serif',
            'body'    => '"Noto Sans SC", "PingFang SC", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@600;700&display=swap");',
        ),
        array(
            'heading' => '"Source Han Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif',
            'body'    => '"Source Han Sans SC", "PingFang SC", sans-serif',
            'import'  => '',
        ),
        array(
            'heading' => '"ZCOOL XiaoWei", "STKaiti", serif',
            'body'    => '"Noto Sans SC", "PingFang SC", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=ZCOOL+XiaoWei&display=swap");',
        ),
        array(
            'heading' => '"Inter", "PingFang SC", "Microsoft YaHei", sans-serif',
            'body'    => '"Inter", "PingFang SC", "Microsoft YaHei", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");',
        ),
        array(
            'heading' => '"Lora", "Noto Serif SC", serif',
            'body'    => '"Noto Sans SC", "PingFang SC", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=Lora:wght@600;700&display=swap");',
        ),
        array(
            'heading' => '"Playfair Display", "Noto Serif SC", serif',
            'body'    => '"Noto Sans SC", "PingFang SC", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&display=swap");',
        ),
        array(
            'heading' => '"Raleway", "PingFang SC", "Microsoft YaHei", sans-serif',
            'body'    => '"Raleway", "PingFang SC", "Microsoft YaHei", sans-serif',
            'import'  => '@import url("https://fonts.googleapis.com/css2?family=Raleway:wght@400;500;600;700&display=swap");',
        ),
    );
}

// ──────────────────────────────────────────────
// 3. 间距节奏 + 圆角风格
// ──────────────────────────────────────────────
function variation_spacing_scales()
{
    return array(
        'compact'  => array('--v-space-xs' => '0.25rem', '--v-space-sm' => '0.5rem', '--v-space-md' => '0.875rem', '--v-space-lg' => '1.5rem', '--v-space-xl' => '2.5rem', '--v-space-2xl' => '3.5rem'),
        'normal'   => array('--v-space-xs' => '0.375rem', '--v-space-sm' => '0.75rem', '--v-space-md' => '1rem', '--v-space-lg' => '2rem', '--v-space-xl' => '3rem', '--v-space-2xl' => '4.5rem'),
        'relaxed'  => array('--v-space-xs' => '0.5rem', '--v-space-sm' => '1rem', '--v-space-md' => '1.25rem', '--v-space-lg' => '2.5rem', '--v-space-xl' => '4rem', '--v-space-2xl' => '6rem'),
    );
}

function variation_border_styles()
{
    return array(
        'sharp'   => array('--v-radius-sm' => '0', '--v-radius-md' => '0', '--v-radius-lg' => '2px', '--v-radius-xl' => '4px', '--v-radius-full' => '0'),
        'subtle'  => array('--v-radius-sm' => '3px', '--v-radius-md' => '6px', '--v-radius-lg' => '10px', '--v-radius-xl' => '14px', '--v-radius-full' => '9999px'),
        'rounded' => array('--v-radius-sm' => '6px', '--v-radius-md' => '10px', '--v-radius-lg' => '14px', '--v-radius-xl' => '18px', '--v-radius-full' => '9999px'),
        'pill'    => array('--v-radius-sm' => '9999px', '--v-radius-md' => '9999px', '--v-radius-lg' => '16px', '--v-radius-xl' => '20px', '--v-radius-full' => '9999px'),
    );
}

// ──────────────────────────────────────────────
// 4a. 文章页布局（固定不参与变异）
// ──────────────────────────────────────────────
// 侧边栏布局不再参与变异，始终保持模板原始布局（有侧边栏就显示）
function variation_article_layouts()
{
    return array('sidebar-right');
}

function variation_article_font_sizes()
{
    return array(
        'text-base' => '16px',
        'text-lg'   => '17px',
        'text-xl'   => '18px',
    );
}

function variation_article_line_heights()
{
    return array(
        'leading-normal'  => '1.75',
        'leading-relaxed' => '1.85',
        'leading-loose'   => '2.0',
    );
}

function variation_article_para_spacings()
{
    return array(
        'para-compact'  => '1em',
        'para-normal'   => '1.5em',
        'para-spacious' => '2em',
    );
}

function variation_article_title_styles()
{
    return array('title-plain', 'title-underline', 'title-center', 'title-accent-left');
}

// ──────────────────────────────────────────────
// 4c. 首屏 Hero 样式预设（4 组）
// ──────────────────────────────────────────────
function variation_hero_styles()
{
    return array(
        // 0: dark-gradient — 深色渐变，微弱主色调
        array(
            '--v-hero-bg'             => 'linear-gradient(165deg, var(--v-dark-bg) 0%, color-mix(in srgb, var(--v-primary-dark) 20%, #111827) 100%)',
            '--v-hero-text'           => '#ffffff',
            '--v-hero-text-secondary' => 'rgba(255,255,255,0.75)',
            '--v-hero-text-muted'     => 'rgba(255,255,255,0.55)',
            '--v-hero-surface'        => 'rgba(255,255,255,0.04)',
            '--v-hero-surface-border' => 'rgba(255,255,255,0.08)',
            '--v-hero-surface-hover'  => 'rgba(255,255,255,0.08)',
            '--v-hero-btn2-border'    => 'rgba(255,255,255,0.30)',
            '--v-hero-btn2-hover-bg'  => 'rgba(255,255,255,0.08)',
            '--v-hero-btn2-hover-border' => 'rgba(255,255,255,0.50)',
            '--v-hero-divider'        => 'rgba(255,255,255,0.06)',
            '--v-hero-deco'           => 'radial-gradient(circle, color-mix(in srgb, var(--v-primary) 15%, transparent) 0%, transparent 70%)',
        ),
        // 1: primary-vivid — 鲜艳主色渐变，视觉冲击强
        array(
            '--v-hero-bg'             => 'linear-gradient(150deg, var(--v-primary-dark) 0%, var(--v-primary) 60%, color-mix(in srgb, var(--v-accent) 30%, var(--v-primary)) 100%)',
            '--v-hero-text'           => '#ffffff',
            '--v-hero-text-secondary' => 'rgba(255,255,255,0.88)',
            '--v-hero-text-muted'     => 'rgba(255,255,255,0.65)',
            '--v-hero-surface'        => 'rgba(0,0,0,0.15)',
            '--v-hero-surface-border' => 'rgba(255,255,255,0.12)',
            '--v-hero-surface-hover'  => 'rgba(0,0,0,0.22)',
            '--v-hero-btn2-border'    => 'rgba(255,255,255,0.40)',
            '--v-hero-btn2-hover-bg'  => 'rgba(255,255,255,0.12)',
            '--v-hero-btn2-hover-border' => 'rgba(255,255,255,0.60)',
            '--v-hero-divider'        => 'rgba(255,255,255,0.10)',
            '--v-hero-deco'           => 'radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%)',
        ),
        // 2: light-clean — 白色/浅色背景，深色文字，完全不同的观感
        array(
            '--v-hero-bg'             => 'linear-gradient(180deg, var(--v-bg-subtle) 0%, #ffffff 100%)',
            '--v-hero-text'           => 'var(--v-dark-bg, #0B1E3A)',
            '--v-hero-text-secondary' => 'var(--v-text, #1E2A4A)',
            '--v-hero-text-muted'     => '#64748b',
            '--v-hero-surface'        => '#ffffff',
            '--v-hero-surface-border' => '#e2e8f0',
            '--v-hero-surface-hover'  => 'var(--v-bg-subtle, #f8fafc)',
            '--v-hero-btn2-border'    => 'var(--v-primary, #2563eb)',
            '--v-hero-btn2-hover-bg'  => 'color-mix(in srgb, var(--v-primary) 8%, transparent)',
            '--v-hero-btn2-hover-border' => 'var(--v-primary-dark, #1d4ed8)',
            '--v-hero-divider'        => '#e2e8f0',
            '--v-hero-deco'           => 'radial-gradient(circle, color-mix(in srgb, var(--v-primary) 6%, transparent) 0%, transparent 70%)',
        ),
        // 3: accent-duotone — 主色→强调色双色渐变
        array(
            '--v-hero-bg'             => 'linear-gradient(135deg, var(--v-dark-bg) 0%, var(--v-primary-dark) 45%, color-mix(in srgb, var(--v-accent) 45%, var(--v-primary-dark)) 100%)',
            '--v-hero-text'           => '#ffffff',
            '--v-hero-text-secondary' => 'rgba(255,255,255,0.78)',
            '--v-hero-text-muted'     => 'rgba(255,255,255,0.55)',
            '--v-hero-surface'        => 'rgba(0,0,0,0.18)',
            '--v-hero-surface-border' => 'rgba(255,255,255,0.10)',
            '--v-hero-surface-hover'  => 'rgba(0,0,0,0.25)',
            '--v-hero-btn2-border'    => 'rgba(255,255,255,0.35)',
            '--v-hero-btn2-hover-bg'  => 'rgba(255,255,255,0.10)',
            '--v-hero-btn2-hover-border' => 'rgba(255,255,255,0.55)',
            '--v-hero-divider'        => 'rgba(255,255,255,0.08)',
            '--v-hero-deco'           => 'radial-gradient(circle, color-mix(in srgb, var(--v-accent) 18%, transparent) 0%, transparent 70%)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4e. 页脚 Footer 样式预设（4 组）
// ──────────────────────────────────────────────
function variation_footer_styles()
{
    return array(
        // 0: dark-solid — 纯深色背景，经典风格
        array(
            '--v-footer-bg'           => 'var(--v-dark-bg, #0B1E3A)',
            '--v-footer-text'         => '#ffffff',
            '--v-footer-text-muted'   => '#8896AA',
            '--v-footer-border'       => 'rgba(255,255,255,0.08)',
            '--v-footer-link-hover'   => 'var(--v-primary-light, #dbeafe)',
            '--v-footer-divider'      => 'linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent)',
            '--v-footer-tag-bg'       => 'rgba(255,255,255,0.06)',
            '--v-footer-tag-border'   => 'rgba(255,255,255,0.10)',
            '--v-footer-tag-hover-bg' => 'rgba(255,255,255,0.10)',
        ),
        // 1: primary-dark — 主色暗色背景，更有品牌感
        array(
            '--v-footer-bg'           => 'var(--v-primary-dark, #1d4ed8)',
            '--v-footer-text'         => '#ffffff',
            '--v-footer-text-muted'   => 'rgba(255,255,255,0.70)',
            '--v-footer-border'       => 'rgba(255,255,255,0.12)',
            '--v-footer-link-hover'   => '#ffffff',
            '--v-footer-divider'      => 'linear-gradient(90deg, transparent, rgba(255,255,255,0.20), transparent)',
            '--v-footer-tag-bg'       => 'rgba(255,255,255,0.10)',
            '--v-footer-tag-border'   => 'rgba(255,255,255,0.15)',
            '--v-footer-tag-hover-bg' => 'rgba(255,255,255,0.18)',
        ),
        // 2: light — 白色/浅色背景，深色文字
        array(
            '--v-footer-bg'           => 'var(--v-bg-subtle, #f8fafc)',
            '--v-footer-text'         => 'var(--v-dark-bg, #0B1E3A)',
            '--v-footer-text-muted'   => '#64748b',
            '--v-footer-border'       => '#e2e8f0',
            '--v-footer-link-hover'   => 'var(--v-primary, #2563eb)',
            '--v-footer-divider'      => 'linear-gradient(90deg, transparent, #cbd5e1, transparent)',
            '--v-footer-tag-bg'       => '#ffffff',
            '--v-footer-tag-border'   => '#e2e8f0',
            '--v-footer-tag-hover-bg' => 'color-mix(in srgb, var(--v-primary) 8%, transparent)',
        ),
        // 3: gradient — 深色渐变，融合主色
        array(
            '--v-footer-bg'           => 'linear-gradient(180deg, color-mix(in srgb, var(--v-primary-dark) 25%, var(--v-dark-bg)) 0%, var(--v-dark-bg) 100%)',
            '--v-footer-text'         => '#ffffff',
            '--v-footer-text-muted'   => 'rgba(255,255,255,0.65)',
            '--v-footer-border'       => 'rgba(255,255,255,0.10)',
            '--v-footer-link-hover'   => 'var(--v-primary-light, #dbeafe)',
            '--v-footer-divider'      => 'linear-gradient(90deg, transparent, color-mix(in srgb, var(--v-primary-light) 30%, transparent), transparent)',
            '--v-footer-tag-bg'       => 'rgba(0,0,0,0.15)',
            '--v-footer-tag-border'   => 'rgba(255,255,255,0.10)',
            '--v-footer-tag-hover-bg' => 'rgba(255,255,255,0.08)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4f. CTA 转化区样式预设（4 组）
// ──────────────────────────────────────────────
function variation_cta_styles()
{
    return array(
        // 0: dark-gradient — 深色渐变（默认）
        array(
            '--v-cta-bg'              => 'linear-gradient(135deg, var(--v-dark-bg) 0%, color-mix(in srgb, var(--v-primary-dark) 20%, #111827) 100%)',
            '--v-cta-text'            => '#ffffff',
            '--v-cta-text-muted'      => 'rgba(255,255,255,0.70)',
            '--v-cta-btn2-color'      => '#ffffff',
            '--v-cta-btn2-border'     => 'rgba(255,255,255,0.25)',
            '--v-cta-btn2-hover-bg'   => 'rgba(255,255,255,0.06)',
            '--v-cta-btn2-hover-border' => 'rgba(255,255,255,0.45)',
        ),
        // 1: primary-bold — 主色充满背景，视觉冲击强
        array(
            '--v-cta-bg'              => 'linear-gradient(135deg, var(--v-primary-dark) 0%, var(--v-primary) 50%, color-mix(in srgb, var(--v-accent) 25%, var(--v-primary)) 100%)',
            '--v-cta-text'            => '#ffffff',
            '--v-cta-text-muted'      => 'rgba(255,255,255,0.85)',
            '--v-cta-btn2-color'      => '#ffffff',
            '--v-cta-btn2-border'     => 'rgba(255,255,255,0.40)',
            '--v-cta-btn2-hover-bg'   => 'rgba(255,255,255,0.12)',
            '--v-cta-btn2-hover-border' => 'rgba(255,255,255,0.60)',
        ),
        // 2: light-card — 浅色背景，深色文字
        array(
            '--v-cta-bg'              => 'linear-gradient(180deg, var(--v-bg-subtle, #f8fafc) 0%, #ffffff 100%)',
            '--v-cta-text'            => 'var(--v-dark-bg, #0B1E3A)',
            '--v-cta-text-muted'      => '#64748b',
            '--v-cta-btn2-color'      => 'var(--v-primary, #2563eb)',
            '--v-cta-btn2-border'     => 'var(--v-primary, #2563eb)',
            '--v-cta-btn2-hover-bg'   => 'color-mix(in srgb, var(--v-primary) 8%, transparent)',
            '--v-cta-btn2-hover-border' => 'var(--v-primary-dark, #1d4ed8)',
        ),
        // 3: accent-wave — 强调色→主色渐变，双色调
        array(
            '--v-cta-bg'              => 'linear-gradient(135deg, color-mix(in srgb, var(--v-accent) 40%, var(--v-dark-bg)) 0%, var(--v-primary-dark) 100%)',
            '--v-cta-text'            => '#ffffff',
            '--v-cta-text-muted'      => 'rgba(255,255,255,0.75)',
            '--v-cta-btn2-color'      => '#ffffff',
            '--v-cta-btn2-border'     => 'rgba(255,255,255,0.30)',
            '--v-cta-btn2-hover-bg'   => 'rgba(255,255,255,0.10)',
            '--v-cta-btn2-hover-border' => 'rgba(255,255,255,0.50)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4g. 侧边栏风格样式预设（4 组）
// ──────────────────────────────────────────────
function variation_sidebar_styles()
{
    return array(
        // 0: card-shadow — 白色卡片 + 阴影（经典）
        array(
            '--v-sidebar-bg'           => '#ffffff',
            '--v-sidebar-border'       => 'none',
            '--v-sidebar-shadow'       => '0 2px 12px rgba(0,0,0,0.06)',
            '--v-sidebar-title-color'  => 'var(--v-dark-bg, #0B1E3A)',
            '--v-sidebar-title-border' => '2px solid var(--v-primary, #2563eb)',
            '--v-sidebar-text'         => 'var(--v-dark-bg, #334155)',
            '--v-sidebar-link-hover'   => 'var(--v-primary, #2563eb)',
            '--v-sidebar-item-border'  => '#f1f5f9',
            '--v-sidebar-icon-bg'      => 'color-mix(in srgb, var(--v-primary) 10%, transparent)',
            '--v-sidebar-icon-color'   => 'var(--v-primary, #2563eb)',
        ),
        // 1: bordered — 白色 + 边框无阴影，简洁线条感
        array(
            '--v-sidebar-bg'           => '#ffffff',
            '--v-sidebar-border'       => '1px solid #e2e8f0',
            '--v-sidebar-shadow'       => 'none',
            '--v-sidebar-title-color'  => 'var(--v-dark-bg, #0B1E3A)',
            '--v-sidebar-title-border' => '2px solid var(--v-primary, #2563eb)',
            '--v-sidebar-text'         => '#475569',
            '--v-sidebar-link-hover'   => 'var(--v-primary, #2563eb)',
            '--v-sidebar-item-border'  => '#e2e8f0',
            '--v-sidebar-icon-bg'      => 'transparent',
            '--v-sidebar-icon-color'   => 'var(--v-primary, #2563eb)',
        ),
        // 2: tinted — 主色调浅底卡片
        array(
            '--v-sidebar-bg'           => 'color-mix(in srgb, var(--v-primary) 4%, #ffffff)',
            '--v-sidebar-border'       => '1px solid color-mix(in srgb, var(--v-primary) 12%, transparent)',
            '--v-sidebar-shadow'       => '0 1px 6px color-mix(in srgb, var(--v-primary) 8%, transparent)',
            '--v-sidebar-title-color'  => 'var(--v-primary-dark, #1d4ed8)',
            '--v-sidebar-title-border' => '2px solid var(--v-primary, #2563eb)',
            '--v-sidebar-text'         => '#334155',
            '--v-sidebar-link-hover'   => 'var(--v-primary-dark, #1d4ed8)',
            '--v-sidebar-item-border'  => 'color-mix(in srgb, var(--v-primary) 10%, transparent)',
            '--v-sidebar-icon-bg'      => 'color-mix(in srgb, var(--v-primary) 15%, transparent)',
            '--v-sidebar-icon-color'   => 'var(--v-primary, #2563eb)',
        ),
        // 3: dark — 深色侧边栏卡片
        array(
            '--v-sidebar-bg'           => 'var(--v-dark-bg, #0B1E3A)',
            '--v-sidebar-border'       => '1px solid rgba(255,255,255,0.08)',
            '--v-sidebar-shadow'       => '0 2px 12px rgba(0,0,0,0.20)',
            '--v-sidebar-title-color'  => '#ffffff',
            '--v-sidebar-title-border' => '2px solid var(--v-primary-light, #93c5fd)',
            '--v-sidebar-text'         => 'rgba(255,255,255,0.80)',
            '--v-sidebar-link-hover'   => 'var(--v-primary-light, #93c5fd)',
            '--v-sidebar-item-border'  => 'rgba(255,255,255,0.06)',
            '--v-sidebar-icon-bg'      => 'rgba(255,255,255,0.08)',
            '--v-sidebar-icon-color'   => 'var(--v-primary-light, #93c5fd)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4h. 栏目页文章列表布局预设（4 种）
// ──────────────────────────────────────────────
function variation_archive_layouts()
{
    return array('horizontal', 'grid', 'text-only', 'large-cover');
}

// ──────────────────────────────────────────────
// 4i. 栏目页文章列表卡片风格预设（4 组）
// ──────────────────────────────────────────────
function variation_archive_styles()
{
    return array(
        // 0: card-shadow — 白色卡片 + 阴影（经典）
        array(
            '--v-list-bg'           => '#ffffff',
            '--v-list-border'       => 'none',
            '--v-list-shadow'       => '0 1px 4px rgba(0,0,0,0.05)',
            '--v-list-shadow-hover' => '0 8px 28px rgba(0,0,0,0.10)',
            '--v-list-title-color'  => 'var(--v-dark-bg, #0B1E3A)',
            '--v-list-title-hover'  => 'var(--v-primary, #2563eb)',
            '--v-list-desc-color'   => '#6B7B8D',
            '--v-list-time-bg'      => 'rgba(0,0,0,0.55)',
            '--v-list-time-color'   => '#ffffff',
            '--v-list-radius'       => 'var(--v-radius-lg, 10px)',
        ),
        // 1: bordered — 边框线条风格
        array(
            '--v-list-bg'           => '#ffffff',
            '--v-list-border'       => '1px solid #e2e8f0',
            '--v-list-shadow'       => 'none',
            '--v-list-shadow-hover' => '0 4px 16px rgba(0,0,0,0.08)',
            '--v-list-title-color'  => 'var(--v-dark-bg, #0B1E3A)',
            '--v-list-title-hover'  => 'var(--v-primary, #2563eb)',
            '--v-list-desc-color'   => '#64748b',
            '--v-list-time-bg'      => 'rgba(0,0,0,0.50)',
            '--v-list-time-color'   => '#ffffff',
            '--v-list-radius'       => 'var(--v-radius-lg, 10px)',
        ),
        // 2: tinted — 主色调浅底卡片
        array(
            '--v-list-bg'           => 'color-mix(in srgb, var(--v-primary) 3%, #ffffff)',
            '--v-list-border'       => '1px solid color-mix(in srgb, var(--v-primary) 10%, transparent)',
            '--v-list-shadow'       => '0 1px 6px color-mix(in srgb, var(--v-primary) 6%, transparent)',
            '--v-list-shadow-hover' => '0 6px 24px color-mix(in srgb, var(--v-primary) 12%, transparent)',
            '--v-list-title-color'  => 'var(--v-dark-bg, #0B1E3A)',
            '--v-list-title-hover'  => 'var(--v-primary-dark, #1d4ed8)',
            '--v-list-desc-color'   => '#475569',
            '--v-list-time-bg'      => 'color-mix(in srgb, var(--v-primary-dark) 75%, #000000)',
            '--v-list-time-color'   => '#ffffff',
            '--v-list-radius'       => 'var(--v-radius-lg, 10px)',
        ),
        // 3: dark — 深色卡片
        array(
            '--v-list-bg'           => 'var(--v-dark-bg, #0B1E3A)',
            '--v-list-border'       => '1px solid rgba(255,255,255,0.08)',
            '--v-list-shadow'       => '0 2px 8px rgba(0,0,0,0.20)',
            '--v-list-shadow-hover' => '0 8px 32px rgba(0,0,0,0.30)',
            '--v-list-title-color'  => '#ffffff',
            '--v-list-title-hover'  => 'var(--v-primary-light, #93c5fd)',
            '--v-list-desc-color'   => 'rgba(255,255,255,0.65)',
            '--v-list-time-bg'      => 'rgba(255,255,255,0.15)',
            '--v-list-time-color'   => '#ffffff',
            '--v-list-radius'       => 'var(--v-radius-lg, 10px)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4j. 首页服务面板布局预设（4 种）
// ──────────────────────────────────────────────
function variation_hp_panel_layouts()
{
    // default: 面板在右侧 | left: 面板在左侧 | top: 面板在上方全宽 | hidden: 隐藏面板，服务卡片全宽3列
    return array('default', 'left', 'top', 'hidden');
}

// ──────────────────────────────────────────────
// 4k. 首页亮点卡片布局预设（5 种）
// ──────────────────────────────────────────────
function variation_hp_features_layouts()
{
    // grid3: 默认3列 | grid2: 2列大卡 | grid4: 4列+2列 | horizontal: 全宽水平卡 | alternating: 交替大小卡
    return array('grid3', 'grid2', 'grid4', 'horizontal', 'alternating');
}

// ──────────────────────────────────────────────
// 4l. 首页最新动态布局预设（4 种）
// ──────────────────────────────────────────────
function variation_hp_latest_layouts()
{
    // grid4: 默认4列带图 | grid3: 3列带图 | grid2: 2列带图
    // text-list: 纯标题+描述双列无图
    // 注：hero-left / hero-right 两种"一大图+侧标题列表"组合已移除（首屏空洞且与首图重复）
    return array('grid4', 'grid3', 'grid2', 'text-list');
}

// ──────────────────────────────────────────────
// 4m. 导航菜单样式预设（7 种）
// ──────────────────────────────────────────────
function variation_nav_styles()
{
    // underline: 底部下划线（默认）| pill: 药丸形/椭圆背景 | rounded: 圆角矩形色块
    // square: 直角矩形色块 | outline-pill: 椭圆描边 | dot: 底部小圆点 | bracket: 左右方括号
    return array('underline', 'pill', 'rounded', 'square', 'outline-pill', 'dot', 'bracket');
}

function variation_nav_positions()
{
    // left: logo左+导航紧跟 | center: 导航居中 | right: 导航靠右(默认)
    return array('left', 'center', 'right');
}

function variation_nav_gaps()
{
    // tight: 紧凑 | normal: 标准 | wide: 宽松
    return array('tight', 'normal', 'wide');
}

// ──────────────────────────────────────────────
// 4m-d. 分页样式预设
// ──────────────────────────────────────────────
function variation_pagination_styles()
{
    return array(
        // 0: bordered-center — 带边框居中（默认）
        array('align' => 'center', 'radius' => 'var(--v-radius-md,6px)', 'border' => '1px solid var(--border-color,#e2e8f0)', 'bg' => 'var(--bg-white,#fff)'),
        // 1: pill-center — 胶囊居中
        array('align' => 'center', 'radius' => '9999px', 'border' => '1px solid var(--border-color,#e2e8f0)', 'bg' => 'var(--bg-white,#fff)'),
        // 2: flat-left — 无边框靠左
        array('align' => 'flex-start', 'radius' => 'var(--v-radius-md,6px)', 'border' => 'none', 'bg' => 'var(--bg-subtle,#f1f5f9)'),
        // 3: flat-right — 无边框靠右
        array('align' => 'flex-end', 'radius' => 'var(--v-radius-md,6px)', 'border' => 'none', 'bg' => 'var(--bg-subtle,#f1f5f9)'),
        // 4: bordered-right — 带边框靠右
        array('align' => 'flex-end', 'radius' => 'var(--v-radius-md,6px)', 'border' => '1px solid var(--border-color,#e2e8f0)', 'bg' => 'var(--bg-white,#fff)'),
        // 5: pill-left — 胶囊靠左
        array('align' => 'flex-start', 'radius' => '9999px', 'border' => '1px solid var(--border-color,#e2e8f0)', 'bg' => 'var(--bg-white,#fff)'),
        // 6: square-center — 直角居中
        array('align' => 'center', 'radius' => '0', 'border' => '1px solid var(--border-color,#e2e8f0)', 'bg' => 'var(--bg-white,#fff)'),
    );
}

// ──────────────────────────────────────────────
// 4m-e. 页脚导航样式预设
// ──────────────────────────────────────────────
function variation_footer_nav_styles()
{
    return array(
        // 0: horizontal — 横向排列(默认)
        array('display' => 'flex', 'gap' => '0.5rem 1.25rem', 'separator' => 'none'),
        // 1: horizontal-tight — 横向紧凑
        array('display' => 'flex', 'gap' => '0.25rem 0.75rem', 'separator' => 'none'),
        // 2: horizontal-wide — 横向宽松
        array('display' => 'flex', 'gap' => '0.5rem 2rem', 'separator' => 'none'),
        // 3: horizontal-dot — 横向+圆点分隔
        array('display' => 'flex', 'gap' => '0.5rem 0.5rem', 'separator' => 'dot'),
        // 4: horizontal-line — 横向+竖线分隔
        array('display' => 'flex', 'gap' => '0.5rem 0', 'separator' => 'line'),
        // 5: vertical — 纵向列表
        array('display' => 'block', 'gap' => '0', 'separator' => 'none'),
    );
}

// ──────────────────────────────────────────────
// 4m-f. 首屏统计卡片样式预设
// ──────────────────────────────────────────────
function variation_stat_styles()
{
    return array(
        // 0: flat-4col — 扁平4列（默认）
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => '0',
            'bg' => 'transparent',
            'border' => 'none',
            'padding' => '1.5rem',
            'hover' => false,
            'text' => 'inherit',
            'text_secondary' => 'inherit',
            'num_bg' => 'linear-gradient(135deg, rgba(74,155,230,0.22), rgba(26,111,184,0.36))',
            'num_color' => 'inherit',
        ),
        // 1: card-4col — 卡片4列
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => 'var(--v-radius-lg, 10px)',
            'bg' => 'var(--bg-white, #fff)',
            'border' => '1px solid var(--border-color, #e2e8f0)',
            'padding' => '1.75rem 1rem',
            'hover' => true,
            'text' => '#0B1E3A',
            'text_secondary' => '#64748b',
            'num_bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 10%, transparent)',
            'num_color' => 'var(--v-primary, #3b82f6)',
        ),
        // 2: circle-4col — 圆形4列
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => '50%',
            'bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 6%, transparent)',
            'border' => '2px solid color-mix(in srgb, var(--v-primary, #3b82f6) 15%, transparent)',
            'padding' => '2rem 1rem',
            'hover' => true,
            'aspect' => true,
            'text' => 'inherit',
            'text_secondary' => 'inherit',
            'num_bg' => 'linear-gradient(135deg, rgba(74,155,230,0.22), rgba(26,111,184,0.36))',
            'num_color' => 'inherit',
        ),
        // 3: card-2col — 卡片2列
        array(
            'cols' => 'repeat(2, minmax(0, 1fr))',
            'radius' => 'var(--v-radius-lg, 10px)',
            'bg' => 'var(--bg-white, #fff)',
            'border' => '1px solid var(--border-color, #e2e8f0)',
            'padding' => '2rem 1.5rem',
            'hover' => true,
            'text' => '#0B1E3A',
            'text_secondary' => '#64748b',
            'num_bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 10%, transparent)',
            'num_color' => 'var(--v-primary, #3b82f6)',
        ),
        // 4: pill-4col — 胶囊4列
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => '9999px',
            'bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 5%, var(--bg-white, #fff))',
            'border' => '1px solid color-mix(in srgb, var(--v-primary, #3b82f6) 12%, transparent)',
            'padding' => '1.25rem 2rem',
            'hover' => true,
            'text' => '#0B1E3A',
            'text_secondary' => '#64748b',
            'num_bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 10%, transparent)',
            'num_color' => 'var(--v-primary, #3b82f6)',
        ),
        // 5: tinted-4col — 主色浅底4列
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => 'var(--v-radius-md, 8px)',
            'bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 4%, var(--bg-white, #fff))',
            'border' => 'none',
            'padding' => '1.75rem 1rem',
            'hover' => true,
            'text' => '#0B1E3A',
            'text_secondary' => '#475569',
            'num_bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 12%, transparent)',
            'num_color' => 'var(--v-primary-dark, #1d4ed8)',
        ),
        // 6: circle-mix — 前2圆形+后2卡片
        array(
            'cols' => 'repeat(4, minmax(0, 1fr))',
            'radius' => 'var(--v-radius-lg, 10px)',
            'bg' => 'var(--bg-white, #fff)',
            'border' => '1px solid var(--border-color, #e2e8f0)',
            'padding' => '1.75rem 1rem',
            'hover' => true,
            'mix' => true,
            'text' => '#0B1E3A',
            'text_secondary' => '#64748b',
            'num_bg' => 'color-mix(in srgb, var(--v-primary, #3b82f6) 10%, transparent)',
            'num_color' => 'var(--v-primary, #3b82f6)',
        ),
    );
}

// ──────────────────────────────────────────────
// 4n. 首页CTA转化区布局预设（5 种）
// ──────────────────────────────────────────────
function variation_hp_cta_layouts()
{
    // default: 默认斜切clip-path | flat: 无斜切全宽圆角 | rounded: 圆角卡片居中
    // wave: 波浪边缘 | split: 左文右色块分栏
    return array('default', 'flat', 'rounded', 'wave', 'split');
}

// ──────────────────────────────────────────────
// 4o. 首页评价区布局预设（5 种）
// ──────────────────────────────────────────────
function variation_hp_testimonial_layouts()
{
    // carousel: 默认水平排列 | grid2: 2列网格 | grid3: 3列网格
    // featured: 首条放大+其余小卡 | stacked: 垂直堆叠全宽
    return array('carousel', 'grid2', 'grid3', 'featured', 'stacked');
}

// ──────────────────────────────────────────────
// 4p. 类名前缀生成（确定性）
// ──────────────────────────────────────────────
function variation_class_prefix($domainId)
{
    $hash = crc32('variation_prefix_' . (int)$domainId);
    $chars = 'abcdefghijklmnopqrstuvwxyz';
    $prefix = '';
    $absHash = abs($hash);
    for ($i = 0; $i < 2; $i++) {
        $prefix .= $chars[$absHash % 26];
        $absHash = (int)floor($absHash / 26);
    }
    $prefix .= ($domainId % 100);
    return $prefix;
}

// ──────────────────────────────────────────────
// 4.x 页面宽度变异预设
// ──────────────────────────────────────────────
function variation_page_widths()
{
    return array(
        // 0: compact — 紧凑型
        '1080px',
        // 1: normal — 标准
        '1180px',
        // 2: wide — 宽屏
        '1320px',
        // 3: extra-wide — 超宽
        '1440px',
    );
}

// ──────────────────────────────────────────────
// 5. 确定性选择函数
// ──────────────────────────────────────────────
function variation_pick($domainId, $dimension, $optionCount)
{
    $hash = abs(crc32('tv_' . $dimension . '_' . (int)$domainId));
    return $hash % $optionCount;
}

// ──────────────────────────────────────────────
// 6. 域名表字段迁移
// ──────────────────────────────────────────────
function ensure_domains_table_has_variation()
{
    static $checked = false;
    if ($checked) {
        return;
    }
    $checked = true;
    if (!table_exists('domains')) {
        return;
    }
    $pdo = db_connection();
    try {
        $cols = $pdo->query("SHOW COLUMNS FROM domains LIKE 'template_variation'")->fetchAll();
        if (empty($cols)) {
            $pdo->exec("ALTER TABLE `domains` ADD COLUMN `template_variation` TEXT NULL AFTER `template_pack`");
        }
    } catch (Exception $e) {
        // table may not exist yet
    }
}

// ──────────────────────────────────────────────
// 7. 获取域名变异配置（自动 or 手动覆盖）
// ──────────────────────────────────────────────
function get_domain_variation($domainId, $domainRecord = null)
{
    $domainId = (int)$domainId;
    if ($domainId <= 0) {
        return null;
    }

    // 如果域名有手动配置的变异参数，优先使用
    if ($domainRecord === null) {
        ensure_domains_table_has_variation();
        $domainRecord = find_domain_by_id($domainId);
    }
    $manualJson = isset($domainRecord['template_variation']) ? trim((string)$domainRecord['template_variation']) : '';
    if ($manualJson !== '' && $manualJson !== '{}') {
        $manual = @json_decode($manualJson, true);
        if (is_array($manual) && !empty($manual)) {
            // 手动配置可以只覆盖部分维度，其余自动生成
            return array_merge(generate_auto_variation($domainId), $manual);
        }
    }

    return generate_auto_variation($domainId);
}

// ──────────────────────────────────────────────
// 8. 自动变异参数生成
// ──────────────────────────────────────────────
function generate_auto_variation($domainId)
{
    $domainId = (int)$domainId;

    $colorSchemes = variation_color_schemes();
    $fontPairs = variation_font_pairs();
    $spacingKeys = array_keys(variation_spacing_scales());
    $borderKeys = array_keys(variation_border_styles());

    $colorIdx = variation_pick($domainId, 'color', count($colorSchemes));
    $fontIdx = variation_pick($domainId, 'font', count($fontPairs));
    $spacingIdx = variation_pick($domainId, 'spacing', count($spacingKeys));
    $borderIdx = variation_pick($domainId, 'border', count($borderKeys));

    // 文章页布局变异
    $articleLayouts = variation_article_layouts();
    $articleFontSizeKeys = array_keys(variation_article_font_sizes());
    $articleLineHeightKeys = array_keys(variation_article_line_heights());
    $articleParaSpacingKeys = array_keys(variation_article_para_spacings());
    $articleTitleStyles = variation_article_title_styles();

    $articleLayoutIdx = variation_pick($domainId, 'article_layout', count($articleLayouts));
    $articleFontSizeIdx = variation_pick($domainId, 'article_fontsize', count($articleFontSizeKeys));
    $articleLineHeightIdx = variation_pick($domainId, 'article_lineheight', count($articleLineHeightKeys));
    $articleParaSpacingIdx = variation_pick($domainId, 'article_paraspacing', count($articleParaSpacingKeys));
    $articleTitleStyleIdx = variation_pick($domainId, 'article_titlestyle', count($articleTitleStyles));

    // 首屏 Hero 样式变异
    $heroStyles = variation_hero_styles();
    $heroStyleIdx = variation_pick($domainId, 'hero_style', count($heroStyles));

    // 页脚 Footer 样式变异
    $footerStyles = variation_footer_styles();
    $footerStyleIdx = variation_pick($domainId, 'footer_style', count($footerStyles));

    // CTA 转化区样式变异
    $ctaStyles = variation_cta_styles();
    $ctaStyleIdx = variation_pick($domainId, 'cta_style', count($ctaStyles));

    // 侧边栏风格变异
    $sidebarStyles = variation_sidebar_styles();
    $sidebarStyleIdx = variation_pick($domainId, 'sidebar_style', count($sidebarStyles));

    // 栏目页文章列表变异
    $archiveLayouts = variation_archive_layouts();
    $archiveLayoutIdx = variation_pick($domainId, 'archive_layout', count($archiveLayouts));
    $archiveStyles = variation_archive_styles();
    $archiveStyleIdx = variation_pick($domainId, 'archive_style', count($archiveStyles));

    // 首页服务面板布局变异
    $hpPanelLayouts = variation_hp_panel_layouts();
    $hpPanelIdx = variation_pick($domainId, 'hp_panel', count($hpPanelLayouts));

    // 首页亮点卡片布局变异
    $hpFeaturesLayouts = variation_hp_features_layouts();
    $hpFeaturesIdx = variation_pick($domainId, 'hp_features', count($hpFeaturesLayouts));

    // 首页最新动态布局变异
    $hpLatestLayouts = variation_hp_latest_layouts();
    $hpLatestIdx = variation_pick($domainId, 'hp_latest', count($hpLatestLayouts));

    // 导航菜单样式变异
    $navStyles = variation_nav_styles();
    $navStyleIdx = variation_pick($domainId, 'nav_style', count($navStyles));
    $navPositions = variation_nav_positions();
    $navPosIdx = variation_pick($domainId, 'nav_pos', count($navPositions));
    $navGaps = variation_nav_gaps();
    $navGapIdx = variation_pick($domainId, 'nav_gap', count($navGaps));

    // 分页样式变异
    $pagiStyles = variation_pagination_styles();
    $pagiIdx = variation_pick($domainId, 'pagi_style', count($pagiStyles));

    // 页脚导航样式变异
    $fNavStyles = variation_footer_nav_styles();
    $fNavIdx = variation_pick($domainId, 'fnav_style', count($fNavStyles));

    // 首屏统计卡片样式变异
    $statStyles = variation_stat_styles();
    $statIdx = variation_pick($domainId, 'stat_style', count($statStyles));

    // 首页CTA布局变异
    $hpCtaLayouts = variation_hp_cta_layouts();
    $hpCtaIdx = variation_pick($domainId, 'hp_cta', count($hpCtaLayouts));

    // 首页评价区布局变异
    $hpTestimonialLayouts = variation_hp_testimonial_layouts();
    $hpTestimonialIdx = variation_pick($domainId, 'hp_testimonial', count($hpTestimonialLayouts));

    // 相关文章侧边栏布局变异
    $relatedLayouts = variation_related_layouts();
    $relatedLayoutIdx = variation_pick($domainId, 'related_layout', count($relatedLayouts));

    // 页面宽度变异
    $pageWidths = variation_page_widths();
    $pageWidthIdx = variation_pick($domainId, 'page_width', count($pageWidths));

    return array(
        'color_index'   => $colorIdx,
        'font_index'    => $fontIdx,
        'spacing'       => $spacingKeys[$spacingIdx],
        'border'        => $borderKeys[$borderIdx],
        'class_prefix'  => variation_class_prefix($domainId),
        'module_order'  => generate_module_order($domainId),
        'article_layout'       => $articleLayouts[$articleLayoutIdx],
        'article_font_size'    => $articleFontSizeKeys[$articleFontSizeIdx],
        'article_line_height'  => $articleLineHeightKeys[$articleLineHeightIdx],
        'article_para_spacing' => $articleParaSpacingKeys[$articleParaSpacingIdx],
        'article_title_style'  => $articleTitleStyles[$articleTitleStyleIdx],
        'hero_style'           => $heroStyleIdx,
        'footer_style'         => $footerStyleIdx,
        'cta_style'            => $ctaStyleIdx,
        'sidebar_style'        => $sidebarStyleIdx,
        'archive_layout'       => $archiveLayouts[$archiveLayoutIdx],
        'archive_style'        => $archiveStyleIdx,
        'hp_panel_layout'      => $hpPanelLayouts[$hpPanelIdx],
        'hp_features_layout'   => $hpFeaturesLayouts[$hpFeaturesIdx],
        'hp_latest_layout'     => $hpLatestLayouts[$hpLatestIdx],
        'nav_style'            => $navStyles[$navStyleIdx],
        'nav_position'         => $navPositions[$navPosIdx],
        'nav_gap'              => $navGaps[$navGapIdx],
        'pagination_style'     => $pagiIdx,
        'footer_nav_style'     => $fNavIdx,
        'stat_style'           => $statIdx,
        'hp_cta_layout'        => $hpCtaLayouts[$hpCtaIdx],
        'hp_testimonial_layout' => $hpTestimonialLayouts[$hpTestimonialIdx],
        'related_layout'        => $relatedLayouts[$relatedLayoutIdx],
        'page_width'            => $pageWidths[$pageWidthIdx],
    );
}

// ──────────────────────────────────────────────
// 8z. 相关文章侧边栏布局预设
// ──────────────────────────────────────────────
function variation_related_layouts()
{
    return array('2col', '1col', 'list');
}

// ──────────────────────────────────────────────
// 9. 首页模块顺序重排
// ──────────────────────────────────────────────
function generate_module_order($domainId)
{
    // 首页 HTML 中的可重排模块（<section> 块）
    // 模块 0（hero）始终保持首位，其余打乱
    $modules = array(1, 2, 3, 4, 5, 6, 7);
    $seed = abs(crc32('module_order_' . (int)$domainId));
    // Fisher-Yates 确定性洗牌
    for ($i = count($modules) - 1; $i > 0; $i--) {
        $seed = ($seed * 1103515245 + 12345) & 0x7FFFFFFF;
        $j = $seed % ($i + 1);
        $tmp = $modules[$i];
        $modules[$i] = $modules[$j];
        $modules[$j] = $tmp;
    }
    return array_merge(array(0), $modules);
}

// ──────────────────────────────────────────────
// 10. 构建变异 CSS（注入到 <head> 中）
// ──────────────────────────────────────────────
function build_variation_css($variation)
{
    if (!is_array($variation) || empty($variation)) {
        return '';
    }

    $colorSchemes = variation_color_schemes();
    $fontPairs = variation_font_pairs();
    $spacingScales = variation_spacing_scales();
    $borderStyles = variation_border_styles();

    $colorIdx = isset($variation['color_index']) ? (int)$variation['color_index'] : 0;
    $fontIdx = isset($variation['font_index']) ? (int)$variation['font_index'] : 0;
    $spacingKey = isset($variation['spacing']) ? (string)$variation['spacing'] : 'normal';
    $borderKey = isset($variation['border']) ? (string)$variation['border'] : 'rounded';

    $colors = isset($colorSchemes[$colorIdx]) ? $colorSchemes[$colorIdx] : $colorSchemes[0];
    $fonts = isset($fontPairs[$fontIdx]) ? $fontPairs[$fontIdx] : $fontPairs[0];
    $spacing = isset($spacingScales[$spacingKey]) ? $spacingScales[$spacingKey] : $spacingScales['normal'];
    $borders = isset($borderStyles[$borderKey]) ? $borderStyles[$borderKey] : $borderStyles['rounded'];

    $vars = array();

    // 色彩
    foreach ($colors as $prop => $val) {
        $vars[] = $prop . ':' . $val;
    }

    // 字体
    $vars[] = '--v-font-heading:' . $fonts['heading'];
    $vars[] = '--v-font-body:' . $fonts['body'];

    // 间距
    foreach ($spacing as $prop => $val) {
        $vars[] = $prop . ':' . $val;
    }

    // 圆角
    foreach ($borders as $prop => $val) {
        $vars[] = $prop . ':' . $val;
    }

    $css = '';

    // Google Fonts import（如果需要）
    $fontImport = isset($fonts['import']) ? trim($fonts['import']) : '';
    if ($fontImport !== '' && !preg_match('#https?://fonts\.googleapis\.com/#i', $fontImport)) {
        $css .= $fontImport . "\n";
    }

    $css .= ':root{' . implode(';', $vars) . "}\n";

    // 将变异变量映射到模板原始变量名
    $css .= "/* 变异覆盖 */\n";
    $css .= ":root {\n";
    $css .= "  --primary-color: var(--v-primary);\n";
    $css .= "  --primary-dark: var(--v-primary-dark);\n";
    $css .= "  --primary-light: var(--v-primary-light);\n";
    $css .= "  --accent-color: var(--v-accent);\n";
    $css .= "  --bg-subtle: var(--v-bg-subtle);\n";
    $css .= "  --dark-bg: var(--v-dark-bg);\n";
    $css .= "}\n";

    // 字体覆盖：直接覆盖 body 和标题
    $css .= "body { font-family: var(--v-font-body) !important; }\n";
    $css .= "h1,h2,h3,h4,h5,h6 { font-family: var(--v-font-heading) !important; }\n";

    // ── 页面宽度变异 CSS ──
    $pageWidth = isset($variation['page_width']) ? (string)$variation['page_width'] : '1180px';
    $css .= "\n/* == 页面宽度变异 == */\n";
    $css .= ":root{--v-page-width:{$pageWidth};}\n";

    // ── 首屏 Hero 样式变异 CSS ──
    $heroStyles = variation_hero_styles();
    $heroStyleIdx = isset($variation['hero_style']) ? (int)$variation['hero_style'] : 0;
    $heroStyle = isset($heroStyles[$heroStyleIdx]) ? $heroStyles[$heroStyleIdx] : $heroStyles[0];
    $heroVars = array();
    foreach ($heroStyle as $prop => $val) {
        $heroVars[] = $prop . ':' . $val;
    }
    $css .= ":root{" . implode(';', $heroVars) . "}\n";

    // ── 页脚 Footer 样式变异 CSS ──
    $footerStyles = variation_footer_styles();
    $footerStyleIdx = isset($variation['footer_style']) ? (int)$variation['footer_style'] : 0;
    $footerStyle = isset($footerStyles[$footerStyleIdx]) ? $footerStyles[$footerStyleIdx] : $footerStyles[0];
    $footerVars = array();
    foreach ($footerStyle as $prop => $val) {
        $footerVars[] = $prop . ':' . $val;
    }
    $css .= ":root{" . implode(';', $footerVars) . "}\n";

    // ── CTA 转化区样式变异 CSS ──
    $ctaStyles = variation_cta_styles();
    $ctaStyleIdx = isset($variation['cta_style']) ? (int)$variation['cta_style'] : 0;
    $ctaStyle = isset($ctaStyles[$ctaStyleIdx]) ? $ctaStyles[$ctaStyleIdx] : $ctaStyles[0];
    $ctaVars = array();
    foreach ($ctaStyle as $prop => $val) {
        $ctaVars[] = $prop . ':' . $val;
    }
    $css .= ":root{" . implode(';', $ctaVars) . "}\n";

    // ── 侧边栏风格变异 CSS ──
    $sidebarStyles = variation_sidebar_styles();
    $sidebarStyleIdx = isset($variation['sidebar_style']) ? (int)$variation['sidebar_style'] : 0;
    $sidebarStyle = isset($sidebarStyles[$sidebarStyleIdx]) ? $sidebarStyles[$sidebarStyleIdx] : $sidebarStyles[0];
    $sidebarVars = array();
    foreach ($sidebarStyle as $prop => $val) {
        $sidebarVars[] = $prop . ':' . $val;
    }
    $css .= ":root{" . implode(';', $sidebarVars) . "}\n";

    // ── 栏目页文章列表变异 CSS ──
    $archiveStyles = variation_archive_styles();
    $archiveStyleIdx = isset($variation['archive_style']) ? (int)$variation['archive_style'] : 0;
    $archiveStyle = isset($archiveStyles[$archiveStyleIdx]) ? $archiveStyles[$archiveStyleIdx] : $archiveStyles[0];
    $archiveVars = array();
    foreach ($archiveStyle as $prop => $val) {
        $archiveVars[] = $prop . ':' . $val;
    }
    $css .= ":root{" . implode(';', $archiveVars) . "}\n";

    // 栏目页布局变异 — 通过 body class tv-archive-{layout} 控制
    $archiveLayout = isset($variation['archive_layout']) ? (string)$variation['archive_layout'] : 'horizontal';
    $css .= "\n/* == 栏目页列表布局变异 == */\n";

    if ($archiveLayout === 'grid') {
        // 纵向网格：2 列，卡片上图下文
        $css .= ".tv-archive-grid .archive-grid{display:grid !important;grid-template-columns:repeat(2,1fr) !important;gap:20px !important;flex-direction:unset !important;}\n";
        $css .= ".tv-archive-grid .article-list-card-link{flex-direction:column !important;gap:0 !important;padding:0 !important;}\n";
        $css .= ".tv-archive-grid .article-list-thumb{flex:none !important;width:100% !important;height:180px !important;border-radius:var(--v-list-radius, 8px) var(--v-list-radius, 8px) 0 0 !important;}\n";
        $css .= ".tv-archive-grid .article-list-body{padding:16px 18px 20px !important;gap:8px !important;}\n";
        $css .= ".tv-archive-grid .article-list-title{font-size:16px !important;-webkit-line-clamp:2 !important;}\n";
        $css .= "@media(max-width:560px){.tv-archive-grid .archive-grid{grid-template-columns:1fr !important;}}\n";
    } elseif ($archiveLayout === 'text-only') {
        // 纯文字列表：隐藏缩略图，紧凑排列
        $css .= ".tv-archive-text-only .article-list-thumb{display:none !important;}\n";
        $css .= ".tv-archive-text-only .article-list-card-link{padding:14px 20px !important;gap:0 !important;}\n";
        $css .= ".tv-archive-text-only .article-list-body{gap:4px !important;}\n";
        $css .= ".tv-archive-text-only .article-list-title{font-size:16px !important;}\n";
        $css .= ".tv-archive-text-only .article-list-desc{-webkit-line-clamp:1 !important;}\n";
    } elseif ($archiveLayout === 'large-cover') {
        // 大封面：全宽图 + 底部标题
        $css .= ".tv-archive-large-cover .article-list-card-link{flex-direction:column !important;gap:0 !important;padding:0 !important;}\n";
        $css .= ".tv-archive-large-cover .article-list-thumb{flex:none !important;width:100% !important;height:220px !important;border-radius:var(--v-list-radius, 8px) var(--v-list-radius, 8px) 0 0 !important;}\n";
        $css .= ".tv-archive-large-cover .article-list-body{padding:18px 22px 22px !important;gap:8px !important;}\n";
        $css .= ".tv-archive-large-cover .article-list-title{font-size:18px !important;}\n";
        $css .= "@media(max-width:560px){.tv-archive-large-cover .article-list-thumb{height:180px !important;}}\n";
    }
    // horizontal 是默认布局，不需要额外注入

    // ── 文章页排版变异 CSS ──
    $articleFontSizeKey = isset($variation['article_font_size']) ? (string)$variation['article_font_size'] : 'text-base';
    $articleLineHeightKey = isset($variation['article_line_height']) ? (string)$variation['article_line_height'] : 'leading-normal';
    $articleParaSpacingKey = isset($variation['article_para_spacing']) ? (string)$variation['article_para_spacing'] : 'para-normal';
    $articleTitleStyle = isset($variation['article_title_style']) ? (string)$variation['article_title_style'] : 'title-plain';

    $fontSizes = variation_article_font_sizes();
    $lineHeights = variation_article_line_heights();
    $paraSpacings = variation_article_para_spacings();

    $fontSize = isset($fontSizes[$articleFontSizeKey]) ? $fontSizes[$articleFontSizeKey] : '16px';
    $lineHeight = isset($lineHeights[$articleLineHeightKey]) ? $lineHeights[$articleLineHeightKey] : '1.75';
    $paraSpacing = isset($paraSpacings[$articleParaSpacingKey]) ? $paraSpacings[$articleParaSpacingKey] : '1.5em';

    $css .= "\n/* == 文章页排版变异 == */\n";

    // 正文排版
    $css .= ".tv-article-body article p,.tv-article-body .article-content p,.tv-article-body .article-body p,.tv-article-body .sb-article-content p{";
    $css .= "font-size:{$fontSize};line-height:{$lineHeight};margin-bottom:{$paraSpacing};";
    $css .= "}\n";
    $css .= ".tv-article-body article li,.tv-article-body .article-content li,.tv-article-body .sb-article-content li{font-size:{$fontSize};line-height:{$lineHeight};}\n";

    // 标题样式
    if ($articleTitleStyle === 'title-underline') {
        $css .= ".tv-article-title h1.article-title,.tv-article-title article>h1,.tv-article-title .sb-article-body h1{text-align:left;padding-bottom:12px;border-bottom:3px solid var(--v-primary, #2563eb);display:inline-block;}\n";
    } elseif ($articleTitleStyle === 'title-center') {
        $css .= ".tv-article-title h1.article-title,.tv-article-title article>h1,.tv-article-title .sb-article-body h1{text-align:center;}\n";
    } elseif ($articleTitleStyle === 'title-accent-left') {
        $css .= ".tv-article-title h1.article-title,.tv-article-title article>h1,.tv-article-title .sb-article-body h1{text-align:left;padding-left:16px;border-left:4px solid var(--v-primary, #2563eb);}\n";
    }

    // ── 首页最新文章布局变异 ──
    $hpLatestLayout = isset($variation['hp_latest_layout']) ? (string)$variation['hp_latest_layout'] : 'grid4';
    $css .= "\n/* == 首页最新文章布局变异 == */\n";
    // 通过 --v-hp-article-min-w 控制 auto-fill 网格列数
    $latestMinWMap = array('grid4' => '240px', 'grid3' => '300px', 'grid2' => '420px');
    if (isset($latestMinWMap[$hpLatestLayout])) {
        $css .= ":root{--v-hp-article-min-w:" . $latestMinWMap[$hpLatestLayout] . "}\n";
    } elseif ($hpLatestLayout === 'text-list') {
        // 纯文字双列
        $css .= ":root{--v-hp-article-min-w:420px}\n";
        $css .= ".hp-article-cover{display:none !important;}\n";
        $css .= ".hp-article-item{border-radius:var(--v-radius-md,8px) !important;}\n";
        $css .= ".hp-article-body{padding:14px 18px !important;}\n";
        // 同步支持 .mas-grid (menu_articles_sections)
        $css .= ".mas-card-cover{display:none !important;}\n";
        $css .= ".mas-card{border-radius:var(--v-radius-md,8px) !important;}\n";
        $css .= ".mas-card-body{padding:14px 18px !important;}\n";
    }

    // ── 首页服务面板布局变异 ──
    $hpPanelLayout = isset($variation['hp_panel_layout']) ? (string)$variation['hp_panel_layout'] : 'default';
    $css .= "\n/* == 首页服务面板布局变异 == */\n";
    if ($hpPanelLayout === 'hidden') {
        $css .= ".services-panel,.sb-hero-panel{display:none !important;}\n";
        $css .= ".services-grid{grid-template-columns:repeat(3,1fr) !important;}\n";
        $css .= ".sb-hero{grid-template-columns:1fr !important;}\n";
    } elseif ($hpPanelLayout === 'left') {
        $css .= ".sb-hero-panel{order:-1;}\n";
    } elseif ($hpPanelLayout === 'top') {
        $css .= ".sb-hero{grid-template-columns:1fr !important;}\n";
        $css .= ".sb-hero-panel{order:-1;}\n";
    }

    // ── Services 卡片风格跟随列表变量 ──
    $css .= "\n/* == Services 卡片变异 == */\n";
    $css .= ".service-card{background:var(--v-list-bg,#ffffff);border:var(--v-list-border,1px solid var(--border-color,#e2e8f0));border-radius:var(--v-list-radius,var(--radius-xl,16px));box-shadow:var(--v-list-shadow,none);}\n";
    $css .= ".service-card:hover{box-shadow:var(--v-list-shadow-hover,0 8px 28px rgba(0,0,0,0.1));}\n";
    $css .= ".service-card .card-icon{background:color-mix(in srgb, var(--v-primary,#3b82f6) 10%, transparent);}\n";

    // ── 分页样式变异 CSS ──
    $pagiStyles = variation_pagination_styles();
    $pagiIdx = isset($variation['pagination_style']) ? (int)$variation['pagination_style'] : 0;
    $pagiStyle = isset($pagiStyles[$pagiIdx]) ? $pagiStyles[$pagiIdx] : $pagiStyles[0];
    $css .= "\n/* == 分页样式变异 == */\n";
    $css .= ":root{";
    $css .= "--v-pagi-align:" . $pagiStyle['align'] . ";";
    $css .= "--v-pagi-radius:" . $pagiStyle['radius'] . ";";
    $css .= "--v-pagi-border:" . $pagiStyle['border'] . ";";
    $css .= "--v-pagi-bg:" . $pagiStyle['bg'] . ";";
    $css .= "--v-pagi-active-bg:var(--v-primary,#3b82f6);";
    $css .= "--v-pagi-active-color:#fff;";
    $css .= "--v-pagi-hover-color:var(--v-primary,#3b82f6);";
    $css .= "}\n";

    // ── 首屏统计卡片变异 CSS ──
    $statStyles = variation_stat_styles();
    $statIdx = isset($variation['stat_style']) ? (int)$variation['stat_style'] : 0;
    $statStyle = isset($statStyles[$statIdx]) ? $statStyles[$statIdx] : $statStyles[0];
    $css .= "\n/* == 首屏统计卡片变异 == */\n";
    $css .= ":root{";
    $css .= "--v-stat-cols:" . $statStyle['cols'] . ";";
    $css .= "--v-stat-radius:" . $statStyle['radius'] . ";";
    $css .= "--v-stat-bg:" . $statStyle['bg'] . ";";
    $css .= "--v-stat-border:" . $statStyle['border'] . ";";
    $css .= "--v-stat-padding:" . $statStyle['padding'] . ";";
    if (!empty($statStyle['text']) && $statStyle['text'] !== 'inherit') {
        $css .= "--v-stat-text:" . $statStyle['text'] . ";";
    }
    if (!empty($statStyle['text_secondary']) && $statStyle['text_secondary'] !== 'inherit') {
        $css .= "--v-stat-text-secondary:" . $statStyle['text_secondary'] . ";";
    }
    if (!empty($statStyle['num_bg'])) {
        $css .= "--v-stat-num-bg:" . $statStyle['num_bg'] . ";";
    }
    if (!empty($statStyle['num_color']) && $statStyle['num_color'] !== 'inherit') {
        $css .= "--v-stat-num-color:" . $statStyle['num_color'] . ";";
    }
    if (!empty($statStyle['hover'])) {
        $css .= "--v-stat-hover-transform:translateY(-2px);";
        $css .= "--v-stat-hover-shadow:0 4px 16px rgba(0,0,0,0.08);";
    }
    $css .= "}\n";
    // 圆形需要等比
    if (!empty($statStyle['aspect'])) {
        $css .= ".stat-item,.sb-stat{aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center;}\n";
    }
    // 混合模式：前2个圆形、后2个卡片
    if (!empty($statStyle['mix'])) {
        $css .= ".stat-item:nth-child(-n+2),.sb-stat:nth-child(-n+2){border-radius:50%;aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center;background:color-mix(in srgb,var(--v-primary,#3b82f6) 6%,transparent);border:2px solid color-mix(in srgb,var(--v-primary,#3b82f6) 15%,transparent);}\n";
    }

    // ── 页脚导航变异 CSS ──
    $fNavStyles = variation_footer_nav_styles();
    $fNavIdx = isset($variation['footer_nav_style']) ? (int)$variation['footer_nav_style'] : 0;
    $fNavStyle = isset($fNavStyles[$fNavIdx]) ? $fNavStyles[$fNavIdx] : $fNavStyles[0];
    $css .= "\n/* == 页脚导航变异 == */\n";
    $css .= ":root{--v-fnav-display:" . $fNavStyle['display'] . ";--v-fnav-gap:" . $fNavStyle['gap'] . ";}\n";
    if ($fNavStyle['separator'] === 'dot') {
        $css .= ".footer-nav li + li::before,.sb-footer-nav a + a::before{content:'·';color:var(--v-footer-text-muted,rgba(255,255,255,0.4));margin-right:0.5rem;}\n";
    } elseif ($fNavStyle['separator'] === 'line') {
        $css .= ".footer-nav li + li,.sb-footer-nav a + a{padding-left:1rem;border-left:1px solid var(--v-footer-border,rgba(255,255,255,0.15));margin-left:1rem;}\n";
    }
    if ($fNavStyle['display'] === 'block') {
        $css .= ".footer-nav li{margin-bottom:0.625rem;}\n";
    }

    // ── 导航菜单变异 CSS ──
    $navStyle = isset($variation['nav_style']) ? (string)$variation['nav_style'] : 'underline';
    $navPosition = isset($variation['nav_position']) ? (string)$variation['nav_position'] : 'right';
    $navGap = isset($variation['nav_gap']) ? (string)$variation['nav_gap'] : 'normal';
    $css .= "\n/* == 导航菜单变异 == */\n";

    // 导航位置
    if ($navPosition === 'left') {
        $css .= ".header-content,.sb-topbar{justify-content:flex-start;gap:1rem;}\n";
        $css .= ".header-content .logo,.sb-topbar .sb-logo{margin-right:1.5rem;}\n";
        $css .= ".header-content .nav,.sb-topbar .sb-nav{margin-right:auto;}\n";
        $css .= ".header-search{margin-left:auto;}\n";
    } elseif ($navPosition === 'center') {
        $css .= ".header-content,.sb-topbar{justify-content:space-between;}\n";
        $css .= ".header-content .nav,.sb-topbar .sb-nav{position:absolute;left:50%;transform:translateX(-50%);}\n";
        $css .= ".header-content,.sb-topbar{position:relative;}\n";
        $css .= "@media(max-width:1024px){.header-content .nav,.sb-topbar .sb-nav{position:static;transform:none;}}\n";
    }
    // right 是默认（space-between），无需额外CSS

    // 导航间距
    $gapMap = array('tight' => '0.125rem', 'normal' => '0.25rem', 'wide' => '0.75rem');
    $gapVal = isset($gapMap[$navGap]) ? $gapMap[$navGap] : '0.25rem';
    $css .= ".nav-links,.menu-nav,.sb-nav{gap:{$gapVal};}\n";

    // 导航样式
    $pColor = 'var(--v-primary, #3b82f6)';
    $pLight = 'var(--v-primary-light, #dbeafe)';
    switch ($navStyle) {
        case 'underline':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:0;padding:0.5rem 0.75rem;border-bottom:2px solid transparent;}\n";
            $css .= ".nav-links a:hover,.menu-nav a:hover,.sb-nav a:hover{border-bottom-color:{$pColor};background:none;}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{border-bottom-color:{$pColor};color:{$pColor};background:none;font-weight:600;}\n";
            break;
        case 'pill':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:9999px;padding:0.4rem 1rem;}\n";
            $css .= ".nav-links a:hover,.menu-nav a:hover,.sb-nav a:hover{background:color-mix(in srgb,{$pColor} 8%,transparent);}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{background:{$pColor};color:#fff;}\n";
            break;
        case 'rounded':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:8px;padding:0.4rem 0.875rem;}\n";
            $css .= ".nav-links a:hover,.menu-nav a:hover,.sb-nav a:hover{background:color-mix(in srgb,{$pColor} 8%,transparent);}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{background:{$pColor};color:#fff;}\n";
            break;
        case 'square':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:0;padding:0.4rem 0.875rem;}\n";
            $css .= ".nav-links a:hover,.menu-nav a:hover,.sb-nav a:hover{background:color-mix(in srgb,{$pColor} 8%,transparent);}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{background:{$pColor};color:#fff;}\n";
            break;
        case 'outline-pill':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:9999px;padding:0.35rem 0.875rem;border:1.5px solid transparent;}\n";
            $css .= ".nav-links a:hover,.menu-nav a:hover,.sb-nav a:hover{border-color:{$pColor};background:none;}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{border-color:{$pColor};color:{$pColor};background:none;font-weight:600;}\n";
            break;
        case 'dot':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:0;padding:0.5rem 0.75rem;position:relative;}\n";
            $css .= ".nav-links a::after,.menu-nav a::after,.sb-nav a::after{content:'';position:absolute;bottom:2px;left:50%;width:0;height:3px;border-radius:3px;background:{$pColor};transform:translateX(-50%);transition:width 0.2s;}\n";
            $css .= ".nav-links a:hover::after,.menu-nav a:hover::after,.sb-nav a:hover::after{width:6px;}\n";
            $css .= ".nav-links a.is-active::after,.menu-nav a.is-active::after,.sb-nav a.is-active::after{width:6px;}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{color:{$pColor};background:none;font-weight:600;}\n";
            break;
        case 'bracket':
            $css .= ".nav-links a,.menu-nav a,.sb-nav a{border-radius:0;padding:0.5rem 0.75rem;position:relative;}\n";
            $css .= ".nav-links a::before,.nav-links a::after,.menu-nav a::before,.menu-nav a::after,.sb-nav a::before,.sb-nav a::after{content:'';position:absolute;top:50%;width:3px;height:0;background:{$pColor};transition:height 0.2s;transform:translateY(-50%);}\n";
            $css .= ".nav-links a::before,.menu-nav a::before,.sb-nav a::before{left:0;}\n";
            $css .= ".nav-links a::after,.menu-nav a::after,.sb-nav a::after{right:0;}\n";
            $css .= ".nav-links a:hover::before,.nav-links a:hover::after,.menu-nav a:hover::before,.menu-nav a:hover::after,.sb-nav a:hover::before,.sb-nav a:hover::after{height:60%;}\n";
            $css .= ".nav-links a.is-active::before,.nav-links a.is-active::after,.menu-nav a.is-active::before,.menu-nav a.is-active::after,.sb-nav a.is-active::before,.sb-nav a.is-active::after{height:60%;}\n";
            $css .= ".nav-links a.is-active,.menu-nav a.is-active,.sb-nav a.is-active{color:{$pColor};background:none;font-weight:600;}\n";
            break;
    }

    return $css;
}

// ──────────────────────────────────────────────
// 11. HTML 类名前缀替换
// ──────────────────────────────────────────────
function apply_class_prefix($html, $prefix)
{
    $prefix = trim((string)$prefix);
    if ($prefix === '') {
        return $html;
    }

    // 替换 class="xxx" 中的类名，添加前缀
    // 只替换模板自定义类（以字母开头），跳过框架类（如 h-4, w-5 等）
    $html = preg_replace_callback(
        '/\bclass\s*=\s*"([^"]+)"/i',
        function ($match) use ($prefix) {
            $classes = preg_split('/\s+/', trim($match[1]));
            $prefixed = array();
            foreach ($classes as $cls) {
                if ($cls === '') {
                    continue;
                }
                // 跳过工具类：h-N, w-N, p-N, m-N, text-N, flex, grid, hidden 等
                if (preg_match('/^(h|w|p|m|px|py|mx|my|mb|mt|ml|mr|pt|pb|pl|pr|text|flex|grid|hidden|block|inline|relative|absolute|fixed|sticky|overflow|z|gap|col|row|items|justify|self|order|float|clear|sr)-/', $cls)) {
                    $prefixed[] = $cls;
                    continue;
                }
                // 跳过纯数字或尺寸类
                if (preg_match('/^\d/', $cls)) {
                    $prefixed[] = $cls;
                    continue;
                }
                $prefixed[] = $prefix . '-' . $cls;
            }
            return 'class="' . implode(' ', $prefixed) . '"';
        },
        $html
    );

    return $html;
}

// ──────────────────────────────────────────────
// 12. CSS 类名前缀替换（匹配 HTML 变更）
// ──────────────────────────────────────────────
function apply_css_class_prefix($css, $prefix)
{
    $prefix = trim((string)$prefix);
    if ($prefix === '') {
        return $css;
    }

    // 替换 CSS 选择器中的类名 .xxx → .prefix-xxx
    // 保留伪类、伪元素、媒体查询等
    $css = preg_replace_callback(
        '/\.([a-zA-Z][a-zA-Z0-9_-]*)/',
        function ($match) use ($prefix) {
            $cls = $match[1];
            // 跳过工具类前缀
            if (preg_match('/^(h|w|p|m|px|py|mx|my|mb|mt|ml|mr|pt|pb|pl|pr|text|flex|grid|hidden|block|inline|relative|absolute|fixed|sticky|overflow|z|gap|col|row|items|justify|self|order|float|clear|sr)-/', $cls)) {
                return '.' . $cls;
            }
            return '.' . $prefix . '-' . $cls;
        },
        $css
    );

    return $css;
}

// ──────────────────────────────────────────────
// 13. 首页模块顺序重排（在 HTML 中重排 <section> 块）
// ──────────────────────────────────────────────
function apply_module_reorder($html, $moduleOrder)
{
    if (!is_array($moduleOrder) || empty($moduleOrder)) {
        return $html;
    }

    // ── 屏蔽 main/aside/article/nav/header/footer 等容器内部，避免其中嵌套的
    //    <section> 被误认为顶级 section（例如 {{menu_articles_sections}} 生成的
    //    .mas-section 都在 <main> 内部，不应参与首页模块重排）
    $hidden = array();
    $counter = 0;
    $maskPattern = '#<(main|aside|article|nav|header|footer)\b[^>]*>.*?</\1>#is';
    $htmlMasked = preg_replace_callback($maskPattern, function ($m) use (&$hidden, &$counter) {
        $token = '__MR_HIDE_' . $counter++ . '__';
        $hidden[$token] = $m[0];
        return $token;
    }, $html);
    if ($htmlMasked === null) {
        $htmlMasked = $html; // 正则失败时退化为原始 html
    }

    // 在屏蔽后的 HTML 中匹配顶级 <section> 块
    if (!preg_match_all('#(<section\b[^>]*>.*?</section>)#is', $htmlMasked, $matches, PREG_OFFSET_CAPTURE)) {
        return $html;
    }

    $sections = $matches[0]; // 每项: [0] => html, [1] => offset
    if (count($sections) < 2) {
        return $html;
    }

    // 按 moduleOrder 构造新顺序数组（长度 = sections 数量）
    $count = count($sections);
    $newOrder = array();
    foreach ($moduleOrder as $idx) {
        $idx = (int)$idx;
        if ($idx >= 0 && $idx < $count && !in_array($idx, $newOrder, true)) {
            $newOrder[] = $idx;
        }
    }
    for ($i = 0; $i < $count; $i++) {
        if (!in_array($i, $newOrder, true)) {
            $newOrder[] = $i;
        }
    }

    // 就地替换：从后向前遍历原位置，将位置 i 的内容替换为 sections[newOrder[i]] 的 HTML
    // 这样保留 section 之间的所有非 section 内容（包括屏蔽占位符）
    $newMasked = $htmlMasked;
    for ($i = $count - 1; $i >= 0; $i--) {
        $offset = $sections[$i][1];
        $oldLen = strlen($sections[$i][0]);
        $newContent = $sections[$newOrder[$i]][0];
        $newMasked = substr($newMasked, 0, $offset) . $newContent . substr($newMasked, $offset + $oldLen);
    }

    // 还原被屏蔽的容器
    if (!empty($hidden)) {
        $newMasked = str_replace(array_keys($hidden), array_values($hidden), $newMasked);
    }

    return $newMasked;
}

// ──────────────────────────────────────────────
// 14. 语义标签变体
// ──────────────────────────────────────────────
function apply_semantic_variation($html, $domainId)
{
    $variant = variation_pick($domainId, 'semantic', 3);

    switch ($variant) {
        case 1:
            // 将部分 <section> 替换为 <div role="region">
            $count = 0;
            $html = preg_replace_callback('#<section(\b[^>]*)>#i', function ($m) use (&$count) {
                $count++;
                // 每隔一个替换
                if ($count % 2 === 0) {
                    return '<div role="region"' . $m[1] . '>';
                }
                return $m[0];
            }, $html);
            $count = 0;
            $html = preg_replace_callback('#</section>#i', function ($m) use (&$count) {
                $count++;
                if ($count % 2 === 0) {
                    return '</div>';
                }
                return $m[0];
            }, $html);
            break;

        case 2:
            // 将首屏 <h1> 外层添加 <hgroup>
            $html = preg_replace('#(<h1\b[^>]*>.*?</h1>)#is', '<hgroup>$1</hgroup>', $html, 1);
            break;

        default:
            // variant 0: 保持原样
            break;
    }

    return $html;
}

// ──────────────────────────────────────────────
// 15. 主入口：应用所有变异到 HTML
// ──────────────────────────────────────────────
function apply_template_variation($html, $cssContent, $domainId, $isHomepage = false)
{
    $domainId = (int)$domainId;
    if ($domainId <= 0) {
        return array('html' => $html, 'css' => $cssContent);
    }

    $variation = get_domain_variation($domainId);
    if (!is_array($variation) || empty($variation)) {
        return array('html' => $html, 'css' => $cssContent);
    }

    $prefix = isset($variation['class_prefix']) ? (string)$variation['class_prefix'] : '';

    // 1. 首页模块顺序重排
    if ($isHomepage && isset($variation['module_order'])) {
        $html = apply_module_reorder($html, $variation['module_order']);
    }

    // 2. 语义标签变体
    $html = apply_semantic_variation($html, $domainId);

    // 3. 类名前缀替换
    if ($prefix !== '') {
        $html = apply_class_prefix($html, $prefix);
        $cssContent = apply_css_class_prefix($cssContent, $prefix);
    }

    // 4. 构建变异 CSS
    $variationCss = build_variation_css($variation);

    // 将变异 CSS 追加到模板 CSS 后面（确保优先级覆盖）
    $cssContent = $cssContent . "\n/* == Template Variation == */\n" . $variationCss;

    return array('html' => $html, 'css' => $cssContent);
}
