# Create a custom Qesh theme

## Desktop theme

Open Configure. Replace the `theme` object with a palette below, save, and open a new window. No named theme selector is built into version 0.4.0; these are copyable examples.

### Dark charcoal

```json
{
  "theme": {
    "background": "#0e0d11",
    "surface": "#141318",
    "foreground": "#d4d4d4",
    "muted": "#a09ca8",
    "border": "#45414e",
    "primary": "#9cdcfe",
    "error": "#f48771",
    "selection": "#264f78"
  }
}
```

### Warm graphite

```json
{
  "theme": {
    "background": "#151311",
    "surface": "#211e1a",
    "foreground": "#e8e1d7",
    "muted": "#afa69a",
    "border": "#514b43",
    "primary": "#d8b47a",
    "error": "#ff9b8f",
    "selection": "#514638"
  }
}
```

Merge the theme object into your existing configuration if you want to retain other settings.

## What the colors affect

| Key | Use |
| --- | --- |
| `background` | Terminal background |
| `surface` | Workspace surfaces |
| `foreground` | Default text |
| `muted` | Secondary labels |
| `border` | Dividers and control outlines |
| `primary` | Accent and focused controls |
| `error` | Error state |
| `selection` | Selected text background |

Qesh uses a fixed VS Code-style 16-color ANSI palette. Programs can emit their own true-color output. Changing `primary` does not recolor every shell command or syntax token.

## CLI theme

`qh` loads theme colors from the global configuration. To temporarily override them, use the legacy `q-terminal` launch path with the environment example below.

From your cloned repository, launch with a JSON environment variable:

```sh
QENTRAH_THEME='{"background":"#151311","surface":"#211e1a","foreground":"#e8e1d7","primary":"#d8b47a","selection":"#514638"}' ./bin/q-terminal
```

Omitted colors keep their defaults. Invalid JSON or invalid color values are ignored by the CLI theme loader. Exit and relaunch the CLI to change its palette.

## Check a palette

Before using a full desktop configuration, validate a saved file from the repository:

```sh
node -e 'const fs=require("node:fs"); const config=require("./desktop/config.cjs"); config.validate(JSON.parse(fs.readFileSync(process.argv[1],"utf8"))); console.log("Configuration valid")' ./qesh.config.json
```

Expect `Configuration valid`. A validation error names the setting to correct. The loader merges omitted fields with defaults.
