From f88eadfdf2629ff0d1086b6cf9299be2713ee3b6 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Wed, 30 Sep 2026 23:04:26 -0300 Subject: 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 --- docs/typ/themes.typ | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 docs/typ/themes.typ (limited to 'docs/typ') 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 ` 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 + +#word("DumpThemes") writes every compiled theme to +`/themes/builtin/.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 ` 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], +) -- cgit v1.3