Coverage for src / local_deep_research / web / themes / schema.py: 100%
16 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-25 01:07 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-25 01:07 +0000
1"""
2Theme Schema - Data structures for theme metadata.
3"""
5from dataclasses import dataclass
6from pathlib import Path
7from typing import Literal
10# Required CSS variables that every theme must define
11REQUIRED_VARIABLES: list[str] = [
12 "--bg-primary",
13 "--bg-secondary",
14 "--bg-tertiary",
15 "--accent-primary",
16 "--accent-secondary",
17 "--accent-tertiary",
18 "--text-primary",
19 "--text-secondary",
20 "--text-muted",
21 "--border-color",
22 "--success-color",
23 "--warning-color",
24 "--error-color",
25]
27# RGB variants for rgba() usage
28REQUIRED_RGB_VARIANTS: list[str] = [
29 "--bg-primary-rgb",
30 "--bg-secondary-rgb",
31 "--bg-tertiary-rgb",
32 "--accent-primary-rgb",
33 "--accent-secondary-rgb",
34 "--accent-tertiary-rgb",
35 "--text-primary-rgb",
36 "--text-secondary-rgb",
37 "--text-muted-rgb",
38 "--border-color-rgb",
39 "--success-color-rgb",
40 "--warning-color-rgb",
41 "--error-color-rgb",
42]
44# Valid theme groups
45ThemeGroup = Literal["core", "nature", "dev", "research", "system", "other"]
47# Valid theme types (for luminance classification)
48ThemeType = Literal["dark", "light"]
51@dataclass
52class ThemeMetadata:
53 """Theme metadata extracted from CSS frontmatter."""
55 id: str # kebab-case identifier (e.g., "nord", "dracula")
56 label: str # Display label for UI (e.g., "Nord", "Dracula")
57 icon: str # FontAwesome icon class (e.g., "fa-snowflake")
58 group: ThemeGroup # Category for grouping in UI
59 type: ThemeType = "dark" # dark/light for luminance classification
60 description: str = "" # Optional description
61 author: str = "" # Optional author attribution
62 css_path: Path | None = (
63 None # Path to CSS file (None for virtual themes like "system")
64 )
66 def to_dict(self) -> dict:
67 """Convert to dictionary for JSON serialization."""
68 return {
69 "label": self.label,
70 "icon": self.icon,
71 "group": self.group,
72 "type": self.type,
73 }
76# Group labels for UI display
77GROUP_LABELS: dict[str, str] = {
78 "core": "Core Themes",
79 "nature": "Nature",
80 "dev": "Developer Themes",
81 "research": "Research & Reading",
82 "system": "System",
83 "other": "Other",
84}