commit fb41cedf250627575c014183856640059dc863e4 Author: Sam G. Date: Sun Aug 4 04:38:52 2024 -0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e7a7ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# generic py +__pycache__/ +.pytest_cache/ +*.egg-info/ +.ipynb_checkpoints/ +.pytest_cache/ +.python-version + +# vendor and build files +dist/ +build/ +docs/_autoref/ +docs/_autosummary/ +docs/_build/ + +# local +notebooks/ +/Makefile + +data/ diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..b3f970d --- /dev/null +++ b/DESIGN.md @@ -0,0 +1 @@ +![How themes are created](images/theme_creation.svg) diff --git a/README.md b/README.md new file mode 100644 index 0000000..7cf2348 --- /dev/null +++ b/README.md @@ -0,0 +1,127 @@ +# Monobiome +`monobiome` is a minimal, balanced color palette for use in terminals and text editors. It +was designed in OKLCH space to achieve perceptual uniformity across all hues at various +levels of luminance, and does so for _four_ monotone bases and _five_ accent colors. Each +of the monotone base colors (named according to a natural biome whose colors they loosely +resemble) are designed to achieve identical contrast with the accents, and thus any one of +the four can be selected to change the feeling of the palette without sacrificing +readability. + +![Diagram of palette accents and monotones](images/palette.svg) + +The name "monobiome" connects the palette to its two key sources of inspiration: + +- `mono-`: `monobiome` is inspired by the `monoindustrial` theme, and attempts to extend + and balance its accents while retaining similar color identities. +- `-biome`: the desire for several distinct monotone options entailed finding a way to ground the + subtle color variations that were needed, and I liked the idea of tying the choices to + naturally occurring environmental variation like Earth's biomes (even if it is a very + loose affiliation, e.g., green-ish = grass, basically). + +# Concrete themes +Each biome ("flavor") has 3 levels of "harshness": soft, regular (default), hard. The +harshness level determines the extent of the bg/fg extremes. + +![Diagram of the 24 available concrete theme options](images/themes.svg) + +The following general +constraints are followed as palette options are mapping onto concrete themes: + ++ Harshness levels have monotone differences of a single shade. ++ "Hard" themes anchor their background to the most extreme shade appropriate for the + scheme (i.e., lightest shade for "light," darkest shade for "dark"), ensuring the + palette's "monotone width" is fully spanned by the theme options. ++ App-specific monotone settings have differences of a single shade compared to the + system monotone settings. ++ Shade differences between corresponding background/foreground settings should be + constant (e.g., between `bg0` and `fg3`, `bg1` and `fg2`, etc) + +The primary goal of these constraints is to ensure each theme in a collection defined +around a single palette is sufficiently _distinct_ and attains sufficient _breadth_ +under the palette. + +## Example +The following is a natural solution to these constraints, demonstrated on a general +example setting: A possible useful analogy is a sliding window that, on its own spans a +given theme's bg0 - fg0 settings, while globally sliding across all available values in +the palette. If associating integers 0-10 to indices in a list of monotone shades, and +`bg-fg` is the syntax used to indicate that theme's shade range, we might have the +following for dark mode themes across harshness levels: + +``` +Dark (system) 0-7 ; 1-8 ; 2-9 +Dark (app) 1-8 ; 2-9 ; 3-10 +``` + +There are sliding windows at both the system-app level *and* the harshness-level, in a +sense. Constraints are followed: + ++ Harshness levels, separated by semicolon, differ by a single shade from hard to soft. ++ The hard theme anchors its background to the darkest available shade. ++ Monotones between system and app differ by a single shade. ++ Differences between bg/fg (value of 7) remains constant across all themes. + +Mapping this onto the common values used in my theme definition files: + +``` +System, dark +| Hard | Regular | Soft +| bg0 <- l15 | bg0 <- l20 | bg0 <- l25 +| fg0 <- l80 | fg0 <- l85 | fg0 <- l90 + +App, dark +| Hard | Regular | Soft +| bg0 <- l20 | bg0 <- l25 | bg0 <- l30 +| fg0 <- l85 | fg0 <- l90 | fg0 <- l95 + +System, light +| Hard | Regular | Soft +| bg0 <- l95 | bg0 <- l90 | bg0 <- l85 +| fg0 <- l25 | fg0 <- l20 | fg0 <- l15 +``` + +# MONOBIOME SPECIFIC + +## Accent contrast +Each group of biome monotones have nearly identical (WCAG 2) contrast ratios against +white/black for all lightness levels (ratios identical between biomes). These are +selected in a heavily constrained OKLCH context, and given the perceptual uniformity +attached to lightness, we can expect very similar contrast ratios for each accent under +a given biome lightness (e.g., the `l65` red tone will have the same ratio under the +grassland, tundra, and savanna monotones). + +In terms of selecting accents for themes (by harshness and scheme), what matters is +at what lightness level all accent colors meet/exceed a particular contrast threshold. +Again, the ratios themselves are effectively constant across biome monotones, and thus +dependent entirely on the monotone lightness being used. This of course is determined +primarily by whether the theme is a light or dark one, and what level of harshness is +being used. The following are the relevant values for making a decision. We want to +ensure all accents can reach >4.5 WCAG 2 contrast ratio (the standard requirement for +small text on the web) against all biome monotones for each theme: + ++ For BG l20 (harsh, dark) -> l65 is min lightness where all accents have CR >=4.5 ++ For BG l25 (regular, dark) -> l65 is min lightness where all accents have CR >=4.5 ++ For BG l30 (soft, dark) -> l70 is min lightness where all accents have CR >=4.5 + ++ For BG l90 (harsh, dark) -> l45 is max lightness where all accents have CR >=4.5 ++ For BG l85 (regular, dark) -> l45 is min lightness where all accents have CR >=4.5 ++ For BG l80 (soft, dark) -> l40 is min lightness where all accents have CR >=4.5 + +For the monotone boundaries (l15 and l95, neither of which are possible backgrounds for +terminal or nvim in the current theme definitions), the relevant lightness levels are +l60 and l50, respectively. + +While not necessary, it feels intuitive for us to shift the accent colors up/down by the +relative change in monotones across harshness levels. This has led to the choice of l60 +accents for the harsh-dark theme, l65 for regular-dark, and l70 for soft-dark. This +technically breaks the 4.5 ratio requirement, though, for the harsh theme, so you +ultimately need to pick one: either soften the contrast constraint, or allow different +harshness levels to use the same accent lightness. I think either is acceptable, but for +now I've gone with the former, loosening the contrast to a ratio of >4.0 with respect to +the background. This allows for the slightly tighter group of accent lightnesses: +l45-l50-l55 for light, l60-l65-l70 for dark. Note that the "center shade" of the l15-l95 +shade group is l55, meaning these groups are very central (the light triplet could move +down by one shade step, but we want these accents to be as bright as we can get away +with; otherwise, they are extremely dull in the light modes, and we thus don't mind bias +toward a brighter lightness). + diff --git a/colors/monobiome.toml b/colors/monobiome.toml new file mode 100644 index 0000000..10a3f25 --- /dev/null +++ b/colors/monobiome.toml @@ -0,0 +1,171 @@ +[default] +l15 = "#0b0b0b" +l20 = "#161616" +l25 = "#222222" +l30 = "#2e2e2e" +l35 = "#3a3a3a" +l40 = "#484848" +l45 = "#555555" +l50 = "#636363" +l55 = "#717171" +l60 = "#808080" +l65 = "#8f8f8f" +l70 = "#9e9e9e" +l75 = "#aeaeae" +l80 = "#bebebe" +l85 = "#cecece" +l90 = "#dedede" +l95 = "#eeeeee" + +[grassland] +l15 = "#070d0a" +l20 = "#111815" +l25 = "#1d2321" +l30 = "#29302d" +l35 = "#353c3a" +l40 = "#424a47" +l45 = "#505754" +l50 = "#5d6562" +l55 = "#6c7470" +l60 = "#7a827f" +l65 = "#89918e" +l70 = "#98a19d" +l75 = "#a8b0ad" +l80 = "#b7c0bc" +l85 = "#c7d0cc" +l90 = "#d7e0dd" +l95 = "#e8f1ed" + +[tundra] +l15 = "#080c10" +l20 = "#12161b" +l25 = "#1e2227" +l30 = "#2a2e33" +l35 = "#363b40" +l40 = "#43484e" +l45 = "#51565b" +l50 = "#5f6469" +l55 = "#6d7278" +l60 = "#7b8187" +l65 = "#8a9096" +l70 = "#999fa5" +l75 = "#a9afb5" +l80 = "#b9bec5" +l85 = "#c8ced5" +l90 = "#d9dfe5" +l95 = "#e9eff6" + +[savanna] +l15 = "#0d0b06" +l20 = "#181610" +l25 = "#24211c" +l30 = "#302e28" +l35 = "#3d3a34" +l40 = "#4a4841" +l45 = "#58554e" +l50 = "#66635c" +l55 = "#74716a" +l60 = "#838079" +l65 = "#928f88" +l70 = "#a19e97" +l75 = "#b0aea6" +l80 = "#c0bdb6" +l85 = "#d0cec6" +l90 = "#e1ded6" +l95 = "#f1eee6" + +[red] +l15 = "#1e0000" +l20 = "#310201" +l25 = "#440503" +l30 = "#590906" +l35 = "#6f0f0a" +l40 = "#86130d" +l45 = "#9d1912" +l50 = "#b52119" +l55 = "#ca2e23" +l60 = "#dc4134" +l65 = "#e95949" +l70 = "#f37060" +l75 = "#fa897a" +l80 = "#fea294" +l85 = "#febab0" +l90 = "#ffd2ca" +l95 = "#fee9e5" + +[orange] +l15 = "#140801" +l20 = "#221203" +l25 = "#311c08" +l30 = "#42260a" +l35 = "#54310d" +l40 = "#673c0c" +l45 = "#7c4706" +l50 = "#905201" +l55 = "#a45e00" +l60 = "#b86b05" +l65 = "#ca791c" +l70 = "#da8934" +l75 = "#e79a51" +l80 = "#f1ad6f" +l85 = "#fac18f" +l90 = "#fed5b3" +l95 = "#ffead9" + +[yellow] +l15 = "#0c0c03" +l20 = "#181709" +l25 = "#242211" +l30 = "#312f19" +l35 = "#3e3c20" +l40 = "#4c4928" +l45 = "#5b572e" +l50 = "#6a6535" +l55 = "#79743d" +l60 = "#888346" +l65 = "#989250" +l70 = "#a7a15f" +l75 = "#b7b170" +l80 = "#c6c182" +l85 = "#d5d19a" +l90 = "#e4e1b4" +l95 = "#f2f0d2" + +[green] +l15 = "#010f03" +l20 = "#041c09" +l25 = "#0b2911" +l30 = "#14361a" +l35 = "#1c4524" +l40 = "#25532e" +l45 = "#2e6337" +l50 = "#377242" +l55 = "#42824e" +l60 = "#4f925a" +l65 = "#5da268" +l70 = "#6eb178" +l75 = "#80c089" +l80 = "#94cf9c" +l85 = "#a9ddaf" +l90 = "#beecc4" +l95 = "#d4fad8" + +[blue] +l15 = "#010924" +l20 = "#041336" +l25 = "#091f49" +l30 = "#112b5d" +l35 = "#1a3771" +l40 = "#234485" +l45 = "#2d5299" +l50 = "#3860ac" +l55 = "#456fbe" +l60 = "#557ecc" +l65 = "#658ed9" +l70 = "#799ee3" +l75 = "#8daeeb" +l80 = "#a2bef2" +l85 = "#b7cff9" +l90 = "#cedffc" +l95 = "#e6efff" + diff --git a/images/palette.svg b/images/palette.svg new file mode 100644 index 0000000..84a2c5a --- /dev/null +++ b/images/palette.svg @@ -0,0 +1,21 @@ + + + + + + + + MONOBIOME PALETTEredyelloworangegreenbluegrasslandtundrasavannadefaultl15l20l25l30l35l40l45l50l55l60l65l70l75l80l900bg1bg0st1stl85l95midshadebackgroundsbackgroundsbackgrounds0bg1st1bg0stmonotonesaccentslight accentsdark accentsOKLCH LIGHTNESS \ No newline at end of file diff --git a/images/theme_creation.svg b/images/theme_creation.svg new file mode 100644 index 0000000..b98971e --- /dev/null +++ b/images/theme_creation.svg @@ -0,0 +1,21 @@ + + + + + + + + MONOBIOME THEME CREATIONABCABCABCABCABCABCABCABCABCABC1. Full palette view2. Split palette by lightness groups3. Highlight relevant colors for concrete themes4. Background colors are aligned with accents to ensure constant WCAG 2 contrast ratio5. Align accents with backgrounds to produce the concrete themes across monotones, scheme, harshnessmonotones - defaultmonotones - tundrascheme - lightscheme - darkharshness - defaultharshness - soft \ No newline at end of file diff --git a/images/themes.svg b/images/themes.svg new file mode 100644 index 0000000..7226523 --- /dev/null +++ b/images/themes.svg @@ -0,0 +1,21 @@ + + + + + + + + ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCDARKSCHEMELIGHTHARDHARDSOFTSOFTDEFAULTDEFAULTGRASSLANDMONOTONES(BIOMES)TUNDRASAVANNADEFAULT \ No newline at end of file