Ember ships redshift-safe palettes for terminals and charts

Ember is a set of color palettes released as an open-source project and shared on Hacker News, aimed at a specific failure mode of ordinary color schemes: once a warm-screen filter such as macOS Night Shift or a Linux redshift tool is turned on, colors that looked distinct during the day can become visually identical at night. A warm filter is not a tint laid on top of the image; it multiplies the red, green, and blue channels of every color by different gains, so channels that carried a color's identity can be crushed toward zero. Ember's design goal is that its colors stay distinguishable in both states, before and after that transform is applied. It does not apply any filter itself; the documentation is explicit that users keep running whatever filter they already have and Ember simply authors colors that survive it.
Ember ships four palette families: 3400K Dark, 3400K Light, 2000K Dark, and 1200K Dark. The 3400K palettes are for general use and are tuned to roughly match a MacBook's maximum Night Shift effect. The 2000K and 1200K palettes serve a narrower audience of people running much deeper warm filters, including astronomers who need very low blue light at night. The deeper the target filter, the smaller the space of colors that remain distinguishable: at Ember's 1200K model the blue channel's gain drops to zero, so colors that differ only in blue become identical output, and at 2000K only 9% of the commanded blue value survives the transform. Because of that shrinking color space, the palettes support fewer simultaneous colors as the filter deepens: six categorical color identities at 3400K, four at 2000K, and three at 1200K, a capacity that is also repeated across the sixteen slots of a terminal's ANSI color bank.
Each family exports as terminal themes for Alacritty, iTerm2, and Windows Terminal, as a set of UI surface roles (a six-step background ladder from bg_0 to bg_5, used consistently across dark and light families), as categorical colors for charts, and as a 256-sample sequential colormap for heatmaps, all delivered through Matplotlib, CSS, JSON, and Python packaging. Installation is a git clone for the terminal themes, CSS, and JSON manifest, or a direct pip install from the GitHub repository for the Python package; CSS consumers select a family with a data-ember-palette attribute and read colors from CSS custom properties, while the Python API exposes surfaces(), categorical(), categorical_norm(), and sequential() functions that plug into Matplotlib plots.
The project describes its construction method as a reversal of the usual approach: rather than picking colors that look good in daylight and hoping they survive a filter, Ember first sets hard numeric targets for contrast, lightness and chroma geometry, and minimum perceptual separation in the Oklab color space after the filter transform is applied, then chooses, among the commanded colors that hit those transformed targets, a moderate-chroma set that also separates well in daylight. An automated build enforces this with concrete release gates: exactly four palette families with categorical capacities of 6, 6, 4, and 3; categorical colors kept to a mean Oklab chroma between 0.09 and 0.105 with none above 0.111; every foreground-capable terminal accent clearing 4.5:1 contrast against the terminal's base background after its target transform; and no authored accent deviating by more than 0.15 units of Oklab distance (delta-E-OK) from its transformed target once serialized. The build also runs a pytest suite and a ruff lint pass, and reproduces every generated artifact from source as part of the check. The Show HN post had drawn 90 points and 19 comments at the time it was checked, a few days after posting.
Key facts
- Ember ships four palettes, 3400K Dark, 3400K Light, 2000K Dark, and 1200K Dark, engineered to stay visually distinct both under a warm-screen filter and without one.
- At the deepest 1200K profile the modeled blue channel gain is zero, so colors that differ only in blue become identical output; at 2000K only 9% of the blue value survives the transform.
- How many colors a palette can distinguish shrinks as the target filter deepens: six categorical identities at 3400K, four at 2000K, three at 1200K.
- Automated release gates enforce numeric targets, including 4.5:1 contrast for every terminal accent against the base background after its transform, and no more than 0.15 Oklab-distance deviation from an accent's authored target.
- Ember exports as terminal themes for Alacritty, iTerm2, and Windows Terminal, plus CSS, JSON, and a Python/Matplotlib package, installed via git clone or a direct pip install from GitHub.
Why it matters
Warm-screen filters like Night Shift or redshift tools do not tint an image; they multiply each of the red, green, and blue channels by a different gain, and a deep enough filter can push one channel toward zero. That means two colors chosen to look different in daylight, in a terminal theme, a chart legend, or a UI, can converge into the same output color once a filter is switched on, silently breaking whatever the color was meant to signal. Most palettes are designed only for the unfiltered case and never account for this. Ember's contribution is treating the filtered and unfiltered views as two conditions that must both be satisfied, rather than optimizing for daylight and hoping the filtered result holds up.
Who it affects
The main audience is developers and designers who spend long hours in a terminal or a code editor with a warm filter running, and who need syntax highlighting or ANSI colors that still read correctly at night. It also covers people building charts and heatmaps in Matplotlib or on the web who want a categorical or sequential color scale that survives a filtered display, and CSS-based UI work that needs a consistent set of background and accent roles across light and dark variants. The 2000K and 1200K profiles narrow this further to people running unusually aggressive warm filters, including astronomers who need minimal blue light at night.
How to use it
The terminal themes, CSS file, and JSON manifest are obtained with a git clone of the repository; theme files for Alacritty, iTerm2, and Windows Terminal are then copied or imported following each terminal's own import steps. Python users can skip the clone and install the package directly from GitHub with pip. In code, the package exposes surfaces() for UI background and foreground roles, and categorical(), categorical_norm(), and sequential() for Matplotlib colormaps, with a palette slug such as 2000k-dark selecting the family. On the web, a data-ember-palette attribute on a container selects the family and colors are read from CSS custom properties such as the background and category variables. Users are told to start with the 3400K Dark palette unless they deliberately run a deeper filter, since a filtered light-mode canvas becomes a large orange-red field.
How solid is it
The project backs its design with an explicit measurement method: colors are authored in commanded sRGB, then verified against modeled per-channel RGB gains for each color temperature, with hard numeric targets for contrast, lightness and chroma geometry, and minimum perceptual separation set in the Oklab color space after the filter transform. An automated build enforces these as release gates rather than leaving them as design intentions, including exact categorical capacities per family (6, 6, 4, 3), a bounded chroma range for categorical colors, a 4.5:1 contrast floor for terminal accents against the base background, and a cap of 0.15 Oklab-distance deviation between an authored transformed target and the color actually shipped. The same build runs a pytest suite, a ruff lint check, and reproduces every generated artifact from source. As a Show HN submission it had reached 90 points and 19 comments a few days after posting.
Risks and caveats
The text does not name an individual author or maintainer, state a version number or release date, or specify the license under which Ember is distributed, even though a license section is listed in its table of contents. It does not compare Ember by name to other established palettes, nor does it cite adoption numbers or independent reviews. The palettes themselves are also explicitly limited: the deeper profiles support fewer simultaneous colors, down to three at 1200K, so they trade color variety for filtered legibility and are only useful to people actually running that filter. The project itself cautions that its figures are software signal simulations of a warm filter, not calibrated physical color temperatures or a prediction of every real display pipeline; the actual result on any given screen still depends on the display, operating system, calibration, brightness, and ambient light, and viewers are told to turn off any active warm filter before judging the unfiltered figures so the transform is not applied twice.
“Ember does not apply the filter; keep using the one you already have.”
— Ember project documentation