Designing a color system from one hex value
Most apps ship with a fixed palette — pick "dark mode" or "light mode" and that's it. Glifo takes a different approach: you provide a single hex color, and the app generates an entire palette from it.
The problem
A full color system needs at least 8-10 values: background, surface, text (3 levels), accent, accent hover, border, code background, code text. Designing these by hand is tedious and error-prone — especially when you need both dark and light variants.
One color in, full palette out
Set base_color in your config to any hex value:
[theme]
base_color = "#6366f1"
color_intensity = 0.7
Glifo extracts the hue and saturation, then generates every color in the system by mapping them to specific lightness targets. The color_intensity slider (0.0 to 1.0) controls how much of the base color comes through — 0.0 is grayscale, 1.0 is fully saturated.
How it works
The generation process:
- Convert the base hex to HSL
- For each palette slot, define a target lightness (different for dark/light mode)
- Mix the base hue/saturation with the target lightness
- Apply the intensity multiplier to blend between neutral gray and the colorized version
- Convert back to hex for CSS variables
The result is a cohesive palette where every color feels related, because they all share the same hue.
Vibrancy
The color system works hand-in-hand with macOS vibrancy. Glifo uses real NSVisualEffectView — not a CSS blur hack. The vibrancy layer sits behind the webview and is always active, giving the window a native frosted glass appearance.
The Opacity slider (20%–95%) controls how transparent the app surface is — lower values let more of the vibrancy show through.
Dark and light
Switch between dark, light, or system auto-detect. The entire palette regenerates instantly — no restart, no flash. CSS variables update in place, and the NSVisualEffectView material adjusts to match.
The best color system is one you set once and forget. Pick a color that feels right, adjust the intensity slider, and every surface in the app follows.