# Design and theme

> The theme of a trulyform form: colors, the contrast every form must pass, font, corner radius, spacing, images and the logo, with palettes that work.

## What you need to know

- The theme sets the colors, font, corner radius and spacing of the whole form.
- Text must contrast at least 4.5:1 with the background, and button text with the button color. Otherwise the form cannot be published.
- Images and logos are uploaded in the trulyform editor, not over MCP. Keep every asset ID that `get_form` returns, and use `null` for new questions.
- A custom logo needs the Business plan.

## Theme fields

| Field | Notes |
| --- | --- |
| `preset` | Name of the starting theme, up to 40 characters, such as `paper`, `midnight` or `warm` from the editor. Any name is accepted, and it does not change the colors below. |
| `background` | Page background, as #RRGGBB. |
| `foreground` | Text color, as #RRGGBB. Needs a 4.5:1 contrast ratio with background. |
| `primary` | Button and accent color, as #RRGGBB. |
| `buttonText` | Text on buttons, as #RRGGBB. Needs a 4.5:1 contrast ratio with primary. |
| `font` | One of: `Inter`, `Georgia`, `system-ui`. |
| `radius` | Corner radius in pixels, a whole number from 0 to 24. |
| `density` | One of: `comfortable`, `compact`. |
| `logoAssetId` | An uploaded logo, or null. Keep the value get_form returns; assets cannot be uploaded over MCP. |
| `backgroundAssetId` | An uploaded background image, or null. Keep the value get_form returns. |

## Readable colors

trulyform checks two pairs before publishing: `foreground` on `background`, and `buttonText` on `primary`. Each needs a contrast ratio of at least 4.5:1, the WCAG AA level for normal text. Dark text on a light background passes, and so does white text on a saturated, fairly dark button color.

These palettes come from the [worked examples](https://trulyform.com/docs/examples.md), which all pass:

- **Workshop registration:** background `#fffaf3`, foreground `#1f2933`, primary `#c2410c`, buttonText `#ffffff`, font `Inter`, radius 12, density `comfortable`.
- **Customer feedback:** background `#f5f7ff`, foreground `#111827`, primary `#4338ca`, buttonText `#ffffff`, font `Inter`, radius 16, density `comfortable`.
- **Job application:** background `#ffffff`, foreground `#0f172a`, primary `#047857`, buttonText `#ffffff`, font `Georgia`, radius 4, density `compact`.
- **Contact request:** background `#ffffff`, foreground `#111827`, primary `#2563eb`, buttonText `#ffffff`, font `Inter`, radius 12, density `comfortable`.

## Images

`mediaDefaults` holds the form-wide image, and each question's `media` says whether it uses that image or its own:

- `mediaDefaults`: `{assetId, layout, altText}`. `layout` is `above`, `side` or `background`.
- A question's `media`: `{inherit, assetId, layout}`. With `"inherit": true` the question uses the form-wide image. With `false`, it uses its own `assetId`, and its `imageAlt` setting describes the image.

Over MCP:

- Keep `mediaDefaults` and existing `media` values exactly as `get_form` returns them.
- Give new questions `{"inherit": true, "assetId": null, "layout": "above"}`.
- Never invent an `assetId`. An asset ID that does not belong to the form makes the save fail.

## Logo

`theme.logoAssetId` shows a logo on the form. Adding or replacing a logo needs the Business plan, and new forms in a Business organization may already start with the organization's logo. Keep the value `get_form` returns.


---

Previous: [Calculations and piping](https://trulyform.com/docs/calculations-and-piping.md) · Next: [Examples](https://trulyform.com/docs/examples.md)

All pages: https://trulyform.com/llms.txt. Connected over MCP? Call read_docs with a page name instead.
