omarchy / themes

OMARCHY THEMES / DOCUMENTATION

Palette best practices

Contrast, the neutral ramp, choosing an accent, and the differences that matter in light mode.

← All documentation

Palette best practices

Contrast first

A theme is a reading surface for eight hours a day. Contrast is not an accessibility checkbox here; it is whether the theme is usable.

  • foreground against background: aim for 7:1, treat 4.5:1 as the floor. This is the ratio the Theme Studio enforces on generated palettes.
  • dark_foreground against background: at least 4.5:1. Secondary text is still text. Comments below 3:1 are the single most common flaw in community themes.
  • accent against background: at least 3:1, and more if the accent ever carries text rather than just a border.
  • Every ANSI colour against background: at least 4.5:1. They are syntax highlighting, and a blue that vanishes into a dark background makes code unreadable.
  • bright_foreground against selection: at least 4.5:1, because that is the selected-text pairing Omarchy derives.

Measure, do not guess. The Theme Studio reports live ratios for every pair as you edit.

Build the neutral ramp deliberately

The neutral ramp runs from background to bright_foreground. On a dark theme it should read darkest to lightest; on a light theme, lightest to darkest. Seven steps, in this order:

darker_background  →  dark_background  →  background  →  lighter_background
                                        ↓
     dark_foreground  →  foreground  →  light_foreground  →  bright_foreground
  • Keep the steps even. A ramp that jumps from one surface to the next and then barely moves looks broken in a card-heavy interface.
  • Tint the neutrals. Pure greys next to a saturated accent look dead; carrying a few degrees of the accent’s hue through the ramp is what makes a theme feel designed.
  • Do not let lighter_background collide with selection. Both appear behind text, and if they match, selection becomes invisible.
  • Leave real distance between background and dark_background. Recessed surfaces that are one or two percent apart read as a rendering artefact.

The sixteen ANSI colours

These are not decoration. They are the terminal, and through it every TUI, diff and syntax highlighter you use.

  • Keep the semantics. Red must read as error, green as success, yellow as warning. A green that is actually teal makes git diff lie to you.
  • Red and green must be separable for colour-blind users. Differ in lightness as well as hue — do not rely on the hue alone to carry the meaning.
  • Make the bright_* variants visibly brighter, not just more saturated. The default derivation mixes 20% toward white; if you write them yourself, at least match that.
  • Do not reuse the exact same hex for a colour and its bright variant unless you mean to lose the distinction — some light themes reasonably do, but it flattens bold text in the terminal.
  • Check them together, not one at a time. Print a colour table in the terminal and look for two that are hard to tell apart.

Choosing an accent

  • Pick one accent and commit. It appears on focused window borders, the active bar element, selected menu rows and links; a second competing accent just reads as noise.
  • It usually matches one of your ANSI colours — most bundled themes set accent to the same value as blue or cyan. That is a feature: it keeps the terminal and the desktop consistent.
  • It must survive being a thin one-pixel border on a large surface. Very dark or very desaturated accents disappear at that size.
  • It must not be so loud that a focused window is uncomfortable to sit in front of. Saturated pure red or pure magenta rarely survive a full day.

Light themes need different thinking

A light theme is not a dark theme with the ends swapped. The most common mistake is taking a dark palette’s ANSI colours unchanged.

  • Set mode = "light". Nothing else makes applications pick their light variants reliably.
  • Darken and desaturate the ANSI colours. A yellow that is legible on #1a1b26 is invisible on #fffcf0; bundled light themes routinely drop lightness by a third.
  • The bright_* colours often cannot be brighter, because brighter means closer to the background. Look at flexoki-light, which sets several of them identical to their base colour and brightens only where it helps.
  • Remember that Omarchy’s automatic derivation mixes toward black for dark_background and toward white for the bright colours. Neither rule is right for a light theme, so write those keys explicitly.
  • Avoid a pure white background. An off-white such as #fffcf0 or #faf4ed is markedly easier to read for a full day.

Ready to make one?

The Theme Studio builds a palette in the browser, measures contrast as you pick, and publishes an installable repository.

Open the Theme Studio