array( 'primary' => '#3b82f6', 'secondary' => '#64748b', 'accent' => '#f59e0b', 'success' => '#22c55e', 'danger' => '#ef4444', 'warning' => '#eab308', 'info' => '#06b6d4', 'light' => '#f3f4f6', 'dark' => '#111827', 'muted' => '#6b7280', ), 'fonts' => array( 'heading' => 'Inter', 'body' => 'Inter', ), ); const COLOR_LABELS = array( 'primary' => 'Primary', 'secondary' => 'Secondary', 'accent' => 'Accent', 'success' => 'Success', 'danger' => 'Danger', 'warning' => 'Warning', 'info' => 'Info', 'light' => 'Light', 'dark' => 'Dark', 'muted' => 'Muted', ); const NONCE_ACTION = 'wpaddons_save_tailwind_theme'; /** * @var self|null */ private static $instance = null; public function __construct() { self::$instance = $this; } /** * Shared instance used by the Advanced Addons admin menu. */ public static function instance(): self { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } public function render_settings_page(): void { if ( ! current_user_can( 'manage_options' ) ) { return; } // Handle form submission directly — bypass Settings API nesting issues. $saved = false; if ( isset( $_POST['wpaddons_save_theme'] ) && check_admin_referer( self::NONCE_ACTION, 'wpaddons_theme_nonce' ) ) { $this->save_theme( $_POST ); $saved = true; } $theme = self::get_theme(); ?>

$label ) : $value = isset( $theme['colors'][ $key ] ) ? $theme['colors'][ $key ] : self::DEFAULTS['colors'][ $key ]; ?>

__( 'Heading Font', 'advanced-animation' ), 'body' => __( 'Body Font', 'advanced-animation' ), ); $common_fonts = array( 'Inter', 'System UI', 'Arial', 'Helvetica', 'Georgia', 'Times New Roman', 'Verdana', 'Roboto', 'Open Sans', 'Lato', 'Montserrat', 'Playfair Display', 'Merriweather', 'Poppins', 'Raleway', 'Source Sans Pro', ); foreach ( $font_fields as $key => $label ) : $value = isset( $theme['fonts'][ $key ] ) ? $theme['fonts'][ $key ] : self::DEFAULTS['fonts'][ $key ]; ?>


bg-primary text-light rounded-lg p-4

$label ) { if ( isset( $post_data['wpaddons_theme_colors'][ $key ] ) ) { $color = sanitize_hex_color( wp_unslash( $post_data['wpaddons_theme_colors'][ $key ] ) ); if ( $color ) { $theme['colors'][ $key ] = $color; } } } } if ( isset( $post_data['wpaddons_theme_fonts'] ) && is_array( $post_data['wpaddons_theme_fonts'] ) ) { foreach ( array( 'heading', 'body' ) as $key ) { if ( isset( $post_data['wpaddons_theme_fonts'][ $key ] ) && is_string( $post_data['wpaddons_theme_fonts'][ $key ] ) ) { $font = sanitize_text_field( wp_unslash( trim( $post_data['wpaddons_theme_fonts'][ $key ] ) ) ); if ( $font ) { $theme['fonts'][ $key ] = $font; } } } } update_option( self::OPTION_NAME, wp_json_encode( $theme ) ); } public static function get_theme(): array { $theme = get_option( self::OPTION_NAME, '' ); $decoded = json_decode( $theme, true ); if ( ! is_array( $decoded ) ) { return self::DEFAULTS; } return array_replace_recursive( self::DEFAULTS, $decoded ); } /** * Convert the theme array into a Tailwind v4 @theme CSS block. */ public static function get_theme_css(): string { $theme = self::get_theme(); $lines = array( '@theme {' ); foreach ( $theme['colors'] as $name => $hex ) { $lines[] = sprintf( ' --color-%s: %s;', $name, $hex ); } if ( ! empty( $theme['fonts']['heading'] ) && 'Inter' !== $theme['fonts']['heading'] ) { $escaped = esc_attr( $theme['fonts']['heading'] ); $lines[] = sprintf( ' --font-heading: "%s", sans-serif;', $escaped ); } if ( ! empty( $theme['fonts']['body'] ) && 'Inter' !== $theme['fonts']['body'] ) { $escaped = esc_attr( $theme['fonts']['body'] ); $lines[] = sprintf( ' --font-body: "%s", sans-serif;', $escaped ); } $lines[] = '}'; return implode( "\n", $lines ); } public static function get_colors_for_js(): array { $theme = self::get_theme(); return $theme['colors'] ?? self::DEFAULTS['colors']; } public static function get_fonts_for_js(): array { $theme = self::get_theme(); return $theme['fonts'] ?? self::DEFAULTS['fonts']; } }