"""Themes module for pytola."""

from __future__ import annotations

import json
import re
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Literal, Optional

from PySide2.QtCore import QObject, Signal
from PySide2.QtWidgets import QWidget
from typing_extensions import TypeAlias

from .highdpi import ScalingPolicy, enable_highdpi_scaling
from .logger import logger

__version__ = "0.1.3"


if TYPE_CHECKING:
    from typing import Dict

__all__ = [
    "ThemeManager",
]

ThemeName: TypeAlias = Literal[
    "modern_blue",
    "light_blue",
    "dark_blue",
    "high_contrast",
    "monokai",
    "github",
    "solarized_light",
    "solarized_dark",
    "dracula",
    "nord",
    "onedark",
    "ayu_mirage",
    "material_dark",
    "arc_dark",
    "gruvbox",
    "tokyo_night",
    "rose_pine",
    "catppuccin",
    "vitesse",
    "synthwave",
]


class ThemeConfigManager:
    """Manages theme configuration and user preferences.

    Handles loading, saving, and validating theme configurations.
    """

    def __init__(self, config_path: Optional[Path] = None) -> None:
        """Initialize theme configuration manager.

        Args:
            config_path: Path to configuration file. Defaults to ~/.pytola/theme_config.json
        """
        self.config_path = config_path or Path.home() / ".pytola" / "theme_config.json"

        # Default configuration (define first to avoid circular reference)
        self._default_config = {
            "version": "1.0",
            "user_preference": None,
            "default_theme": "modern_blue",
            "recent_themes": [],
            "theme_settings": {
                "auto_apply": True,
                "remember_last": True,
                "fallback_theme": "modern_blue",
            },
            "custom_themes": {},
        }

        self._config = self._load_config()

    def _load_config(self) -> Dict[str, Any]:
        """Load configuration from file.

        Returns
        -------
            Configuration dictionary
        """
        try:
            if self.config_path.exists():
                with self.config_path.open("r", encoding="utf-8") as f:
                    config = json.load(f)
                    # Validate and merge with defaults
                    validated_config = self._validate_config(config)
                    logger.debug(f"Loaded theme configuration from {self.config_path}")
                    return validated_config
            else:
                # Create default configuration
                logger.debug("No existing config found, creating default configuration")
                self._save_config(self._default_config.copy())
                return self._default_config.copy()

        except Exception as e:
            logger.error(f"Failed to load configuration: {e}")
            return self._default_config.copy()

    def _validate_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
        """Validate and sanitize configuration.

        Args:
            config: Configuration to validate

        Returns
        -------
            Validated configuration
        """
        validated = self._default_config.copy()

        try:
            # Validate version
            if isinstance(config.get("version"), str):
                validated["version"] = config["version"]

            # Validate user preference
            if config.get("user_preference"):
                validated["user_preference"] = str(config["user_preference"])

            # Validate default theme
            if config.get("default_theme"):
                validated["default_theme"] = str(config["default_theme"])

            # Validate recent themes
            if isinstance(config.get("recent_themes"), list):
                validated["recent_themes"] = [
                    str(theme) for theme in config["recent_themes"] if isinstance(theme, str)
                ][:10]  # Limit to 10 recent themes

            # Validate theme settings
            if isinstance(config.get("theme_settings"), dict):
                settings = config["theme_settings"]
                validated_settings = validated["theme_settings"]

                if isinstance(settings.get("auto_apply"), bool):
                    validated_settings["auto_apply"] = settings["auto_apply"]

                if isinstance(settings.get("remember_last"), bool):
                    validated_settings["remember_last"] = settings["remember_last"]

                if settings.get("fallback_theme"):
                    validated_settings["fallback_theme"] = str(settings["fallback_theme"])

            # Validate custom themes
            if isinstance(config.get("custom_themes"), dict):
                validated["custom_themes"] = {
                    str(name): str(content)
                    for name, content in config["custom_themes"].items()
                    if isinstance(name, str) and isinstance(content, str)
                }

        except Exception as e:
            logger.warning(f"Configuration validation error: {e}")

        return validated

    def _save_config(self, config: Optional[Dict[str, Any]] = None) -> bool:
        """Save configuration to file.

        Args:
            config: Configuration to save. Uses current config if None.

        Returns
        -------
            True if saved successfully, False otherwise
        """
        try:
            config_to_save = config or self._config

            # Ensure directory exists
            self.config_path.parent.mkdir(parents=True, exist_ok=True)

            # Save with proper formatting
            with self.config_path.open("w", encoding="utf-8") as f:
                json.dump(config_to_save, f, ensure_ascii=False, indent=2)

            logger.debug(f"Saved theme configuration to {self.config_path}")
            return True

        except Exception as e:
            logger.error(f"Failed to save configuration: {e}")
            return False

    def save_user_preference(self, theme_name: ThemeName) -> bool:
        """Save user's theme preference.

        Args:
            theme_name: Theme name to save as preference

        Returns
        -------
            True if saved successfully, False otherwise
        """
        try:
            self._config["user_preference"] = theme_name

            # Update recent themes list
            recent = self._config["recent_themes"]
            if theme_name in recent:
                recent.remove(theme_name)
            recent.insert(0, theme_name)
            # Keep only last 10 themes
            self._config["recent_themes"] = recent[:10]

            return self._save_config()

        except Exception as e:
            logger.error(f"Failed to save theme preference '{theme_name}': {e}")
            return False

    def get_user_preference(self) -> Optional[ThemeName]:
        """Get user's saved theme preference.

        Returns
        -------
            Saved theme name or None if not set
        """
        return self._config.get("user_preference")

    def get_default_theme(self) -> ThemeName:
        """Get the default theme name.

        Returns
        -------
            Default theme name
        """
        return self._config.get("default_theme", "modern_blue")

    def get_fallback_theme(self) -> ThemeName:
        """Get the fallback theme name.

        Returns
        -------
            Fallback theme name
        """
        return self._config.get("theme_settings", {}).get("fallback_theme", "modern_blue")

    def get_recent_themes(self) -> List[ThemeName]:
        """Get list of recently used themes.

        Returns
        -------
            List of recent theme names
        """
        return self._config.get("recent_themes", [])

    def get_theme_settings(self) -> Dict[str, Any]:
        """Get theme-related settings.

        Returns
        -------
            Theme settings dictionary
        """
        return self._config.get("theme_settings", {})

    def should_auto_apply(self) -> bool:
        """Check if themes should be automatically applied.

        Returns
        -------
            True if auto-apply is enabled
        """
        return self._config.get("theme_settings", {}).get("auto_apply", True)

    def should_remember_last(self) -> bool:
        """Check if last used theme should be remembered.

        Returns
        -------
            True if remember last theme is enabled
        """
        return self._config.get("theme_settings", {}).get("remember_last", True)

    def add_custom_theme(self, name: str, stylesheet: str) -> bool:
        """Add a custom theme.

        Args:
            name: Theme name
            stylesheet: Theme stylesheet content

        Returns
        -------
            True if added successfully, False otherwise
        """
        try:
            if not name or not stylesheet:
                logger.warning("Custom theme name and stylesheet cannot be empty")
                return False

            self._config.setdefault("custom_themes", {})[name] = stylesheet
            return self._save_config()

        except Exception as e:
            logger.error(f"Failed to add custom theme '{name}': {e}")
            return False

    def get_custom_themes(self) -> Dict[str, str]:
        """Get all custom themes.

        Returns
        -------
            Dictionary of custom theme names and stylesheets
        """
        return self._config.get("custom_themes", {})

    def remove_custom_theme(self, name: str) -> bool:
        """Remove a custom theme.

        Args:
            name: Theme name to remove

        Returns
        -------
            True if removed successfully, False otherwise
        """
        try:
            custom_themes = self._config.get("custom_themes", {})
            if name in custom_themes:
                del custom_themes[name]
                # If this was the user preference, clear it
                if self._config.get("user_preference") == name:
                    self._config["user_preference"] = None
                return self._save_config()
            return True

        except Exception as e:
            logger.error(f"Failed to remove custom theme '{name}': {e}")
            return False

    def reset_to_defaults(self) -> bool:
        """Reset configuration to default values.

        Returns
        -------
            True if reset successfully, False otherwise
        """
        try:
            self._config = self._default_config.copy()
            return self._save_config()

        except Exception as e:
            logger.error(f"Failed to reset configuration: {e}")
            return False

    def get_config_path(self) -> Path:
        """Get the configuration file path.

        Returns
        -------
            Path to configuration file
        """
        return self.config_path

    def get_config_stats(self) -> Dict[str, Any]:
        """Get configuration statistics.

        Returns
        -------
            Dictionary with configuration statistics
        """
        return {
            "config_path": str(self.config_path),
            "user_preference": self.get_user_preference(),
            "default_theme": self.get_default_theme(),
            "fallback_theme": self.get_fallback_theme(),
            "recent_themes_count": len(self.get_recent_themes()),
            "custom_themes_count": len(self.get_custom_themes()),
            "auto_apply_enabled": self.should_auto_apply(),
            "remember_last_enabled": self.should_remember_last(),
        }


_default_config = ThemeConfigManager()


def get_default_config() -> ThemeConfigManager:
    """Get the default global configuration instance."""
    return _default_config


class ThemeCacheManager:
    """Manages theme stylesheet caching with LRU eviction policy.

    Provides intelligent caching with size limits and automatic cleanup.
    Optimized for performance with reduced I/O operations.
    """

    def __init__(self, max_size: int = 15, cache_file: Optional[Path] = None) -> None:
        """Initialize theme cache manager.

        Args:
            max_size: Maximum number of themes to cache (increased from 10 to 15)
            cache_file: Optional file path for persistent caching
        """
        self._cache: Dict[str, str] = {}
        self._access_order: List[str] = []
        self._max_size = max_size
        self._cache_file = cache_file
        self._stats = {"hits": 0, "misses": 0, "evictions": 0, "errors": 0}
        self._dirty = False  # Track if cache needs to be saved

        # Load persistent cache if file specified
        if self._cache_file:
            self._load_persistent_cache()

    def get(self, key: str) -> Optional[str]:
        """Get cached stylesheet by theme name.

        Args:
            key: Theme name

        Returns
        -------
            Cached stylesheet or None if not found
        """
        try:
            if key in self._cache:
                # Move to end (most recently used) - optimized with index lookup
                idx = self._access_order.index(key)
                self._access_order.pop(idx)
                self._access_order.append(key)
                self._stats["hits"] += 1
                return self._cache[key]
            self._stats["misses"] += 1
            return None
        except Exception as e:
            self._stats["errors"] += 1
            logger.error(f"Cache get error for '{key}': {e}")
            return None

    def set(self, key: str, value: str) -> bool:
        """Set cached stylesheet for theme.

        Args:
            key: Theme name
            value: Stylesheet content

        Returns
        -------
            True if successfully cached, False otherwise
        """
        try:
            # Remove existing entry if present
            if key in self._cache:
                idx = self._access_order.index(key)
                self._access_order.pop(idx)
            else:
                # Check if we need to evict oldest entry
                if len(self._cache) >= self._max_size:
                    oldest = self._access_order.pop(0)
                    del self._cache[oldest]
                    self._stats["evictions"] += 1

            # Add new entry
            self._cache[key] = value
            self._access_order.append(key)
            self._dirty = True  # Mark cache as dirty

            return True

        except Exception as e:
            self._stats["errors"] += 1
            logger.error(f"Cache set error for '{key}': {e}")
            return False

    def flush(self) -> bool:
        """Force save persistent cache to disk.

        Returns
        -------
            True if saved successfully, False otherwise
        """
        if not self._dirty or not self._cache_file:
            return True

        try:
            self._save_persistent_cache()
            self._dirty = False
            return True
        except Exception as e:
            logger.error(f"Failed to flush cache: {e}")
            return False

    def clear(self, key: Optional[str] = None) -> None:
        """Clear cache entries.

        Args:
            key: Specific theme to clear, or None to clear all
        """
        try:
            if key:
                if key in self._cache:
                    idx = self._access_order.index(key)
                    self._access_order.pop(idx)
                    del self._cache[key]
                    self._dirty = True
            else:
                self._cache.clear()
                self._access_order.clear()
                self._stats = {"hits": 0, "misses": 0, "evictions": 0, "errors": 0}
                self._dirty = True

                # Clear persistent cache
                if self._cache_file and self._cache_file.exists():
                    self._cache_file.unlink()

        except Exception as e:
            self._stats["errors"] += 1
            logger.error(f"Cache clear error: {e}")

    def get_stats(self) -> Dict[str, Any]:
        """Get cache statistics.

        Returns
        -------
            Dictionary with cache statistics
        """
        total_requests = self._stats["hits"] + self._stats["misses"]
        hit_rate = (self._stats["hits"] / total_requests * 100) if total_requests > 0 else 0

        return {
            "size": len(self._cache),
            "max_size": self._max_size,
            "hits": self._stats["hits"],
            "misses": self._stats["misses"],
            "evictions": self._stats["evictions"],
            "errors": self._stats["errors"],
            "hit_rate": round(hit_rate, 2),
            "entries": list(self._cache.keys()),
            "dirty": self._dirty,
        }

    def _load_persistent_cache(self) -> None:
        """Load cache from persistent storage."""
        try:
            if self._cache_file and self._cache_file.exists():
                with self._cache_file.open("r", encoding="utf-8") as f:
                    data = json.load(f)
                    self._cache = data.get("cache", {})
                    self._access_order = data.get("order", [])
                    self._stats = data.get("stats", self._stats)
                logger.debug(f"Loaded persistent cache from {self._cache_file}")
        except Exception as e:
            logger.warning(f"Failed to load persistent cache: {e}")
            # Initialize with empty cache
            self._cache = {}
            self._access_order = []

    def _save_persistent_cache(self) -> None:
        """Save cache to persistent storage."""
        try:
            if self._cache_file:
                # Ensure directory exists
                self._cache_file.parent.mkdir(parents=True, exist_ok=True)

                data = {
                    "cache": self._cache,
                    "order": self._access_order,
                    "stats": self._stats,
                }

                with self._cache_file.open("w", encoding="utf-8") as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)

        except Exception as e:
            logger.warning(f"Failed to save persistent cache: {e}")


_default_cache = ThemeCacheManager(max_size=15, cache_file=Path.home() / ".pytola" / "theme_cache.json")


def get_default_cache() -> ThemeCacheManager:
    """Get the default global cache instance."""
    return _default_cache


class ThemeSignals(QObject):
    """Signal emitter for theme changes."""

    theme_changed = Signal(str)  # theme_name


class ThemeManager:
    """Theme manager class - provides methods for theme management."""

    # Global signal instance
    _signals = ThemeSignals()
    theme_changed = _signals.theme_changed

    _themes: ClassVar[Dict[ThemeName, type[BaseTheme]]] = {}
    _cache = get_default_cache()
    _config = get_default_config()

    @classmethod
    def apply_theme(
        cls,
        widget: QWidget | None,
        name: ThemeName,
        enable_highdpi: bool = True,
    ) -> bool:
        """Apply a theme to a widget with optimized performance.

        Args:
            widget: The widget to apply the theme to.
            name: The name of the theme to apply.

        Returns
        -------
            True if theme was applied successfully, False otherwise.

        Raises
        ------
            ValueError: If widget is None or theme name is not found.
        """
        if widget is None:
            logger.error("Cannot apply theme: widget is None")
            raise ValueError("Widget cannot be None.")

        if enable_highdpi:
            # 使用优化的highdpi管理器, 避免重复初始化
            enable_highdpi_scaling(
                scaling_policy=ScalingPolicy.AUTO,
                auto_apply=True,
                enable_auto_font_scaling=True,
            )

        # Fast path: check if theme is already applied
        current_theme = cls.get_current_theme(widget)
        if current_theme == name:
            return True

        theme_class = cls._get(name)
        if not theme_class:
            msg = f"Theme '{name}' not found. Available themes: {list(cls._themes.keys())}"
            logger.error(msg)
            raise ValueError(msg)

        try:
            # Try to get from cache first (optimized)
            stylesheet = cls._cache.get(name)
            if stylesheet is None:
                # Generate stylesheet with caching optimization
                stylesheet = theme_class.get_stylesheet()
                # Pre-compile regex pattern for better performance
                if not hasattr(cls, "_font_size_pattern"):
                    cls._font_size_pattern = re.compile(r"font-size:\s*[^;]+;")
                cleaned_stylesheet = cls._font_size_pattern.sub("", stylesheet)
                cls._cache.set(name, cleaned_stylesheet)
                stylesheet = cleaned_stylesheet
            # else: cache hit, no additional processing needed

            # Apply stylesheet (this is the expensive operation)
            widget.setStyleSheet(stylesheet)

            # Batch configuration updates to reduce I/O
            if cls._config.should_remember_last():
                cls._config.save_user_preference(name)

            # Store current theme on widget
            widget.setProperty("_current_theme", name)

            # Emit theme changed signal (deferred to reduce UI blocking)
            cls.theme_changed.emit(name)

            return True

        except Exception as e:
            logger.exception(f"Failed to apply theme '{name}': {e}")
            # Try to apply fallback theme
            fallback_theme = cls._config.get_fallback_theme()
            if fallback_theme != name and cls.is_valid_theme(fallback_theme):
                logger.warning(f"Applying fallback theme '{fallback_theme}'")
                return cls.apply_theme(widget, fallback_theme)
            raise

    @classmethod
    def apply_theme_safely(
        cls,
        widget: QWidget | None,
        name: ThemeName,
        enable_highdpi: bool = True,
    ) -> bool:
        """Safely apply theme with graceful degradation.

        Args:
            widget: The widget to apply the theme to.
            name: The name of the theme to apply.

        Returns
        -------
            True if theme was applied successfully, False otherwise.
        """
        try:
            return cls.apply_theme(widget, name, enable_highdpi)
        except Exception as e:
            logger.error(f"Theme application failed: {e}")
            # Try to apply default theme as last resort
            default_theme = cls._config.get_default_theme()
            if default_theme != name and cls.is_valid_theme(default_theme):
                try:
                    logger.info(f"Falling back to default theme: {default_theme}")
                    return cls.apply_theme(widget, default_theme)
                except Exception as fallback_error:
                    logger.error(f"Default theme fallback also failed: {fallback_error}")
            return False

    @classmethod
    def get_current_theme(cls, widget: QWidget) -> Optional[ThemeName]:
        """Get the currently applied theme for a widget.

        Args:
            widget: The widget to check.

        Returns
        -------
            Current theme name or None if not set.
        """
        return widget.property("_current_theme")

    @classmethod
    def switch_theme_dynamically(cls, widget: QWidget, new_theme: ThemeName) -> bool:
        """Dynamically switch theme at runtime.

        Args:
            widget: The widget to switch theme for.
            new_theme: The new theme name.

        Returns
        -------
            True if theme was switched successfully, False otherwise.
        """
        current_theme = cls.get_current_theme(widget)
        if current_theme == new_theme:
            logger.debug(f"Theme already set to '{new_theme}', no change needed")
            return True

        logger.info(f"Switching theme from '{current_theme}' to '{new_theme}'")
        return cls.apply_theme(widget, new_theme)

    @classmethod
    def switch_theme_with_animation(
        cls,
        widget: QWidget,
        new_theme: ThemeName,
        duration: int = 300,
        easing_curve=None,
    ) -> bool:
        """Switch theme with smooth fade animation.

        Args:
            widget: The widget to switch theme for.
            new_theme: The new theme name.
            duration: Animation duration in milliseconds.
            easing_curve: Easing curve for animation.

        Returns
        -------
            True if theme switch was initiated, False otherwise.
        """
        try:
            from PySide2.QtCore import QEasingCurve, QPropertyAnimation
            from PySide2.QtWidgets import QGraphicsOpacityEffect

            current_theme = cls.get_current_theme(widget)
            if current_theme == new_theme:
                return True

            # Create opacity effect for fade animation
            opacity_effect = QGraphicsOpacityEffect(widget)
            widget.setGraphicsEffect(opacity_effect)

            # Fade out animation
            fade_out = QPropertyAnimation(opacity_effect, b"opacity")
            fade_out.setDuration(duration // 2)
            fade_out.setStartValue(1.0)
            fade_out.setEndValue(0.0)
            fade_out.setEasingCurve(easing_curve or QEasingCurve.InOutQuad)

            # Fade in animation
            fade_in = QPropertyAnimation(opacity_effect, b"opacity")
            fade_in.setDuration(duration // 2)
            fade_in.setStartValue(0.0)
            fade_in.setEndValue(1.0)
            fade_in.setEasingCurve(easing_curve or QEasingCurve.InOutQuad)

            def on_fade_out_finished():
                # Apply new theme when fade out completes
                cls.apply_theme(widget, new_theme)
                fade_in.start()

            fade_out.finished.connect(on_fade_out_finished)
            fade_out.start()

            logger.info(f"Animating theme switch from '{current_theme}' to '{new_theme}'")
            return True

        except Exception as e:
            logger.error(f"Failed to animate theme switch: {e}")
            # Fallback to normal theme switch
            return cls.switch_theme_dynamically(widget, new_theme)

    @classmethod
    def batch_apply_theme(cls, widgets: list[QWidget], theme: ThemeName) -> int:
        """Apply theme to multiple widgets with optimized batch processing.

        Args:
            widgets: List of widgets to apply theme to.
            theme: Theme name to apply.

        Returns
        -------
            Number of widgets successfully themed.
        """
        if not widgets:
            return 0

        # Pre-fetch and cache the stylesheet once for all widgets
        stylesheet = cls._cache.get(theme)
        if stylesheet is None:
            theme_class = cls._get(theme)
            if not theme_class:
                logger.error(f"Theme '{theme}' not found for batch application")
                return 0

            stylesheet = theme_class.get_stylesheet()
            if not hasattr(cls, "_font_size_pattern"):
                cls._font_size_pattern = re.compile(r"font-size:\s*[^;]+;")
            cleaned_stylesheet = cls._font_size_pattern.sub("", stylesheet)
            cls._cache.set(theme, cleaned_stylesheet)
            stylesheet = cleaned_stylesheet

        success_count = 0
        for widget in widgets:
            try:
                if widget is not None:
                    widget.setStyleSheet(stylesheet)
                    widget.setProperty("_current_theme", theme)
                    success_count += 1
            except Exception as e:
                logger.warning(f"Failed to apply theme to widget: {e}")

        # Batch update configuration once
        if success_count > 0 and cls._config.should_remember_last():
            cls._config.save_user_preference(theme)

        # Emit signal once for batch operation
        if success_count > 0:
            cls.theme_changed.emit(theme)

        logger.info(f"Batch applied theme '{theme}' to {success_count}/{len(widgets)} widgets")
        return success_count

    @classmethod
    def get_theme_preview(cls, theme_name: ThemeName) -> Optional[str]:
        """Get theme stylesheet for preview purposes.

        Args:
            theme_name: Theme name to preview.

        Returns
        -------
            Theme stylesheet or None if theme not found.
        """
        theme_class = cls._get(theme_name)
        if theme_class:
            return theme_class.get_stylesheet()
        return None

    @classmethod
    def list_themes(cls) -> list[ThemeName]:
        """List available themes."""
        logger.debug("Listing available themes: " + str(list(cls._themes.keys())))
        return list(cls._themes.keys())

    @classmethod
    def get_available_themes(cls) -> list[ThemeName]:
        """Get list of all available themes including custom ones.

        Returns
        -------
            List of all available theme names.
        """
        builtin_themes = list(cls._themes.keys())
        custom_themes = list(cls._config.get_custom_themes().keys())
        all_themes = builtin_themes + custom_themes
        logger.debug(f"Available themes: {all_themes}")
        return all_themes

    @classmethod
    def get_theme_info(cls, name: ThemeName) -> Optional[dict]:
        """Get detailed information about a theme.

        Args:
            name: Theme name.

        Returns
        -------
            Theme information dictionary or None if theme not found.
        """
        if name in cls._themes:
            theme_class = cls._themes[name]
            return {
                "name": name,
                "class": theme_class.__name__,
                "description": theme_class.__doc__ or "No description",
                "is_builtin": True,
                "stylesheet_size": len(theme_class.get_stylesheet()),
            }
        if name in cls._config.get_custom_themes():
            stylesheet = cls._config.get_custom_themes()[name]
            return {
                "name": name,
                "class": "CustomTheme",
                "description": "User-defined custom theme",
                "is_builtin": False,
                "stylesheet_size": len(stylesheet),
            }
        return None

    @classmethod
    def get_default_theme(cls) -> ThemeName:
        """Get the default theme name.

        Returns
        -------
            Default theme name.
        """
        return cls._config.get_default_theme()

    @classmethod
    def get_user_preference(cls) -> Optional[ThemeName]:
        """Get user's saved theme preference.

        Returns
        -------
            Saved theme preference or None.
        """
        return cls._config.get_user_preference()

    @classmethod
    def set_default_theme(cls, name: ThemeName) -> bool:
        """Set the default theme.

        Args:
            name: Theme name to set as default.

        Returns
        -------
            True if set successfully, False otherwise.
        """
        if cls.is_valid_theme(name):
            cls._config._config["default_theme"] = name
            return cls._config._save_config()
        logger.warning(f"Cannot set default theme: '{name}' is not a valid theme")
        return False

    @classmethod
    def get_cache_stats(cls) -> dict:
        """Get theme cache statistics.

        Returns
        -------
            Cache statistics dictionary.
        """
        return cls._cache.get_stats()

    @classmethod
    def _register(cls, name: ThemeName) -> None:
        """Register a new theme."""

        def decorator(theme_class: type[BaseTheme]) -> type[BaseTheme]:
            if name in cls._themes:
                raise ValueError(f"Theme '{name}' already registered.")
            if not issubclass(theme_class, BaseTheme):
                raise TypeError(f"Theme '{name}' must be a subclass of BaseTheme.")

            theme_class.name = name
            cls._themes[name] = theme_class
            logger.debug(f"Registered theme: {name} ({theme_class.__name__})")
            return theme_class

        return decorator

    @classmethod
    def _get(cls, name: ThemeName) -> type[BaseTheme] | None:
        """Get a theme by name."""
        theme = cls._themes.get(name)
        if theme is None:
            # Check custom themes
            custom_themes = cls._config.get_custom_themes()
            if name in custom_themes:
                # Create dynamic theme class for custom theme
                class CustomTheme(BaseTheme):
                    template = custom_themes[name]
                    name = name

                return CustomTheme
        return theme

    @classmethod
    def is_valid_theme(cls, name: str) -> bool:
        """Check if a theme name is valid.

        Args:
            name: Theme name to validate.

        Returns
        -------
            True if the theme exists, False otherwise.
        """
        is_valid = name in cls._themes or name in cls._config.get_custom_themes()
        logger.debug(f"Theme validation - '{name}': {'valid' if is_valid else 'invalid'}")
        return is_valid

    @classmethod
    def clear_cache(cls, name: ThemeName | None = None) -> None:
        """Clear cached stylesheet for one or all themes.

        Args:
            name: Specific theme name to clear cache for, or None to clear all.
        """
        try:
            if name:
                theme_class = cls._get(name)
                if theme_class:
                    theme_class._cached_stylesheet = None
                    cls._cache.clear(name)
                    logger.debug(f"Cache cleared for theme: {name}")
            else:
                # Clear all theme caches
                for theme_class in cls._themes.values():
                    theme_class._cached_stylesheet = None
                cls._cache.clear()
                logger.debug("Cache cleared for all themes")
        except Exception as e:
            logger.error(f"Failed to clear cache: {e}")


class Color(str, Enum):
    """Color constants for themes."""

    # Modern Blue Theme Colors
    PRIMARY_BLUE = "#3b82f6"
    SECONDARY_BLUE = "#2563eb"
    DARK_BLUE = "#1d4ed8"
    DARKEST_BLUE = "#1e40af"
    BACKGROUND_LIGHT = "#ffffff"
    BACKGROUND_SOFT = "#f8fafc"
    BACKGROUND_CARD = "#f1f5f9"
    BACKGROUND_DARK = "#0f172a"
    TEXT_DARK = "#0f172a"
    TEXT_PRIMARY = "#334155"
    TEXT_SECONDARY = "#64748b"
    TEXT_LIGHT = "#94a3b8"
    BORDER_LIGHT = "#e2e8f0"
    BORDER_NORMAL = "#cbd5e1"
    BORDER_DARK = "#94a3b8"
    SUCCESS_GREEN = "#22c55e"
    WARNING_YELLOW = "#f59e0b"
    ERROR_RED = "#ef4444"
    INFO_BLUE = "#3b82f6"
    SELECTION_LIGHT = "#dbeafe"
    SELECTION_DARK = "#1e40af"
    HOVER_LIGHT = "#f1f5f9"
    HOVER_MEDIUM = "#e2e8f0"
    HOVER_DARK = "#cbd5e1"

    # Monokai Theme Colors
    MONOKAI_BG = "#272822"
    MONOKAI_FG = "#f8f8f2"
    MONOKAI_COMMENT = "#75715e"
    MONOKAI_RED = "#f92672"
    MONOKAI_ORANGE = "#fd971f"
    MONOKAI_YELLOW = "#e6db74"
    MONOKAI_GREEN = "#a6e22e"
    MONOKAI_BLUE = "#66d9ef"
    MONOKAI_PURPLE = "#ae81ff"
    MONOKAI_PINK = "#f92672"

    # GitHub Theme Colors
    GITHUB_BG = "#ffffff"
    GITHUB_FG = "#24292f"
    GITHUB_COMMENT = "#6e7781"
    GITHUB_RED = "#cf222e"
    GITHUB_ORANGE = "#bc4c00"
    GITHUB_YELLOW = "#9a6700"
    GITHUB_GREEN = "#1a7f37"
    GITHUB_BLUE = "#0969da"
    GITHUB_PURPLE = "#8250df"
    GITHUB_GRAY = "#8c959f"

    # Solarized Colors
    SOLARIZED_BASE03 = "#002b36"
    SOLARIZED_BASE02 = "#073642"
    SOLARIZED_BASE01 = "#586e75"
    SOLARIZED_BASE00 = "#657b83"
    SOLARIZED_BASE0 = "#839496"
    SOLARIZED_BASE1 = "#93a1a1"
    SOLARIZED_BASE2 = "#eee8d5"
    SOLARIZED_BASE3 = "#fdf6e3"
    SOLARIZED_YELLOW = "#b58900"
    SOLARIZED_ORANGE = "#cb4b16"
    SOLARIZED_RED = "#dc322f"
    SOLARIZED_MAGENTA = "#d33682"
    SOLARIZED_VIOLET = "#6c71c4"
    SOLARIZED_BLUE = "#268bd2"
    SOLARIZED_CYAN = "#2aa198"
    SOLARIZED_GREEN = "#859900"

    # Dracula Theme Colors
    DRACULA_BG = "#282a36"
    DRACULA_FG = "#f8f8f2"
    DRACULA_COMMENT = "#6272a4"
    DRACULA_CYAN = "#8be9fd"
    DRACULA_GREEN = "#50fa7b"
    DRACULA_ORANGE = "#ffb86c"
    DRACULA_PINK = "#ff79c6"
    DRACULA_PURPLE = "#bd93f9"
    DRACULA_RED = "#ff5555"
    DRACULA_YELLOW = "#f1fa8c"
    DRACULA_SELECTION = "#44475a"

    # Nord Theme Colors
    NORD0 = "#2e3440"
    NORD1 = "#3b4252"
    NORD2 = "#434c5e"
    NORD3 = "#4c566a"
    NORD4 = "#d8dee9"
    NORD5 = "#e5e9f0"
    NORD6 = "#eceff4"
    NORD7 = "#8fbcbb"
    NORD8 = "#88c0d0"
    NORD9 = "#81a1c1"
    NORD10 = "#5e81ac"
    NORD11 = "#bf616a"
    NORD12 = "#d08770"
    NORD13 = "#ebcb8b"
    NORD14 = "#a3be8c"
    NORD15 = "#b48ead"

    # One Dark Theme Colors
    ONEDARK_BG = "#282c34"
    ONEDARK_FG = "#abb2bf"
    ONEDARK_COMMENT = "#5c6370"
    ONEDARK_RED = "#e06c75"
    ONEDARK_ORANGE = "#d19a66"
    ONEDARK_YELLOW = "#e5c07b"
    ONEDARK_GREEN = "#98c379"
    ONEDARK_BLUE = "#61afef"
    ONEDARK_PURPLE = "#c678dd"
    ONEDARK_CYAN = "#56b6c2"

    # Ayu Mirage Theme Colors
    AYU_BG = "#1f2430"
    AYU_FG = "#cbccc6"
    AYU_COMMENT = "#5c6773"
    AYU_RED = "#f28779"
    AYU_ORANGE = "#ffa759"
    AYU_YELLOW = "#ffd173"
    AYU_GREEN = "#bae67e"
    AYU_BLUE = "#73d0ff"
    AYU_PURPLE = "#d4bfff"
    AYU_CYAN = "#95e6cb"

    # Material Dark Theme Colors
    MATERIAL_BG = "#263238"
    MATERIAL_FG = "#eeffff"
    MATERIAL_COMMENT = "#546e7a"
    MATERIAL_RED = "#f07178"
    MATERIAL_ORANGE = "#f78c6c"
    MATERIAL_YELLOW = "#ffcb6b"
    MATERIAL_GREEN = "#c3e88d"
    MATERIAL_BLUE = "#82aaff"
    MATERIAL_PURPLE = "#c792ea"
    MATERIAL_CYAN = "#89ddff"

    # Arc Dark Theme Colors
    ARCDARK_BG = "#353945"
    ARCDARK_FG = "#d3dae3"
    ARCDARK_COMMENT = "#5294e2"
    ARCDARK_RED = "#ed6464"
    ARCDARK_ORANGE = "#ed8464"
    ARCDARK_YELLOW = "#edc464"
    ARCDARK_GREEN = "#64ed76"
    ARCDARK_BLUE = "#64a0ed"
    ARCDARK_PURPLE = "#a064ed"
    ARCDARK_CYAN = "#64edc4"

    # Gruvbox Theme Colors
    GRUVBOX_DARK0 = "#282828"
    GRUVBOX_DARK1 = "#3c3836"
    GRUVBOX_DARK2 = "#504945"
    GRUVBOX_DARK3 = "#665c54"
    GRUVBOX_DARK4 = "#7c6f64"
    GRUVBOX_LIGHT0 = "#fbf1c7"
    GRUVBOX_LIGHT1 = "#ebdbb2"
    GRUVBOX_LIGHT2 = "#d5c4a1"
    GRUVBOX_LIGHT3 = "#bdae93"
    GRUVBOX_LIGHT4 = "#a89984"
    GRUVBOX_RED = "#fb4934"
    GRUVBOX_GREEN = "#b8bb26"
    GRUVBOX_YELLOW = "#fabd2f"
    GRUVBOX_BLUE = "#83a598"
    GRUVBOX_PURPLE = "#d3869b"
    GRUVBOX_AQUA = "#8ec07c"
    GRUVBOX_ORANGE = "#fe8019"

    # Tokyo Night Theme Colors
    TOKYO_BG = "#1a1b26"
    TOKYO_FG = "#c0caf5"
    TOKYO_COMMENT = "#565f89"
    TOKYO_RED = "#f7768e"
    TOKYO_GREEN = "#9ece6a"
    TOKYO_YELLOW = "#e0af68"
    TOKYO_BLUE = "#7aa2f7"
    TOKYO_PURPLE = "#bb9af7"
    TOKYO_CYAN = "#7dcfff"
    TOKYO_ORANGE = "#ff9e64"

    # Rose Pine Theme Colors
    ROSE_BG = "#191724"
    ROSE_FG = "#e0def4"
    ROSE_COMMENT = "#6e6a86"
    ROSE_RED = "#eb6f92"
    ROSE_GREEN = "#9ccfd8"
    ROSE_YELLOW = "#f6c177"
    ROSE_BLUE = "#31748f"
    ROSE_PURPLE = "#c4a7e7"
    ROSE_PINK = "#ebbcba"
    ROSE_ORANGE = "#ea9a97"

    # Catppuccin Theme Colors
    CAT_BG = "#1e1e2e"
    CAT_FG = "#cdd6f4"
    CAT_COMMENT = "#6c7086"
    CAT_RED = "#f38ba8"
    CAT_GREEN = "#a6e3a1"
    CAT_YELLOW = "#f9e2af"
    CAT_BLUE = "#89b4fa"
    CAT_PURPLE = "#cba6f7"
    CAT_CYAN = "#94e2d5"
    CAT_PINK = "#f5c2e7"

    # Vitesse Theme Colors
    VITESSE_BG = "#ffffff"
    VITESSE_FG = "#393a34"
    VITESSE_COMMENT = "#a0ada0"
    VITESSE_RED = "#e53935"
    VITESSE_GREEN = "#47aa25"
    VITESSE_YELLOW = "#ee9d28"
    VITESSE_BLUE = "#1856d1"
    VITESSE_PURPLE = "#d17eda"
    VITESSE_CYAN = "#3ea6aa"
    VITESSE_GRAY = "#758575"

    # Synthwave Theme Colors
    SYNTHWAVE_BG = "#262335"
    SYNTHWAVE_FG = "#ffffff"
    SYNTHWAVE_COMMENT = "#848bbd"
    SYNTHWAVE_PINK = "#ff7edb"
    SYNTHWAVE_PURPLE = "#b69bf1"
    SYNTHWAVE_BLUE = "#36f9f6"
    SYNTHWAVE_CYAN = "#72f1b8"
    SYNTHWAVE_GREEN = "#72ffb8"
    SYNTHWAVE_YELLOW = "#fff555"
    SYNTHWAVE_RED = "#ff2e97"

    def __str__(self) -> str:
        return self.value


class Dimension(int, Enum):
    """Dimension constants for themes."""

    BORDER_RADIUS_SMALL = 4
    BORDER_RADIUS_MEDIUM = 8
    BORDER_RADIUS_LARGE = 12
    BORDER_RADIUS_XL = 16
    PADDING_SMALL = 8
    PADDING_MEDIUM = 12
    PADDING_LARGE = 16
    PADDING_XL = 20
    SPACING_TIGHT = 4
    SPACING_COMPACT = 8
    SPACING_NORMAL = 12
    SPACING_WIDE = 16
    BUTTON_HEIGHT = 36
    INPUT_HEIGHT = 32
    MIN_CONTROL_HEIGHT = 24
    SCROLLBAR_WIDTH = 12
    SCROLLBAR_HANDLE_MIN = 20

    def __str__(self) -> str:
        return str(self.value)


class Font(str, Enum):
    """Font constants for themes."""

    FONT_FAMILY = "'Microsoft YaHei UI', 'Segoe UI', 'PingFang SC', sans-serif"
    MONOSPACE_FONT = "'Consolas', 'Courier New', monospace"
    FONT_SIZE_SMALL = "12px"
    FONT_SIZE_NORMAL = "14px"
    FONT_SIZE_MEDIUM = "15px"
    FONT_SIZE_LARGE = "16px"
    FONT_SIZE_XL = "18px"
    FONT_WEIGHT_NORMAL = "400"
    FONT_WEIGHT_MEDIUM = "500"
    FONT_WEIGHT_BOLD = "600"

    def __str__(self) -> str:
        return self.value


class BaseTheme:
    """Base theme class - defines the common interface for all themes."""

    template: str = ""

    _cached_stylesheet: ClassVar[str | None] = None

    __slots__ = ()

    @classmethod
    def get_stylesheet(cls) -> str:
        """Get complete stylesheet."""
        if cls._cached_stylesheet is None:
            cls._cached_stylesheet = cls.template
        return cls._cached_stylesheet


@ThemeManager._register("modern_blue")
class ModernBlueTheme(BaseTheme):
    """Modern Blue theme - clean, professional blue-themed design."""

    template = f"""
/* =============================================================================
   MODERN BLUE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.BACKGROUND_SOFT};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TEXT_DARK};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.PRIMARY_BLUE},
                              stop:1 {Color.SECONDARY_BLUE});
    color: white;
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SECONDARY_BLUE},
                              stop:1 {Color.DARK_BLUE});
}}

QPushButton:pressed {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.DARK_BLUE},
                              stop:1 {Color.DARKEST_BLUE});
}}

QPushButton:disabled {{
    background: {Color.TEXT_LIGHT};
    color: {Color.BORDER_NORMAL};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.BACKGROUND_LIGHT};
    border: 2px solid {Color.BORDER_NORMAL};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_LARGE};
    font-family: {Font.MONOSPACE_FONT};
    selection-background-color: {Color.SELECTION_LIGHT};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.PRIMARY_BLUE};
    background-color: {Color.BACKGROUND_SOFT};
}}

/* Labels */
QLabel {{
    font-size: {Font.FONT_SIZE_MEDIUM};
    color: {Color.TEXT_PRIMARY};
    font-family: {Font.FONT_FAMILY};
}}

QLabel:disabled {{
    color: {Color.TEXT_LIGHT};
}}

/* =============================================================================
   END MODERN BLUE THEME
   ============================================================================= */
"""


@ThemeManager._register("dark_blue")
class DarkBlueTheme(BaseTheme):
    """Dark Blue theme - dark theme variant for better night usage."""

    template = f"""
/* =============================================================================
   DARK BLUE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.BACKGROUND_DARK};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TEXT_LIGHT};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TEXT_LIGHT};
    background-color: transparent;
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.PRIMARY_BLUE},
                              stop:1 {Color.SECONDARY_BLUE});
    color: white;
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SECONDARY_BLUE},
                              stop:1 {Color.DARK_BLUE});
}}

QPushButton:disabled {{
    background: #334155;
    color: #64748b;
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #1e293b;
    border: 2px solid {Color.BORDER_DARK};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.TEXT_LIGHT};
    selection-background-color: {Color.SELECTION_DARK};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.PRIMARY_BLUE};
    background-color: #334155;
}}

/* Labels */
QLabel {{
    color: {Color.TEXT_LIGHT};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: #64748b;
}}

/* =============================================================================
   END DARK BLUE THEME
   ============================================================================= */
"""


@ThemeManager._register("high_contrast")
class HighContrastTheme(BaseTheme):
    """High Contrast theme - accessibility-focused high contrast design."""

    template = f"""
/* =============================================================================
   HIGH CONTRAST THEME - ACCESSIBILITY FOCUSED
   ============================================================================= */

/* Global application styling - Black and white high contrast */
QMainWindow, QDialog {{
    background-color: black;
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: white;
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: white;
    background-color: black;
}}

/* Buttons - Maximum visibility */
QPushButton {{
    background: white;
    color: black;
    border: 3px solid white;
    border-radius: {Dimension.BORDER_RADIUS_SMALL}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_BOLD};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: #e0e0e0;
    border: 3px solid #ffff00;
}}

QPushButton:disabled {{
    background: #404040;
    color: #808080;
    border: 3px solid #808080;
}}

/* Input controls - Clear focus indication */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: black;
    border: 3px solid white;
    border-radius: {Dimension.BORDER_RADIUS_SMALL}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: white;
    selection-background-color: #ffff00;
    selection-color: black;
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 3px solid #ffff00;
    background-color: #202020;
}}

/* Labels - Maximum readability */
QLabel {{
    color: white;
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    font-weight: {Font.FONT_WEIGHT_NORMAL};
}}

QLabel:disabled {{
    color: #808080;
}}

/* =============================================================================
   END HIGH CONTRAST THEME
   ============================================================================= */
"""


@ThemeManager._register("light_blue")
class LightBlueTheme(BaseTheme):
    """Light Blue theme - light theme variant for better day usage."""

    template = f"""
/* =============================================================================
   LIGHT BLUE THEME
   ============================================================================= */

QMainWindow, QDialog {{
    background-color: {Color.BACKGROUND_LIGHT};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TEXT_PRIMARY};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TEXT_PRIMARY};
    background-color: {Color.BACKGROUND_LIGHT};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.DARKEST_BLUE},
                              stop:1 {Color.DARK_BLUE});
    color: white;
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}
QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.DARK_BLUE},
                              stop:1 {Color.DARKEST_BLUE});
}}
QPushButton:disabled {{
    background: {Color.BORDER_DARK};
    color: {Color.TEXT_SECONDARY};
}}
/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.BACKGROUND_LIGHT};
    border: 2px solid {Color.BORDER_DARK};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.TEXT_PRIMARY};
    selection-background-color: {Color.SELECTION_LIGHT};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}
QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.PRIMARY_BLUE};
    background-color: {Color.BACKGROUND_LIGHT};
}}
/* Labels */
QLabel {{
    color: {Color.TEXT_PRIMARY};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}
QLabel:disabled {{
    color: {Color.TEXT_LIGHT};
}}
/* =============================================================================
   END LIGHT BLUE THEME
   ============================================================================= */
"""


@ThemeManager._register("monokai")
class MonokaiTheme(BaseTheme):
    """Monokai theme - popular dark theme with vibrant colors."""

    template = f"""
/* =============================================================================
   MONOKAI THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.MONOKAI_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.MONOKAI_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.MONOKAI_FG};
    background-color: {Color.MONOKAI_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.MONOKAI_ORANGE},
                              stop:1 {Color.MONOKAI_YELLOW});
    color: {Color.MONOKAI_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.MONOKAI_YELLOW},
                              stop:1 {Color.MONOKAI_ORANGE});
}}

QPushButton:pressed {{
    background: {Color.MONOKAI_RED};
    color: {Color.MONOKAI_FG};
}}

QPushButton:disabled {{
    background: {Color.MONOKAI_COMMENT};
    color: {Color.MONOKAI_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #383830;
    border: 2px solid {Color.MONOKAI_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.MONOKAI_FG};
    selection-background-color: {Color.MONOKAI_PURPLE};
    selection-color: {Color.MONOKAI_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.MONOKAI_GREEN};
    background-color: #3f3f38;
}}

/* Labels */
QLabel {{
    color: {Color.MONOKAI_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.MONOKAI_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("github")
class GithubTheme(BaseTheme):
    """GitHub theme - clean light theme inspired by GitHub."""

    template = f"""
/* =============================================================================
   GITHUB THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.GITHUB_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.GITHUB_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.GITHUB_FG};
    background-color: {Color.GITHUB_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.GITHUB_BLUE},
                              stop:1 #0759d1);
    color: white;
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 #0759d1,
                              stop:1 {Color.GITHUB_BLUE});
}}

QPushButton:pressed {{
    background: {Color.GITHUB_BLUE};
}}

QPushButton:disabled {{
    background: {Color.GITHUB_GRAY};
    color: {Color.GITHUB_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.GITHUB_BG};
    border: 2px solid {Color.GITHUB_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.GITHUB_FG};
    selection-background-color: {Color.GITHUB_BLUE};
    selection-color: white;
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.GITHUB_BLUE};
    background-color: #f6f8fa;
}}

/* Labels */
QLabel {{
    color: {Color.GITHUB_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.GITHUB_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("solarized_light")
class SolarizedLightTheme(BaseTheme):
    """Solarized Light theme - warm, eye-friendly light theme."""

    template = f"""
/* =============================================================================
   SOLARIZED LIGHT THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.SOLARIZED_BASE3};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SOLARIZED_BASE00};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SOLARIZED_BASE00};
    background-color: {Color.SOLARIZED_BASE3};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SOLARIZED_BLUE},
                              stop:1 {Color.SOLARIZED_CYAN});
    color: {Color.SOLARIZED_BASE3};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SOLARIZED_CYAN},
                              stop:1 {Color.SOLARIZED_BLUE});
}}

QPushButton:pressed {{
    background: {Color.SOLARIZED_GREEN};
}}

QPushButton:disabled {{
    background: {Color.SOLARIZED_BASE1};
    color: {Color.SOLARIZED_BASE2};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.SOLARIZED_BASE2};
    border: 2px solid {Color.SOLARIZED_BASE1};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.SOLARIZED_BASE00};
    selection-background-color: {Color.SOLARIZED_YELLOW};
    selection-color: {Color.SOLARIZED_BASE3};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.SOLARIZED_BLUE};
    background-color: {Color.SOLARIZED_BASE2};
}}

/* Labels */
QLabel {{
    color: {Color.SOLARIZED_BASE00};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.SOLARIZED_BASE1};
}}

/* ============================================================================= */
"""


@ThemeManager._register("solarized_dark")
class SolarizedDarkTheme(BaseTheme):
    """Solarized Dark theme - dark variant of the Solarized theme."""

    template = f"""
/* =============================================================================
   SOLARIZED DARK THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.SOLARIZED_BASE03};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SOLARIZED_BASE0};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SOLARIZED_BASE0};
    background-color: {Color.SOLARIZED_BASE03};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SOLARIZED_BLUE},
                              stop:1 {Color.SOLARIZED_CYAN});
    color: {Color.SOLARIZED_BASE3};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SOLARIZED_CYAN},
                              stop:1 {Color.SOLARIZED_BLUE});
}}

QPushButton:pressed {{
    background: {Color.SOLARIZED_GREEN};
}}

QPushButton:disabled {{
    background: {Color.SOLARIZED_BASE01};
    color: {Color.SOLARIZED_BASE02};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.SOLARIZED_BASE02};
    border: 2px solid {Color.SOLARIZED_BASE01};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.SOLARIZED_BASE0};
    selection-background-color: {Color.SOLARIZED_YELLOW};
    selection-color: {Color.SOLARIZED_BASE03};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.SOLARIZED_BLUE};
    background-color: {Color.SOLARIZED_BASE02};
}}

/* Labels */
QLabel {{
    color: {Color.SOLARIZED_BASE0};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.SOLARIZED_BASE01};
}}

/* ============================================================================= */
"""


@ThemeManager._register("dracula")
class DraculaTheme(BaseTheme):
    """Dracula theme - dark theme with vibrant purple accents."""

    template = f"""
/* =============================================================================
   DRACULA THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.DRACULA_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.DRACULA_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.DRACULA_FG};
    background-color: {Color.DRACULA_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.DRACULA_PURPLE},
                              stop:1 {Color.DRACULA_PINK});
    color: {Color.DRACULA_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.DRACULA_PINK},
                              stop:1 {Color.DRACULA_PURPLE});
}}

QPushButton:pressed {{
    background: {Color.DRACULA_RED};
}}

QPushButton:disabled {{
    background: {Color.DRACULA_COMMENT};
    color: {Color.DRACULA_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #333545;
    border: 2px solid {Color.DRACULA_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.DRACULA_FG};
    selection-background-color: {Color.DRACULA_SELECTION};
    selection-color: {Color.DRACULA_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.DRACULA_GREEN};
    background-color: #3a3c4e;
}}

/* Labels */
QLabel {{
    color: {Color.DRACULA_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.DRACULA_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("nord")
class NordTheme(BaseTheme):
    """Nord theme - arctic, north-bluish color palette."""

    template = f"""
/* =============================================================================
   NORD THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.NORD0};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.NORD4};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.NORD4};
    background-color: {Color.NORD0};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.NORD8},
                              stop:1 {Color.NORD9});
    color: {Color.NORD0};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.NORD9},
                              stop:1 {Color.NORD8});
}}

QPushButton:pressed {{
    background: {Color.NORD10};
}}

QPushButton:disabled {{
    background: {Color.NORD3};
    color: {Color.NORD1};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.NORD1};
    border: 2px solid {Color.NORD3};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.NORD4};
    selection-background-color: {Color.NORD7};
    selection-color: {Color.NORD0};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.NORD8};
    background-color: {Color.NORD2};
}}

/* Labels */
QLabel {{
    color: {Color.NORD4};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.NORD3};
}}

/* ============================================================================= */
"""


@ThemeManager._register("onedark")
class OneDarkTheme(BaseTheme):
    """One Dark theme - Atom's iconic dark theme."""

    template = f"""
/* =============================================================================
   ONE DARK THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.ONEDARK_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ONEDARK_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ONEDARK_FG};
    background-color: {Color.ONEDARK_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ONEDARK_BLUE},
                              stop:1 {Color.ONEDARK_PURPLE});
    color: {Color.ONEDARK_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ONEDARK_PURPLE},
                              stop:1 {Color.ONEDARK_BLUE});
}}

QPushButton:pressed {{
    background: {Color.ONEDARK_RED};
}}

QPushButton:disabled {{
    background: {Color.ONEDARK_COMMENT};
    color: {Color.ONEDARK_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #2c313a;
    border: 2px solid {Color.ONEDARK_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.ONEDARK_FG};
    selection-background-color: #3e4451;
    selection-color: {Color.ONEDARK_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.ONEDARK_BLUE};
    background-color: #333841;
}}

/* Labels */
QLabel {{
    color: {Color.ONEDARK_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.ONEDARK_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("ayu_mirage")
class AyuMirageTheme(BaseTheme):
    """Ayu Mirage theme - dark theme with warm accents."""

    template = f"""
/* =============================================================================
   AYU MIRAGE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.AYU_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.AYU_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.AYU_FG};
    background-color: {Color.AYU_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.AYU_BLUE},
                              stop:1 {Color.AYU_PURPLE});
    color: {Color.AYU_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.AYU_PURPLE},
                              stop:1 {Color.AYU_BLUE});
}}

QPushButton:pressed {{
    background: {Color.AYU_RED};
}}

QPushButton:disabled {{
    background: {Color.AYU_COMMENT};
    color: {Color.AYU_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #272d38;
    border: 2px solid {Color.AYU_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.AYU_FG};
    selection-background-color: {Color.AYU_COMMENT};
    selection-color: {Color.AYU_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.AYU_GREEN};
    background-color: #2d343f;
}}

/* Labels */
QLabel {{
    color: {Color.AYU_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.AYU_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("material_dark")
class MaterialDarkTheme(BaseTheme):
    """Material Dark theme - Google's Material Design dark theme."""

    template = f"""
/* =============================================================================
   MATERIAL DARK THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.MATERIAL_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.MATERIAL_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.MATERIAL_FG};
    background-color: {Color.MATERIAL_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.MATERIAL_BLUE},
                              stop:1 {Color.MATERIAL_PURPLE});
    color: {Color.MATERIAL_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.MATERIAL_PURPLE},
                              stop:1 {Color.MATERIAL_BLUE});
}}

QPushButton:pressed {{
    background: {Color.MATERIAL_RED};
}}

QPushButton:disabled {{
    background: {Color.MATERIAL_COMMENT};
    color: {Color.MATERIAL_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #37474f;
    border: 2px solid {Color.MATERIAL_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.MATERIAL_FG};
    selection-background-color: #455a64;
    selection-color: {Color.MATERIAL_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.MATERIAL_BLUE};
    background-color: #3f51b5;
}}

/* Labels */
QLabel {{
    color: {Color.MATERIAL_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.MATERIAL_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("arc_dark")
class ArcDarkTheme(BaseTheme):
    """Arc Dark theme - popular Linux desktop theme."""

    template = f"""
/* =============================================================================
   ARC DARK THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.ARCDARK_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ARCDARK_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ARCDARK_FG};
    background-color: {Color.ARCDARK_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ARCDARK_BLUE},
                              stop:1 {Color.ARCDARK_PURPLE});
    color: {Color.ARCDARK_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ARCDARK_PURPLE},
                              stop:1 {Color.ARCDARK_BLUE});
}}

QPushButton:pressed {{
    background: {Color.ARCDARK_RED};
}}

QPushButton:disabled {{
    background: {Color.ARCDARK_COMMENT};
    color: {Color.ARCDARK_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #3c404d;
    border: 2px solid {Color.ARCDARK_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.ARCDARK_FG};
    selection-background-color: {Color.ARCDARK_COMMENT};
    selection-color: {Color.ARCDARK_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.ARCDARK_GREEN};
    background-color: #424654;
}}

/* Labels */
QLabel {{
    color: {Color.ARCDARK_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.ARCDARK_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("gruvbox")
class GruvboxTheme(BaseTheme):
    """Gruvbox theme - retro groove color scheme."""

    template = f"""
/* =============================================================================
   GRUVBOX THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.GRUVBOX_DARK0};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.GRUVBOX_LIGHT1};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.GRUVBOX_LIGHT1};
    background-color: {Color.GRUVBOX_DARK0};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.GRUVBOX_BLUE},
                              stop:1 {Color.GRUVBOX_PURPLE});
    color: {Color.GRUVBOX_DARK0};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.GRUVBOX_PURPLE},
                              stop:1 {Color.GRUVBOX_BLUE});
}}

QPushButton:pressed {{
    background: {Color.GRUVBOX_RED};
}}

QPushButton:disabled {{
    background: {Color.GRUVBOX_DARK3};
    color: {Color.GRUVBOX_DARK1};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.GRUVBOX_DARK1};
    border: 2px solid {Color.GRUVBOX_DARK3};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.GRUVBOX_LIGHT1};
    selection-background-color: {Color.GRUVBOX_DARK2};
    selection-color: {Color.GRUVBOX_LIGHT1};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.GRUVBOX_GREEN};
    background-color: {Color.GRUVBOX_DARK2};
}}

/* Labels */
QLabel {{
    color: {Color.GRUVBOX_LIGHT1};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.GRUVBOX_DARK3};
}}

/* ============================================================================= */
"""


@ThemeManager._register("tokyo_night")
class TokyoNightTheme(BaseTheme):
    """Tokyo Night theme - dark theme with vibrant colors."""

    template = f"""
/* =============================================================================
   TOKYO NIGHT THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.TOKYO_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TOKYO_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.TOKYO_FG};
    background-color: {Color.TOKYO_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.TOKYO_BLUE},
                              stop:1 {Color.TOKYO_PURPLE});
    color: {Color.TOKYO_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.TOKYO_PURPLE},
                              stop:1 {Color.TOKYO_BLUE});
}}

QPushButton:pressed {{
    background: {Color.TOKYO_RED};
}}

QPushButton:disabled {{
    background: {Color.TOKYO_COMMENT};
    color: {Color.TOKYO_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #24283b;
    border: 2px solid {Color.TOKYO_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.TOKYO_FG};
    selection-background-color: {Color.TOKYO_COMMENT};
    selection-color: {Color.TOKYO_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.TOKYO_GREEN};
    background-color: #2a2f45;
}}

/* Labels */
QLabel {{
    color: {Color.TOKYO_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.TOKYO_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("rose_pine")
class RosePineTheme(BaseTheme):
    """Rose Pine theme - elegant dark theme with rose gold accents."""

    template = f"""
/* =============================================================================
   ROSE PINE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.ROSE_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ROSE_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.ROSE_FG};
    background-color: {Color.ROSE_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ROSE_BLUE},
                              stop:1 {Color.ROSE_PURPLE});
    color: {Color.ROSE_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.ROSE_PURPLE},
                              stop:1 {Color.ROSE_BLUE});
}}

QPushButton:pressed {{
    background: {Color.ROSE_RED};
}}

QPushButton:disabled {{
    background: {Color.ROSE_COMMENT};
    color: {Color.ROSE_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #1f1d2e;
    border: 2px solid {Color.ROSE_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.ROSE_FG};
    selection-background-color: {Color.ROSE_COMMENT};
    selection-color: {Color.ROSE_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.ROSE_GREEN};
    background-color: #26233a;
}}

/* Labels */
QLabel {{
    color: {Color.ROSE_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.ROSE_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("catppuccin")
class CatppuccinTheme(BaseTheme):
    """Catppuccin theme - soothing pastel theme."""

    template = f"""
/* =============================================================================
   CATPPUCCIN THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.CAT_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.CAT_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.CAT_FG};
    background-color: {Color.CAT_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.CAT_BLUE},
                              stop:1 {Color.CAT_PURPLE});
    color: {Color.CAT_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.CAT_PURPLE},
                              stop:1 {Color.CAT_BLUE});
}}

QPushButton:pressed {{
    background: {Color.CAT_RED};
}}

QPushButton:disabled {{
    background: {Color.CAT_COMMENT};
    color: {Color.CAT_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #313244;
    border: 2px solid {Color.CAT_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.CAT_FG};
    selection-background-color: {Color.CAT_COMMENT};
    selection-color: {Color.CAT_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.CAT_GREEN};
    background-color: #38394c;
}}

/* Labels */
QLabel {{
    color: {Color.CAT_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.CAT_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("vitesse")
class VitesseTheme(BaseTheme):
    """Vitesse theme - clean light theme with subtle colors."""

    template = f"""
/* =============================================================================
   VITESSE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.VITESSE_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.VITESSE_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.VITESSE_FG};
    background-color: {Color.VITESSE_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.VITESSE_BLUE},
                              stop:1 {Color.VITESSE_PURPLE});
    color: white;
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.VITESSE_PURPLE},
                              stop:1 {Color.VITESSE_BLUE});
}}

QPushButton:pressed {{
    background: {Color.VITESSE_RED};
}}

QPushButton:disabled {{
    background: {Color.VITESSE_COMMENT};
    color: {Color.VITESSE_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: {Color.VITESSE_BG};
    border: 2px solid {Color.VITESSE_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.VITESSE_FG};
    selection-background-color: {Color.VITESSE_BLUE};
    selection-color: white;
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.VITESSE_BLUE};
    background-color: #f8f8f8;
}}

/* Labels */
QLabel {{
    color: {Color.VITESSE_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.VITESSE_COMMENT};
}}

/* ============================================================================= */
"""


@ThemeManager._register("synthwave")
class SynthwaveTheme(BaseTheme):
    """Synthwave theme - retro futuristic theme with neon colors."""

    template = f"""
/* =============================================================================
   SYNTHWAVE THEME
   ============================================================================= */

/* Global application styling */
QMainWindow, QDialog {{
    background-color: {Color.SYNTHWAVE_BG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SYNTHWAVE_FG};
}}

QWidget {{
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
    color: {Color.SYNTHWAVE_FG};
    background-color: {Color.SYNTHWAVE_BG};
}}

/* Buttons */
QPushButton {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SYNTHWAVE_PINK},
                              stop:1 {Color.SYNTHWAVE_PURPLE});
    color: {Color.SYNTHWAVE_BG};
    border: none;
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-size: {Font.FONT_SIZE_MEDIUM};
    font-weight: {Font.FONT_WEIGHT_MEDIUM};
    min-height: {Dimension.BUTTON_HEIGHT}px;
    min-width: 80px;
}}

QPushButton:hover {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SYNTHWAVE_PURPLE},
                              stop:1 {Color.SYNTHWAVE_PINK});
}}

QPushButton:pressed {{
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                              stop:0 {Color.SYNTHWAVE_RED},
                              stop:1 {Color.SYNTHWAVE_PINK});
}}

QPushButton:disabled {{
    background: {Color.SYNTHWAVE_COMMENT};
    color: {Color.SYNTHWAVE_BG};
}}

/* Input controls */
QLineEdit, QTextEdit, QPlainTextEdit {{
    background-color: #2d2a45;
    border: 2px solid {Color.SYNTHWAVE_COMMENT};
    border-radius: {Dimension.BORDER_RADIUS_MEDIUM}px;
    padding: {Dimension.PADDING_MEDIUM}px {Dimension.PADDING_LARGE}px;
    font-family: {Font.MONOSPACE_FONT};
    font-size: {Font.FONT_SIZE_NORMAL};
    color: {Color.SYNTHWAVE_FG};
    selection-background-color: {Color.SYNTHWAVE_COMMENT};
    selection-color: {Color.SYNTHWAVE_FG};
    min-height: {Dimension.INPUT_HEIGHT}px;
}}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {{
    border: 2px solid {Color.SYNTHWAVE_CYAN};
    background-color: #33304d;
}}

/* Labels */
QLabel {{
    color: {Color.SYNTHWAVE_FG};
    font-family: {Font.FONT_FAMILY};
    font-size: {Font.FONT_SIZE_LARGE};
}}

QLabel:disabled {{
    color: {Color.SYNTHWAVE_COMMENT};
}}

/* ============================================================================= */
"""
