Theme Manager Architecture
The central controller for all color theming in Monolex.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ THEME MANAGER - Central Controller │
│ │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ ║│
│ ║ PRIVATE STATE ║│
│ ║ ============= ║│
│ ║ ║│
│ ║ ┌───────────────────┬──────────────────────────────────────────┐ ║│
│ ║ │ themes │ Collection of all available themes │ ║│
│ ║ ├───────────────────┼──────────────────────────────────────────┤ ║│
│ ║ │ currentTheme │ Name of active theme │ ║│
│ ║ ├───────────────────┼──────────────────────────────────────────┤ ║│
│ ║ │ currentMode │ "dark" or "light" │ ║│
│ ║ ├───────────────────┼──────────────────────────────────────────┤ ║│
│ ║ │ darkTheme │ Theme to use for dark mode │ ║│
│ ║ ├───────────────────┼──────────────────────────────────────────┤ ║│
│ ║ │ lightTheme │ Theme to use for light mode │ ║│
│ ║ └───────────────────┴──────────────────────────────────────────┘ ║│
│ ║ ║│
│ ╠═════════════════════════════════════════════════════════════════════════╣│
│ ║ ║│
│ ║ PUBLIC METHODS ║│
│ ║ ============== ║│
│ ║ ║│
│ ║ Theme Application: ║│
│ ║ ├── init() --> Initialize theme system ║│
│ ║ ├── applyTheme(name) --> Activate a theme ║│
│ ║ ├── toggleMode() --> Switch dark/light ║│
│ ║ └── setMode(mode) --> Set specific mode ║│
│ ║ ║│
│ ║ Theme Queries: ║│
│ ║ ├── getCurrentTheme() --> Get active theme name ║│
│ ║ ├── getCurrentMode() --> Get "dark" or "light" ║│
│ ║ └── getAvailableThemes()--> List all themes ║│
│ ║ ║│
│ ║ External Sync: ║│
│ ║ ├── applyThemeToMonaco()--> Sync colors to editor ║│
│ ║ └── forceMonacoSync() --> Force editor update ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Theme Application Flow
What happens when you switch themes.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ THEME APPLICATION SEQUENCE │
│ │
│ User calls: applyTheme("dracula") │
│ │ │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ STEP 1: Deactivate Old Theme ║│
│ ║ ──────────────────────────────── ║│
│ ║ ║│
│ ║ Remove existing theme classes ║│
│ ║ Detach old theme stylesheets ║│
│ ║ ║│
│ ║ [old-theme] --> [removed] ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │ │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ STEP 2: Set Mode Class ║│
│ ║ ────────────────────────── ║│
│ ║ ║│
│ ║ If theme is light: Add "light-mode" class ║│
│ ║ If theme is dark: No class (default) ║│
│ ║ ║│
│ ║ body.classList = ["theme-dracula"] ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │ │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ STEP 3: Load Theme Stylesheet ║│
│ ║ ───────────────────────────────── ║│
│ ║ ║│
│ ║ Inject new theme CSS file ║│
│ ║ Add theme class identifier ║│
│ ║ ║│
│ ║ <link href="dracula.css" /> ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │ │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ STEP 4: Propagate Changes ║│
│ ║ ───────────────────────────── ║│
│ ║ ║│
│ ║ Emit "themechange" event ║│
│ ║ Sync to external systems (Editor, etc.) ║│
│ ║ ║│
│ ║ Event --> All listeners --> UI Updated ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
CSS Variable Auto-Update
The magic of Flow colors: they update automatically.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ FLOW COLORS AUTO-UPDATE │
│ │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ ║│
│ ║ BEFORE: Theme A (Blue Primary) ║│
│ ║ ║│
│ ║ CORE Primary = Blue ║│
│ ║ │ ║│
│ ║ ├───> FLOW Hover = Lighter Blue ║│
│ ║ ├───> FLOW Active = Darker Blue ║│
│ ║ └───> FLOW Background = Transparent Blue ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │ │
│ │ Theme Switch │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ ║│
│ ║ AFTER: Theme B (Purple Primary) ║│
│ ║ ║│
│ ║ CORE Primary = Purple ║│
│ ║ │ ║│
│ ║ ├───> FLOW Hover = Lighter Purple (AUTO!) ║│
│ ║ ├───> FLOW Active = Darker Purple (AUTO!) ║│
│ ║ └───> FLOW Background = Transparent Purple (AUTO!) ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │
│ KEY INSIGHT: │
│ ============ │
│ │
│ Flow Colors reference Core Colors via CSS variables. │
│ When Core changes, CSS cascade recalculates Flows. │
│ │
│ RESULT: Zero JavaScript for Flow Color recalculation. │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
External System Synchronization
Some systems need explicit color updates.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ MONACO EDITOR SYNCHRONIZATION │
│ │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ ║│
│ ║ Monaco Editor uses its own color system. ║│
│ ║ We must explicitly sync colors after theme changes. ║│
│ ║ ║│
│ ║ ┌────────────────────┐ ║│
│ ║ │ Theme Manager │ ║│
│ ║ └──────────┬─────────┘ ║│
│ ║ │ ║│
│ ║ │ 1. Theme changes ║│
│ ║ v ║│
│ ║ ┌────────────────────┐ ║│
│ ║ │ Extract CSS Values │ ║│
│ ║ │ from computed │ ║│
│ ║ │ styles │ ║│
│ ║ └──────────┬─────────┘ ║│
│ ║ │ ║│
│ ║ │ 2. Map to Monaco format ║│
│ ║ v ║│
│ ║ ┌────────────────────┐ ║│
│ ║ │ Color Mapping │ ║│
│ ║ ├────────────────────┤ ║│
│ ║ │ Background --> editor.background ║│
│ ║ │ Text --> editor.foreground ║│
│ ║ │ Accent --> cursor color ║│
│ ║ │ Success --> added lines ║│
│ ║ │ Warning --> modified lines ║│
│ ║ │ Danger --> deleted lines ║│
│ ║ └──────────┬─────────┘ ║│
│ ║ │ ║│
│ ║ │ 3. Apply to Monaco ║│
│ ║ v ║│
│ ║ ┌────────────────────┐ ║│
│ ║ │ Monaco Editor │ ║│
│ ║ │ (colors synced) │ ║│
│ ║ └────────────────────┘ ║│
│ ║ ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Event System
How theme changes propagate through the application.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ THEME CHANGE EVENT PROPAGATION │
│ │
│ ┌───────────────────┐ │
│ │ Theme Manager │ │
│ │ applyTheme() │ │
│ └────────┬──────────┘ │
│ │ │
│ │ Emit "themechange" event │
│ v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ EVENT BUS ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │ │ │ │
│ v v v │
│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │
│ │ Auto-Unique │ │ Syntax Colors │ │ Hybrid Theme │ │
│ │ Color System │ │ System │ │ Handler │ │
│ ├───────────────────┤ ├───────────────────┤ ├───────────────────┤ │
│ │ Update unique │ │ Update syntax │ │ Merge theme │ │
│ │ agent colors │ │ highlighting │ │ with overrides │ │
│ └───────────────────┘ └───────────────────┘ └───────────────────┘ │
│ │ │ │ │
│ v v v │
│ ╔═════════════════════════════════════════════════════════════════════════╗│
│ ║ UI UPDATED ║│
│ ╚═════════════════════════════════════════════════════════════════════════╝│
│ │
│ All color systems listen for theme changes. │
│ Each system updates its own CSS variables. │
│ Result: Unified color experience. │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Theme Types
Different sources for theme definitions.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ THEME SOURCES │
│ │
│ ╔══════════════════════════╗ │
│ ║ FILE THEMES ║ │
│ ║ ─────────── ║ │
│ ║ Location: /themes/ ║ │
│ ║ Format: CSS files ║ │
│ ║ Loading: Link injection ║ │
│ ╚══════════════════════════╝ │
│ │
│ ╔══════════════════════════╗ │
│ ║ CUSTOM THEMES ║ │
│ ║ ───────────── ║ │
│ ║ Location: AppData ║ │
│ ║ Format: JSON configs ║ │
│ ║ Loading: Parse & apply ║ │
│ ╚══════════════════════════╝ │
│ │
│ ╔══════════════════════════╗ │
│ ║ HYBRID THEMES ║ │
│ ║ ───────────── ║ │
│ ║ Source: Database + CSS ║ │
│ ║ Format: Combined ║ │
│ ║ Loading: Merge sources ║ │
│ ╚══════════════════════════╝ │
│ │
│ ╔══════════════════════════╗ │
│ ║ BUILT-IN THEMES ║ │
│ ║ ─────────────── ║ │
│ ║ Location: Embedded ║ │
│ ║ Format: Base variables ║ │
│ ║ Loading: Mode class ║ │
│ ╚══════════════════════════╝ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Performance Comparison
Why this architecture is fast.Copy
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ PERFORMANCE METRICS │
│ │
│ Theme Switch Time: │
│ ================== │
│ │
│ Core & Flow: │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ [=] < 0.1ms │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ Material Design: │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ [═════════════════════════════════════════════] 5-10ms │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ │
│ Bundle Size Impact: │
│ =================== │
│ │
│ Core & Flow: 0 KB (CSS native) │
│ Material HCT: 45 KB (JavaScript library) │
│ │
│ │
│ Runtime Overhead: │
│ ================= │
│ │
│ Core & Flow: None (browser handles color math) │
│ Material HCT: CPU (JavaScript color calculations) │
│ │
│ │
│ WHY SO FAST? │
│ ============ │
│ │
│ 1. Pre-computed Flow Colors │
│ Browser evaluates color-mix() natively │
│ │
│ 2. CSS Cascade │
│ No JavaScript recalculation needed │
│ │
│ 3. Native Browser Support │
│ 92%+ browsers handle OKLCH/OKLAB natively │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
“Core Colors define identity. Flow Colors handle everything in between.”
Decision Flow
Learn when to use Core vs Flow colors