Dual Implementation
Monolex maintains identical color algorithms in two languages, each serving a different purpose.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ DUAL IMPLEMENTATION ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────┐ ┌───────────────────────────┐ │
│ │ RUST (Production) │ │ TYPESCRIPT (Lab Tool) │ │
│ ├───────────────────────────┤ ├───────────────────────────┤ │
│ │ │ │ │ │
│ │ Purpose: │ │ Purpose: │ │
│ │ - Runtime transforms │ │ - Interactive tuning │ │
│ │ - LRU caching │ │ - Visual verification │ │
│ │ - High performance │ │ - Parameter exploration │ │
│ │ │ │ │ │
│ │ Speed: │ │ Speed: │ │
│ │ < 1 microsecond │ │ Real-time preview │ │
│ │ per transform │ │ in browser │ │
│ │ │ │ │ │
│ └─────────────┬─────────────┘ └─────────────┬─────────────┘ │
│ │ │ │
│ └────────────────┬───────────────┘ │
│ │ │
│ v │
│ ┌───────────────────────────┐ │
│ │ IDENTICAL ALGORITHM │ │
│ ├───────────────────────────┤ │
│ │ │ │
│ │ - Same color math │ │
│ │ - Same parameters │ │
│ │ - Same results │ │
│ │ │ │
│ └───────────────────────────┘ │
│ │
│ Why two implementations? │
│ - Rust: Speed for production (thousands of colors per frame) │
│ - TypeScript: Convenience for theme designers (instant feedback) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
The Transform Pipeline
Every color passes through seven steps. Here’s the complete flow.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ COMPLETE TRANSFORM PIPELINE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ INPUT: RGB Color (e.g., #FF5733) │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 1: RGB to OKLAB │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ #FF5733 │ │
│ │ │ │ │
│ │ └── Extract R, G, B (0-255) │ │
│ │ │ │ │
│ │ └── Gamma expand (sRGB to linear) │ │
│ │ │ │ │
│ │ └── Matrix M1: RGB to LMS │ │
│ │ │ │ │
│ │ └── Cube root (perceptual) │ │
│ │ │ │ │
│ │ └── Matrix M2: LMS' to OKLAB │ │
│ │ │ │ │
│ │ v │ │
│ │ OKLAB(L=0.68, a=0.18, b=0.14) │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 2: OKLAB to OKLCH (Polar Form) │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ L = 0.68 (Lightness, unchanged) │ │
│ │ │ │
│ │ C = sqrt(a^2 + b^2) │ │
│ │ = sqrt(0.18^2 + 0.14^2) │ │
│ │ = 0.23 (Chroma) │ │
│ │ │ │
│ │ H = atan2(b, a) │ │
│ │ = atan2(0.14, 0.18) │ │
│ │ = 38 degrees (Hue) │ │
│ │ │ │
│ │ Result: OKLCH(L=0.68, C=0.23, H=38 deg) │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 3: Lightness Mapping │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ Weber-Fechner perceptual correction │ │
│ │ (human eyes perceive brightness non-linearly) │
│ │ │ │
│ │ L = 0.68 --> L_corrected = 0.65 │ │
│ │ │ │
│ │ Uses precomputed lookup table (8 steps) │ │
│ │ for fast interpolation │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 4: Chroma Scaling │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ Reduce saturation for theme harmony │ │
│ │ │ │
│ │ C = 0.23 * chroma_ratio │ │
│ │ = 0.23 * 0.82 │ │
│ │ = 0.19 │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 5: Frame Drag (Tint Blending) │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ Pull hue toward theme's tint color │ │
│ │ (Like gravity pulling nearby objects) │ │
│ │ │ │
│ │ tint_hue = 250 deg (Blue) │ │
│ │ tint_strength = 10% │ │
│ │ │ │
│ │ H = 38 deg * 0.90 + 250 deg * 0.10 │ │
│ │ = 34.2 + 25 │ │
│ │ = ~36 deg (shifted slightly toward blue) │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 6: Einstein Arc │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ Is color INSIDE or OUTSIDE Caustic zone? │ │
│ │ │ │
│ │ Caustic center = 130 deg │ │
│ │ Caustic width = 90 deg │ │
│ │ Zone = 40 deg to 220 deg │ │
│ │ │ │
│ │ H = 36 deg is OUTSIDE zone (< 40 deg) │ │
│ │ │ │
│ │ OUTSIDE: Apply hue expansion │ │
│ │ H = 36 deg --> H = 32 deg │ │
│ │ (expanded as zone compressed) │ │
│ │ │ │
│ │ Convert back to OKLAB: │ │
│ │ a = C * cos(H) = 0.19 * cos(32 deg) │ │
│ │ b = C * sin(H) = 0.19 * sin(32 deg) │ │
│ │ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ STEP 7: OKLAB to RGB │ │
│ ├──────────────────────────────────────────────┤ │
│ │ │ │
│ │ OKLAB(L=0.65, a=0.16, b=0.10) │ │
│ │ │ │ │
│ │ └── Matrix M2 inverse: OKLAB to LMS' │ │
│ │ │ │ │
│ │ └── Cube (inverse of cube root) │ │
│ │ │ │ │
│ │ └── Matrix M1 inverse: LMS to RGB │ │
│ │ │ │ │
│ │ └── Gamma compress (linear to sRGB) │ │
│ │ │ │ │
│ │ v │ │
│ │ #E07055 │ │
│ │ │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ OUTPUT: #E07055 (Theme-harmonized coral) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Performance Architecture
The Tint System is optimized for speed at every level.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ PERFORMANCE ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ LAYER 1: Theme Load (happens once when switching themes) │
│ ======================================================== │
│ │
│ User Parameters Precomputed Cache │
│ (human-friendly) --> (machine-optimized) │
│ │
│ tintHue: 250 deg --> tint_hue: 4.36 radians │
│ tintStrength: 10% --> tint_strength: 0.10 │
│ causticWidth: 90 --> caustic_width: 1.57 radians │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ ThemeTransformCache (74+ precomputed fields) │ │
│ ├───────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Core Parameters (already in radians) │ │
│ │ - tint_hue, anchor_hue, caustic_hue │ │
│ │ - caustic_width, caustic_strength │ │
│ │ │ │
│ │ Precomputed Values (avoid runtime calculation) │ │
│ │ - l_corrected[8]: Weber-Fechner lookup table │ │
│ │ - caustic_left, caustic_right: zone boundaries │ │
│ │ - chroma_ratio: saturation multiplier │ │
│ │ - ... 60+ more fields │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ Time: ~10 milliseconds (one-time cost per theme switch) │
│ │
│ ─────────────────────────────────────────────────────────────────── │
│ │
│ LAYER 2: Color Transform (happens for every color) │
│ =================================================== │
│ │
│ Input Color │
│ │ │
│ v │
│ ┌───────────────────┐ │
│ │ LRU Cache │ │
│ │ (1024 colors) │ │
│ └────────┬──────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │ │ │
│ HIT MISS │
│ │ │ │
│ v v │
│ Return Compute │
│ cached transform │
│ result │ │
│ │ └── Store in cache │
│ │ │ │
│ v v │
│ Output Output │
│ (<0.1 us) (~1 us) │
│ │
│ Cache Strategy: │
│ - 1024 most recent colors stored │
│ - LRU eviction (least recently used removed first) │
│ - Terminal output often repeats colors (syntax highlighting) │
│ - Hit rate typically > 80% │
│ │
└─────────────────────────────────────────────────────────────────────────┘
The Coordinate Dance
Colors constantly switch between two coordinate systems.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ COORDINATE SYSTEM FLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ INPUT: RGB (0x00-0xFF per channel) │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ sRGB --> Linear RGB │ │
│ │ (gamma expansion) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ Linear RGB --> LMS --> LMS' --> OKLAB │ │
│ │ (matrix transforms + cube root) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ╔══════════════════════════════════════════════╗ │
│ ║ OKLAB (CARTESIAN) ║ │
│ ║ ║ │
│ ║ L = Lightness (0 to 1) ║ │
│ ║ a = Green-Red axis (-0.5 to 0.5) ║ │
│ ║ b = Blue-Yellow axis (-0.5 to 0.5) ║ │
│ ║ ║ │
│ ╚══════════════════════╦═══════════════════════╝ │
│ │ │
│ v │
│ ╔══════════════════════════════════════════════╗ │
│ ║ OKLCH (POLAR) ║ │
│ ║ ║ │
│ ║ L = Lightness (same as OKLAB) ║ │
│ ║ C = Chroma = sqrt(a^2 + b^2) ║ │
│ ║ H = Hue = atan2(b, a) ║ │
│ ║ ║ │
│ ║ Used for: Frame Drag, Einstein Arc ║ │
│ ║ (hue-based operations) ║ │
│ ║ ║ │
│ ╚══════════════════════╦═══════════════════════╝ │
│ │ │
│ │ Einstein Arc may return │
│ │ to OKLAB for gradient │
│ │ │
│ v │
│ ╔══════════════════════════════════════════════╗ │
│ ║ OKLAB (CARTESIAN) ║ │
│ ║ ║ │
│ ║ Used for: Caustic gradient fill ║ │
│ ║ (smooth transitions) ║ │
│ ║ ║ │
│ ╚══════════════════════╦═══════════════════════╝ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ OKLAB --> LMS' --> LMS --> Linear RGB │ │
│ │ (inverse transforms + cube) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ ┌──────────────────────────────────────────────┐ │
│ │ Linear RGB --> sRGB │ │
│ │ (gamma compression) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ v │
│ OUTPUT: RGB (0x00-0xFF per channel) │
│ │
│ ═══════════════════════════════════════════════════════════════════ │
│ │
│ POLAR (OKLCH) is for: CARTESIAN (OKLAB) is for: │
│ - Hue operations - Smooth gradients │
│ - User parameters - Color mixing │
│ - Identity (what color) - Transitions (between colors) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Development Workflow
Theme designers use TypeScript for experimentation, then Rust runs in production.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ DEVELOPMENT WORKFLOW │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 1. EXPERIMENT (TypeScript Lab Tool) │ │
│ ├───────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Open hue-warp-lab.html in browser │ │
│ │ │ │
│ │ ┌────────────────────────┐ ┌────────────────────────┐ │ │
│ │ │ Color Wheel │ │ Parameter Sliders │ │ │
│ │ │ │ │ │ │ │
│ │ │ @@@@@ │ │ tintHue: [====│===] │ │ │
│ │ │ @@@@@@@@@ │ │ strength: [==│====] │ │ │
│ │ │ @@@@@@@@@@@ │ │ width: [=====│==] │ │ │
│ │ │ @@@@@@@@@ │ │ │ │ │
│ │ │ @@@@@ │ │ [Apply] [Reset] │ │ │
│ │ │ │ │ │ │ │
│ │ └────────────────────────┘ └────────────────────────┘ │ │
│ │ │ │
│ │ Real-time preview as you adjust parameters │ │
│ │ │ │
│ └─────────────────────────────┬─────────────────────────────┘ │
│ │ │
│ v │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 2. VERIFY (Visual Inspection) │ │
│ ├───────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ - Check color harmony │ │
│ │ - Test edge cases (pure black, white, saturated) │ │
│ │ - Compare before/after │ │
│ │ - Export theme configuration │ │
│ │ │ │
│ └─────────────────────────────┬─────────────────────────────┘ │
│ │ │
│ v │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 3. APPLY (Rust Production) │ │
│ ├───────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Copy theme parameters to configuration │ │
│ │ Or pass dynamically via Tauri invoke() │ │
│ │ │ │
│ │ Since algorithms are identical: │ │
│ │ TypeScript preview = Rust production │ │
│ │ │ │
│ └─────────────────────────────┬─────────────────────────────┘ │
│ │ │
│ v │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 4. TEST (Actual Terminal) │ │
│ ├───────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ - Run colorful terminal applications │ │
│ │ - Check syntax highlighting │ │
│ │ - Verify ANSI color semantics │ │
│ │ - Performance profiling │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
The Math is Language-Agnostic
The Gestalt Color System works the same in any programming language.Copy
┌─────────────────────────────────────────────────────────────────────────┐
│ LANGUAGE-AGNOSTIC MATH │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ The core insight: │
│ │
│ Color math is based on universal mathematical operations. │
│ These work identically in any language. │
│ │
│ POLAR OPERATIONS (OKLCH): │
│ ========================= │
│ │
│ atan2(b, a) --> Hue calculation │
│ cos(H), sin(H) --> Convert back to Cartesian │
│ angle_lerp() --> Blend hue angles │
│ │
│ Same in: Rust, TypeScript, Python, Go, C++, ... │
│ │
│ CARTESIAN OPERATIONS (OKLAB): │
│ ============================== │
│ │
│ lerp(a1, a2, t) --> Linear interpolation │
│ matrix multiply --> Color space conversion │
│ sqrt(), cbrt() --> Chroma, cube root │
│ │
│ Same in: Rust, TypeScript, Python, Go, C++, ... │
│ │
│ ═══════════════════════════════════════════════════════════════════ │
│ │
│ The Gestalt Color System is not a Rust feature. │
│ It's a mathematical framework that happens to be implemented │
│ in Rust for performance. │
│ │
│ You could implement it in any language and get identical results. │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Key Takeaways
- Dual implementation - Rust for production speed, TypeScript for design convenience
- Precomputation wins - Theme parameters converted once, used millions of times
- LRU cache - Most colors are repeated; cache hit rate > 80%
- Coordinate dance - Polar for identity, Cartesian for transitions
- Math is universal - Same algorithm works in any language
Architecture Overview
Return to Tint System architecture