> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cowagent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Themes

> Switch built-in themes in the Web console and the desktop app, import theme packages, or let the Agent design your own colors, wallpaper and logo.

The Web console and the desktop app both support themes (skins). They share one themes folder, so a theme imported or generated in one is available in the other. A theme only describes colors, corner radius, fonts and a background wallpaper, never the UI layout, so themes keep working across updates.

## Switch Themes

* **Web console**: click the version number at the bottom-left and hover "Theme" in the menu to show the theme list
* **Desktop app**: open the "More" menu at the bottom-left and hover "Theme" to show the theme list

Click a theme to apply it. Themes are independent of light / dark mode, and every theme covers both.

Built-in color themes:

* **Meadow** (default): fresh green
* **Ocean**: ocean blue
* **Clay**: warm terracotta
* **Sakura**: cherry-blossom pink
* **Lavender**: lavender purple

## Import Themes

Click "Custom theme…" at the bottom of the theme list to open the custom theme dialog, then drag a theme `.zip` or theme folder onto it. You can also click it to browse instead (in the Windows app, pick the `theme.json` inside a folder to import that folder). The imported theme is applied right away.

On import CowAgent checks that:

* `theme.json` sits at the root of the package, or inside its single top-level folder
* Only `theme.json` and images (`jpg` / `png` / `webp` / `gif` / `svg`) are copied; other files are ignored
* Each file is at most 16MB and the whole theme at most 64MB
* An existing theme with the same ID is only replaced after you confirm; an ID taken by a built-in theme is renamed automatically

Imported themes live in `~/cow/system/themes/` (`system/themes/` under your Agent workspace if you moved it), one folder per theme; the custom theme dialog shows the path at the bottom. Delete a folder to remove a theme, or copy a theme folder in directly; it shows up the next time you open the theme list. In the desktop app, "Open themes folder" in that dialog opens it for you. When CowAgent runs on a server, the folder is on the machine running CowAgent.

> [!NOTE]
>
> The Web console does not support `shape` (corner radius, fonts) yet; colors, wallpapers and logos all work.

## Theme Structure

```
my-theme/
├── theme.json        # required
├── wallpaper.jpg     # optional background wallpaper
└── logo.png          # optional icon in the middle of the new-chat page
```

Example `theme.json`:

```json theme={null}
{
  "specVersion": 1,
  "id": "midnight-neon",
  "name": "Midnight Neon",
  "preview": { "accent": "#8b5cf6", "bg": "#f7f6fb", "surface": "#ffffff" },
  "shape": { "radiusCard": "14px", "radiusBtn": "10px" },
  "wallpaper": { "image": "wallpaper.jpg", "overlayOpacity": 0.25, "glass": true },
  "light": {
    "colors": {
      "accent": "#7c4dff",
      "accentSoft": "rgba(124, 77, 255, 0.10)",
      "bgBase": "#f7f6fb",
      "textPrimary": "#1f1b2e"
    }
  },
  "dark": {
    "colors": {
      "accent": "#8b5cf6",
      "accentSoft": "rgba(139, 92, 246, 0.18)",
      "bgBase": "#0d0b14",
      "bgSurface": "#151220",
      "textPrimary": "#f2effa"
    }
  }
}
```

| Field | Description |
| - | - |
| `id` | Unique theme ID; defaults to the folder name |
| `name` | Name shown in the theme list |
| `specVersion` | Theme spec version, currently `1` |
| `preview` | Swatch in the theme list: `accent` / `bg` / `surface`; derived from the colors when omitted |
| `shape` | Appearance-independent shape: `radiusCard`, `radiusBtn`, `radiusSm`, `fontSans`, `fontMono` |
| `wallpaper` | Background wallpaper shared by light and dark |
| `light` / `dark` | `colors` for that appearance, plus an optional `wallpaper` of its own |
| `identity.logo` | Icon in the middle of the new-chat page; a square image works best. A `logo.png` in the theme folder is used automatically, so set this only for a different file name |

### Colors

Values accept any CSS color (e.g. `#7c4dff`, `rgba(...)`). Keys you leave out fall back to the default theme, and unknown keys are ignored. If the colors make text hard to tell apart from its background, the default theme is used instead.

| Key | Used for |
| - | - |
| `accent` / `accentHover` / `accentActive` | Theme color and its hover / pressed states (buttons, selection, links) |
| `accentSoft` | Light accent fill (selected rows, tags) |
| `accentContrast` | Text drawn on the accent color |
| `bubbleUserBg` / `bubbleUserText` | User message bubble background and text |
| `bgBase` | App background |
| `bgSurface` / `bgSurface2` | Panels and cards, plus nested layers and hover fills |
| `bgElevated` | Menus and dialogs |
| `bgInset` / `bgInset2` | Inputs, plus nested fills such as code blocks |
| `textPrimary` / `textSecondary` / `textTertiary` / `textDisabled` | Four levels of text |
| `borderDefault` / `borderStrong` / `borderSubtle` | Three levels of borders |

### Wallpaper

One wallpaper is enough: set it at the top level and both light and dark use it. To give each appearance its own image, set `wallpaper` under `light` / `dark`; those take precedence. If only one appearance sets a wallpaper, the other reuses it, and a `wallpaper.jpg` in the theme folder is used automatically when none is set anywhere.

For different wallpapers per appearance, drop the top-level `wallpaper` and set one under each of `light` / `dark`:

```json theme={null}
{
  "light": {
    "colors": { "...": "..." },
    "wallpaper": { "image": "wallpaper-light.jpg", "glass": true }
  },
  "dark": {
    "colors": { "...": "..." },
    "wallpaper": { "image": "wallpaper-dark.jpg", "glass": true }
  }
}
```

| Key | Description |
| - | - |
| `image` | Image path inside the theme folder |
| `focusX` / `focusY` | Focal point (0–1) kept in view as the window resizes; default `0.5` |
| `overlayOpacity` | Scrim strength over the image (0–1) for readable text; defaults to `0.4` light, `0.3` dark. Tune it if the wallpaper looks too dark or too busy |
| `glass` | When `true`, panels turn translucent frosted glass so the wallpaper shows through the whole UI |

## Let the Agent Create a Theme

The Agent can build a theme for you. It writes the theme to `~/cow/system/themes/`, and if image generation is configured it can generate the wallpaper and logo too.

The quickest way is the "Start" button next to "Let the Agent create one" in the custom theme dialog: it opens a new chat with the prompt filled in, so you only add the style you want at the end and send it. You can also attach reference images (a character or scene you like), and the Agent will base the wallpaper and logo on them.

You can also send the prompt below in any chat, with the style you want on the last line. To fine-tune afterwards, such as "make the wallpaper brighter" or "switch the accent to teal", just tell the Agent; reopen the theme list to see the change.

```text theme={null}
Create a theme for this app.

Requirements:
1. Create theme.json in ~/cow/system/themes/<theme-id>/ with a lowercase, hyphenated id, shaped like {"specVersion": 1, "id", "name", "light": {"colors": {...}}, "dark": {"colors": {...}}}.
2. Fill these keys in both light and dark colors: accent, accentHover, accentActive, accentSoft, accentContrast, bubbleUserBg, bubbleUserText, bgBase, bgSurface, bgSurface2, bgElevated, bgInset, bgInset2, textPrimary, textSecondary, textTertiary, textDisabled, borderDefault, borderStrong, borderSubtle. Keep backgrounds low-saturation, text easy to read, and white text on the accent legible.
3. If you can generate images, use an image generation skill to make two images without text in the same folder:
   - wallpaper.jpg: a 16:9 wallpaper with the subject toward the right, moderately bright rather than dark; add "wallpaper": {"image": "wallpaper.jpg", "overlayOpacity": 0.25, "glass": true} at the top level of theme.json, shared by both appearances. If I ask for different wallpapers per appearance, generate wallpaper-light.jpg and wallpaper-dark.jpg instead, skip the top-level wallpaper, and add a wallpaper to light and to dark pointing to each image
   - logo.png: square, used as the icon in the middle of the new-chat page (not the app icon); just put it in the folder, no need to add it to theme.json
4. If I attached reference images, pass them to the image generation as input images so the characters and art style match them, and take the colors from them too.
5. Check that theme.json is valid JSON, then tell me the theme name.

The style I want: <e.g. "cyberpunk city at night, neon purple and cyan">
```

Then open the theme list at the bottom-left to find and apply the new theme. To share it, zip the theme folder and send it; others can drop it onto the "Custom theme" dialog.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.