6 Commits
1.5.0 ... 1.5.1

Author SHA1 Message Date
99ed1c9557 add release figure genereation script 2026-01-16 16:13:28 -08:00
356442395e regenerate colors and app themes for v1.5.1 2026-01-16 03:35:35 -08:00
fcaa25e2f5 add sequential bounding for chroma curves 2026-01-16 03:14:07 -08:00
4a5f8cbb39 remove readme description of symconf dependence 2025-12-29 23:05:06 -08:00
eb02be9582 fix README links to template files 2025-12-28 17:43:01 -08:00
74c22552df fix a few README typos 2025-12-20 04:56:12 -08:00
45 changed files with 203 additions and 205 deletions

2
.gitignore vendored
View File

@@ -23,3 +23,5 @@ archive/
notebooks/color_spaces_manyview.ipynb
notebooks/oklch_srgb_spherical.ipynb
notebooks/v1.4.0/
notebooks/v1.5.1/
CHECKLIST.md

View File

@@ -31,12 +31,12 @@ Monotone curves have fixed chroma, whereas the accent curves' chroma varies
smoothly as a function of lightness within sRGB gamut bounds.
| Chroma curves | Color trajectories |
|---|---|
| ![Chroma curves](images/curves/cstar-curves-v140.png) | ![Trajectories](images/trajectories.gif) |
|----------------------------------------------------------|------------------------------------------|
| ![Chroma curves](images/release/1.5.1/chroma-curves.png) | ![Trajectories](images/trajectories.gif) |
| Palette |
|---|
| ![Palette](images/palette.png) |
|----------------------------------------------|
| ![Palette](images/release/1.5.1/palette.png) |
Chroma curves are designed specifically to establish a distinct role for each
accent and are non-intersecting over the lightness domain (hence the distinct
@@ -61,7 +61,7 @@ varying only in lightness from dark to light grey.
## Themes
| Dark themes | Light themes |
|---|---|
|----------------------------------------|------------------------------------------|
| ![Dark themes](images/dark_themes.png) | ![Light themes](images/light_themes.png) |
Themes are derived from the `monobiome` palette by selecting a monotone base
@@ -79,7 +79,7 @@ The following plots show the intersection of the sphere centered at a fixed
background color (`alpine` biome with a lightness of 20) under variable radii:
| | `-l 20 -d 0.3` | `-l 20 -d 0.4` | `-l 20 -d 0.5` |
|---|---|---|---|
|---------------------|---------------------------------------------------|---------------------------------------------------|---------------------------------------------------|
| Color visualization | ![](images/oklch/mb_b20_d30.gif) | ![](images/oklch/mb_b20_d40.gif) | ![](images/oklch/mb_b20_d50.gif) |
| Editor preview | ![](images/render/v140-demo-alpine-dark-d0.3.png) | ![](images/render/v140-demo-alpine-dark-d0.4.png) | ![](images/render/v140-demo-alpine-dark-d0.5.png) |
@@ -117,10 +117,10 @@ theme pipeline can be seen in detail below:
![Generation pipeline](images/theme_generation_pipeline.png)
This figure demonstrates how `kitty` themes are generated, but the process is
generic to any palette, scheme, and app. This implemented in two stages using
the `monobiome` CLI:
generic to any palette, scheme, and app. This is implemented in two stages
using the `monobiome` CLI:
- First generate the scheme file, the definitions that respect perceptual
- First generate the scheme file, the lightness choices that achieve perceptual
uniformity of accents with respect to the base monotone:
```sh
@@ -137,19 +137,14 @@ the `monobiome` CLI:
monobiome fill scheme.toml templates/kitty/active.theme -o kitty.theme
```
This writes a concrete theme to `kitty.theme` that matches the user
preferences, i.e., the contrast (`-d`), background lightness (`-l`), mode
(`dark`), and biome (`grassland`). Every part of this process can be
customized: the scheme parameters, the scheme definitions/file, the app
template.
This writes a concrete `kitty` theme to `kitty.theme` that matches the user
preferences as captured in the previously generated scheme file, i.e., the
contrast (`-d`), background lightness (`-l`), mode (`dark`), and biome
(`grassland`). Every part of this process can be customized: the scheme
parameters, the scheme definitions/file, the app template.
Running these commands in sequence from the repo root should work
out-of-the-box, after having installed the CLI tool.
The `monobiome` CLI
produces the scheme file for requested parameters, and the [`symconf`][3] CLI
pushes palette colors through the scheme and into the app templates to yield a
concrete theme.
out-of-the-box after having installed the CLI tool.
## Applications
This repo provides palette-agnostic theme templates for `kitty`,
@@ -178,7 +173,7 @@ One can set these themes for the provided applications as follows:
```
Themes are generated using the [`kitty` theme
template](templates/apps/kitty/templates/active.theme).
template](templates/kitty/active.theme).
- `vim`/`neovim`
@@ -193,7 +188,7 @@ One can set these themes for the provided applications as follows:
```
Themes are generated using the [`vim` theme
template](templates/apps/nvim/templates/theme.vim).
template](templates/nvim/theme.vim).
- `fzf`
@@ -206,7 +201,7 @@ One can set these themes for the provided applications as follows:
```
Themes are generated using the [`fzf` theme
template](templates/apps/fzf/templates/active.theme).
template](templates/fzf/active.theme).
- Firefox
@@ -214,13 +209,11 @@ One can set these themes for the provided applications as follows:
add-ons][2], and switch between light/dark schemes based on system settings.
You can also download raw XPI files for each theme in `app-config/firefox/`,
each of which is generated using the [Firefox `manifest.json`
template](templates/apps/firefox/templates/none-dark.manifest.json).
template](templates/firefox/auto-manifest.json).
Static [light][4] and [dark][5] themes are additionally available (i.e., that
don't change with system settings).
![Firefox theme previews](images/firefox/themes.png)
## CLI installation
A brief theme generation guide was provided in the [Generation
section](#generation), making use of the `monobiome` CLI. This tool can be
@@ -232,7 +225,7 @@ uv tool install monobiome
pipx install monobiome
```
The `monobiome` has provides three subcommands:
`monobiome` provides three subcommands:
- `monobiome palette`: generate palette files from raw parameterized curves
@@ -295,6 +288,14 @@ The `monobiome` has provides three subcommands:
output file to write filled template
```
## Config management
The `monobiome` CLI tool attempts to provide the minimal functionality needed
to produce customized themes for individual applications. If seeking a more
holistic, system-wide approach, you might consider using [`symconf`][3], a
general-purpose application config manager. `symconf` provides the templating
subsystem used for `monobiome` internals, and can be configured to apply live
theme updates to many apps with a single command line invocation.
[1]: https://github.com/isa/TextMate-Themes/blob/master/monoindustrial.tmTheme
[2]: https://addons.mozilla.org/en-US/firefox/collections/18495484/monobiome/

View File

@@ -1,4 +1,4 @@
version = "1.5.0"
version = "1.5.1"
[alpine]
l10 = "#030303"
@@ -271,7 +271,7 @@ l94 = "#f1eae4"
l95 = "#f4ede7"
l96 = "#f7f0ea"
l97 = "#fbf4ee"
l98 = "#fef7f1"
l98 = "#fdf7f2"
[savanna]
l10 = "#040301"
@@ -362,7 +362,7 @@ l94 = "#ecece3"
l95 = "#efefe7"
l96 = "#f3f2ea"
l97 = "#f6f6ed"
l98 = "#f9f9f1"
l98 = "#f9f9f2"
[grassland]
l10 = "#020402"
@@ -453,7 +453,7 @@ l94 = "#e6ede7"
l95 = "#eaf1ea"
l96 = "#edf4ee"
l97 = "#f0f7f1"
l98 = "#f4fbf4"
l98 = "#f4faf5"
[reef]
l10 = "#010404"
@@ -544,7 +544,7 @@ l94 = "#e3edef"
l95 = "#e7f1f2"
l96 = "#eaf4f5"
l97 = "#edf7f9"
l98 = "#f0fbfc"
l98 = "#f2fafb"
[tundra]
l10 = "#020306"
@@ -726,7 +726,7 @@ l94 = "#ede9f1"
l95 = "#f0edf4"
l96 = "#f3f0f8"
l97 = "#f7f3fb"
l98 = "#faf7ff"
l98 = "#faf7fe"
[moorland]
l10 = "#050204"
@@ -817,7 +817,7 @@ l94 = "#f1e8ec"
l95 = "#f5ecef"
l96 = "#f8eff3"
l97 = "#fbf2f6"
l98 = "#fff6f9"
l98 = "#fef6f9"
[red]
l10 = "#0d0000"
@@ -1443,18 +1443,18 @@ l83 = "#d6b8f7"
l84 = "#d8bcf8"
l85 = "#dbc1f9"
l86 = "#ddc5f9"
l87 = "#e0c9fa"
l88 = "#e2cdfb"
l89 = "#e5d1fb"
l90 = "#e7d5fc"
l91 = "#e9d9fc"
l92 = "#ecdefd"
l93 = "#eee2fd"
l94 = "#f1e6fe"
l95 = "#f3eafe"
l96 = "#f5eefe"
l97 = "#f8f2fe"
l98 = "#faf7ff"
l87 = "#dfc9f9"
l88 = "#e2cdfa"
l89 = "#e4d2fa"
l90 = "#e6d6fa"
l91 = "#e9dafb"
l92 = "#ebdefb"
l93 = "#eee2fb"
l94 = "#f0e6fc"
l95 = "#f2ebfc"
l96 = "#f5effd"
l97 = "#f7f3fd"
l98 = "#faf7fe"
[magenta]
l10 = "#080104"
@@ -1540,9 +1540,9 @@ l89 = "#f7cde0"
l90 = "#f8d2e2"
l91 = "#f9d6e5"
l92 = "#fadbe8"
l93 = "#fbdfeb"
l94 = "#fce4ee"
l93 = "#fadfeb"
l94 = "#fbe4ee"
l95 = "#fce8f1"
l96 = "#fdedf4"
l97 = "#fef1f6"
l96 = "#fdedf3"
l97 = "#fdf1f6"
l98 = "#fef6f9"

View File

@@ -1,4 +1,4 @@
version = "1.5.0"
version = "1.5.1"
[alpine]
l10 = "oklch(10.0% 0.0000 0.0)"
@@ -180,7 +180,7 @@ l94 = "oklch(94.0% 0.0110 29.0)"
l95 = "oklch(95.0% 0.0110 29.0)"
l96 = "oklch(96.0% 0.0110 29.0)"
l97 = "oklch(97.0% 0.0110 29.0)"
l98 = "oklch(98.0% 0.0097 29.0)"
l98 = "oklch(98.0% 0.0092 29.0)"
[chaparral]
l10 = "oklch(10.0% 0.0110 62.5)"
@@ -271,7 +271,7 @@ l94 = "oklch(94.0% 0.0110 62.5)"
l95 = "oklch(95.0% 0.0110 62.5)"
l96 = "oklch(96.0% 0.0110 62.5)"
l97 = "oklch(97.0% 0.0110 62.5)"
l98 = "oklch(98.0% 0.0110 62.5)"
l98 = "oklch(98.0% 0.0092 62.5)"
[savanna]
l10 = "oklch(10.0% 0.0110 104.0)"
@@ -362,7 +362,7 @@ l94 = "oklch(94.0% 0.0110 104.0)"
l95 = "oklch(95.0% 0.0110 104.0)"
l96 = "oklch(96.0% 0.0110 104.0)"
l97 = "oklch(97.0% 0.0110 104.0)"
l98 = "oklch(98.0% 0.0110 104.0)"
l98 = "oklch(98.0% 0.0092 104.0)"
[grassland]
l10 = "oklch(10.0% 0.0110 148.0)"
@@ -453,7 +453,7 @@ l94 = "oklch(94.0% 0.0110 148.0)"
l95 = "oklch(95.0% 0.0110 148.0)"
l96 = "oklch(96.0% 0.0110 148.0)"
l97 = "oklch(97.0% 0.0110 148.0)"
l98 = "oklch(98.0% 0.0110 148.0)"
l98 = "oklch(98.0% 0.0092 148.0)"
[reef]
l10 = "oklch(10.0% 0.0110 205.0)"
@@ -544,7 +544,7 @@ l94 = "oklch(94.0% 0.0110 205.0)"
l95 = "oklch(95.0% 0.0110 205.0)"
l96 = "oklch(96.0% 0.0110 205.0)"
l97 = "oklch(97.0% 0.0110 205.0)"
l98 = "oklch(98.0% 0.0110 205.0)"
l98 = "oklch(98.0% 0.0092 205.0)"
[tundra]
l10 = "oklch(10.0% 0.0110 262.0)"
@@ -635,7 +635,7 @@ l94 = "oklch(94.0% 0.0110 262.0)"
l95 = "oklch(95.0% 0.0110 262.0)"
l96 = "oklch(96.0% 0.0110 262.0)"
l97 = "oklch(97.0% 0.0110 262.0)"
l98 = "oklch(98.0% 0.0094 262.0)"
l98 = "oklch(98.0% 0.0092 262.0)"
[heathland]
l10 = "oklch(10.0% 0.0110 306.0)"
@@ -726,7 +726,7 @@ l94 = "oklch(94.0% 0.0110 306.0)"
l95 = "oklch(95.0% 0.0110 306.0)"
l96 = "oklch(96.0% 0.0110 306.0)"
l97 = "oklch(97.0% 0.0110 306.0)"
l98 = "oklch(98.0% 0.0110 306.0)"
l98 = "oklch(98.0% 0.0092 306.0)"
[moorland]
l10 = "oklch(10.0% 0.0110 350.0)"
@@ -817,7 +817,7 @@ l94 = "oklch(94.0% 0.0110 350.0)"
l95 = "oklch(95.0% 0.0110 350.0)"
l96 = "oklch(96.0% 0.0110 350.0)"
l97 = "oklch(97.0% 0.0110 350.0)"
l98 = "oklch(98.0% 0.0110 350.0)"
l98 = "oklch(98.0% 0.0092 350.0)"
[red]
l10 = "oklch(10.0% 0.0406 29.0)"
@@ -1087,10 +1087,10 @@ l91 = "oklch(91.0% 0.0402 104.0)"
l92 = "oklch(92.0% 0.0360 104.0)"
l93 = "oklch(93.0% 0.0317 104.0)"
l94 = "oklch(94.0% 0.0273 104.0)"
l95 = "oklch(95.0% 0.0229 104.0)"
l96 = "oklch(96.0% 0.0184 104.0)"
l95 = "oklch(95.0% 0.0228 104.0)"
l96 = "oklch(96.0% 0.0183 104.0)"
l97 = "oklch(97.0% 0.0138 104.0)"
l98 = "oklch(98.0% 0.0093 104.0)"
l98 = "oklch(98.0% 0.0092 104.0)"
[green]
l10 = "oklch(10.0% 0.0178 148.0)"
@@ -1442,19 +1442,19 @@ l82 = "oklch(82.0% 0.0964 306.0)"
l83 = "oklch(83.0% 0.0915 306.0)"
l84 = "oklch(84.0% 0.0865 306.0)"
l85 = "oklch(85.0% 0.0815 306.0)"
l86 = "oklch(86.0% 0.0764 306.0)"
l87 = "oklch(87.0% 0.0712 306.0)"
l88 = "oklch(88.0% 0.0660 306.0)"
l89 = "oklch(89.0% 0.0607 306.0)"
l90 = "oklch(90.0% 0.0554 306.0)"
l91 = "oklch(91.0% 0.0500 306.0)"
l92 = "oklch(92.0% 0.0446 306.0)"
l93 = "oklch(93.0% 0.0391 306.0)"
l94 = "oklch(94.0% 0.0336 306.0)"
l95 = "oklch(95.0% 0.0281 306.0)"
l96 = "oklch(96.0% 0.0225 306.0)"
l97 = "oklch(97.0% 0.0169 306.0)"
l98 = "oklch(98.0% 0.0113 306.0)"
l86 = "oklch(86.0% 0.0758 306.0)"
l87 = "oklch(87.0% 0.0697 306.0)"
l88 = "oklch(88.0% 0.0638 306.0)"
l89 = "oklch(89.0% 0.0579 306.0)"
l90 = "oklch(90.0% 0.0522 306.0)"
l91 = "oklch(91.0% 0.0466 306.0)"
l92 = "oklch(92.0% 0.0410 306.0)"
l93 = "oklch(93.0% 0.0356 306.0)"
l94 = "oklch(94.0% 0.0302 306.0)"
l95 = "oklch(95.0% 0.0250 306.0)"
l96 = "oklch(96.0% 0.0198 306.0)"
l97 = "oklch(97.0% 0.0147 306.0)"
l98 = "oklch(98.0% 0.0097 306.0)"
[magenta]
l10 = "oklch(10.0% 0.0242 350.0)"
@@ -1538,11 +1538,11 @@ l87 = "oklch(87.0% 0.0619 350.0)"
l88 = "oklch(88.0% 0.0574 350.0)"
l89 = "oklch(89.0% 0.0528 350.0)"
l90 = "oklch(90.0% 0.0481 350.0)"
l91 = "oklch(91.0% 0.0435 350.0)"
l92 = "oklch(92.0% 0.0387 350.0)"
l93 = "oklch(93.0% 0.0340 350.0)"
l94 = "oklch(94.0% 0.0292 350.0)"
l95 = "oklch(95.0% 0.0244 350.0)"
l96 = "oklch(96.0% 0.0196 350.0)"
l97 = "oklch(97.0% 0.0147 350.0)"
l98 = "oklch(98.0% 0.0098 350.0)"
l91 = "oklch(91.0% 0.0433 350.0)"
l92 = "oklch(92.0% 0.0384 350.0)"
l93 = "oklch(93.0% 0.0334 350.0)"
l94 = "oklch(94.0% 0.0285 350.0)"
l95 = "oklch(95.0% 0.0237 350.0)"
l96 = "oklch(96.0% 0.0189 350.0)"
l97 = "oklch(97.0% 0.0141 350.0)"
l98 = "oklch(98.0% 0.0094 350.0)"

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -17,7 +17,7 @@ def register_parser(subparsers: _SubparserType) -> None:
type=str,
default="hex",
choices=["hex", "oklch"],
help="Color notation to export (either hex or oklch)",
help="color notation to export (either hex or oklch)",
)
parser.add_argument(
"-f",
@@ -25,13 +25,13 @@ def register_parser(subparsers: _SubparserType) -> None:
type=str,
default="toml",
choices=["json", "toml"],
help="Format of palette file (either JSON or TOML)",
help="format of palette file (either JSON or TOML)",
)
parser.add_argument(
"-o",
"--output",
type=str,
help="Output file to write palette content",
help="output file to write palette content",
)
parser.set_defaults(func=handle_palette)

View File

@@ -16,13 +16,13 @@ def register_parser(subparsers: _SubparserType) -> None:
"mode",
type=str,
choices=["dark", "light"],
help="Scheme mode (light or dark)"
help="scheme mode (light or dark)"
)
parser.add_argument(
"biome",
type=str,
choices=list(monotone_h_map.keys()),
help="Biome setting for scheme."
help="biome setting for scheme"
)
parser.add_argument(
"-m",
@@ -30,7 +30,7 @@ def register_parser(subparsers: _SubparserType) -> None:
type=str,
default="oklch",
choices=["wcag", "oklch", "lightness"],
help="Metric to use for measuring swatch distances."
help="metric to use for measuring swatch distances"
)
# e.g., wcag=4.5; oklch=0.40; lightness=40
@@ -39,13 +39,13 @@ def register_parser(subparsers: _SubparserType) -> None:
"--distance",
type=float,
default=0.40,
help="Distance threshold for specified metric",
help="distance threshold for specified metric",
)
parser.add_argument(
"-o",
"--output",
type=str,
help="Output file to write scheme content",
help="output file to write scheme content",
)
# these params remain rooted in lightness; no need to accommodate metric
@@ -58,13 +58,13 @@ def register_parser(subparsers: _SubparserType) -> None:
"--l-base",
type=int,
default=20,
help="Minimum lightness level (default: 20)",
help="minimum lightness level (default: 20)",
)
parser.add_argument(
"--l-step",
type=int,
default=5,
help="Lightness step size (default: 5)",
help="lightness step size (default: 5)",
)
# gaps
@@ -72,19 +72,19 @@ def register_parser(subparsers: _SubparserType) -> None:
"--fg-gap",
type=int,
default=50,
help="Foreground lightness gap (default: 50)",
help="foreground lightness gap (default: 50)",
)
parser.add_argument(
"--grey-gap",
type=int,
default=30,
help="Grey lightness gap (default: 30)",
help="grey lightness gap (default: 30)",
)
parser.add_argument(
"--term-fg-gap",
type=int,
default=65,
help="Terminal foreground lightness gap (default: 60)",
help="terminal foreground lightness gap (default: 60)",
)
parser.set_defaults(func=handle_scheme)

View File

@@ -121,3 +121,21 @@ for h_str, L_points_C in Lpoints_Cqbr_Hmap.items():
max(0, min(_C, l_maxC_h(_L, _h)))
for _L, _C in zip(L_points, L_points_C, strict=True)
]
# strictly enforce curve bounds s.t. there are no intersections
# order is determined by the max attained chromap
max_Cstar_Horder = [
(h_str, max(Lpoints_Cstar))
for h_str, Lpoints_Cstar in Lpoints_Cstar_Hmap.items()
]
max_Cstar_Horder = sorted(max_Cstar_Horder, key=lambda t: t[1], reverse=True)
for i in range(len(max_Cstar_Horder)-1):
outer_h, _ = max_Cstar_Horder[i]
inner_h, _ = max_Cstar_Horder[i+1]
Lpoints_Cstar_Hmap[inner_h] = [
min(inner_c, Lpoints_Cstar_Hmap[outer_h][ci])
for ci, inner_c in enumerate(Lpoints_Cstar_Hmap[inner_h])
]

View File

@@ -1,6 +1,9 @@
from importlib.metadata import version
import numpy as np
import matplotlib.pyplot as plt
from coloraide import Color
from matplotlib.collections import LineCollection
from monobiome.palette import compute_hlc_map
from monobiome.constants import (
@@ -10,11 +13,13 @@ from monobiome.constants import (
accent_h_map,
monotone_h_map,
Lspace_Cmax_Hmap,
max_Cstar_Horder,
Lpoints_Cstar_Hmap,
)
VERSION = version("monobiome")
def plot_hue_chroma_bounds() -> None:
def plot_hue_chroma_bounds() -> tuple[plt.Figure, plt.Axes]:
name_h_map = {}
ax_h_map = {}
fig, axes = plt.subplots(
@@ -63,36 +68,63 @@ def plot_hue_chroma_bounds() -> None:
ncol=3
)
plt.suptitle("$C^*$ curves for hue groups")
plt.show()
plt.suptitle(f"$C^*$ curves for hue groups (v{VERSION})")
return fig, axes
def plot_hue_chroma_star() -> None:
def plot_hue_chroma_star() -> tuple[plt.Figure, plt.Axes]:
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
# uncomment to preview 5 core term colors
colors = accent_h_map.keys()
#colors = set(["red", "orange", "yellow", "green", "blue"])
for h_str in Lpoints_Cstar_Hmap:
for h_str, _ in max_Cstar_Horder:
Lpoints_Cstar = Lpoints_Cstar_Hmap[h_str]
if h_str not in accent_h_map or h_str not in colors:
continue
ax.fill_between(
L_points,
Lpoints_Cstar_Hmap[h_str],
alpha=0.2,
color='grey',
label=h_str
)
x, y = L_points, Lpoints_Cstar_Hmap[h_str]
n = int(0.45*len(x))
ax.text(x[n], y[n]-0.01, h_str, rotation=10, va='center', ha='left')
_h = h_map[h_str]
h_colors = [
Color('oklch', [_l/100, _c, _h]).convert("srgb")
for _l, _c in zip(L_points, Lpoints_Cstar, strict=True)
]
# # ax.fill_between(
# ax.scatter(
# L_points,
# Lpoints_Cstar,
# alpha=0.7,
# c=h_colors,
# #alpha=0.2,
# #color='grey',
# label=h_str
# )
# x, y = L_points, Lpoints_Cstar_Hmap[h_str]
# n = int(0.45*len(x))
# ax.text(x[n], y[n]-0.01, h_str, rotation=10, va='center', ha='left')
x = np.asarray(L_points)
y = np.asarray(Lpoints_Cstar)
pts = np.column_stack([x, y]).reshape(-1, 1, 2)
segs = np.concatenate([pts[:-1], pts[1:]], axis=1)
rgb = np.asarray(h_colors)
seg_colors = (rgb[:-1] + rgb[1:]) / 2
lc = LineCollection(segs, colors=seg_colors, linewidth=3,
capstyle="round", joinstyle="round",
label=h_str)
ax.add_collection(lc)
ax.autoscale_view()
ax.set_xlabel("Lightness (%)")
ax.set_xticks([L_points[0], 45, 50, 55, 60, 65, 70, L_points[-1]])
plt.suptitle("$C^*$ curves (v1.4.0)")
fig.show()
plt.suptitle(f"$C^*$ curves (v{VERSION})")
return fig, ax
def palette_image(

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "monobiome"
version = "1.5.0"
version = "1.5.1"
description = "Monobiome color palette"
requires-python = ">=3.12"
authors = [

View File

@@ -1,82 +0,0 @@
# ++ monobiome scheme file ++
# ++ generated CLI @ 1.5.0 ++
version = "1.5.0"
mode = "dark"
biome = "moorland"
metric = "oklch"
distance = "0.42"
l_base = "20"
l_step = "5"
fg_gap = "50"
grey_gap = "30"
term_fg_gap = "65"
bg0 = "f{{moorland.l20}}"
bg1 = "f{{moorland.l25}}"
bg2 = "f{{moorland.l30}}"
bg3 = "f{{moorland.l35}}"
fg3 = "f{{moorland.l70}}"
fg2 = "f{{moorland.l75}}"
fg1 = "f{{moorland.l80}}"
fg0 = "f{{moorland.l85}}"
black = "f{{moorland.l20}}"
grey = "f{{moorland.l50}}"
white = "f{{moorland.l75}}"
red = "f{{red.l59}}"
orange = "f{{orange.l61}}"
yellow = "f{{yellow.l62}}"
green = "f{{green.l61}}"
cyan = "f{{cyan.l61}}"
blue = "f{{blue.l60}}"
violet = "f{{violet.l60}}"
magenta = "f{{orange.l61}}"
[term]
background = "f{{moorland.l25}}"
selection_bg = "f{{moorland.l30}}"
selection_fg = "f{{moorland.l85}}"
foreground = "f{{moorland.l90}}"
cursor = "f{{moorland.l85}}"
cursor_text = "f{{moorland.l30}}"
[term.normal]
black = "f{{moorland.l25}}"
grey = "f{{moorland.l55}}"
white = "f{{moorland.l80}}"
red = "f{{red.l64}}"
yellow = "f{{yellow.l67}}"
green = "f{{green.l66}}"
cyan = "f{{blue.l65}}"
blue = "f{{blue.l65}}"
magenta = "f{{orange.l66}}"
[term.bright]
black = "f{{moorland.l35}}"
grey = "f{{moorland.l65}}"
white = "f{{moorland.l90}}"
red = "f{{red.l75}}"
yellow = "f{{yellow.l77}}"
green = "f{{green.l76}}"
cyan = "f{{blue.l76}}"
blue = "f{{blue.l76}}"
magenta = "f{{orange.l76}}"
[vim]
bg0 = "f{{moorland.l25}}"
bg1 = "f{{moorland.l30}}"
bg2 = "f{{moorland.l35}}"
bg3 = "f{{moorland.l40}}"
fg3 = "f{{moorland.l75}}"
fg2 = "f{{moorland.l80}}"
fg1 = "f{{moorland.l85}}"
fg0 = "f{{moorland.l90}}"
black = "f{{moorland.l25}}"
grey = "f{{moorland.l55}}"
white = "f{{moorland.l80}}"
red = "f{{red.l64}}"
orange = "f{{orange.l66}}"
yellow = "f{{yellow.l67}}"
green = "f{{green.l66}}"
cyan = "f{{green.l66}}"
blue = "f{{blue.l65}}"
violet = "f{{blue.l65}}"
magenta = "f{{red.l64}}"

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# note: this script is not portable; to be run in the monobiome scripts/
# directory (notice the `rm` invocations)
# note: this script is not portable; script to be placed in the monobiome
# scripts/ directory and run from the repo root (notice the `rm` invocations)
# clean existing config
rm -rf app-config/*
@@ -37,6 +37,9 @@ for biome in "${biomes[@]}"; do
done
done
# remove lingering scheme file
rm scheme.toml
cd app-config/firefox
shopt -s nullglob
for f in *; do

24
scripts/plots.py Normal file
View File

@@ -0,0 +1,24 @@
from pathlib import Path
import monobiome as mb
from monobiome import plotting
from monobiome.palette import compute_hlc_map
figure_dir = Path(f"images/release/{mb.__version__}")
figure_dir.mkdir(parents=True, exist_ok=True)
fig, ax = plotting.plot_hue_chroma_bounds()
fig.savefig(Path(figure_dir, "chroma-bounds.png"))
fig, ax = plotting.plot_hue_chroma_star()
fig.savefig(Path(figure_dir, "chroma-curves.png"))
# compute the palette as hex to ensure the rendering matches; using
# "oklch" causes some slight hex drift when later using an eyedropper
hlc_map = compute_hlc_map("hex") # ("oklch")
fig, ax = plotting.show_palette(hlc_map)
fig.savefig(Path(figure_dir, "palette.png"))
fig, ax = plotting.show_palette(hlc_map, show_labels=False)
fig.savefig(Path(figure_dir, "palette-bare.png"), pad_inches=0)

2
uv.lock generated
View File

@@ -882,7 +882,7 @@ wheels = [
[[package]]
name = "monobiome"
version = "1.5.0"
version = "1.5.1"
source = { editable = "." }
dependencies = [
{ name = "coloraide" },