All posts

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:

  1. Convert the base hex to HSL
  2. For each palette slot, define a target lightness (different for dark/light mode)
  3. Mix the base hue/saturation with the target lightness
  4. Apply the intensity multiplier to blend between neutral gray and the colorized version
  5. 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.