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