Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

datum

A light and dark colorscheme for your whole terminal — Neovim, Ghostty, Kitty, Alacritty, WezTerm, VS Code, tmux, fzf, bat, delta and the shell — derived, not picked.

Most schemes are tuned by nudging hex values until a sample file looks right on the author's monitor. Every color here comes out of a reproducible pipeline instead: hue angles anchored on the Okabe–Ito colorblind-safe set, placed in OKLCH, verified against WCAG 2.2 and APCA contrast, and validated by simulating all three types of color-vision deficiency. Every number in the docs is generated by tools/derive.py, and every port is generated from that same palette — so they can't drift apart.

datum dark datum light

Every token carries a hue, but saturation encodes frequency: the sparse reference points (strings, numbers, constants, types, definitions) run at full chroma, while the ubiquitous glue (variables, calls, parameters, operators — about 75% of the text) gets quiet pastels of the same hue. Vivid, but still hierarchical.

datum.w0zro.com — the live palette, ports, and the ideas behind it.

📄 The ideas — the research, the derivation pipeline, the full palette tables, and the CVD numbers including the unflattering ones. 🎨 Live palette — contrast readouts computed in your browser.

Quick start

git clone https://github.com/w0zro/datum && cd datum
./start                 # what's available + where it goes
./start docs            # preview the palette + docs at localhost:8000
./start apply ghostty   # install a theme, or print how to enable it
./start apply all       # every terminal it finds, plus instructions

./start builds every port and installs the ones you ask for — it prints the exact line to enable each and never edits your configs behind your back (an existing real file is backed up to *.bak-datum before a symlink replaces it).

Ports

Terminals and editors ship separate dark + light files. Shell/CLI tools that run inside a terminal are emitted once, using ANSI color indices, so they inherit the terminal's datum theme and follow light/dark automatically.

target files enable
Neovim / Vim colors/datum.vim { 'w0zro/datum' } then colorscheme datum
Ghostty ports/ghostty/datum-{dark,light} theme = light:datum-light,dark:datum-dark
Kitty ports/kitty/datum-{dark,light}.conf include datum-dark.conf
Alacritty ports/alacritty/datum-{dark,light}.toml [general] import = [...]
WezTerm ports/wezterm/datum-{dark,light}.toml config.color_scheme = 'datum-dark'
VS Code ports/vscode/ (a ready extension) ./start apply vscode (symlinks it in), or publish to the Marketplace
tmux ports/tmux/datum.tmux TPM: set -g @plugin 'w0zro/datum' · or source-file …/datum.tmux
fzf ports/fzf/datum.sh source …/datum.sh
bat ports/bat/datum-{dark,light}.tmTheme bat --theme=datum-dark
delta ports/delta/datum.gitconfig [include] path = …
shell (ls, zsh) ports/shell/datum.sh source …/datum.sh

./start apply <target> does the file placement and prints the enable line for each.

Design at a glance

  • Data-anchored hues. Accent hue angles come from the Okabe–Ito colorblind-safe set (blue = keywords, orange = numbers, yellow = constants, green = strings, teal = types, purple = function defs, red = errors). Cool is how the code is built, warm is the data running through it.
  • Two moods, one identity. Every accent keeps the same OKLCH hue angle across modes; only lightness and chroma change per background. A dark theme is not an inverted light one.
  • Chroma-tiered highlighting. Every token carries a hue, but saturation encodes frequency — full chroma for the sparse reference points, pastels of the same hue for the ubiquitous glue, separated by lightness (the one channel no CVD collapses).
  • Accessible by construction. All eleven syntax colors clear WCAG 4.5:1 in both modes; APCA and color-vision-deficiency simulation guided every tuning decision.
  • Tree-sitter recommended (Neovim). The tiers rely on Tree-sitter to tell a function call from a definition and to color variables, parameters and operators; under base regex syntax those fall back to plain foreground.

Generating

The palette in tools/derive.py is the single source of truth. Everything else is generated from it, so nothing can silently fall out of sync.

make build                          # regenerate every port + the previews
make check                          # everything CI checks, locally
make release                        # tag the next patch version and push

python3 tools/derive.py             # palette + contrast + CVD report
python3 tools/derive.py --json      # the palette as JSON
python3 tools/derive.py --check     # assert the contrast + CVD claims (CI)
python3 tools/gen_ports.py --check  # non-zero exit if any port is stale (CI)
python3 tools/gen_preview.py --check # non-zero exit if the previews are stale (CI)

The generated files are committed, so nobody has to run the generator to use datum — it's a build step for maintainers only. If you change the palette in tools/derive.py, re-run make build and commit the results.

Verification

The claims on the box are asserted, not just printed. derive.py --check fails the build if any text role drops below WCAG 4.5:1 on the canvas, if comments stop clearing APCA Lc 45, if a tier-1 accent and its tier-2 sibling lose their lightness split (the mechanism the whole scheme rests on), or if two co-occurring accents become inseparable under protan/deutan/tritan simulation. Design aims the palette doesn't fully meet yet are reported as warnings rather than quietly dropped.

Because the previews are rendered on a Mac (Chrome + Monaspace), CI can't re-render them — so each PNG carries a fingerprint of the palette it came from, and gen_preview.py --check fails if the palette has moved on since.

Releasing

The tag is the version: release.yml packages the extension as ${TAG#v}, so there's nothing to bump by hand. make release refuses to tag a dirty tree, a non-main branch, or unpushed commits, runs every check first, then creates the annotated tag and pushes it.

make release                  # next patch after the highest existing tag
make release VERSION=0.2.0    # explicit

License

MIT.

Releases

Packages

Contributors

Languages