MorningHue

A vivid light color theme for VS Code, Vim, iTerm2, and tmux. Warm off-white background, WCAG-verified contrast ratios, and research-backed design for brightly-lit environments.

AAA 7:1+ Keywords AA 4.5:1+ All Syntax Light Theme VS Code 256-Color iTerm2 zsh

View on GitHub · iTerm2 · zsh

Color Palette

Every color is verified against the warm off-white background (#F1EDE5). Keywords and control flow exceed AAA (7:1), all other syntax colors meet AA (4.5:1).

Background & Foreground

Aa Bb Cc
Background
#F1EDE5
The quick brown fox
Foreground
#444444 · cterm 238 · CR 8.33
CursorLine
Cursor Line
#E4DED6 · cterm 254
// comment
Comment
#949494 · cterm 246 · Subtle

AAA Tier — CR ≥ 7:1

module
Vivid Blue
#0000d7 · 20 · CR 9.08
`define
Dark Crimson
#870000 · 88 · CR 8.86
always_ff
Deep Magenta
#870087 · 90 · CR 7.56
logic
Vivid Purple
#5f00d7 · 56 · CR 7.29

AA Tier — CR ≥ 4.5:1

"string"
Dark Green
#005f00 · 22 · CR 6.82
1'b1
Sea Teal
#005f5f · 23 · CR 6.42
Error
Deep Red
#af0000 · 124 · CR 6.37
a + b
Medium Blue
#005faf · 25 · CR 5.52
my_func()
Dark Teal
#005f87 · 24 · CR 6.06
32'hFF
Dark Golden
#875f00 · 94 · CR 4.90
assert
Bright Purple
#af00d7 · 128 · CR 4.73
import
Vivid Red
#d70000 · 160 · CR 4.62

Code Examples

MorningHue highlights all standard Vim syntax groups, so any language Vim supports works automatically. Here are examples from several languages commonly used in hardware verification and software development.

SystemVerilog

alu_scoreboard.sv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
`include "uvm_macros.svh" `define TIMEOUT 1000 module alu_scoreboard #(parameter int WIDTH = 32) ( input logic clk, input logic rst_n, input logic [WIDTH-1:0] a, b, output logic [WIDTH-1:0] result ); logic [WIDTH-1:0] expected; always_comb begin case (opcode) 3'b000: expected = a + b; 3'b001: expected = a - b; default: expected = '0; endcase end assert property (@(posedge clk) result === expected) else $error("Mismatch: got %h, exp %h", result, expected); endmodule

Python

regression.py
1 2 3 4 5 6 7 8 9 10 11 12 13
import subprocess from pathlib import Path MAX_PARALLEL = 8 def run_regression(test_dir: str, seed: int = 42) -> bool: """Execute a full regression run.""" test_path = Path(test_dir) if not test_path.exists(): raise FileNotFoundError(f"Test dir missing") for cfg in test_path.glob("*.cfg"): result = subprocess.run(["simv", "+seed=" + str(seed)]) return True

C

driver.c
1 2 3 4 5 6 7 8 9 10 11 12
#include <stdio.h> #include <stdlib.h> #define BUF_SIZE 1024 int process_data(const char *input, size_t len) { char buffer[BUF_SIZE]; if (input == NULL || len == 0) { return -1; } printf("Processing %zu bytes\n", len); return 0; }

Makefile

Makefile
1 2 3 4 5 6 7 8
# Simulation build targets VCS_HOME := /tools/synopsys/vcs/R-2023.12 SEED := 42 compile: filelist.f $(VCS_HOME)/bin/vcs -sverilog -f filelist.f sim: compile ./simv +ntb_random_seed=$(SEED)

TCL

run_sim.tcl
1 2 3 4 5 6 7 8
# Simulation run script proc run_test {testname seed} { set logfile "logs/${testname}_${seed}.log" if {[file exists $logfile]} { file delete $logfile } puts "Running: $testname with seed $seed" source "configs/${testname}.tcl" }

Bash / Shell

run_tests.sh
1 2 3 4 5 6 7 8 9
#!/bin/bash PROJ_DIR="/home/user/verification" NUM_SEEDS=10 for seed in $(seq 1 $NUM_SEEDS); do echo "Running seed: $seed" if ! ./simv +seed=$seed; then echo "FAILED at seed $seed" >&2 fi done

JSON

config.json
1 2 3 4 5 6 7 8
{ "testbench": "alu_tb", "num_tests": 1000, "coverage": true, "timeout_ns": 50000, "debug": false, "seed": null }

Markdown

README.md
1 2 3 4 5 6 7
# ALU Verification This project contains the UVM testbench for the ALU module. ## Getting Started `make compile` followed by `make sim` to run. [Documentation](https://example.com)

UI Elements

Vim Statusline

 NORMAL  | alu_scoreboard.sv [+]                utf-8 | systemverilog   15:24
 regression.py                                                          1:1

tmux Status Bar

[verif]
0:build
1:vim
2:sim
3:waves
14:32   18-Feb-26

Diagnostics & Selection

Visual: selected text
Search: /pattern/
Error: undefined 'clk_i'
Warning: unused 'debug_en'
TODO: add edge case coverage
MatchParen: begin )

Diff View

− logic [7:0] data_old;
+ logic [15:0] data_wide;
  assign result = a + b + carry;

Broken Symlinks (ls --color)

A common problem with light themes: broken symlinks are invisible. MorningHue's dircolors configuration fixes this.

src/ include/ build/ Makefile run.tcl sim.py alu.sv libvcs.so -> /tools/lib/libvcs.so broken_link -> /missing/target ← clearly visible!

Accessibility & Contrast Ratios

All contrast ratios are calculated against the background (#F1EDE5, luminance 0.849) using the WCAG 2.1 formula. Colors are sorted by contrast ratio.

ColorHexctermContrast RatioGradeUsage
#0000d7209.08 : 1 AAAKeyword, module, structure
#870000888.86 : 1 AAAPreProc, `define, `ifdef
#4444442388.33 : 1 AAANormal text
#870087907.56 : 1 AAAControl flow, always, if
#5f00d7567.29 : 1 AAAType, StorageClass
#005f00226.82 : 1 AAString
#005f5f236.42 : 1 AABoolean, tag
#af00001246.37 : 1 AAError, exception
#005f87246.06 : 1 AAFunction, Identifier
#005faf255.52 : 1 AAOperator, delimiter
#875f00944.90 : 1 AANumber, constant
#af00d71284.73 : 1 AAStatement, assert
#d700001604.62 : 1 AAImport, include
#9494942462.60 : 1 SubtleComment (italic)
#1c1c1c16.29 : 1 AAAANSI color15 (bright white) — remapped for TUI tool visibility

* ANSI palette slots color7 (#444444, listed above as Normal text) and color15 (#1c1c1c) are remapped to dark values. On a light background, tools like GitHub Copilot CLI render text in these slots; keeping them light would make the output invisible.

Why Accessibility Matters for Code

Engineers spend hours reading code on screen. A theme with poor contrast forces the eyes to work harder, leading to fatigue and missed details. MorningHue ensures:

Comparison with PaperColor

PaperColor is an excellent theme, but several of its colors fall below the WCAG AA threshold on its own background. MorningHue addresses every one:

ElementPaperColorCRMorningHueCRChange
Background#eeeeee#F1EDE5Warmer, less harsh
Strings#5f87003.65#005f006.82+87%
Statement#d700874.27#af00d74.73+11%
Operator#0087af3.56#005faf5.52+55%
Numbers#d75f003.28#875f004.90+49%
Boolean#0087004.05#005f5f6.42+59%
Broken symlinksInvisibleBold red on pinkFixed

Why a Light Theme?

MorningHue is designed for brightly-lit environments. There is peer-reviewed research supporting this design choice — but the picture is nuanced. This section presents what the evidence actually says.

The positive polarity advantage

Polarity is the term researchers use for the relationship between text and background luminance. Positive polarity means dark text on a light background; negative polarity means light text on a dark background.

Multiple controlled studies find that positive polarity produces better proofreading accuracy and faster reading speed under typical office lighting. The clearest mechanistic explanation is optical, not perceptual: a bright background causes the pupil to constrict. Smaller pupils reduce spherical and chromatic aberrations in the eye's lens, producing a sharper retinal image. A 2014 study by Piepenbrock, Mayr, and Buchner directly measured smaller pupil sizes and better performance with positive polarity displays.¹ The same group found the effect was more pronounced with smaller character sizes² — relevant for code, where identifiers and operators are often small.

Importantly, a 2007 study by Buchner and Baumgartner⁴ found that when display luminance was equalized between the two polarity conditions, the performance difference disappeared. The advantage is a luminance effect, not a polarity effect per se. In normal use, positive polarity displays are brighter overall, and it is that extra luminance — driving pupil constriction — that produces the reading benefit.

Positive polarity
int
result = 42;
Bright bg → pupil constricts
→ sharper retinal image
Negative polarity
int
result = 42;
Dark bg → pupil dilates
→ more optical aberration

Ambient light is the key variable

The advantage is conditional on environment. A 2024 study⁵ found that under high ambient brightness, negative polarity actually produced lower eye fatigue — the dark screen reduces total luminance load when the room itself is already very bright. Research by Dobres et al. (2017)⁶ consistently shows that what matters most is matching screen luminance to ambient light: when screen brightness is close to the environmental brightness, visual fatigue is reduced regardless of polarity.

Design rationale: MorningHue is designed for bright offices and indoor workspaces where ambient and screen luminance are naturally similar — the context where the positive polarity advantage is most consistent and most measured.

Warm white, not pure white

Pure white backgrounds (#ffffff) maximize the luminance benefit but can introduce halation — a perception of light "bleeding" into surrounding dark text, especially noticeable for users with astigmatism. The warm off-white background of MorningHue (#F1EDE5) retains enough luminance to drive pupil constriction while reducing the harshness that makes extended reading on pure-white screens uncomfortable.

When a dark theme is the right choice

The research does not support positive polarity as universally superior. Dark themes are a legitimate choice in several contexts:

There is also no peer-reviewed research specifically on dark vs light themes for code reading. Any claim that one polarity is objectively better for programming goes beyond the available evidence.

Sources

  1. Piepenbrock, C., Mayr, S., & Buchner, A. (2014). Smaller pupil size and better proofreading performance with positive than with negative polarity displays. Ergonomics, 57(11), 1670–1677. pubmed.ncbi.nlm.nih.gov/25135324
  2. Piepenbrock, C., Mayr, S., Mund, I., & Buchner, A. (2013). Positive display polarity is advantageous for both younger and older adults. Ergonomics, 56(7), 1116–1124. doi:10.1080/00140139.2013.790485
  3. Piepenbrock, C., Mayr, S., & Buchner, A. (2014). Positive display polarity is particularly advantageous for small character sizes. Human Factors, 56(5), 942–951. doi:10.1177/0018720813515509
  4. Buchner, A., & Baumgartner, N. (2007). Text–background polarity affects performance irrespective of ambient illumination and colour contrast. Ergonomics, 50(7), 1036–1063. pubmed.ncbi.nlm.nih.gov/19562598
  5. Eichenbaum et al. (2024). Effects of ambient illuminance on display polarity, visual fatigue, and reading performance. BMC Ophthalmology / PMC. pmc.ncbi.nlm.nih.gov/articles/PMC11175232
  6. Dobres, J., Chahine, N., & Reimer, B. (2017). Perceptual and legibility thresholds for positive and negative polarity text in indoor and outdoor environments. Applied Ergonomics, 65, 41–47. doi:10.1016/j.apergo.2016.08.011
  7. Wang, Y. et al. (2025). The dark side of dark mode: an eye-tracking study. ACM CHI 2025. doi:10.1145/3715669.3725879

Installation

VS Code

Clone into your VS Code extensions directory:

# Linux / macOS git clone https://github.com/glenzac/morninghue-theme ~/.vscode/extensions/morninghue # Windows git clone https://github.com/glenzac/morninghue-theme %USERPROFILE%\.vscode\extensions\morninghue

Then restart VS Code, open the Command Palette (Ctrl+Shift+P), type Preferences: Color Theme, and select MorningHue.

Vim / Neovim

mkdir -p ~/.vim/colors cp colors/morninghue.vim ~/.vim/colors/

Add to ~/.vimrc:

set background=light colorscheme morninghue

iTerm2 (macOS)

  1. Open iTerm2 → Preferences → Profiles → Colors
  2. Click Color Presets… → Import… and select morninghue.itermcolors
  3. Select MorningHue from the Color Presets dropdown

zsh prompt theme

oh-my-zsh:

cp morninghue.zsh-theme ~/.oh-my-zsh/themes/morninghue.zsh-theme

Set ZSH_THEME="morninghue" in ~/.zshrc.

Standalone:

source /path/to/morninghue.zsh-theme # add to ~/.zshrc

The prompt uses ANSI palette colors — combine with the iTerm2 preset so the prompt accents automatically match the theme's exact hues.

xterm (.Xresources)

cp morninghue.Xresources ~/.Xresources xrdb -merge ~/.Xresources

ANSI palette slots color7 and color15 are remapped to dark values so TUI tools like GitHub Copilot CLI render text visibly on the light background. Several bright slots are also semantically remapped — see the ANSI palette table.

tmux

Add to ~/.tmux.conf:

source-file /path/to/morninghue.tmux.conf

dircolors (fixes broken symlinks)

Add to your shell rc file:

# bash / zsh [ -f /path/to/morninghue.dircolors ] && eval $(dircolors /path/to/morninghue.dircolors) # tcsh / csh if ( -f /path/to/morninghue.dircolors ) eval `dircolors -c /path/to/morninghue.dircolors`