Back
other

Flexoki

An inky color scheme for prose and code.

by Steph Ango stephango.com 1,300 words
View original

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.

bg

bg-2

ui

ui-2

ui-3

tx-3

tx-2

tx

re

or

ye

gr

cy

bl

pu

ma

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 cardboard 1. 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:

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.

ColorHexLight themeDark theme
black#100F0Ftxbg
base-950#1C1B1Abg-2
base-900#282726ui
base-850#343331ui-2
base-800#403E3Cui-3
base-700#575653tx-3
base-600#6F6E69tx-2
base-500#878580tx-2
base-300#B7B5ACtx-3
base-200#CECDC3ui-3tx
base-150#DAD8CEui-2
base-100#E6E4D9ui
base-50#F2F0E5bg-2
paper#FFFCF0bg

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.

ColorHexLight themeDark theme
red-600#AF3029rere-2
orange-600#BC5215oror-2
yellow-600#AD8301yeye-2
green-600#66800Bgrgr-2
cyan-600#24837Bcycy-2
blue-600#205EA6blbl-2
purple-600#5E409Dpupu-2
magenta-600#A02F6Fmama-2
ColorHexLight themeDark theme
red-400#D14D41re-2re
orange-400#DA702Cor-2or
yellow-400#D0A215ye-2ye
green-400#879A39gr-2gr
cyan-400#3AA99Fcy-2cy
blue-400#4385BEbl-2bl
purple-400#8B7EC8pu-2pu
magenta-400#CE5D97ma-2ma

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.

Base

50

#F2F0E5

100

#E6E4D9

150

#DAD8CE

200

#CECDC3

300

#B7B5AC

400

#9F9D96

500

#878580

600

#6F6E69

700

#575653

800

#403E3C

850

#343331

900

#282726

950

#1C1B1A

Red

50

#FFE1D5

100

#FFCABB

150

#FDB2A2

200

#F89A8A

300

#E8705F

400

#D14D41

500

#C03E35

600

#AF3029

700

#942822

800

#6C201C

850

#551B18

900

#3E1715

950

#261312

Orange

50

#FFE7CE

100

#FED3AF

150

#FCC192

200

#F9AE77

300

#EC8B49

400

#DA702C

500

#CB6120

600

#BC5215

700

#9D4310

800

#71320D

850

#59290D

900

#40200D

950

#27180E

Yellow

50

#FAEEC6

100

#F6E2A0

150

#F1D67E

200

#ECCB60

300

#DFB431

400

#D0A215

500

#BE9207

600

#AD8301

700

#8E6B01

800

#664D01

850

#503D02

900

#3A2D04

950

#241E08

Green

50

#EDEECF

100

#DDE2B2

150

#CDD597

200

#BEC97E

300

#A0AF54

400

#879A39

500

#768D21

600

#66800B

700

#536907

800

#3D4C07

850

#313D07

900

#252D09

950

#1A1E0C

Cyan

50

#DDF1E4

100

#BFE8D9

150

#A2DECE

200

#87D3C3

300

#5ABDAC

400

#3AA99F

500

#2F968D

600

#24837B

700

#1C6C66

800

#164F4A

850

#143F3C

900

#122F2C

950

#101F1D

Blue

50

#E1ECEB

100

#C6DDE8

150

#ABCFE2

200

#92BFDB

300

#66A0C8

400

#4385BE

500

#3171B2

600

#205EA6

700

#1A4F8C

800

#163B66

850

#133051

900

#12253B

950

#101A24

Purple

50

#F0EAEC

100

#E2D9E9

150

#D3CAE6

200

#C4B9E0

300

#A699D0

400

#8B7EC8

500

#735EB5

600

#5E409D

700

#4F3685

800

#3C2A62

850

#31234E

900

#261C39

950

#1A1623

Magenta

50

#FEE4E5

100

#FCCFDA

150

#F9B9CF

200

#F4A4C2

300

#E47DA8

400

#CE5D97

500

#B74583

600

#A02F6F

700

#87285E

800

#641F46

850

#4F1B39

900

#39172B

950

#24131D

Mappings

This table describes how to use each variable in the context of user interfaces and syntax highlighting.

ColorVariableUISyntax highlighting
bgMain background
bg-2Secondary background
uiBorders
ui-2Hovered borders
ui-3Active borders
tx-3Faint textComments
tx-2Muted textPunctuation, operators
txPrimary text
reError textInvalid, imports
orWarning textFunctions
yeConstants
grSuccess textKeywords
cyLinks, active statesStrings
blVariables, attributes
puNumbers
maLanguage features

Ports

Flexoki is available for the following apps and tools. See the full list.

Apps

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‑072.0Add 88 new values from 50 to 950 for accent colors.
2023‑10‑071.0Initial release.

Footnotes

  1. I also have a dog named Flexo whose greatness deserved to be immortalized.