Skip to content

Theming ​

Every visual surface in Mayfly is driven by one semantic color table. The /theme command hot-switches between providers of that table — a switch rebuilds the render tree, but your input draft, history, and input mode survive through a draft stash.

/theme usage ​

usage: /theme [<theme>|auto|custom <path> [<base theme>]]
  • /theme — a picker of every built-in palette, grouped for dark terminals and for light terminals, each by name with a one-line description, the live one checked (✓)
  • /theme <key> — switch to a built-in palette, for example /theme tide
  • /theme auto — follow the terminal background (OSC 11 detection): Mayfly Dark or Mayfly Light
  • /theme custom <path> [<base theme>] — mount a file palette over a built-in palette (default dark)

A switch replaces the provider's fiber wholesale; theme-dependent plugins (transcript, input) reload with it. A failed mount falls back to Mayfly Dark — the UI is never left without a theme.

Built-in palettes ​

Every palette follows one recipe: four neutral inks of one quiet hue, one brand hue for primary and the tokens around it, and the status colors (green, amber, red) kept apart from the brand. Each is designed for a terminal background (its canvas); themes paint no background, so set your terminal to it for the intended look.

Mayfly's own palettes (the first rows of each picker group):

keynamestylecanvas
darkMayfly Darkthe default violet: slate ink on near-black#0A0A0C
lightMayfly Lightthe default on white#FFFFFF
tideTidedeep water, an aqua brand#08191D
duskDuskwarm plum, an orchid brand#1B1118
graphiteGraphiteneutral greys, a cobalt brand#141414
linenLinenink on paper: warm grey on cream, an ink-blue brand#F8F3E9
mistMistteal on a pale blue-white#F3F8FA
heatherHeatherlilac-grey, a plum brand#F8F4F9
obsidianObsidianhigh contrast on black: every tone at 7:1 or more#000000
porcelainPorcelainhigh contrast on white: every tone at 7:1 or more#FFFFFF

auto is not a palette of its own — it picks between Mayfly Dark and Mayfly Light from the terminal background; custom is covered below.

Ports of ready-made palettes ​

22 ports keep their schemes' own colors, assigned to Mayfly's roles. A tone that would read under 4.5:1 on the scheme's background is lightened or darkened just enough, keeping its hue; Gruvbox takes its blue as the primary color because its orange sits on its warning yellow. The sources and licenses are in THIRD-PARTY-NOTICES.md of the package.

familyfor dark terminalsfor light terminals
Catppuccincatppuccin-mocha, catppuccin-macchiato, catppuccin-frappecatppuccin-latte
Rosé Pinerose-pine, rose-pine-moonrose-pine-dawn
Draculadracula
Nordnord
Tokyo Nighttokyo-night, tokyo-night-stormtokyo-night-day
Solarizedsolarized-darksolarized-light
Gruvboxgruvbox-darkgruvbox-light
Oneone-darkone-light
Kanagawakanagawa-wavekanagawa-lotus
Everforesteverforest-darkeverforest-light

The persisted default theme ​

/theme switches the theme for the session; the persisted default lives in the mayfly: section of settings.yaml (or the /settings panel's Theme row — it lists the palettes by name with their dark or light tag, applies live, and writes through):

yaml
mayfly:
  theme: tide   # any palette key above, or auto

The default applies at startup; an in-session /theme pick overrides it, and unrelated settings writes never stomp that pick. A saved value that names no palette (ocean or paper from an earlier version) starts on Mayfly Dark and leaves every other setting as it is. Custom palettes (/theme custom <path>) stay session-only — they never persist.

custom: JSON palettes ​

The custom theme reads a JSON file mapping tokens to #rrggbb hexes, layered over a base (any built-in palette key):

json
{
  "primary": "#9A86E6",
  "accent": "#C9C0F0",
  "roleUser": "#9A86E6",
  "selectedBg": "#2b2b30"
}

Rules:

  • only write the tokens you want to override; the rest fall through to base;
  • unknown tokens (not in the table below, nor logoInks) and invalid colors (not #rrggbb) are dropped with a warning, falling back to the base entry;
  • logoInks is the only token taking an array — exactly five #rrggbb hexes painting the banner mark: its body, its wings, then the fly-in's trail from the nearest pixel to the farthest;
  • selectedBg, diffAddedBg, and diffRemovedBg paint backgrounds; every other color token paints a foreground;
  • an unreadable or non-object file falls back to the whole base palette.

Semantic tokens ​

Reference values from Mayfly Dark (every palette has its own; auto picks between Mayfly Dark and Mayfly Light per OSC 11):

Base ​

tokendarkused for
text#EDEDF2body text, brightest footer tier (model, context)
textStrong#F5F5F7emphasized text
muted#9AA3B8secondary text, middle footer tier (cwd, git badge)
textMuted#5C6476dimmest tier (tool summary lines, tips, code-block borders)
accent#C9C0F0secondary highlight (pointers, secondary emphasis)
primary#9A86E6primary (slash-context editor frame, running tool dot, links)
border#45406Bregular borders
success#4ec87esuccess
error#e85454error
warning#e8a838warning
selectedBg#2b2b30selected list-row background
roleUser#9A86E6user-message » rail
shellMode#C9C0F0! bash mode (editor frame, $ prefix)
modelHighlight#E9E6F4banner model-row highlight
logoInks#9A86E6 …the banner mark: body, wings, three trail shades

Markdown ​

tokendarkused for
mdHeading#F5F5F7headings
mdLink#B9A9F0link text
mdLinkUrl#5C6476link URLs
mdCode#C9C0F0inline code
mdCodeBlock#EDEDF2code-block body
mdCodeBlockBorder#45406Bcode-block border
mdQuote#9AA3B8quote text
mdQuoteBorder#5C6476quote bar
mdHr#45406Bhorizontal rules
mdListBullet#C9C0F0list bullets

Diff ​

tokendarkused for
diffAdded#4ec87eadded-line + sign
diffRemoved#e85454removed-line - sign
diffAddedBg#1E3A2Badded-line background band
diffRemovedBg#43232Aremoved-line background band
diffMeta#9AA3B8diff file headers

Preview · v0.1.4-rc.1