<?php
/**
 * ZERTI admin visual themes — catalog, customization, and CSS variable output.
 */
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Available visual themes for the ZERTI admin panel.
 *
 * @return array<string, string>
 */
function zerti_visual_theme_catalog(): array
{
    return apply_filters('zerti_visual_theme_catalog', [
        'zerti' => __('Zerti theme original', 'zerti'),
        'rabbitmp' => __('rabbitMP theme', 'zerti'),
        'demerzel' => __('Demerzel theme', 'zerti'),
    ]);
}

/**
 * Sanitize stored visual theme id.
 */
function zerti_sanitize_visual_theme(string $value): string
{
    $value = sanitize_key($value);
    if ($value === 'rabitmh') {
        $value = 'rabbitmp';
    }

    return array_key_exists($value, zerti_visual_theme_catalog()) ? $value : 'zerti';
}

/**
 * Active visual theme for the ZERTI admin shell.
 */
function zerti_get_visual_theme(): string
{
    $settings = zerti_get_plugin_settings();

    return zerti_sanitize_visual_theme(
        isset($settings['general']['visual_theme']) ? (string) $settings['general']['visual_theme'] : 'zerti'
    );
}

/**
 * Default customizable values for the rabbitMP theme.
 *
 * @return array<string, string>
 */
function zerti_rabbitmp_theme_defaults(): array
{
    return [
        'brand' => '#e8590c',
        'brand_hover' => '#d9480f',
        'dark_bg' => '#1a1b1e',
        'dark_subtle_bg' => '#25262b',
        'dark_border' => '#373a40',
        'dark_text' => '#e9ecef',
        'dark_muted' => '#adb5bd',
        'dark_link_hover' => '#ced4da',
        'light_bg' => '#ffffff',
        'light_subtle_bg' => '#f8f9fa',
        'light_border' => '#dee2e6',
        'light_text' => '#212529',
        'light_muted' => '#6c757d',
        'light_link_hover' => '#6c757d',
        'btn_primary_grad_1' => '#862e0e',
        'btn_primary_grad_2' => '#e8590c',
        'btn_primary_grad_3' => '#fd7e14',
        'btn_primary_grad_4' => '#fab005',
        'btn_primary_grad_5' => '#ffe8cc',
        'btn_outline_grad_1' => '#e8590c',
        'btn_outline_grad_2' => '#fd7e14',
        'btn_outline_grad_3' => '#20c997',
        'font_size_base' => '9pt',
        'font_size_sm' => '0.875em',
        'btn_font_size' => '0.8125rem',
        'btn_min_height' => '2.125rem',
        'btn_border_radius' => '6px',
        'radius_sm' => '4px',
        'radius_md' => '6px',
        'radius_lg' => '8px',
        'radius_panel' => '14px',
        'radius_input' => '6px',
        'radius_card' => '12px',
        'radius_pill' => '25px',
    ];
}

/**
 * Original Zerti theme border-radius defaults (from zerti-tokens.css).
 *
 * @return array<string, string>
 */
function zerti_theme_radius_zerti_defaults(): array
{
    return [
        'radius_sm' => '4px',
        'radius_md' => '6px',
        'radius_lg' => '8px',
        'radius_panel' => '14px',
        'radius_input' => '6px',
        'radius_card' => '12px',
        'radius_pill' => '25px',
        'btn_border_radius' => '6px',
    ];
}

/**
 * Zerti default radius for one rabbitMP radius key (px integer for the slider).
 */
function zerti_theme_radius_zerti_default_px(string $key): int
{
    $defaults = zerti_theme_radius_zerti_defaults();
    $value = isset($defaults[$key]) ? (string) $defaults[$key] : '0px';

    return zerti_theme_radius_value_to_px_int($value, 0);
}

/**
 * Maximum border-radius slider value (px) in rabbitMP theme settings.
 */
function zerti_theme_radius_px_max(): int
{
    return 25;
}

/**
 * Parse a stored radius into an integer pixel value for the range slider.
 */
function zerti_theme_radius_value_to_px_int(string $value, int $fallback = 0): int
{
    $value = trim($value);
    $max = zerti_theme_radius_px_max();

    if (preg_match('/^(\d+)px$/i', $value, $matches)) {
        return min($max, max(0, (int) $matches[1]));
    }
    if (preg_match('/^(\d+(?:\.\d+)?)rem$/', $value, $matches)) {
        return min($max, max(0, (int) round((float) $matches[1] * 16)));
    }
    if (preg_match('/^(\d+(?:\.\d+)?)em$/', $value, $matches)) {
        return min($max, max(0, (int) round((float) $matches[1] * 16)));
    }

    return min($max, max(0, $fallback));
}

/**
 * Sanitize a rabbitMP border-radius value as px between 0 and 25.
 */
function zerti_sanitize_theme_radius_px(string $value, string $fallback): string
{
    $fallback_px = zerti_theme_radius_value_to_px_int($fallback, 0);
    $px = zerti_theme_radius_value_to_px_int($value, $fallback_px);

    return $px . 'px';
}

/**
 * Whether a customizable theme setting key is a px radius slider.
 */
function zerti_customizable_theme_is_radius_key(string $key): bool
{
    return zerti_str_starts_with($key, 'radius_') || $key === 'btn_border_radius';
}

/**
 * Whether a rabbitMP theme setting key is a px radius slider.
 */
function zerti_rabbitmp_theme_is_radius_key(string $key): bool
{
    return zerti_customizable_theme_is_radius_key($key);
}

/**
 * Sanitize a hex color value (#rgb or #rrggbb).
 */
function zerti_sanitize_theme_color(string $value, string $fallback): string
{
    $value = sanitize_text_field(trim($value));
    if (preg_match('/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $value)) {
        return strtolower($value);
    }

    return $fallback;
}

/**
 * Sanitize a CSS length value (pt, px, rem, em, %).
 */
function zerti_sanitize_theme_length(string $value, string $fallback): string
{
    $value = sanitize_text_field(trim($value));
    if ($value === '') {
        return $fallback;
    }
    if (preg_match('/^\d+(\.\d+)?(pt|px|rem|em|%)$/', $value)) {
        return $value;
    }

    return $fallback;
}

/**
 * @param array<string, mixed> $raw
 * @param array<string, string> $defaults
 * @return array<string, string>
 */
function zerti_sanitize_customizable_theme_settings(array $raw, array $defaults): array
{
    $sanitized = [];

    foreach ($defaults as $key => $default) {
        $raw_value = isset($raw[$key]) ? (string) $raw[$key] : $default;
        if (zerti_customizable_theme_is_radius_key($key)) {
            $sanitized[$key] = zerti_sanitize_theme_radius_px($raw_value, $default);
        } elseif (zerti_str_starts_with($key, 'font_') || zerti_str_starts_with($key, 'btn_')) {
            $sanitized[$key] = zerti_sanitize_theme_length($raw_value, $default);
        } else {
            $sanitized[$key] = zerti_sanitize_theme_color($raw_value, $default);
        }
    }

    return $sanitized;
}

/**
 * @param array<string, mixed> $raw
 * @return array<string, string>
 */
function zerti_sanitize_rabbitmp_theme_settings(array $raw): array
{
    return zerti_sanitize_customizable_theme_settings($raw, zerti_rabbitmp_theme_defaults());
}

/**
 * Stored rabbitMP theme customization (merged with defaults).
 *
 * @return array<string, string>
 */
function zerti_get_rabbitmp_theme_settings(): array
{
    $defaults = zerti_rabbitmp_theme_defaults();
    $settings = zerti_get_plugin_settings();
    $stored = [];
    if (isset($settings['general']['rabbitmp_theme']) && is_array($settings['general']['rabbitmp_theme'])) {
        $stored = $settings['general']['rabbitmp_theme'];
    } elseif (isset($settings['general']['rabitmh_theme']) && is_array($settings['general']['rabitmh_theme'])) {
        $stored = $settings['general']['rabitmh_theme'];
    }

    return zerti_sanitize_rabbitmp_theme_settings(array_merge($defaults, $stored));
}

/**
 * Convert #rrggbb to comma-separated RGB components.
 */
function zerti_theme_hex_to_rgb(string $hex): string
{
    $hex = ltrim($hex, '#');
    if (strlen($hex) === 3) {
        $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
    }
    if (strlen($hex) !== 6 || !ctype_xdigit($hex)) {
        return '113, 44, 249';
    }

    return sprintf(
        '%d, %d, %d',
        hexdec(substr($hex, 0, 2)),
        hexdec(substr($hex, 2, 2)),
        hexdec(substr($hex, 4, 2))
    );
}

/**
 * Build CSS custom properties for the active rabbitMP theme.
 *
 * @return array<string, string>
 */
function zerti_rabbitmp_theme_css_variables(): array
{
    $t = zerti_get_rabbitmp_theme_settings();
    $brand_rgb = zerti_theme_hex_to_rgb($t['brand']);

    return [
        '--zerti-brand' => $t['brand'],
        '--zerti-brand-hover' => $t['brand_hover'],
        '--zerti-brand-rgb' => $brand_rgb,
        '--zerti-bs-purple' => $t['brand'],
        '--zerti-bs-purple-hover' => $t['brand_hover'],
        '--bs-primary' => $t['brand'],
        '--bs-primary-rgb' => $brand_rgb,
        '--bs-link-color' => $t['brand'],
        '--bs-link-color-rgb' => $brand_rgb,
        '--bs-focus-ring-color' => sprintf('rgba(%s, 0.25)', $brand_rgb),
        '--zerti-font-size-base' => $t['font_size_base'],
        '--zerti-font-size-sm' => $t['font_size_sm'],
        '--zerti-btn-font-size' => $t['btn_font_size'],
        '--zerti-btn-min-height' => $t['btn_min_height'],
        '--zerti-btn-border-radius' => $t['btn_border_radius'],
        '--zerti-radius-sm' => $t['radius_sm'],
        '--zerti-radius-md' => $t['radius_md'],
        '--zerti-radius-lg' => $t['radius_lg'],
        '--zerti-radius-panel' => $t['radius_panel'],
        '--zerti-component-panel-radius' => $t['radius_panel'],
        '--zerti-radius-input' => $t['radius_input'],
        '--zerti-radius-card' => $t['radius_card'],
        '--zerti-radius-pill' => $t['radius_pill'],
        '--zerti-btn-primary-gradient' => sprintf(
            'linear-gradient(135deg, %s 0%%, %s 18%%, %s 45%%, %s 72%%, %s 100%%)',
            $t['btn_primary_grad_1'],
            $t['btn_primary_grad_2'],
            $t['btn_primary_grad_3'],
            $t['btn_primary_grad_4'],
            $t['btn_primary_grad_5']
        ),
        '--zerti-btn-primary-hover-shadow' => sprintf('rgba(%s, 0.45)', $brand_rgb),
        '--zerti-btn-primary-focus-shadow' => sprintf('rgba(%s, 0.45)', $brand_rgb),
        '--zerti-btn-outline-border-gradient' => sprintf(
            'linear-gradient(135deg, %s 0%%, %s 45%%, %s 100%%)',
            $t['btn_outline_grad_1'],
            $t['btn_outline_grad_2'],
            $t['btn_outline_grad_3']
        ),
        '--zerti-btn-outline-hover-shadow' => sprintf('rgba(%s, 0.28)', $brand_rgb),
        '--zerti-btn-outline-focus-shadow' => sprintf('rgba(%s, 0.35)', $brand_rgb),
        '--zerti-docs-accent' => $t['brand'],
        '--wp-admin-theme-color' => $t['brand'],
        '--zerti-chart-brand-border' => sprintf('rgba(%s, 0.85)', $brand_rgb),
        '--zerti-chart-brand-fill' => sprintf('rgba(%s, 0.12)', $brand_rgb),
    ];
}

/**
 * Build rabbitMP visual theme CSS (for wp_add_inline_style).
 */
function zerti_get_rabbitmp_theme_inline_css(): string
{
    if (zerti_get_visual_theme() !== 'rabbitmp') {
        return '';
    }

    $t = zerti_get_rabbitmp_theme_settings();
    $vars = zerti_rabbitmp_theme_css_variables();
    $base_rules = [];
    foreach ($vars as $name => $value) {
        $base_rules[] = $name . ':' . $value;
    }

    $dark_rules = [
        '--zerti-docs-bg:' . $t['dark_bg'],
        '--zerti-docs-subtle-bg:' . $t['dark_subtle_bg'],
        '--zerti-docs-border:' . $t['dark_border'],
        '--zerti-docs-text:' . $t['dark_text'],
        '--zerti-docs-muted:' . $t['dark_muted'],
        '--zerti-link-hover-color:' . $t['dark_link_hover'],
    ];
    $light_rules = [
        '--zerti-docs-bg:' . $t['light_bg'],
        '--zerti-docs-subtle-bg:' . $t['light_subtle_bg'],
        '--zerti-docs-border:' . $t['light_border'],
        '--zerti-docs-text:' . $t['light_text'],
        '--zerti-docs-muted:' . $t['light_muted'],
        '--zerti-link-hover-color:' . $t['light_link_hover'],
    ];

    return '#zertiAdmin[data-zerti-visual-theme="rabbitmp"]{' . implode(';', $base_rules) . ';}'
        . '#zertiAdmin[data-zerti-visual-theme="rabbitmp"][data-bs-theme="dark"]{' . implode(';', $dark_rules) . ';}'
        . '#zertiAdmin[data-zerti-visual-theme="rabbitmp"][data-bs-theme="light"]{' . implode(';', $light_rules) . ';}';
}

/**
 * Style handle that is always enqueued on the ZERTI admin screen (last CSS layer).
 */
function zerti_visual_theme_inline_style_handle(): string
{
    return function_exists('zerti_admin_css_stack_handle')
        ? zerti_admin_css_stack_handle()
        : 'zerti-tokens';
}

/**
 * Enqueue active visual theme overrides on the ZERTI admin screen.
 */
function zerti_enqueue_visual_theme_inline_styles(): void
{
    $css = zerti_get_rabbitmp_theme_inline_css() . zerti_get_demerzel_theme_inline_css();
    if ($css === '') {
        return;
    }

    wp_add_inline_style(zerti_visual_theme_inline_style_handle(), $css);
}

/**
 * Enqueue rabbitMP theme overrides on the ZERTI admin screen.
 */
function zerti_enqueue_rabbitmp_theme_inline_style(): void
{
    zerti_enqueue_visual_theme_inline_styles();
}

/**
 * Default customizable values for the Demerzel theme (cursor.com-inspired).
 *
 * @return array<string, string>
 */
function zerti_demerzel_theme_defaults(): array
{
    return [
        'brand' => '#e4e4e4',
        'brand_hover' => '#ffffff',
        'dark_bg' => '#0b0b0b',
        'dark_subtle_bg' => '#141414',
        'dark_border' => '#2a2a2a',
        'dark_text' => '#ececec',
        'dark_muted' => '#8e8e8e',
        'dark_link_hover' => '#ffffff',
        'light_bg' => '#f7f7f4',
        'light_subtle_bg' => '#ffffff',
        'light_border' => '#e6e5e0',
        'light_text' => '#26251e',
        'light_muted' => '#807d72',
        'light_link_hover' => '#5a5852',
        'btn_primary_grad_1' => '#4c1d95',
        'btn_primary_grad_2' => '#5b21b6',
        'btn_primary_grad_3' => '#712cf9',
        'btn_primary_grad_4' => '#4c6ef5',
        'btn_primary_grad_5' => '#228be6',
        'btn_outline_grad_1' => '#712cf9',
        'btn_outline_grad_2' => '#4c6ef5',
        'btn_outline_grad_3' => '#15aabf',
        'font_size_base' => '10pt',
        'font_size_sm' => '0.875em',
        'btn_font_size' => '0.875rem',
        'btn_min_height' => '2.5rem',
        'btn_border_radius' => '8px',
        'radius_sm' => '4px',
        'radius_md' => '8px',
        'radius_lg' => '12px',
        'radius_panel' => '12px',
        'radius_input' => '8px',
        'radius_card' => '12px',
        'radius_pill' => '25px',
    ];
}

/**
 * @param array<string, mixed> $raw
 * @return array<string, string>
 */
function zerti_sanitize_demerzel_theme_settings(array $raw): array
{
    return zerti_sanitize_customizable_theme_settings($raw, zerti_demerzel_theme_defaults());
}

/**
 * Stored Demerzel theme customization (merged with defaults).
 *
 * @return array<string, string>
 */
function zerti_get_demerzel_theme_settings(): array
{
    $defaults = zerti_demerzel_theme_defaults();
    $settings = zerti_get_plugin_settings();
    $stored = [];
    if (isset($settings['general']['demerzel_theme']) && is_array($settings['general']['demerzel_theme'])) {
        $stored = $settings['general']['demerzel_theme'];
    }

    return zerti_sanitize_demerzel_theme_settings(array_merge($defaults, $stored));
}

/**
 * Default radius for one theme radius key (px integer for the slider reset).
 */
function zerti_theme_radius_default_px(string $theme_slug, string $key): int
{
    if ($theme_slug === 'demerzel') {
        $defaults = zerti_demerzel_theme_defaults();
        $value = isset($defaults[$key]) ? (string) $defaults[$key] : '0px';

        return zerti_theme_radius_value_to_px_int($value, 0);
    }

    return zerti_theme_radius_zerti_default_px($key);
}

/**
 * Build CSS custom properties for the active Demerzel theme.
 *
 * @return array<string, string>
 */
function zerti_demerzel_theme_css_variables(): array
{
    $t = zerti_get_demerzel_theme_settings();
    $brand_rgb = zerti_theme_hex_to_rgb($t['brand']);

    return [
        '--zerti-brand' => $t['brand'],
        '--zerti-brand-hover' => $t['brand_hover'],
        '--zerti-brand-rgb' => $brand_rgb,
        '--zerti-bs-purple' => $t['brand'],
        '--zerti-bs-purple-hover' => $t['brand_hover'],
        '--bs-primary' => $t['brand'],
        '--bs-primary-rgb' => $brand_rgb,
        '--bs-link-color' => $t['brand'],
        '--bs-link-color-rgb' => $brand_rgb,
        '--bs-focus-ring-color' => sprintf('rgba(%s, 0.25)', $brand_rgb),
        '--zerti-font-size-base' => $t['font_size_base'],
        '--zerti-font-size-sm' => $t['font_size_sm'],
        '--zerti-btn-font-size' => $t['btn_font_size'],
        '--zerti-btn-min-height' => $t['btn_min_height'],
        '--zerti-btn-border-radius' => $t['btn_border_radius'],
        '--zerti-radius-sm' => $t['radius_sm'],
        '--zerti-radius-md' => $t['radius_md'],
        '--zerti-radius-lg' => $t['radius_lg'],
        '--zerti-radius-panel' => $t['radius_panel'],
        '--zerti-component-panel-radius' => $t['radius_panel'],
        '--zerti-radius-input' => $t['radius_input'],
        '--zerti-radius-card' => $t['radius_card'],
        '--zerti-radius-pill' => $t['radius_pill'],
        '--zerti-btn-primary-gradient' => sprintf(
            'linear-gradient(135deg, %s 0%%, %s 18%%, %s 45%%, %s 72%%, %s 100%%)',
            $t['btn_primary_grad_1'],
            $t['btn_primary_grad_2'],
            $t['btn_primary_grad_3'],
            $t['btn_primary_grad_4'],
            $t['btn_primary_grad_5']
        ),
        '--zerti-btn-primary-hover-shadow' => 'rgba(113, 44, 249, 0.45)',
        '--zerti-btn-primary-focus-shadow' => 'rgba(113, 44, 249, 0.45)',
        '--zerti-btn-outline-border-gradient' => sprintf(
            'linear-gradient(135deg, %s 0%%, %s 45%%, %s 100%%)',
            $t['btn_outline_grad_1'],
            $t['btn_outline_grad_2'],
            $t['btn_outline_grad_3']
        ),
        '--zerti-btn-outline-hover-shadow' => 'rgba(113, 44, 249, 0.28)',
        '--zerti-btn-outline-focus-shadow' => 'rgba(113, 44, 249, 0.35)',
        '--zerti-docs-accent' => $t['brand'],
        '--wp-admin-theme-color' => $t['brand'],
        '--zerti-chart-brand-border' => sprintf('rgba(%s, 0.85)', $brand_rgb),
        '--zerti-chart-brand-fill' => sprintf('rgba(%s, 0.12)', $brand_rgb),
    ];
}

/**
 * Cursor-style structural overrides (flat surfaces, no masthead gradients).
 */
function zerti_demerzel_theme_chrome_css(): string
{
    $d = '#zertiAdmin[data-zerti-visual-theme="demerzel"]';
    $dd = $d . '[data-bs-theme="dark"]';
    $dl = $d . '[data-bs-theme="light"]';

    return $d . '{font-family:var(--zerti-font-family)!important;}'
        . $d . ' .zerti-sidebar,'
        . $d . ' .zerti-sidebar .nav-link,'
        . $d . ' .offcanvas,'
        . $d . ' .offcanvas .nav-link{font-family:var(--zerti-font-family)!important;}'
        . $dd . ','
        . $dl . '{background-image:none!important;background-attachment:scroll!important;}'
        . $dd . '{--bs-body-bg:var(--zerti-docs-bg);--bs-body-bg-rgb:11,11,11;--bd-pink-rgb:11,11,11;--bd-accent-rgb:20,20,20;--bd-violet-rgb:20,20,20;}'
        . $dl . '{--bs-body-bg:var(--zerti-docs-bg);--bs-body-bg-rgb:247,247,244;--bd-pink-rgb:247,247,244;--bd-accent-rgb:230,229,224;--bd-violet-rgb:230,229,224;}'
        . $dd . ' .zerti-sidebar,'
        . $dd . ' #zertiSidebar.offcanvas{background:var(--zerti-docs-bg)!important;border-color:var(--zerti-docs-border)!important;}'
        . $dl . ' .zerti-sidebar,'
        . $dl . ' #zertiSidebar.offcanvas{background:var(--zerti-docs-bg)!important;border-color:var(--zerti-docs-border)!important;}'
        . $dd . ' .zerti-sidebar .nav-link.active:not(:has(.zerti-nav-pro-badge)),'
        . $dd . ' .offcanvas .nav-link.active:not(:has(.zerti-nav-pro-badge)){background:rgba(255,255,255,.08)!important;border-color:transparent!important;color:var(--zerti-docs-text)!important;font-weight:500!important;box-shadow:none!important;}'
        . $dl . ' .zerti-sidebar .nav-link.active:not(:has(.zerti-nav-pro-badge)),'
        . $dl . ' .offcanvas .nav-link.active:not(:has(.zerti-nav-pro-badge)){background:var(--zerti-docs-subtle-bg)!important;border-color:var(--zerti-docs-border)!important;color:var(--zerti-docs-text)!important;font-weight:500!important;box-shadow:none!important;}'
        . $dd . ' .zerti-sidebar .nav-link:hover:not(:has(.zerti-nav-pro-badge)),'
        . $dd . ' .offcanvas .nav-link:hover:not(:has(.zerti-nav-pro-badge)){background:rgba(255,255,255,.05)!important;border-color:transparent!important;}'
        . $dl . ' .zerti-sidebar .nav-link:hover:not(:has(.zerti-nav-pro-badge)),'
        . $dl . ' .offcanvas .nav-link:hover:not(:has(.zerti-nav-pro-badge)){background:var(--zerti-docs-subtle-bg)!important;border-color:var(--zerti-docs-border)!important;}'
        . $d . ' .btn.btn-outline-secondary,'
        . $d . ' .btn.btn-outline-primary{background-image:none!important;box-shadow:none!important;}'
        . $dd . ' .btn.btn-outline-secondary,'
        . $dd . ' .btn.btn-outline-primary{color:var(--zerti-docs-text)!important;border-color:var(--zerti-docs-border)!important;background:transparent!important;}'
        . $dl . ' .btn.btn-outline-secondary,'
        . $dl . ' .btn.btn-outline-primary{color:var(--zerti-docs-text)!important;border-color:var(--zerti-docs-border)!important;background:var(--zerti-docs-subtle-bg)!important;}'
        . $d . ' .zerti-theme-switch-track{background-image:none!important;background-color:var(--zerti-docs-border)!important;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12)!important;}'
        . $d . ' .zerti-home-stat-card,'
        . $d . ' .zerti-home-leaderboard-card,'
        . $d . ' .zerti-main-content .card{background:var(--zerti-docs-subtle-bg)!important;border:1px solid var(--zerti-docs-border)!important;box-shadow:none!important;}'
        . $d . ' .zerti-global-search__toggle,'
        . $d . ' .zerti-mobile-menu-btn{background:var(--zerti-docs-subtle-bg)!important;border:1px solid var(--zerti-docs-border)!important;box-shadow:none!important;color:var(--zerti-docs-text)!important;}'
        . $d . ' input[type=checkbox]:not(.zerti-settings-toggle-input):checked{background:var(--zerti-docs-text)!important;border-color:var(--zerti-docs-text)!important;}';
}

/**
 * Build Demerzel visual theme CSS (for wp_add_inline_style).
 */
function zerti_get_demerzel_theme_inline_css(): string
{
    if (zerti_get_visual_theme() !== 'demerzel') {
        return '';
    }

    $t = zerti_get_demerzel_theme_settings();
    $vars = zerti_demerzel_theme_css_variables();
    $base_rules = [];
    foreach ($vars as $name => $value) {
        $base_rules[] = $name . ':' . $value;
    }

    $dark_rgb = zerti_theme_hex_to_rgb($t['dark_bg']);
    $light_rgb = zerti_theme_hex_to_rgb($t['light_bg']);
    $dark_rules = [
        '--zerti-docs-bg:' . $t['dark_bg'],
        '--zerti-docs-subtle-bg:' . $t['dark_subtle_bg'],
        '--zerti-docs-border:' . $t['dark_border'],
        '--zerti-docs-text:' . $t['dark_text'],
        '--zerti-docs-muted:' . $t['dark_muted'],
        '--zerti-link-hover-color:' . $t['dark_link_hover'],
        '--bs-body-bg:' . $t['dark_bg'],
        '--bs-body-bg-rgb:' . $dark_rgb,
    ];
    $light_rules = [
        '--zerti-docs-bg:' . $t['light_bg'],
        '--zerti-docs-subtle-bg:' . $t['light_subtle_bg'],
        '--zerti-docs-border:' . $t['light_border'],
        '--zerti-docs-text:' . $t['light_text'],
        '--zerti-docs-muted:' . $t['light_muted'],
        '--zerti-link-hover-color:' . $t['light_link_hover'],
        '--bs-body-bg:' . $t['light_bg'],
        '--bs-body-bg-rgb:' . $light_rgb,
    ];

    return '#zertiAdmin[data-zerti-visual-theme="demerzel"]{' . implode(';', $base_rules) . ';}'
        . '#zertiAdmin[data-zerti-visual-theme="demerzel"][data-bs-theme="dark"]{' . implode(';', $dark_rules) . ';}'
        . '#zertiAdmin[data-zerti-visual-theme="demerzel"][data-bs-theme="light"]{' . implode(';', $light_rules) . ';}'
        . zerti_demerzel_theme_chrome_css();
}

/**
 * Enqueue Demerzel theme overrides on the ZERTI admin screen.
 */
function zerti_enqueue_demerzel_theme_inline_style(): void
{
    zerti_enqueue_visual_theme_inline_styles();
}

/**
 * @deprecated 1.2.8 Use zerti_enqueue_rabbitmp_theme_inline_style().
 */
function zerti_render_theme_inline_styles(): void
{
}

/**
 * Render one color field for rabbitMP theme settings.
 *
 * @param array{id:string,name:string,label:string,value:string} $field
 */
function zerti_render_theme_color_field(array $field): void
{
    $id = (string) $field['id'];
    $name = (string) $field['name'];
    $label = (string) $field['label'];
    $value = (string) $field['value'];
    $picker_value = preg_match('/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $value) ? $value : '#000000';
    ?>
    <div class="col-12 col-md-6 col-lg-4 zerti-settings-themes__field">
        <label class="form-label" for="<?php echo esc_attr($id); ?>"><?php echo esc_html($label); ?></label>
        <div class="input-group zerti-theme-color-field zerti-settings-themes__color-group">
            <input type="color" class="form-control form-control-color zerti-theme-color-picker zerti-settings-themes__color-picker" id="<?php echo esc_attr($id); ?>Picker" value="<?php echo esc_attr($picker_value); ?>" data-zerti-theme-color-picker-for="<?php echo esc_attr($id); ?>" aria-label="<?php echo esc_attr($label); ?>">
            <input type="text" class="form-control zerti-theme-color-text zerti-settings-themes__control zerti-settings-themes__color-text" id="<?php echo esc_attr($id); ?>" name="<?php echo esc_attr($name); ?>" value="<?php echo esc_attr($value); ?>" pattern="^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" data-zerti-theme-color-text inputmode="text" dir="ltr">
        </div>
    </div>
    <?php
}

/**
 * Render one length field for rabbitMP theme settings.
 *
 * @param array{id:string,name:string,label:string,value:string,help?:string} $field
 */
function zerti_render_theme_length_field(array $field): void
{
    $id = (string) $field['id'];
    $name = (string) $field['name'];
    $label = (string) $field['label'];
    $value = (string) $field['value'];
    $help = isset($field['help']) ? (string) $field['help'] : '';
    ?>
    <div class="col-12 col-md-6 col-lg-4 zerti-settings-themes__field">
        <label class="form-label" for="<?php echo esc_attr($id); ?>"><?php echo esc_html($label); ?></label>
        <input type="text" class="form-control zerti-settings-themes__control zerti-settings-themes__length-input" id="<?php echo esc_attr($id); ?>" name="<?php echo esc_attr($name); ?>" value="<?php echo esc_attr($value); ?>" inputmode="decimal">
        <?php if ($help !== '') : ?>
            <p class="form-text zerti-settings-themes__help mb-0"><?php echo esc_html($help); ?></p>
        <?php endif; ?>
    </div>
    <?php
}

/**
 * Render one px radius range field (0–25px) for theme settings.
 *
 * @param array{id:string,name:string,label:string,value:string,key?:string,theme_slug?:string} $field
 */
function zerti_render_theme_radius_field(array $field): void
{
    $id = (string) $field['id'];
    $name = (string) $field['name'];
    $label = (string) $field['label'];
    $value = (string) $field['value'];
    $key = (string) ($field['key'] ?? '');
    $theme_slug = (string) ($field['theme_slug'] ?? 'zerti');
    $px = zerti_theme_radius_value_to_px_int($value, 0);
    $max = zerti_theme_radius_px_max();
    $reset_default_px = $key !== '' ? zerti_theme_radius_default_px($theme_slug, $key) : 0;
    $reset_label = $theme_slug === 'demerzel'
        ? __('Reset to Demerzel default', 'zerti')
        : __('Reset to Zerti default', 'zerti');
    ?>
    <div class="col-12 col-md-6 col-lg-4 zerti-settings-themes__field">
        <label class="form-label" for="<?php echo esc_attr($id); ?>"><?php echo esc_html($label); ?></label>
        <div class="zerti-settings-themes__radius-control">
            <input
                type="range"
                class="zerti-settings-themes__radius-range"
                id="<?php echo esc_attr($id); ?>"
                min="0"
                max="<?php echo esc_attr((string) $max); ?>"
                step="1"
                value="<?php echo esc_attr((string) $px); ?>"
                data-zerti-theme-radius-range
                aria-valuemin="0"
                aria-valuemax="<?php echo esc_attr((string) $max); ?>"
                aria-valuenow="<?php echo esc_attr((string) $px); ?>"
                aria-label="<?php echo esc_attr($label); ?>"
            >
            <output class="zerti-settings-themes__radius-value" id="<?php echo esc_attr($id); ?>Value" for="<?php echo esc_attr($id); ?>" data-zerti-theme-radius-display><?php echo esc_html($px . 'px'); ?></output>
            <button
                type="button"
                class="zerti-settings-themes__radius-reset"
                data-zerti-theme-radius-reset
                data-zerti-theme-radius-default="<?php echo esc_attr((string) $reset_default_px); ?>"
                title="<?php echo esc_attr($reset_label); ?>"
                aria-label="<?php echo esc_attr($reset_label); ?>"
            >
                <i class="fa-solid fa-arrow-rotate-left" aria-hidden="true"></i>
            </button>
            <input type="hidden" name="<?php echo esc_attr($name); ?>" value="<?php echo esc_attr($px . 'px'); ?>" data-zerti-theme-radius-hidden>
        </div>
    </div>
    <?php
}

/**
 * Render customizable theme settings panel (rabbitMP, Demerzel, etc.).
 *
 * @param array{
 *     slug:string,
 *     heading:string,
 *     settings:array<string,string>,
 *     name_prefix:string,
 *     id_prefix:string,
 *     visible:bool
 * } $panel
 */
function zerti_render_visual_theme_customization_panel(array $panel): void
{
    $slug = (string) $panel['slug'];
    $heading = (string) $panel['heading'];
    $theme_settings = $panel['settings'];
    $name_prefix = (string) $panel['name_prefix'];
    $id_prefix = (string) $panel['id_prefix'];
    $visible = !empty($panel['visible']);
    ?>
    <div class="zerti-settings-<?php echo esc_attr($slug); ?>-customization<?php echo $visible ? '' : ' d-none'; ?>" data-zerti-<?php echo esc_attr($slug); ?>-customization>
        <h6 class="zerti-settings-themes__heading mb-3"><?php echo esc_html($heading); ?></h6>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Brand colors', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            zerti_render_theme_color_field([
                'id' => $id_prefix . 'Brand',
                'name' => $name_prefix . '[brand]',
                'label' => __('Primary brand color', 'zerti'),
                'value' => $theme_settings['brand'] ?? '',
            ]);
            zerti_render_theme_color_field([
                'id' => $id_prefix . 'BrandHover',
                'name' => $name_prefix . '[brand_hover]',
                'label' => __('Brand hover color', 'zerti'),
                'value' => $theme_settings['brand_hover'] ?? '',
            ]);
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Dark mode colors', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            foreach ([
                'dark_bg' => __('Background', 'zerti'),
                'dark_subtle_bg' => __('Subtle background', 'zerti'),
                'dark_border' => __('Border', 'zerti'),
                'dark_text' => __('Text', 'zerti'),
                'dark_muted' => __('Muted text', 'zerti'),
                'dark_link_hover' => __('Link hover', 'zerti'),
            ] as $key => $label) {
                zerti_render_theme_color_field([
                    'id' => $id_prefix . ucfirst(str_replace('_', '', $key)),
                    'name' => $name_prefix . '[' . $key . ']',
                    'label' => $label,
                    'value' => $theme_settings[$key] ?? '',
                ]);
            }
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Light mode colors', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            foreach ([
                'light_bg' => __('Background', 'zerti'),
                'light_subtle_bg' => __('Subtle background', 'zerti'),
                'light_border' => __('Border', 'zerti'),
                'light_text' => __('Text', 'zerti'),
                'light_muted' => __('Muted text', 'zerti'),
                'light_link_hover' => __('Link hover', 'zerti'),
            ] as $key => $label) {
                zerti_render_theme_color_field([
                    'id' => $id_prefix . ucfirst(str_replace('_', '', $key)),
                    'name' => $name_prefix . '[' . $key . ']',
                    'label' => $label,
                    'value' => $theme_settings[$key] ?? '',
                ]);
            }
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Primary button gradient', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            foreach (range(1, 5) as $i) {
                $key = 'btn_primary_grad_' . $i;
                zerti_render_theme_color_field([
                    'id' => $id_prefix . 'BtnPrimaryGrad' . $i,
                    'name' => $name_prefix . '[' . $key . ']',
                    'label' => sprintf(
                        /* translators: %d: gradient stop number */
                        __('Gradient stop %d', 'zerti'),
                        $i
                    ),
                    'value' => $theme_settings[$key] ?? '',
                ]);
            }
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Outline button border gradient', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            foreach (range(1, 3) as $i) {
                $key = 'btn_outline_grad_' . $i;
                zerti_render_theme_color_field([
                    'id' => $id_prefix . 'BtnOutlineGrad' . $i,
                    'name' => $name_prefix . '[' . $key . ']',
                    'label' => sprintf(
                        /* translators: %d: gradient stop number */
                        __('Border stop %d', 'zerti'),
                        $i
                    ),
                    'value' => $theme_settings[$key] ?? '',
                ]);
            }
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Typography and button sizes', 'zerti'); ?></p>
        <div class="row g-3 mb-4">
            <?php
            zerti_render_theme_length_field([
                'id' => $id_prefix . 'FontSizeBase',
                'name' => $name_prefix . '[font_size_base]',
                'label' => __('Base font size', 'zerti'),
                'value' => $theme_settings['font_size_base'] ?? '',
                'help' => __('Example: 9pt, 10pt, 0.875rem', 'zerti'),
            ]);
            zerti_render_theme_length_field([
                'id' => $id_prefix . 'FontSizeSm',
                'name' => $name_prefix . '[font_size_sm]',
                'label' => __('Small font size', 'zerti'),
                'value' => $theme_settings['font_size_sm'] ?? '',
                'help' => __('Example: 0.875em, 8pt', 'zerti'),
            ]);
            zerti_render_theme_length_field([
                'id' => $id_prefix . 'BtnFontSize',
                'name' => $name_prefix . '[btn_font_size]',
                'label' => __('Button font size', 'zerti'),
                'value' => $theme_settings['btn_font_size'] ?? '',
            ]);
            zerti_render_theme_length_field([
                'id' => $id_prefix . 'BtnMinHeight',
                'name' => $name_prefix . '[btn_min_height]',
                'label' => __('Button minimum height', 'zerti'),
                'value' => $theme_settings['btn_min_height'] ?? '',
            ]);
            ?>
        </div>

        <p class="zerti-settings-themes__section-title mb-2"><?php esc_html_e('Border radiuses', 'zerti'); ?></p>
        <div class="row g-3">
            <?php
            foreach ([
                'radius_sm' => __('Small radius', 'zerti'),
                'radius_md' => __('Medium radius', 'zerti'),
                'radius_lg' => __('Large radius', 'zerti'),
                'radius_panel' => __('Panel radius', 'zerti'),
                'radius_input' => __('Input and select radius', 'zerti'),
                'radius_card' => __('Card radius', 'zerti'),
                'radius_pill' => __('Pill radius', 'zerti'),
                'btn_border_radius' => __('Button radius', 'zerti'),
            ] as $radius_key => $radius_label) {
                zerti_render_theme_radius_field([
                    'id' => $id_prefix . str_replace('_', '', ucwords($radius_key, '_')),
                    'name' => $name_prefix . '[' . $radius_key . ']',
                    'label' => $radius_label,
                    'value' => $theme_settings[$radius_key] ?? '',
                    'key' => $radius_key,
                    'theme_slug' => $slug,
                ]);
            }
            ?>
        </div>
    </div>
    <?php
}
