Flexoki
Flexoki is an inky color scheme for prose and code. Flexoki is designed for reading and writing on digital screens. It is inspired by analog inks and warm shades of paper.
Flexoki is minimalistic and high-contrast. The colors are calibrated for legibility and perceptual balance across devices and when switching between light and dark modes.
Flexoki is open-source under the MIT license. Flexoki is available for dozens of popular apps, including Obsidian using my theme Minimal.
Palette
Flexoki is the color palette used on this site. To switch between light and dark mode press the D key or use the toggle at the top of the page. Click any swatch to copy a color to your clipboard.
Syntax highlighting
Why?
I created Flexoki for my personal site, stephango.com. You’re reading it now. I wanted the colors to feel distinctive yet familiar. Like ink on paper.
The name Flexoki comes from flexography — a common printing process for paper and cardboard1. I spent many years working with dyes and inks particularly for my companies Inkodye and Lumi. I also have a fascination with digital paper. I wanted to bring the comfort of analog color to emissive digital screens.
One challenge is that ink on paper is a subtractive process whereas LCD and OLED screens use additive color. Replicating the effect of mixing pigments digitally is difficult. The following video illustrates the problem:
See the full SIGGRAPH 2021 talk
Mixing blue and yellow paint creates green, whereas digital color mixing results in a brownish hue. Watercolors retain their saturation when you dilute them, whereas reducing the opacity of digital colors makes them look desaturated.
Another challenge with digital color is human perception across color spaces. For example, yellow appears much brighter than blue. Ethan Schoonover’s color scheme Solarized (2011) was an important inspiration for Flexoki. His emphasis on lightness relationships in the CIELAB color space helped me understand how to find colors that appear cohesive. Flexoki derives colors from the more recent Oklab color space to maintain those perceptual relationships at the light and dark ends of the spectrum — ramping up color intensity exponentially to emulate the vibrancy that pigments exhibit even when diluted.
I found that choosing colors with perfect perceptual consistency can be at odds with the distinctiveness of colors in practical applications like syntax highlighting. If you adhere too closely to evenness in perceptual lightness you can end up with a palette that looks washed out and difficult to parse.
This project has been a battle between my competing desires in science and art. One part of my brain searches for reliability and precision, while another part searches for those elusive imperfections that remind us what feels real. Solving for all these problems is how I arrived at Flexoki. I hope you find it useful.
Base color
Flexoki uses warm monochromatic base values that blend the black value with the paper value. 8 values are used in light and dark mode:
- 3 text values: normal, muted, faint
- 3 interface values: normal, hover, active
- 2 background values: primary, secondary
Incremental values can be derived using opacity. For example, you can use a 60% opacity black value on top of the paper value to create the 600 value.
Color | Hex | Light theme | Dark theme |
---|---|---|---|
black
|
#100F0F |
tx |
bg |
base-950
|
#1C1B1A |
bg-2 |
|
base-900
|
#282726 |
ui |
|
base-850
|
#343331 |
ui-2 |
|
base-800
|
#403E3C |
ui-3 |
|
base-700
|
#575653 |
tx-3 |
|
base-600
|
#6F6E69 |
tx-2 |
|
base-500
|
#878580 |
tx-2 |
|
base-300
|
#B7B5AC |
tx-3 |
|
base-200
|
#CECDC3 |
ui-3 |
tx |
base-150
|
#DAD8CE |
ui-2 |
|
base-100
|
#E6E4D9 |
ui |
|
base-50
|
#F2F0E5 |
bg-2 |
|
paper
|
#FFFCF0 |
bg |
Accent colors
8 accent colors are available for accents and syntax highlighting. Unlike the base values, accent values cannot be derived using opacity because this desaturates the pigment effect. Use the extended palette for the full range of values.
The following 16 values are the main accent values used for syntax highlighting and interface elements like buttons and links. Light themes should use 600 for syntax highlighted text, dark themes should use 400.
Color | Hex | Light theme | Dark theme |
---|---|---|---|
red-600
|
#AF3029 |
re |
re-2 |
orange-600
|
#BC5215 |
or |
or-2 |
yellow-600
|
#AD8301 |
ye |
ye-2 |
green-600
|
#66800B |
gr |
gr-2 |
cyan-600
|
#24837B |
cy |
cy-2 |
blue-600
|
#205EA6 |
bl |
bl-2 |
purple-600
|
#5E409D |
pu |
pu-2 |
magenta-600
|
#A02F6F |
ma |
ma-2 |
Color | Hex | Light theme | Dark theme |
---|---|---|---|
red-400
|
#D14D41 |
re-2 |
re |
orange-400
|
#DA702C |
or-2 |
or |
yellow-400
|
#D0A215 |
ye-2 |
ye |
green-400
|
#879A39 |
gr-2 |
gr |
cyan-400
|
#3AA99F |
cy-2 |
cy |
blue-400
|
#4385BE |
bl-2 |
bl |
purple-400
|
#8B7EC8 |
pu-2 |
pu |
magenta-400
|
#CE5D97 |
ma-2 |
ma |
Extended palette
If you wish to use Flexoki for more complex applications beyond syntax highlighting and basic color schemes, the extended palette includes a complete set of values for every accent color from 50 to 950.
Note that paper and black are special values that represent the lightest and darkest colors in the palette, equivalent to 0 and 1000.
Flexoki emulates the feeling of pigment on paper by exponentially increasing intensity as colors get lighter or darker. This makes the colors feel vibrant and warm, like watercolor inks.
Mappings
This table describes how to use each variable in the context of user interfaces and syntax highlighting. Best viewed on desktop.
Color | Variable | UI | Syntax highlighting | |
---|---|---|---|---|
bg |
Main background | |||
bg-2 |
Secondary background | |||
ui |
Borders | |||
ui-2 |
Hovered borders | |||
ui-3 |
Active borders | |||
tx-3 |
Faint text | Comments | ||
tx-2 |
Muted text | Punctuation, operators | ||
tx |
Primary text | |||
re |
Error text | Invalid, imports | ||
or |
Warning text | Functions | ||
ye |
Constants | |||
gr |
Success text | Keywords | ||
cy |
Links, active states | Strings | ||
bl |
Variables, attributes | |||
pu |
Numbers | |||
ma |
Language features |
Ports
Flexoki is available for the following apps and tools. See the full list.
Apps
- Alacritty
- Emacs
- Ghostty (built-in)
- IntelliJ
- iTerm2
- Kitty
- Lite XL
- macOS Terminal
- Neovim
- Obsidian and included with Minimal
- Slack
- Standard Notes
- Sublime Text
- tmux
- Ulysses
- VS Code
- Warp
- WezTerm
- Windows Terminal
- Xresources
Frameworks
Other
Contributing
Flexoki is MIT licensed. You are free to port Flexoki to any app. Please include attribution and a link to stephango.com/flexoki. You can submit your port to the list via pull request on the Flexoki repo.
Changelog
Date | ||
---|---|---|
2025‑01‑07 | 2.0 |
Add 88 new values from 50 to 950 for accent colors. |
2023‑10‑07 | 1.0 |
Initial release. |
-
I also have a dog named Flexo whose greatness deserved to be immortalized. ↩