docs(coding-agent): merge theme.md into themes.md, add hot reload info

- Merged theme.md content into themes.md
- Added hot reload documentation
- Updated all references from theme.md to themes.md
- Fixed outdated info (vars not defs, complete example with all 50 tokens)
- Removed dev-focused Implementation section
This commit is contained in:
Mario Zechner 2026-01-25 20:39:49 +01:00
parent 94952bd6c0
commit d79eb99cd2
5 changed files with 263 additions and 631 deletions

View file

@ -1,617 +0,0 @@
> pi can create themes. Ask it to build one for your use case.
# Pi Coding Agent Themes
Themes allow you to customize the colors used throughout the coding agent TUI.
## Color Tokens
Every theme must define all color tokens. There are no optional colors.
### Core UI (10 colors)
| Token | Purpose | Examples |
|-------|---------|----------|
| `accent` | Primary accent color | Logo, selected items, cursor () |
| `border` | Normal borders | Selector borders, horizontal lines |
| `borderAccent` | Highlighted borders | Changelog borders, special panels |
| `borderMuted` | Subtle borders | Editor borders, secondary separators |
| `success` | Success states | Success messages, diff additions |
| `error` | Error states | Error messages, diff deletions |
| `warning` | Warning states | Warning messages |
| `muted` | Secondary/dimmed text | Metadata, descriptions, output |
| `dim` | Very dimmed text | Less important info, placeholders |
| `text` | Default text color | Main content (usually `""`) |
| `thinkingText` | Thinking block text | Assistant reasoning traces |
### Backgrounds & Content Text (11 colors)
| Token | Purpose |
|-------|---------|
| `selectedBg` | Selected/active line background (e.g., tree selector) |
| `userMessageBg` | User message background |
| `userMessageText` | User message text color |
| `customMessageBg` | Hook custom message background |
| `customMessageText` | Hook custom message text color |
| `customMessageLabel` | Hook custom message label/type text |
| `toolPendingBg` | Tool execution box (pending state) |
| `toolSuccessBg` | Tool execution box (success state) |
| `toolErrorBg` | Tool execution box (error state) |
| `toolTitle` | Tool execution title/heading (e.g., `$ command`, `read file.txt`) |
| `toolOutput` | Tool execution output text |
### Markdown (10 colors)
| Token | Purpose |
|-------|---------|
| `mdHeading` | Heading text (`#`, `##`, etc) |
| `mdLink` | Link text |
| `mdLinkUrl` | Link URL (in parentheses) |
| `mdCode` | Inline code (backticks) |
| `mdCodeBlock` | Code block content |
| `mdCodeBlockBorder` | Code block fences (```) |
| `mdQuote` | Blockquote text |
| `mdQuoteBorder` | Blockquote border (`│`) |
| `mdHr` | Horizontal rule (`---`) |
| `mdListBullet` | List bullets/numbers |
### Tool Diffs (3 colors)
| Token | Purpose |
|-------|---------|
| `toolDiffAdded` | Added lines in tool diffs |
| `toolDiffRemoved` | Removed lines in tool diffs |
| `toolDiffContext` | Context lines in tool diffs |
Note: Diff colors are specific to tool execution boxes and must work with tool background colors.
### Syntax Highlighting (9 colors)
Future-proofing for syntax highlighting support:
| Token | Purpose |
|-------|---------|
| `syntaxComment` | Comments |
| `syntaxKeyword` | Keywords (`if`, `function`, etc) |
| `syntaxFunction` | Function names |
| `syntaxVariable` | Variable names |
| `syntaxString` | String literals |
| `syntaxNumber` | Number literals |
| `syntaxType` | Type names |
| `syntaxOperator` | Operators (`+`, `-`, etc) |
| `syntaxPunctuation` | Punctuation (`;`, `,`, etc) |
### Thinking Level Borders (6 colors)
Editor border colors that indicate the current thinking/reasoning level:
| Token | Purpose |
|-------|---------|
| `thinkingOff` | Border when thinking is off (most subtle) |
| `thinkingMinimal` | Border for minimal thinking |
| `thinkingLow` | Border for low thinking |
| `thinkingMedium` | Border for medium thinking |
| `thinkingHigh` | Border for high thinking |
| `thinkingXhigh` | Border for xhigh thinking (most prominent, OpenAI codex-max only) |
These create a visual hierarchy: off → minimal → low → medium → high → xhigh
### Bash Mode (1 color)
| Token | Purpose |
|-------|---------|
| `bashMode` | Editor border color when in bash mode (! prefix) |
**Total: 50 color tokens** (all required)
### HTML Export Colors (optional)
The `export` section is optional and controls colors used when exporting sessions to HTML via `/export`. If not specified, these colors are automatically derived from `userMessageBg` based on luminance detection.
| Token | Purpose |
|-------|---------|
| `pageBg` | Page background color |
| `cardBg` | Card/container background (headers, stats boxes) |
| `infoBg` | Info sections background (system prompt, notices, compaction) |
Example:
```json
{
"export": {
"pageBg": "#18181e",
"cardBg": "#1e1e24",
"infoBg": "#3c3728"
}
}
```
## Theme Format
Themes are defined in JSON files with the following structure:
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",
"gray": 242,
"brightCyan": 51
},
"colors": {
"accent": "blue",
"muted": "gray",
"thinkingText": "gray",
"text": "",
...
}
}
```
### Color Values
Four formats are supported:
1. **Hex colors**: `"#ff0000"` (6-digit hex RGB)
2. **256-color palette**: `39` (number 0-255, xterm 256-color palette)
3. **Color references**: `"blue"` (must be defined in `vars`)
4. **Terminal default**: `""` (empty string, uses terminal's default color)
### The `vars` Section
The optional `vars` section allows you to define reusable colors:
```json
{
"vars": {
"nord0": "#2E3440",
"nord1": "#3B4252",
"nord8": "#88C0D0",
"brightBlue": 39
},
"colors": {
"accent": "nord8",
"muted": "nord1",
"mdLink": "brightBlue"
}
}
```
Benefits:
- Reuse colors across multiple tokens
- Easier to maintain theme consistency
- Can reference standard color palettes
Variables can be hex colors (`"#ff0000"`), 256-color indices (`42`), or references to other variables.
### Terminal Default (empty string)
Use `""` (empty string) to inherit the terminal's default foreground/background color:
```json
{
"colors": {
"text": "" // Uses terminal's default text color
}
}
```
This is useful for:
- Main text color (adapts to user's terminal theme)
- Creating themes that blend with terminal appearance
## Built-in Themes
Pi comes with two built-in themes:
### `dark` (default)
Optimized for dark terminal backgrounds with bright, saturated colors.
### `light`
Optimized for light terminal backgrounds with darker, muted colors.
## Selecting a Theme
Themes are configured in the settings (accessible via `/settings`):
```json
{
"theme": "dark"
}
```
Or use the `/theme` command interactively.
On first run, Pi detects your terminal's background and sets a sensible default (`dark` or `light`).
## Custom Themes
### Theme Locations
Custom themes are loaded from `~/.pi/agent/themes/*.json`.
### Creating a Custom Theme
1. **Create theme directory:**
```bash
mkdir -p ~/.pi/agent/themes
```
2. **Create theme file:**
```bash
vim ~/.pi/agent/themes/my-theme.json
```
3. **Define all colors:**
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
"name": "my-theme",
"vars": {
"primary": "#00aaff",
"secondary": 242,
"brightGreen": 46
},
"colors": {
"accent": "primary",
"border": "primary",
"borderAccent": "#00ffff",
"borderMuted": "secondary",
"success": "brightGreen",
"error": "#ff0000",
"warning": "#ffff00",
"muted": "secondary",
"text": "",
"userMessageBg": "#2d2d30",
"userMessageText": "",
"toolPendingBg": "#1e1e2e",
"toolSuccessBg": "#1e2e1e",
"toolErrorBg": "#2e1e1e",
"toolText": "",
"mdHeading": "#ffaa00",
"mdLink": "primary",
"mdCode": "#00ffff",
"mdCodeBlock": "#00ff00",
"mdCodeBlockBorder": "secondary",
"mdQuote": "secondary",
"mdQuoteBorder": "secondary",
"mdHr": "secondary",
"mdListBullet": "#00ffff",
"toolDiffAdded": "#00ff00",
"toolDiffRemoved": "#ff0000",
"toolDiffContext": "secondary",
"syntaxComment": "secondary",
"syntaxKeyword": "primary",
"syntaxFunction": "#00aaff",
"syntaxVariable": "#ffaa00",
"syntaxString": "#00ff00",
"syntaxNumber": "#ff00ff",
"syntaxType": "#00aaff",
"syntaxOperator": "primary",
"syntaxPunctuation": "secondary",
"thinkingOff": "secondary",
"thinkingMinimal": "primary",
"thinkingLow": "#00aaff",
"thinkingMedium": "#00ffff",
"thinkingHigh": "#ff00ff"
}
}
```
4. **Select your theme:**
- Use `/settings` command and set `"theme": "my-theme"`
- Or use `/theme` command interactively
## Tips
### Light vs Dark Themes
**For dark terminals:**
- Use bright, saturated colors
- Higher contrast
- Example: `#00ffff` (bright cyan)
**For light terminals:**
- Use darker, muted colors
- Lower contrast to avoid eye strain
- Example: `#008888` (dark cyan)
### Color Harmony
- Start with a base palette (e.g., Nord, Gruvbox, Tokyo Night)
- Define your palette in `defs`
- Reference colors consistently
### Testing
Test your theme with:
- Different message types (user, assistant, errors)
- Tool executions (success and error states)
- Markdown content (headings, code, lists, etc)
- Long text that wraps
## Color Format Reference
### Hex Colors
Standard 6-digit hex format:
- `"#ff0000"` - Red
- `"#00ff00"` - Green
- `"#0000ff"` - Blue
- `"#808080"` - Gray
- `"#ffffff"` - White
- `"#000000"` - Black
RGB values: `#RRGGBB` where each component is `00-ff` (0-255)
### 256-Color Palette
Use numeric indices (0-255) to reference the xterm 256-color palette:
**Colors 0-15:** Basic ANSI colors (terminal-dependent, may be themed)
- `0` - Black
- `1` - Red
- `2` - Green
- `3` - Yellow
- `4` - Blue
- `5` - Magenta
- `6` - Cyan
- `7` - White
- `8-15` - Bright variants
**Colors 16-231:** 6×6×6 RGB cube (standardized)
- Formula: `16 + 36×R + 6×G + B` where R, G, B are 0-5
- Example: `39` = bright cyan, `196` = bright red
**Colors 232-255:** Grayscale ramp (standardized)
- `232` - Darkest gray
- `255` - Near white
Example usage:
```json
{
"vars": {
"gray": 242,
"brightCyan": 51,
"darkBlue": 18
},
"colors": {
"muted": "gray",
"accent": "brightCyan"
}
}
```
**Benefits:**
- Works everywhere (`TERM=xterm-256color`)
- No truecolor detection needed
- Standardized RGB cube (16-231) looks the same on all terminals
### Terminal Compatibility
Pi uses 24-bit RGB colors (`\x1b[38;2;R;G;Bm`). Most modern terminals support this:
- ✅ iTerm2, Alacritty, Kitty, WezTerm
- ✅ Windows Terminal
- ✅ VS Code integrated terminal
- ✅ Modern GNOME Terminal, Konsole
For older terminals with only 256-color support, Pi automatically falls back to the nearest 256-color approximation.
To check if your terminal supports truecolor:
```bash
echo $COLORTERM # Should output "truecolor" or "24bit"
```
## Example Themes
See the built-in themes for complete examples:
- [Dark theme](../src/themes/dark.json)
- [Light theme](../src/themes/light.json)
## Schema Validation
Themes are validated on load using [TypeBox](https://github.com/sinclairzx81/typebox) + [Ajv](https://ajv.js.org/).
Invalid themes will show an error with details about what's wrong:
```
Error loading theme 'my-theme':
- colors.accent: must be string or number
- colors.mdHeading: required property missing
```
For editor support, the JSON schema is available at:
```
https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json
```
Add to your theme file for auto-completion and validation:
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
...
}
```
## Implementation
### Theme Class
Themes are loaded and converted to a `Theme` class that provides type-safe color methods:
```typescript
class Theme {
// Apply foreground color
fg(color: ThemeColor, text: string): string
// Apply background color
bg(color: ThemeBg, text: string): string
// Text attributes (preserve current colors)
bold(text: string): string
italic(text: string): string
underline(text: string): string
}
```
### Global Theme Instance
The active theme is available as a global singleton in `coding-agent`:
```typescript
// theme.ts
export let theme: Theme;
export function setTheme(name: string) {
theme = loadTheme(name);
}
// Usage throughout coding-agent
import { theme } from './theme.js';
theme.fg('accent', 'Selected')
theme.bg('userMessageBg', content)
```
### TUI Component Theming
TUI components (like `Markdown`, `SelectList`, `Editor`) are in the `@mariozechner/pi-tui` package and don't have direct access to the theme. Instead, they define interfaces for the colors they need:
```typescript
// In @mariozechner/pi-tui
export interface MarkdownTheme {
heading: (text: string) => string;
link: (text: string) => string;
linkUrl: (text: string) => string;
code: (text: string) => string;
codeBlock: (text: string) => string;
codeBlockBorder: (text: string) => string;
quote: (text: string) => string;
quoteBorder: (text: string) => string;
hr: (text: string) => string;
listBullet: (text: string) => string;
bold: (text: string) => string;
italic: (text: string) => string;
strikethrough: (text: string) => string;
underline: (text: string) => string;
}
```
The `coding-agent` provides themed functions when creating components:
```typescript
// In coding-agent
import { theme } from './theme.js';
import { Markdown } from '@mariozechner/pi-tui';
// Helper to create markdown theme functions
function getMarkdownTheme(): MarkdownTheme {
return {
heading: (text) => theme.fg('mdHeading', text),
link: (text) => theme.fg('mdLink', text),
linkUrl: (text) => theme.fg('mdLinkUrl', text),
code: (text) => theme.fg('mdCode', text),
codeBlock: (text) => theme.fg('mdCodeBlock', text),
codeBlockBorder: (text) => theme.fg('mdCodeBlockBorder', text),
quote: (text) => theme.fg('mdQuote', text),
quoteBorder: (text) => theme.fg('mdQuoteBorder', text),
hr: (text) => theme.fg('mdHr', text),
listBullet: (text) => theme.fg('mdListBullet', text),
bold: (text) => theme.bold(text),
italic: (text) => theme.italic(text),
underline: (text) => theme.underline(text),
strikethrough: (text) => chalk.strikethrough(text),
};
}
// Create markdown with theme
const md = new Markdown(
text,
1, 1,
{ bgColor: theme.bg('userMessageBg') },
getMarkdownTheme()
);
```
This approach:
- Keeps TUI components theme-agnostic (reusable in other projects)
- Maintains type safety via interfaces
- Allows components to have sensible defaults if no theme provided
- Centralizes theme access in `coding-agent`
**Example usage:**
```typescript
const theme = loadTheme('dark');
// Apply foreground colors
theme.fg('accent', 'Selected')
theme.fg('success', '✓ Done')
theme.fg('error', 'Failed')
// Apply background colors
theme.bg('userMessageBg', content)
theme.bg('toolSuccessBg', output)
// Combine styles
theme.bold(theme.fg('accent', 'Title'))
theme.italic(theme.fg('muted', 'metadata'))
// Nested foreground + background
const userMsg = theme.bg('userMessageBg',
theme.fg('userMessageText', 'Hello')
)
```
**Color resolution:**
1. **Detect terminal capabilities:**
- Check `$COLORTERM` env var (`truecolor` or `24bit` → truecolor support)
- Check `$TERM` env var (`*-256color` → 256-color support)
- Fallback to 256-color mode if detection fails
2. **Load JSON theme file**
3. **Resolve `vars` references recursively:**
```json
{
"vars": {
"primary": "#0066cc",
"accent": "primary"
},
"colors": {
"accent": "accent" // → "primary" → "#0066cc"
}
}
```
4. **Convert colors to ANSI codes based on terminal capability:**
**Truecolor mode (24-bit):**
- Hex (`"#ff0000"`) → `\x1b[38;2;255;0;0m`
- 256-color (`42`) → `\x1b[38;5;42m` (keep as-is)
- Empty string (`""`) → `\x1b[39m`
**256-color mode:**
- Hex (`"#ff0000"`) → convert to nearest RGB cube color → `\x1b[38;5;196m`
- 256-color (`42`) → `\x1b[38;5;42m` (keep as-is)
- Empty string (`""`) → `\x1b[39m`
**Hex to 256-color conversion:**
```typescript
// Convert RGB to 6x6x6 cube (colors 16-231)
r_index = Math.round(r / 255 * 5)
g_index = Math.round(g / 255 * 5)
b_index = Math.round(b / 255 * 5)
color_index = 16 + 36 * r_index + 6 * g_index + b_index
```
5. **Cache as `Theme` instance**
This ensures themes work correctly regardless of terminal capabilities, with graceful degradation from truecolor to 256-color.

View file

@ -2,7 +2,17 @@
# Themes
Themes are JSON files that define colors for the TUI. You can select themes in `/settings` or via `settings.json`.
Themes are JSON files that define colors for the TUI.
## Table of Contents
- [Locations](#locations)
- [Selecting a Theme](#selecting-a-theme)
- [Creating a Custom Theme](#creating-a-custom-theme)
- [Theme Format](#theme-format)
- [Color Tokens](#color-tokens)
- [Color Values](#color-values)
- [Tips](#tips)
## Locations
@ -17,30 +27,269 @@ Pi loads themes from:
Disable discovery with `--no-themes`.
## Format
## Selecting a Theme
Themes use this structure:
Select a theme via `/settings` or in `settings.json`:
```json
{
"theme": "my-theme"
}
```
On first run, pi detects your terminal background and defaults to `dark` or `light`.
## Creating a Custom Theme
1. Create a theme file:
```bash
mkdir -p ~/.pi/agent/themes
vim ~/.pi/agent/themes/my-theme.json
```
2. Define the theme with all required colors (see [Color Tokens](#color-tokens)):
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
"name": "my-theme",
"vars": {
"accent": "#00aaff",
"muted": 242
"primary": "#00aaff",
"secondary": 242
},
"colors": {
"accent": "accent",
"muted": "muted",
"accent": "primary",
"border": "primary",
"borderAccent": "#00ffff",
"borderMuted": "secondary",
"success": "#00ff00",
"error": "#ff0000",
"warning": "#ffff00",
"muted": "secondary",
"dim": 240,
"text": "",
"thinkingText": "secondary",
"selectedBg": "#2d2d30",
"userMessageBg": "#2d2d30",
"toolSuccessBg": "#1e2e1e"
"userMessageText": "",
"customMessageBg": "#2d2d30",
"customMessageText": "",
"customMessageLabel": "primary",
"toolPendingBg": "#1e1e2e",
"toolSuccessBg": "#1e2e1e",
"toolErrorBg": "#2e1e1e",
"toolTitle": "primary",
"toolOutput": "",
"mdHeading": "#ffaa00",
"mdLink": "primary",
"mdLinkUrl": "secondary",
"mdCode": "#00ffff",
"mdCodeBlock": "",
"mdCodeBlockBorder": "secondary",
"mdQuote": "secondary",
"mdQuoteBorder": "secondary",
"mdHr": "secondary",
"mdListBullet": "#00ffff",
"toolDiffAdded": "#00ff00",
"toolDiffRemoved": "#ff0000",
"toolDiffContext": "secondary",
"syntaxComment": "secondary",
"syntaxKeyword": "primary",
"syntaxFunction": "#00aaff",
"syntaxVariable": "#ffaa00",
"syntaxString": "#00ff00",
"syntaxNumber": "#ff00ff",
"syntaxType": "#00aaff",
"syntaxOperator": "primary",
"syntaxPunctuation": "secondary",
"thinkingOff": "secondary",
"thinkingMinimal": "primary",
"thinkingLow": "#00aaff",
"thinkingMedium": "#00ffff",
"thinkingHigh": "#ff00ff",
"thinkingXhigh": "#ff0000",
"bashMode": "#ffaa00"
}
}
```
3. Select the theme via `/settings`.
**Hot reload:** When you edit the currently active custom theme file, pi reloads it automatically for immediate visual feedback.
## Theme Format
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",
"gray": 242
},
"colors": {
"accent": "blue",
"muted": "gray",
"text": "",
...
}
}
```
- `name` is required and must be unique.
- `vars` is optional. It lets you reuse colors.
- `colors` must define all required tokens.
- `vars` is optional. Define reusable colors here, then reference them in `colors`.
- `colors` must define all 50 required tokens.
See [theme.md](theme.md) for the full token list, color formats, and validation details.
The `$schema` field enables editor auto-completion and validation.
## Color Tokens
Every theme must define all 50 color tokens. There are no optional colors.
### Core UI (11 colors)
| Token | Purpose |
|-------|---------|
| `accent` | Primary accent (logo, selected items, cursor) |
| `border` | Normal borders |
| `borderAccent` | Highlighted borders |
| `borderMuted` | Subtle borders (editor) |
| `success` | Success states |
| `error` | Error states |
| `warning` | Warning states |
| `muted` | Secondary text |
| `dim` | Tertiary text |
| `text` | Default text (usually `""`) |
| `thinkingText` | Thinking block text |
### Backgrounds & Content (11 colors)
| Token | Purpose |
|-------|---------|
| `selectedBg` | Selected line background |
| `userMessageBg` | User message background |
| `userMessageText` | User message text |
| `customMessageBg` | Extension message background |
| `customMessageText` | Extension message text |
| `customMessageLabel` | Extension message label |
| `toolPendingBg` | Tool box (pending) |
| `toolSuccessBg` | Tool box (success) |
| `toolErrorBg` | Tool box (error) |
| `toolTitle` | Tool title |
| `toolOutput` | Tool output text |
### Markdown (10 colors)
| Token | Purpose |
|-------|---------|
| `mdHeading` | Headings |
| `mdLink` | Link text |
| `mdLinkUrl` | Link URL |
| `mdCode` | Inline code |
| `mdCodeBlock` | Code block content |
| `mdCodeBlockBorder` | Code block fences |
| `mdQuote` | Blockquote text |
| `mdQuoteBorder` | Blockquote border |
| `mdHr` | Horizontal rule |
| `mdListBullet` | List bullets |
### Tool Diffs (3 colors)
| Token | Purpose |
|-------|---------|
| `toolDiffAdded` | Added lines |
| `toolDiffRemoved` | Removed lines |
| `toolDiffContext` | Context lines |
### Syntax Highlighting (9 colors)
| Token | Purpose |
|-------|---------|
| `syntaxComment` | Comments |
| `syntaxKeyword` | Keywords |
| `syntaxFunction` | Function names |
| `syntaxVariable` | Variables |
| `syntaxString` | Strings |
| `syntaxNumber` | Numbers |
| `syntaxType` | Types |
| `syntaxOperator` | Operators |
| `syntaxPunctuation` | Punctuation |
### Thinking Level Borders (6 colors)
Editor border colors indicating thinking level (visual hierarchy from subtle to prominent):
| Token | Purpose |
|-------|---------|
| `thinkingOff` | Thinking off |
| `thinkingMinimal` | Minimal thinking |
| `thinkingLow` | Low thinking |
| `thinkingMedium` | Medium thinking |
| `thinkingHigh` | High thinking |
| `thinkingXhigh` | Extra high thinking |
### Bash Mode (1 color)
| Token | Purpose |
|-------|---------|
| `bashMode` | Editor border in bash mode (`!` prefix) |
### HTML Export (optional)
The `export` section controls colors for `/export` HTML output. If omitted, colors are derived from `userMessageBg`.
```json
{
"export": {
"pageBg": "#18181e",
"cardBg": "#1e1e24",
"infoBg": "#3c3728"
}
}
```
## Color Values
Four formats are supported:
| Format | Example | Description |
|--------|---------|-------------|
| Hex | `"#ff0000"` | 6-digit hex RGB |
| 256-color | `39` | xterm 256-color palette index (0-255) |
| Variable | `"primary"` | Reference to a `vars` entry |
| Default | `""` | Terminal's default color |
### 256-Color Palette
- `0-15`: Basic ANSI colors (terminal-dependent)
- `16-231`: 6×6×6 RGB cube (`16 + 36×R + 6×G + B` where R,G,B are 0-5)
- `232-255`: Grayscale ramp
### Terminal Compatibility
Pi uses 24-bit RGB colors. Most modern terminals support this (iTerm2, Kitty, WezTerm, Windows Terminal, VS Code). For older terminals with only 256-color support, pi falls back to the nearest approximation.
Check truecolor support:
```bash
echo $COLORTERM # Should output "truecolor" or "24bit"
```
## Tips
**Dark terminals:** Use bright, saturated colors with higher contrast.
**Light terminals:** Use darker, muted colors with lower contrast.
**Color harmony:** Start with a base palette (Nord, Gruvbox, Tokyo Night), define it in `vars`, and reference consistently.
**Testing:** Check your theme with different message types, tool states, markdown content, and long wrapped text.
**VS Code:** Set `terminal.integrated.minimumContrastRatio` to `1` for accurate colors.
## Examples
See the built-in themes:
- [dark.json](../src/modes/interactive/theme/dark.json)
- [light.json](../src/modes/interactive/theme/light.json)