▶ YouTube Summaries

← All summaries

Live-designing Halloween dark and light ef-themes

2026-11-01 Sun ⏱ 2 hr 35 min protesilaos

Spontaneous livestream in which Prot builds two new ef-themes, ef-halloween-dark and ef-halloween-light, from scratch, picking colors by eye. The dark variant gets a full first pass of its palette mappings; the light one is only started. The session shows his method: set the big surfaces first, assign named palette colors to semantic roles, check every choice in real buffers (Elisp, C, Magit diffs, Org, email, completion UIs), and leave exact hex values for later. Chat tangents cover AI use, Emacs forks/rewrites, color theory, and why old terminals were green.

Scaffolding

  • Since ef-themes v2 the themes are built on top of modus-themes; a new theme is a ef-<name>-theme.el file plus registration in the main ef-themes file.
  • ef-halloween-dark is cloned from ef-autumn, ef-halloween-light from ef-day; the descriptions stay vague ("legible dark theme with Halloween style").
  • The two themes form a pair, so they can share palette mappings (semantic role → named color) while the base hex values differ.
  • He keeps Emacs core's AGENTS/CLAUDE files in the repo to follow the Emacs policy against LLM-generated contributions.

Order of work on the dark theme

  1. Background: ef-autumn is too dark; he wants "saturated soil" brown. Brown is not dark yellow: it needs a fair amount of blue and is pushed towards red.
  2. Cursor: a muted orange, distinct from ef-autumn's gold.
  3. Main foreground: warm and orangey instead of neutral. A tinted background shifts how "gray" looks: after staring at a red-shifted background, a pure gray looks bluish.
  4. Mode line: a yellowish tone first; it came out almost identical to ef-melissa-dark, so he shifted it greener. The inactive mode line and borders get toned down so the active one stands out.
  5. Parenthesis match, hover, region, hl-line: these four must all differ from each other and from the background. Parens go scarlet, then indigo/purple so they contrast with the cursor; hover is purple; region is reddish; hl-line is a subtler version of the mode line.
  6. Syntax mappings (named colors only, hex values refined later): keywords red-warmer, built-ins yellow-warmer, strings yellow, docstrings yellow-faint, comments magenta-faint, constants magenta-cooler, variables green-faint, preprocessor red. Each one is checked in Elisp, C (xfns.c) and Denote's regexps.
  7. Links and keys: links green-warmer, visited links magenta-faint, key bindings magenta (they read well in keycast too).
  8. Accents and completion: accents 0-3 become red, magenta-cooler, green-warmer, yellow, checked with orderless matching in vertico; the completion selection background goes red-ish, then gets more blue so it doesn't shout.
  9. Diffs: added/removed/refined/fringe backgrounds and foregrounds are tuned in Magit; the removed diff is made more orange to match the theme. In Magit the section heading, file heading and hunk heading backgrounds must form a gradient, with no inner part louder than the heading above it.
  10. Background tiers (bg-dim, active, inactive) are tuned into a subtle gradient; Denote identifiers go red-faint because the purple "doesn't look right in context". In his words: it's a theme, not a color scheme.
  11. Semantic highlighting (elisp-fontify-semantically, also what tree-sitter/LSP use): variable/function "use" faces get colors. He finds the result unusable ("Christmas tree") and turns it off again.
  12. Org: macros, code (red-warmer), verbatim (green, then yellow-warmer), tags/priority cookies yellow-faint, TODO red-warmer, DONE re-colored, table formulas, and eight heading levels. The heading order changes several times to avoid a bluish overall feel and adjacent look-alikes. rainbow-delimiters is installed to check that consecutive levels stay distinguishable.
  13. Email: recipient red-warmer, subject magenta-cooler, other headers yellow; nested citation levels get progressively fainter colors; the signature/GPG part stays a bit more prominent.
  14. Popups and calendar: Corfu and Company popups are made to stand out with a slight blue; the secondary selection (org-read-date) is off-yellow; calendar weekdays yellow, weekends magenta-cooler, holidays green.

Light theme (started)

  • Light themes are less forgiving: a mistake makes them harder to use, whereas a dark-theme mistake mostly just looks exaggerated.
  • He starts with a darker yellowish background, an orange cursor, a tomato/orange mode line, purple parens and hover, and an orange-ish region. The remaining tuning is left for later; he will commit after walking the dogs.

Q&A and tangents

  • Color-blind variants: he started by using GIMP's color-deficiency filters, then built enough intuition that he no longer needs them.
  • Reload current theme: a small command that calls modus-themes-load-theme with (modus-themes-get-current-theme); it works for every modus- and ef-theme.
  • AI use: he doesn't use it. He knows how it works from coaching sessions, but theming is "like a video game", and having AI play it for him would remove the fun.
  • Rust Emacs rewrites (Neo Emacs etc.): what matters is whether there is a social need for a fork. Neovim had one (Vim's maintainer resisted changes); Emacs has no such divide and no BDFL. Without a social need a fork dies when its developers get bored and spreads an already underfunded community thinner. He suggests working with the Emacs maintainers instead, e.g. a branch in emacs.git that rewrites C parts piece by piece so people who build from source can test it.
  • Why no "orange" in named colors: on screens the primaries are R/G/B and the secondaries Y/M/C. Tertiary colors like orange can't hold up in both light and dark themes. The named set matches terminal emulator conventions: black, red, green, yellow, blue, magenta, cyan, white, plus bright variants.
  • Terminal color order: he guesses it comes from traditional painting, where blue was a costly pigment (mined in Afghanistan, prized by Dutch painters) rather than a primary. He admits he may be wrong.
  • Why old terminals were green: among the RGB primaries, green has by far the highest contrast against black and blue the lowest (he shows this with modus-themes-contrast). The ranking flips on light backgrounds, where blue is the most legible.
  • Finding mode line faces: M-x list-faces-display and search; describe-face doesn't work on the mode line.
  • Other mentions: he switched from Gnus to notmuch ~4 years ago (Gnus is still excellent); try ef-reverie if you want something like a light ef-dream; overrides let users lower contrast themselves, since the defaults always keep legible contrast.