# Deck format

> Reference for the Live Deck deck.json format v1: deck, theme presets, slides, backgrounds and validation messages, with every rule and limit.

Source of truth: `shared/deck.ts`. Every object is strict: unknown keys fail validation.

## Deck

| Field | Type | Rules |
| --- | --- | --- |
| `version` | `1` | Required, literal 1. |
| `title` | string | Required, 1–200 chars. Shown in lists and the summary. |
| `theme` | object | Optional. Default `{ background: "#10131a", foreground: "#f4f1ea", accent: "#ff7a45", muted: "#9aa3b2" }`. Prefer `{ "preset": "<name>" }`. |
| `slides` | Slide[] | Required, 1–200. Slide ids unique. |

## Theme

Colors are hex: `#` + 3–8 hex digits.

| Field | Type | Rules |
| --- | --- | --- |
| `preset` | `"estudio"` \| `"editorial"` \| `"neon"` \| `"papel"` \| `"brutalista"` \| `"corporativo"` | Optional. Brings colors, fonts (display/body/mono), slide background (gradient and/or pattern), card style, heading style and chart palette. See `themes.md`. |
| `background` | hex | Required without `preset`; optional override with one. |
| `foreground` | hex | Required without `preset`; optional override with one. |
| `accent` | hex | Required without `preset`; optional override with one. |
| `muted` | hex | Optional. |
| `surface` | hex | Optional. Overrides the card/surface color (cards, `card: true` text, donut gaps). |

- With a preset, override colors only when the user's brand requires it: `{ "preset": "corporativo", "accent": "#0057b8" }`.
- Without a preset the old rules hold exactly: `background`, `foreground`, `accent` required, `muted` optional.

## Slide

| Field | Type | Rules |
| --- | --- | --- |
| `id` | string | Required, `[A-Za-z0-9_-]{1,40}`, unique in the deck. |
| `layout` | `"free"` \| `"quiz"` | Optional, default free. `"quiz"` requires `quiz`, and `quiz` requires `"quiz"`. |
| `background` | hex \| Background | Optional, overrides the theme background. See below. |
| `notes` | string | Optional (always set it), max 5000 chars. Presenter-only; never sent to the audience. |
| `elements` | Element[] | Required (use `[]` on quiz slides), max 60. Element ids unique per slide. |
| `quiz` | Quiz | Only with `layout: "quiz"`. |

### Slide background object

A hex string still works (`"background": "#0b0d12"`). The object form (all fields optional, strict):

| Field | Type | Rules |
| --- | --- | --- |
| `color` | hex | Solid base color. |
| `gradient` | `{ "from": hex, "to": hex, "angle"?: number }` | Linear gradient; `angle` 0–360 (degrees). |
| `image` | asset src | Same rules as image `src` (`https://…` or `assets/<file>`, no `..`). Covers the slide. |
| `dim` | number 0–0.9 | Darkens the image so text stays readable. Use 0.4–0.6 under text. |
| `pattern` | `"dots"` \| `"grid"` \| `"lines"` \| `"noise"` | Subtle texture over the color/gradient. |

```json
{ "background": { "gradient": { "from": "#1b1f3a", "to": "#0b0d12", "angle": 135 }, "pattern": "dots" } }
```

Omit `background` on most slides: the preset already supplies one. Use the object for openers, section breaks and closings.

Imported slides (`live-deck import`) use exactly this field: `"background": { "image": "assets/slide-01.png" }` with no new layout; elements such as the join `qr` may sit on top.

## Validation messages

The CLI prints `path: message`, where path indexes into the JSON (`slides.2.quiz.correctIndex: correctIndex must point to an option`). Fix at that path and re-run.
