// 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") steps through the themes in this order: 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. A `ThemeFile` that fails to load says why in words, a ZON error with its line (`line 3: expected ','`), and changes nothing: the theme shown stays, and #file("/ctl") and #word("DumpConfig") still name the file that last loaded, or none. #word("Restore") and `pardes -l` load a dump's `ThemeFile` again, as a #file("/ctl") write of it does, and one that fails there changes nothing either. 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], )