One palette file, one build step, every app you actually use.
$ git clone https://github.com/espresso20/neonferatu && ./install.py
measured, not vibed
Every colour is placed in OKLCH and checked at build time. Contrast is against this tube's editor background.
L · C · :1L · C · :1L · C · :1L · C · :1L · C · :1L · C · :1L · C · :1L · C · :1L · C · :1five accents, and that's the budget
# the ceiling on how saturated this hue gets, at this lightness def max_chroma(L: float, H: float) -> float: """Walk chroma down until the color fits in sRGB.""" lo, hi = 0.0, 0.5 for _ in range(48): mid = (lo + hi) / 2 if in_gamut(L, mid, H): lo = mid else: hi = mid return lo
one command each
fontMonaspace Krypton, weight 500 in editors, bold in terminalsclaudeall 72 theme keys, spinner rainbow and diff blocks includedvscodelocal extension, 1.55 line height, 3px phase-blinking cursoritermdynamic profile — iTerm2 picks it up live, no restartterminalinstalls the profile and makes it defaultzed~/.config/zed/themes, Cmd+K Cmd+T to picksublimetmTheme, same colorsbatsyntax highlighting in your pagerpython 3, no dependencies
git clone https://github.com/espresso20/neonferatuNothing here phones home.python3 build/build.pyRegenerates every theme file, after the palette passes its checks../install.py --variant phosphorInstalls a tube and activates it. They live side by side.