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

# Themes

> A workspace's look is one design.md: prose agents follow and one CSS block every page renders with.

A workspace has one **design.md**: a few short paragraphs on how pages should look, and one \`\`\`css block. Every page in the workspace renders with that CSS, injected ahead of the page's own styles, so pages use its classes and variables. Saving design.md restyles every page; there are no versions to manage, and a save that carries a stale `fingerprint` is refused rather than overwriting someone else's edit.

| Tool                          | Scope             | Kind                      |
| ----------------------------- | ----------------- | ------------------------- |
| [`read_theme`](#read-theme)   | `documents:read`  | read-only                 |
| [`write_theme`](#write-theme) | `documents:write` | write, destructive, admin |

Admins edit design.md in **Settings → Artifact theme**, or click **Copy setup for agent** and paste the prompt into a coding agent open in their product's code. The agent installs the [`sidecars-themes` skill](/skills), reads the design from the codebase and saves design.md with `write_theme`.

## The format

````md theme={null}
# Design

Plain, calm and direct. A report opens with a masthead (the logo, then the
workspace name) and closes with "Made in Sidecars". Status goes in a .chip.
Never: gradients, drop shadows, emoji as icons.

```css
:root {
  --bg: #ffffff; --text: #1b1b1b; --muted: #585858; --good: #166456;
  --sans: ui-sans-serif, system-ui, sans-serif;
  --logo: url("data:image/svg+xml,%3Csvg …%3E");
}
:root[data-theme="dark"] { --bg: #1d1e20; --text: #f2f3f4; }
body { background: var(--bg); color: var(--text); font-family: var(--sans); }
.masthead { display: flex; align-items: center; gap: 10px; }
.logo { width: 44px; height: 23px; background: var(--logo) center/contain no-repeat; }
.chip { padding: 2px 8px; border-radius: 999px; font-size: 11px; }
```
````

* At most one css block. It may use `data:` URLs only (no `@import`, no external `url()`), up to 64 KB — put the logo in as an SVG data URL.
* The viewer sets `data-theme="dark"` on the page's root in dark mode, so a `:root[data-theme="dark"]` block themes dark mode.
* A css block that is refused still saves the file; pages keep the last good CSS until it is fixed.

## read\_theme

**Scope:** `documents:read` · **Kind:** read-only · **Annotations:** `readOnlyHint: true`, `destructiveHint: false`, `openWorldHint: false`

> Read the workspace's design.md: prose that says how pages should look,
> and one css block every page renders with (`css` is that block as pages
> get it). Call it before creating or rewriting a page, then use its
> classes and variables and follow its prose; do not restate a colour or
> font it already sets. `source: null` when the workspace has none — pages
> then render with only their own styles. Pass the returned `fingerprint`
> to write\_theme.

### Parameters

None.

### Returns

<ResponseField name="theme_id" type="string | null">The theme artifact's id, or `null` when the workspace has no design.md.</ResponseField>
<ResponseField name="url" type="string">The web-app link the theme opens at.</ResponseField>
<ResponseField name="source" type="string | null">design.md, verbatim.</ResponseField>
<ResponseField name="fingerprint" type="string">Pass it to `write_theme`; a save carrying a stale one is refused.</ResponseField>
<ResponseField name="css" type="string">The css every page renders with.</ResponseField>
<ResponseField name="compile_error" type="string">Present when the latest css block was refused; pages keep the last good css.</ResponseField>

## write\_theme

**Scope:** `documents:write` (step-up) · **Kind:** write, admin · **Annotations:** `readOnlyHint: false`, `destructiveHint: true`, `idempotentHint: true`, `openWorldHint: false`

> Replace the workspace's design.md with the whole file `source`, creating
> it if there is none. Admin only. Keep one css block; put the logo in it
> as an SVG data URL — the css may use data: URLs only, up to 64 KB.
> `fingerprint` is required: the one read\_theme returned; if the file changed since, the save
> is refused with the current file — merge your change onto it and save
> again. Every page restyles as soon as it saves. A css block that is refused still
> saves the file and reports `compile_error`; pages keep the last good css
> until it is fixed.

### Parameters

<ParamField body="source" type="string" required>The whole design.md.</ParamField>
<ParamField body="fingerprint" type="string" required>The `fingerprint` `read_theme` returned. If design.md changed since, the save is refused with `error: "design_changed"`, the current `source` and its `fingerprint` — merge and write again.</ParamField>

### Returns

<ResponseField name="theme_id" type="string" />

<ResponseField name="url" type="string" />

<ResponseField name="fingerprint" type="string">The saved file's fingerprint, for the next save.</ResponseField>
<ResponseField name="compile_error" type="string">Present when the css block was refused.</ResponseField>
