Skip to content

Theming ​

Every visual surface in Blue 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 [dark|light|ocean|paper|auto|custom <path> [dark|light|ocean|paper]]
  • /theme — list every theme and mark the current one (dark, light, ocean, paper, auto, custom)
  • /theme dark / /theme light / /theme ocean / /theme paper — switch to a built-in palette
  • /theme auto — follow the terminal background (OSC 11 detection)
  • /theme custom <path> [dark|light] — mount a file palette, with base as the fallback (default dark)

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

Built-in palettes ​

keystyle
darkthe default dark (pi lineage, brand-blue highlights)
lightlight (GitHub primer family, one gray tier deeper so it never reads pale)
oceanblue-tinted dark (sky-blue primary, teal accent)
paperwarm light (burnt-orange primary, ink-teal accent)

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

The persisted default theme ​

/theme switches the theme for the session; the persisted default lives in the blue: section of settings.yaml (or the /settings panel's Theme row — it cycles the value, applies live, and writes through):

yaml
blue:
  theme: ocean   # dark | light | ocean | paper | auto

The default applies at startup; an in-session /theme pick overrides it, and unrelated settings writes never stomp that pick. 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 (dark or light):

json
{
  "primary": "#4fa8ff",
  "accent": "#5bc0be",
  "roleUser": "#ffcb6b",
  "selectedBg": "#3a3a4a"
}

Rules:

  • only write the tokens you want to override; the rest fall through to base;
  • unknown tokens (not in the table below, nor logoGradient) and invalid colors (not #rrggbb) are dropped with a warning, falling back to the base entry;
  • logoGradient is the only token taking an array — a non-empty list of #rrggbb hexes painting the banner logo row by row, top to bottom;
  • an unreadable or non-object file falls back to the whole base palette.

Semantic tokens ​

Reference values from the dark palette (light/ocean/paper have their own; auto picks between dark and light per OSC 11):

Base ​

tokendarkused for
text#e0e0e0body text, brightest footer tier (model, context)
textStrong#ffffffemphasized text
muted#888888secondary text, middle footer tier (cwd, git badge)
textMuted#6b6b6bdimmest tier (tool summary lines, tips, code-block borders)
accent#2bc8e8secondary highlight (pointers, secondary emphasis)
primary#4fa8ffprimary (slash-context editor frame, running tool dot, links)
border#5a5a5aregular borders
borderFocus#e8a838focused border (approval panel rule)
success#4ec87esuccess
error#e85454error
warning#e8a838warning
selectedBg#3a3a4aselected list-row background
roleUser#4d6bfeuser-message » rail
shellMode#bd93f9! bash mode (editor frame, $ prefix)
modelHighlight#8ca8ffbanner model-row highlight

Markdown ​

tokendarkused for
mdHeading#e0e0e0headings
mdLink#4fa8fflink text
mdLinkUrl#6b6b6blink URLs
mdCode#4fa8ffinline code
mdCodeBlock#e0e0e0code-block body
mdCodeBlockBorder#6b6b6bcode-block border
mdQuote#888888quote text
mdQuoteBorder#888888quote bar
mdHr#5a5a5ahorizontal rules
mdListBullet#e0e0e0list bullets

Diff ​

tokendarkused for
diffAdded#4ec87eadded lines
diffRemoved#e85454removed lines
diffAddedStrong#7ad99badded lines (strong)
diffRemovedStrong#f08585removed lines (strong)
diffGutter#6b6b6bdiff gutter
diffMeta#888888diff file headers

Preview · v0.2.0-alpha.1