summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 23:04:26 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commitf88eadfdf2629ff0d1086b6cf9299be2713ee3b6 (patch)
treeb335e598994a6f950fd9e6677cdbc4255ca5c9a3
parent464b3033ac69f6c8256c2216ac385450144740bf (diff)
downloadpardes-f88eadfdf2629ff0d1086b6cf9299be2713ee3b6.tar.gz
pardes-f88eadfdf2629ff0d1086b6cf9299be2713ee3b6.zip
Themes become a short Typst topic: choosing one, the native palettes and ports, and a theme file's roles
Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--docs/themes.md186
-rw-r--r--docs/typ/themes.typ119
-rw-r--r--src/themes/atelier.zig2
-rw-r--r--src/themes/clay.zig2
-rw-r--r--src/themes/daybreak.zig2
-rw-r--r--src/themes/dusk.zig2
-rw-r--r--src/themes/forge.zig2
-rw-r--r--src/themes/forge_black.zig2
-rw-r--r--src/themes/forge_soft.zig2
-rw-r--r--src/themes/harvest.zig2
-rw-r--r--src/themes/ink.zig2
-rw-r--r--src/themes/lagoon.zig2
-rw-r--r--src/themes/orchard.zig2
-rw-r--r--src/themes/orchard_black.zig2
-rw-r--r--src/themes/paper.zig2
-rw-r--r--src/themes/solarium.zig2
-rw-r--r--src/themes/spectrum.zig2
17 files changed, 134 insertions, 201 deletions
diff --git a/docs/themes.md b/docs/themes.md
deleted file mode 100644
index db6349c4..00000000
--- a/docs/themes.md
+++ /dev/null
@@ -1,186 +0,0 @@
-# Pardes themes
-
-Pardes ships fifteen native palettes: six originals, six classic-inspired
-adaptations and three contrast variants, designed for tags, text, search, diagnostics and embedded
-terminals together. `orchard` is the initial theme.
-Execute `Theme <name>` anywhere, or open `Themes` with `SPC t t` and select
-a theme's command. Put the same command in your [startup configuration](config.md)
-to keep a preference. `NextColor` cycles through the native themes first,
-then `acme`, `lapis` and `lapis_plain`, the [faithful ports](#faithful-ports), the legacy
-`helix` and `dark`, and the imported palettes. `Themes` shows the same
-order in sections: `Pardes themes`, one per ported family, `Legacy themes`
-and `Imported themes (helix, zed)`; its navigation skips the section headings.
-`lapis` draws its ornament in the GUI; `lapis_plain` is the same theme on
-flat grounds (no dot grid under the text, no stripes behind the focused
-tag), with lapis's framed and shadowed tags and its file-name shadow.
-See the [Agave visual review](ui-review.md) for the original six-palette gallery.
-
-| Theme | Character | Page | Accent |
-| --- | --- | --- | --- |
-| `orchard` | Near-black evergreen; bright leaf comments and plum syntax | `#0d1410` | `#adcc91` |
-| `dusk` | Soft plum charcoal; copper comments and gentle text | `#39323b` | `#e4b39b` |
-| `ink` | Pure black; bright, distinct signals and ice-blue comments | `#000000` | `#86d8ff` |
-| `paper` | Neutral uncoated paper; graphite and teal | `#f5f3ed` | `#3c6b56` |
-| `daybreak` | High contrast light; white and deep blue ink | `#ffffff` | `#075f91` |
-| `atelier` | Acme homage; butter-yellow paper and blue-green tags | `#fffdeb` | `#3e7a68` |
-| `forge` | Dark Plus-inspired near-black, blue and peach; slate-blue tags | `#0c0c0e` | `#a5c4ee` |
-| `lagoon` | Softer Material-inspired slate; vivid sea-glass comments | `#34464c` | `#89c7b4` |
-| `solarium` | Softer Solarized-inspired blue-green; golden comments and teal tags | `#173e45` | `#d5bc72` |
-| `spectrum` | Monokai-inspired near-black and candy colors; golden comments | `#100e11` | `#ffd866` |
-| `harvest` | Autumn-inspired near-black earth, ember and leaf green | `#100e0b` | `#cfba8b` |
-| `clay` | Gruvbox-inspired near-black and earthy brights; amber comments | `#10100e` | `#8ec07c` |
-| `forge_black` | Pure-black Forge; luminous text and cool slate tags | `#000000` | `#a5c4ee` |
-| `forge_soft` | Neutral-slate Forge; gentler text, still vivid blue comments | `#35383e` | `#a5c4ee` |
-| `orchard_black` | Pure-black Orchard; luminous garden ink and bright leaf comments | `#000000` | `#adcc91` |
-
-The six adaptations retain recognizable classic syntax identities, but are
-not exact ports. Their Acme influence is deliberate: quiet command strips,
-thin boundaries, and a search surface
-distinct from selection. Forge uses cool-neutral chrome instead of green
-tints. Active pane and column tags use a restrained tone-on-tone shift, not
-a light/dark inversion: dark palettes keep dark tags, and light palettes
-keep light tags. A slight text lift and the focus marker retain the cue
-without turning the entire command strip into a highlight.
-The filename at the end of a pane's path uses a distinct hue at the same
-perceived brightness as the tag text. The directory and commands keep
-their usual foreground. Filename text meets the same contrast threshold on
-both normal and active tag backgrounds.
-Column drag grips use a separate accent from pane grips, with matching geometry.
-Comments are colorful first-class text, while line numbers stay quiet;
-the current line number gets a small color emphasis and bold weight, never a bright tag-colored
-block. These are appearance changes only;
-tag editing, commands and terminal interaction are unchanged.
-
-Dark backgrounds make an explicit choice: near-black with bright text, or
-the gentler slate/plum/blue-green of `forge_soft`, `dusk`, `lagoon` and
-`solarium`. The softer group keeps body text around 5.5–6.7:1 contrast; the
-near-black group exceeds 14:1. Try `Theme forge_black` and `Theme forge_soft`
-back-to-back to compare the extremes without changing the syntax identity.
-Light paper and the Acme homage remain available.
-
-Their local references are `vendor/themes/dark_plus.toml`,
-`material_oceanic.toml` (and its `material_deep_ocean.toml` parent),
-`solarized_dark.toml`, `monokai_pro.toml`, `autumn.toml`, and the Gruvbox Dark
-entry in `gruvbox.json`. The original imported themes remain selectable under
-their existing names (one a [faithful port](#faithful-ports) now holds gains
-`_helix`, as in `dracula_helix`); the adaptations have distinct Pardes names and do not
-claim upstream affiliation. Existing vendor provenance and licenses remain
-with those sources.
-
-All fifteen palettes specify their own ANSI colors, so indexed terminal output
-belongs to the same palette as the editor. Explicit true-color output can
-still carry an application's own colors; the existing terminal `Filter`
-command projects those colors through the theme. The older `dark` palette
-continues to inherit the surrounding terminal's default background and text.
-
-The native palettes keep normal text, syntax colors, comments,
-diagnostics and ANSI foregrounds at a calculated sRGB contrast ratio of at
-least 4.5:1 against the page. `ink` and `daybreak` raise that floor to 7:1.
-Comments additionally stay above 5:1. Decorative line numbers sit between
-2.5:1 and 4:1, with current numbers capped at 4.5:1; they deliberately do not
-compete with source text. ANSI bright black is independent of the comment
-color, so making comments vivid does not recolor gray terminal output.
-Tag, active-tag, selection and search text are checked against their respective
-surfaces at the same thresholds. Active/inactive tag backgrounds differ by
-no more than 1.6:1, keeping focus changes quiet. ANSI black is exempt because applications
-also use it as a background. These are palette checks, not a guarantee about
-arbitrary terminal escape sequences, reversed colors or shader effects.
-
-## Faithful ports
-
-These are well-known themes taken as close to their originals as pardes can
-draw them: every colour the original has (page, text, selection, syntax, line
-numbers, diagnostics, terminal ANSI) is its own, read out of the original's
-files, and each theme file cites the file and line of every value. The loose
-adaptations above (`forge`, `solarium`, `spectrum`, ...) stay as they are.
-
-pardes has one colour each for keywords, strings, numbers and comments, so a
-theme that splits a kind (VS Code's control-flow keywords) keeps its main
-one. A pane's tag is the original's window bar (vim's `StatusLine` and
-`StatusLineNC`, emacs's `mode-line` and `mode-line-inactive`) or, in a tabbed
-editor, its tab. What the original lacks (grips, a scroll column) comes from
-its own palette. Where a chrome colour misses one of pardes's floors (rules
-1.5:1 off the page, the focused tag 1.5:1 off the unfocused one on a dark
-page and 1.25:1 on a light one, tag text 4.5:1), only that chrome colour
-moves, just far enough, and the file's header says so. Text, syntax and ANSI
-are never adjusted.
-
-| Family | Themes | Source |
-| --- | --- | --- |
-| Visual Studio Code | `dark_plus` | VS Code 1.130.0 `extensions/theme-defaults/themes/dark_plus.json` and `dark_vs.json`; [microsoft/vscode](https://github.com/microsoft/vscode) 1.130.0 |
-| Solarized | `solarized_dark`, `solarized_light` | [altercation/solarized](https://github.com/altercation/solarized); `~/05-genizah/solarized/vim-colors-solarized/colors/solarized.vim` |
-| Dracula | `dracula`, `dracula_soft`, `alucard` | [dracula/dracula-theme](https://github.com/dracula/dracula-theme); [dracula/visual-studio-code](https://github.com/dracula/visual-studio-code) |
-| Monokai | `monokai` | [download.sublimetext.com](https://download.sublimetext.com/Sublime%20Text%202.0.2%20x64.tar.bz2) |
-| Monokai Pro | `monokai_pro`, `monokai_pro_classic`, `monokai_pro_machine`, `monokai_pro_octagon`, `monokai_pro_ristretto`, `monokai_pro_spectrum`, `monokai_pro_light`, `monokai_pro_light_sun` | [open-vsx.org](https://open-vsx.org/api/monokai/theme-monokai-pro-vscode/2.0.15/file/monokai.theme-monokai-pro-vscode-2.0.15.vsix) |
-| Tokyo Night | `tokyonight_night`, `tokyonight_storm`, `tokyonight_moon`, `tokyonight_day` | [folke/tokyonight.nvim](https://github.com/folke/tokyonight.nvim) |
-| Rosé Pine | `rose_pine`, `rose_pine_moon`, `rose_pine_dawn` | [rose-pine/palette](https://github.com/rose-pine/palette); [rose-pine/neovim](https://github.com/rose-pine/neovim) |
-| Catppuccin | `catppuccin_latte`, `catppuccin_frappe`, `catppuccin_macchiato`, `catppuccin_mocha` | [catppuccin/palette](https://github.com/catppuccin/palette); [catppuccin/nvim](https://github.com/catppuccin/nvim) |
-| Seoul256 | `seoul256_dark_233`, `seoul256_dark_234`, `seoul256_dark_235`, `seoul256_dark_236`, `seoul256_dark_237`, `seoul256_dark_238`, `seoul256_dark_239`, `seoul256_light_252`, `seoul256_light_253`, `seoul256_light_254`, `seoul256_light_255`, `seoul256_light_256` | [junegunn/seoul256.vim](https://github.com/junegunn/seoul256.vim) |
-| Zenbones | `zenbones_light`, `zenbones_dark`, `neobones_light`, `neobones_dark`, `vimbones`, `forestbones_light`, `forestbones_dark`, `nordbones`, `rosebones_light`, `rosebones_dark`, `tokyobones_light`, `tokyobones_dark`, `seoulbones_light`, `seoulbones_dark`, `duckbones`, `zenburned`, `zenwritten_light`, `zenwritten_dark`, `kanagawabones` | [zenbones-theme/zenbones.nvim](https://github.com/zenbones-theme/zenbones.nvim) |
-| Nord | `nord` | [nordtheme/nord](https://github.com/nordtheme/nord); [nordtheme/vim](https://github.com/nordtheme/vim); [nordtheme/visual-studio-code](https://github.com/nordtheme/visual-studio-code) |
-| Ayu | `ayu_dark`, `ayu_mirage`, `ayu_light` | [ayu-theme/ayu-colors](https://github.com/ayu-theme/ayu-colors); [ayu-theme/vscode-ayu](https://github.com/ayu-theme/vscode-ayu) |
-| Doom One | `doom_one`, `doom_one_light` | [doomemacs/themes](https://github.com/doomemacs/themes) |
-
-## Make a theme your own
-
-Run `DumpThemes` to export complete `.zon` files below the configuration
-directory's `themes/builtin/`. Copy a native file to `themes/mine.zon`, change
-its `.name`, and run:
-
-```text
-ThemeFile themes/mine.zon
-```
-
-On hosts with live document reload, saving a valid theme file updates it
-immediately. An incomplete save keeps the last valid version. Selecting a
-built-in theme stops the custom theme watch.
-
-Pardes roles extend the original editor palette with independent choices
-for its UI. Each value is an RGB triple, for example
-`.search_bg = .{ 0x57, 0x47, 0x2a }`. New roles are optional and accept `null`,
-so existing exported themes remain valid.
-
-| Optional role | Purpose | When absent |
-| --- | --- | --- |
-| `tag_active_bg`, `tag_active_fg` | Focused pane tag surface and text; a surface closer than 1.25:1 to `tag_bg` is pushed further the way it already leans, as far as its text keeps its own contrast (or 4.5). Every dark native theme sets one | `tag_bg`, `tag_fg` |
-| `tag_name_fg` | Filename or terminal `Tty` command tint | The corresponding normal or active tag foreground |
-| `tag_active_name_fg` | Filename or terminal `Tty` tint in active tags | `tag_name_fg`, then the active tag foreground |
-| `column_box` | Column grip while held, and its drag rail | `num` |
-| `column_box_dim` | Column drag grip at rest, in every focus state | Equal mix of `column_box` and `tag_bg` |
-| `border` | Quiet separators; one that stands off the page by less than 1.5:1 (a dark rule on a near-black page) is lifted toward the text to 1.6:1. A theme with no page is judged against #121212 | `scroll_track` |
-| `empty_col` | A column with no pane, under its tag (acme: white) | `border`, as drawn |
-| `lineno_active` | Restrained current line number foreground | `lineno` |
-| `search_bg`, `search_fg` | Search matches, independent of selection | `sel_bg`, `sel_fg` |
-| `diagnostic_error` | Error text | `fg`, or `tag_fg` for an inherited foreground |
-| `diagnostic_warning` | Warning text | Same foreground fallback |
-| `diagnostic_info` | Informational diagnostic text | Same foreground fallback |
-| `diagnostic_hint` | Hint text | Same foreground fallback |
-| `tag_sel_bg` | A tag's selection ground | `sel_bg` |
-| `sweep_bg`, `sweep_fg` | Three triples each: the select, exec and look sweeps' ground and ink | `sel_bg` tinted toward `kw`, `str` and `num`, in `sel_fg` |
-| `tag_rule` | The one-pixel rule between a pane's tag and its body, quieter than the `rule_px` rules between panes and columns | Halfway between `tag_bg` and the page the shell draws |
-| `rule_px` | Pixel shells: the width of the rules between columns, between panes stacked in a column, and under the workspace and column tags, in `border` (the rule between a tag and its body is always one pixel), in logical pixels: doubled on a 2x display, as acme scales its Border | 2 |
-| `box_border`, `box_dirty` | The grip is acme's button: `box` filled when focused, else a two-pixel ring of `box_border` round the tag's ground; `box_dirty` fills it inside either ring while its file is unsaved (a grid, which has no ring, shows a bold `*` on `box_dirty` in the grip's second cell) | `box_dim`; `diagnostic_warning`, then `num` |
-| `rail_px` | Pixel shells: the scroll column's width, the grip's button over the scrollbar (thumb a pixel narrower), in pixels at a 17px tagline, scaled with it | 12, acme's Scrollwid |
-| `decor` | Pixel shells: a theme's ornament, drawn inside the chrome it has (lapis's): `page_dots` (a dot grid on the page's own ground, `page_dot_alpha` strong every `page_dot_px`), `rail_checker` (a checker in the scroll track, squares of `rail_checker_px`), `tag_border`, `tag_shadow`, `tag_stripe` (every tag a raised plaque inside its own band: a `tag_border_px` frame round its text and a hard `tag_shadow_px` shadow down and right, both inside the band's rows and columns; the focused pane's plaque striped `tag_stripe_px` with its words on plates of the tag's ground; column and workspace tags a quieter one; opaque windows only) and `title_shadow` (the file name's offset shadow, `title_shadow_px`), sizes in logical pixels. None of it touches a focus indicator | none |
-
-Native palettes give filenames a distinct hue at approximately the same
-brightness as the surrounding tag text. This also applies to output names
-such as `+Search`. Terminal tags instead tint `Tty`, the first builtin after
-the path. Directory paths and the other commands retain the regular tag color.
-
-These colors are shared by the GUI and TTY. Tags and their active tint retain
-the same text, command execution, drag targets and focus behavior. Selection
-and search have separate palette roles because they communicate different
-states. Theme changes use the existing chrome transition; body and terminal
-colors switch directly so syntax and ANSI content stay coherent.
-
-`FocusTint` toggles the focused pane's tag tint, which is on by default.
-`SyntaxBold` toggles bold syntax keywords, which are off by default. Both
-commands take no argument, work in GUI and TTY, and report their states in
-`DumpConfig`. Use them in the startup configuration to reverse the defaults.
-
-The original required roles remain unchanged: nullable `bg` and `fg`,
-`sel_bg`, `sel_fg`, `tag_bg`, `tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`,
-`comment`, `lineno`, `scroll_track`, `scroll_thumb`, and a nullable 16-entry
-`palette`. `ThemeFile` loads a complete theme, with no inheritance or partial
-override syntax. The exported native files are the easiest starting point.
diff --git a/docs/typ/themes.typ b/docs/typ/themes.typ
new file mode 100644
index 00000000..d30fe0bd
--- /dev/null
+++ b/docs/typ/themes.typ
@@ -0,0 +1,119 @@
+// Themes: choosing one, the native palettes and the faithful ports, and
+// the roles a theme file sets.
+#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs
+
+#word("Themes") (#key("SPC t t")) lists every theme as a word to click;
+`Theme <name>` sets one anywhere, and the same line in the startup file
+keeps it. #word("NextColor") walks the ring: the native themes first, then
+`acme`, `lapis` and `lapis_plain`, the faithful ports, the legacy `helix`
+and `dark`, and the palettes imported from helix and zed. `orchard` is the
+default. `lapis` draws its ornament in the GUI; `lapis_plain` is the same
+theme on flat grounds, keeping its framed and shadowed tags and its
+file-name shadow.
+
+= The native themes
+
+#pairs(
+ [`orchard`], [near-black evergreen; bright leaf comments and plum syntax],
+ [`dusk`], [soft plum charcoal; copper comments and gentle text],
+ [`ink`], [pure black; bright, distinct signals and ice-blue comments],
+ [`paper`], [neutral uncoated paper; graphite and teal],
+ [`daybreak`], [high-contrast light; white and deep blue ink],
+ [`atelier`], [acme homage; butter-yellow paper and blue-green tags],
+ [`forge`], [Dark Plus-inspired near-black, blue and peach; slate-blue tags],
+ [`lagoon`], [softer Material-inspired slate; vivid sea-glass comments],
+ [`solarium`], [softer Solarized-inspired blue-green; golden comments and teal tags],
+ [`spectrum`], [Monokai-inspired near-black and candy colours; golden comments],
+ [`harvest`], [autumn-inspired near-black earth, ember and leaf green],
+ [`clay`], [Gruvbox-inspired near-black and earthy brights; amber comments],
+ [`forge_black`], [pure-black Forge; luminous text and cool slate tags],
+ [`forge_soft`], [neutral-slate Forge; gentler text, still vivid blue comments],
+ [`orchard_black`], [pure-black Orchard; luminous garden ink and bright leaf comments],
+)
+
+The six classic-inspired ones (`forge` to `clay`) keep a recognisable
+syntax identity but are not exact ports; their sources are in
+`vendor/themes/`, and they claim no upstream affiliation. The focused
+pane's and column's tags shift tone on tone rather than invert: dark
+palettes keep dark tags, light ones light tags. The file name in a pane's
+path, and `+Search` and the like, take a distinct hue at the same
+brightness as the tag text; a terminal's tag tints its #word("Tty") word
+instead.
+
+Every native palette sets its own ANSI colours, so a terminal's indexed
+colours belong to it; #word("Filter") maps a program's true colours through
+the theme too. Normal text, syntax, comments, diagnostics and ANSI
+foregrounds keep a contrast of at least 4.5:1 against the page (7:1 in
+`ink` and `daybreak`), comments above 5:1; line numbers sit quieter,
+between 2.5:1 and 4:1. Tag, focused-tag, selection and search text are held
+to the same floors on their own grounds. ANSI black is exempt, since
+programs use it as a background. These are checks of the palettes, not a
+promise about a program's own escape sequences or the scene effects.
+#word("FocusTint") (on) and #word("SyntaxBold") (off) toggle the focused
+tag's tint and bold keywords.
+
+= Faithful ports
+
+Well-known themes taken as close to their originals as pardes can draw
+them: every colour the original has (page, text, selection, syntax, line
+numbers, diagnostics, terminal ANSI) is its own, read out of its files,
+and each theme file cites the file and line of every value. pardes has one
+colour each for keywords, strings, numbers and comments, so a theme that
+splits a kind keeps its main one. A pane's tag is the original's window
+bar (vim's `StatusLine`, emacs's `mode-line`) or, in a tabbed editor, its
+tab. Where a chrome colour misses one of pardes's floors (rules 1.5:1 off
+the page, the focused tag 1.5:1 off the unfocused one on a dark page and
+1.25:1 on a light one, tag text 4.5:1), only that colour moves, just far
+enough, and the file's header says so; text, syntax and ANSI never move.
+An imported theme whose name a port now holds is kept with `_helix` added
+(`dracula_helix`).
+
+#pairs(
+ [Visual Studio Code], [`dark_plus`],
+ [Solarized], [`solarized_dark`, `solarized_light`],
+ [Dracula], [`dracula`, `dracula_soft`, `alucard`],
+ [Monokai], [`monokai`],
+ [Monokai Pro], [`monokai_pro`, `monokai_pro_classic`, `monokai_pro_machine`, `monokai_pro_octagon`, `monokai_pro_ristretto`, `monokai_pro_spectrum`, `monokai_pro_light`, `monokai_pro_light_sun`],
+ [Tokyo Night], [`tokyonight_night`, `tokyonight_storm`, `tokyonight_moon`, `tokyonight_day`],
+ [Rosé Pine], [`rose_pine`, `rose_pine_moon`, `rose_pine_dawn`],
+ [Catppuccin], [`catppuccin_latte`, `catppuccin_frappe`, `catppuccin_macchiato`, `catppuccin_mocha`],
+ [Seoul256], [`seoul256_dark_233` to `seoul256_dark_239`, `seoul256_light_252` to `seoul256_light_256`],
+ [Zenbones], [`zenbones_light`, `zenbones_dark`, `neobones_light`, `neobones_dark`, `vimbones`, `forestbones_light`, `forestbones_dark`, `nordbones`, `rosebones_light`, `rosebones_dark`, `tokyobones_light`, `tokyobones_dark`, `seoulbones_light`, `seoulbones_dark`, `duckbones`, `zenburned`, `zenwritten_light`, `zenwritten_dark`, `kanagawabones`],
+ [Nord], [`nord`],
+ [Ayu], [`ayu_dark`, `ayu_mirage`, `ayu_light`],
+ [Doom One], [`doom_one`, `doom_one_light`],
+)
+
+= Making your own <theme-files>
+
+#word("DumpThemes") writes every compiled theme to
+`<config dir>/themes/builtin/<name>.zon`. Copy one to `themes/mine.zon`,
+change its `.name`, and run `ThemeFile themes/mine.zon` (relative to the
+config directory). Where the host reloads files, saving it updates the
+theme at once; a malformed save keeps the last good version, and
+`Theme <name>` stops the watch. The format is `pardes.Theme` as
+`std.zon.stringify` writes it, a complete theme with no inheritance.
+
+The required roles: nullable `bg` and `fg`, `sel_bg`, `sel_fg`, `tag_bg`,
+`tag_fg`, `box`, `box_dim`, `kw`, `str`, `num`, `comment`, `lineno`,
+`scroll_track`, `scroll_thumb`, and a nullable 16-entry `palette`. Each is
+an RGB triple (`.search_bg = .{ 0x57, 0x47, 0x2a }`). The optional roles
+take `null`, so older files stay valid:
+
+#pairs(
+ [`tag_active_bg`, `tag_active_fg`], [the focused pane's tag; a ground closer than 1.25:1 to `tag_bg` is pushed further the way it leans, as far as its text keeps its contrast. Absent: `tag_bg`, `tag_fg`],
+ [`tag_name_fg`, `tag_active_name_fg`], [the file name's or a terminal's #word("Tty") tint, in normal and focused tags. Absent: the tag's foreground],
+ [`column_box`, `column_box_dim`], [a column's grip held (and its drag rail), and at rest. Absent: `num`; a mix of `column_box` and `tag_bg`],
+ [`border`], [quiet separators, lifted to 1.6:1 when under 1.5:1 off the page. Absent: `scroll_track`],
+ [`empty_col`], [a column with no pane, under its tag (acme: white). Absent: `border`],
+ [`lineno_active`], [the current line number. Absent: `lineno`],
+ [`search_bg`, `search_fg`], [search matches, apart from the selection. Absent: `sel_bg`, `sel_fg`],
+ [`diagnostic_error`, `diagnostic_warning`, `diagnostic_info`, `diagnostic_hint`], [diagnostic text. Absent: `fg`, or `tag_fg` for an inherited foreground],
+ [`tag_sel_bg`], [a tag's selection ground. Absent: `sel_bg`],
+ [`sweep_bg`, `sweep_fg`], [three triples each: the select, execute and look sweeps. Absent: `sel_bg` tinted toward `kw`, `str` and `num`, in `sel_fg`],
+ [`tag_rule`], [the one-pixel rule between a pane's tag and its body. Absent: halfway between `tag_bg` and the page],
+ [`rule_px`], [pixel shells: the width of the rules between columns and panes and under the column and workspace tags, in logical pixels. Absent: 2],
+ [`box_border`, `box_dirty`], [the grip as acme's button: a ring of `box_border` when unfocused, filled with `box_dirty` while unsaved. Absent: `box_dim`; `diagnostic_warning`, then `num`],
+ [`rail_px`], [pixel shells: the scroll column's width at a 17px tagline, scaled with it. Absent: 12, acme's Scrollwid],
+ [`decor`], [pixel shells: a theme's ornament (lapis's): `page_dots`, `rail_checker`, `tag_border`, `tag_shadow`, `tag_stripe`, `title_shadow`, with their sizes; none of it touches a focus indicator. Absent: none],
+)
diff --git a/src/themes/atelier.zig b/src/themes/atelier.zig
index f367c341..0ad776fa 100644
--- a/src/themes/atelier.zig
+++ b/src/themes/atelier.zig
@@ -1,6 +1,6 @@
//! Pardes atelier: An Acme homage: butter-yellow paper, blue-green tags and garden ink.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "atelier",
.bg = .{ 0xff, 0xfd, 0xeb },
diff --git a/src/themes/clay.zig b/src/themes/clay.zig
index 85487d48..ba76ad35 100644
--- a/src/themes/clay.zig
+++ b/src/themes/clay.zig
@@ -1,7 +1,7 @@
//! Pardes clay: Gruvbox warm charcoal and earthy brights; deep olive command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/gruvbox.json (Gruvbox Dark).
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "clay",
.bg = .{ 0x10, 0x10, 0x0e },
diff --git a/src/themes/daybreak.zig b/src/themes/daybreak.zig
index 80f4883c..e032b994 100644
--- a/src/themes/daybreak.zig
+++ b/src/themes/daybreak.zig
@@ -1,6 +1,6 @@
//! Pardes daybreak: Crisp white, deep blue ink, and high-contrast navigational cues.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "daybreak",
.bg = .{ 0xff, 0xff, 0xff },
diff --git a/src/themes/dusk.zig b/src/themes/dusk.zig
index b9377992..06f90ab2 100644
--- a/src/themes/dusk.zig
+++ b/src/themes/dusk.zig
@@ -1,6 +1,6 @@
//! Pardes dusk: Soft plum charcoal, copper comments and deliberately gentle text.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "dusk",
.bg = .{ 0x39, 0x32, 0x3b },
diff --git a/src/themes/forge.zig b/src/themes/forge.zig
index a27f66fb..0effa742 100644
--- a/src/themes/forge.zig
+++ b/src/themes/forge.zig
@@ -1,7 +1,7 @@
//! Pardes forge: Dark Plus blue and peach on near-black coal; slate-blue command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/dark_plus.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "forge",
.bg = .{ 0x0c, 0x0c, 0x0e },
diff --git a/src/themes/forge_black.zig b/src/themes/forge_black.zig
index 85f6132e..f51e8594 100644
--- a/src/themes/forge_black.zig
+++ b/src/themes/forge_black.zig
@@ -1,7 +1,7 @@
//! Pardes forge_black: Dark Plus blue and peach on pure black, with cool slate tags.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/dark_plus.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "forge_black",
.bg = .{ 0x00, 0x00, 0x00 },
diff --git a/src/themes/forge_soft.zig b/src/themes/forge_soft.zig
index 0ca062a4..a0cf141b 100644
--- a/src/themes/forge_soft.zig
+++ b/src/themes/forge_soft.zig
@@ -1,7 +1,7 @@
//! Pardes forge_soft: Dark Plus on neutral slate, with softer text and vivid blue comments.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/dark_plus.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "forge_soft",
.bg = .{ 0x35, 0x38, 0x3e },
diff --git a/src/themes/harvest.zig b/src/themes/harvest.zig
index cf10a779..b0ad57c7 100644
--- a/src/themes/harvest.zig
+++ b/src/themes/harvest.zig
@@ -1,7 +1,7 @@
//! Pardes harvest: Autumn ember keywords, leaf greens and cream; deep sage command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/autumn.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "harvest",
.bg = .{ 0x10, 0x0e, 0x0b },
diff --git a/src/themes/ink.zig b/src/themes/ink.zig
index 1e254a3c..4151df7a 100644
--- a/src/themes/ink.zig
+++ b/src/themes/ink.zig
@@ -1,6 +1,6 @@
//! Pardes ink: Near-black with bright, unambiguous signals for demanding contrast.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "ink",
.bg = .{ 0x00, 0x00, 0x00 },
diff --git a/src/themes/lagoon.zig b/src/themes/lagoon.zig
index 4d975794..66473c46 100644
--- a/src/themes/lagoon.zig
+++ b/src/themes/lagoon.zig
@@ -1,7 +1,7 @@
//! Pardes lagoon: Material Oceanic slate and pastel syntax; deep sea-glass command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/material_oceanic.toml (inherits material_deep_ocean.toml).
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "lagoon",
.bg = .{ 0x34, 0x46, 0x4c },
diff --git a/src/themes/orchard.zig b/src/themes/orchard.zig
index f927c50e..b4a35c1f 100644
--- a/src/themes/orchard.zig
+++ b/src/themes/orchard.zig
@@ -1,6 +1,6 @@
//! Pardes orchard: Near-black evergreen, with lively leaf comments and plum syntax.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "orchard",
.bg = .{ 0x0d, 0x14, 0x10 },
diff --git a/src/themes/orchard_black.zig b/src/themes/orchard_black.zig
index c700947f..d9e026bd 100644
--- a/src/themes/orchard_black.zig
+++ b/src/themes/orchard_black.zig
@@ -1,6 +1,6 @@
//! Pardes orchard_black: Pure-black evergreen with bright leaf comments and luminous garden ink.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "orchard_black",
.bg = .{ 0x00, 0x00, 0x00 },
diff --git a/src/themes/paper.zig b/src/themes/paper.zig
index f1d6980b..c86482f7 100644
--- a/src/themes/paper.zig
+++ b/src/themes/paper.zig
@@ -1,6 +1,6 @@
//! Pardes paper: Uncoated paper with graphite text and restrained teal accents.
//! Original palette; editor chrome, search, diagnostics and ANSI output are
-//! designed together. See docs/themes.md for the shared role contract.
+//! designed together. See docs/typ/themes.typ for the shared role contract.
pub const theme = .{
.name = "paper",
.bg = .{ 0xf5, 0xf3, 0xed },
diff --git a/src/themes/solarium.zig b/src/themes/solarium.zig
index 21b4c451..316113eb 100644
--- a/src/themes/solarium.zig
+++ b/src/themes/solarium.zig
@@ -1,7 +1,7 @@
//! Pardes solarium: Solarized deep blue-green and warm ink; teal command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/solarized_dark.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "solarium",
.bg = .{ 0x17, 0x3e, 0x45 },
diff --git a/src/themes/spectrum.zig b/src/themes/spectrum.zig
index a0faf897..f7c25c3d 100644
--- a/src/themes/spectrum.zig
+++ b/src/themes/spectrum.zig
@@ -1,7 +1,7 @@
//! Pardes spectrum: Monokai Pro charcoal and candy syntax; warm umber command rails.
//! A classic-inspired adaptation, not an exact upstream port.
//! Reference: vendor/themes/monokai_pro.toml.
-//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/themes.md.
+//! Pardes-specific tag, search, diagnostic and ANSI roles; see docs/typ/themes.typ.
pub const theme = .{
.name = "spectrum",
.bg = .{ 0x10, 0x0e, 0x11 },