Theme Schema
The theme.json file defines your brand's visual identity for slide generation. It is located at .slide-builder/theme.json and is created by the /pitchsmith:setup command.
This reference documents every section and field in the theme schema.
March 2026 — verified against pitchsmith-plugin/reference/theme-schema.md in the Pitch Smith source.
Root Structure
{
"name": "string",
"version": "string",
"colors": { },
"typography": { },
"shapes": { },
"components": { },
"slides": { },
"gradients": { },
"workflowRules": { },
"personality": { },
"meta": { },
"brandContext": { }
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Theme display name |
version | string | Yes | Theme version identifier |
colors | object | Yes | Color palette definitions |
typography | object | Yes | Font and text scale definitions |
shapes | object | Yes | Border radius, shadow, and border definitions |
components | object | Yes | Component style presets (can be empty {}) |
slides | object | No | Slide dimension and layout definitions |
gradients | object | No | Named gradient definitions |
workflowRules | object | No | Workflow-specific generation rules |
personality | object | No | Brand personality classification and traits |
meta | object | No | Extraction metadata and lock state |
brandContext | object | No | Unstructured brand context data |
colors
Defines the complete color palette used across all generated slides.
{
"colors": {
"primary": "#1E40AF",
"secondary": "#0D9488",
"accent": "#F59E0B",
"background": {
"default": "#FFFFFF",
"alt": "#F3F4F6",
"dark": "#111827",
"light": "#F9FAFB",
"darkAlt": "#1F2937"
},
"text": {
"heading": "#111827",
"body": "#374151",
"muted": "#6B7280",
"onDark": "#F9FAFB",
"onLight": "#111827",
"onPrimary": "#FFFFFF"
},
"brand": { },
"dataViz": {
"palette": ["#3B82F6", "#10B981", "#F59E0B"],
"positive": "#10B981",
"negative": "#EF4444"
},
"semantic": { }
}
}
| Field | Type | Required | Description |
|---|---|---|---|
primary | hex color | Yes | Main brand color |
secondary | hex color | Yes | Supporting brand color |
accent | hex color | Yes | Highlight / CTA color |
background.default | hex color | Yes | Main background |
background.alt | hex color | Yes | Alternate background |
background.dark | hex color | No | Dark background variant |
background.light | hex color | No | Light background variant |
background.darkAlt | hex color | No | Alternate dark background |
text.heading | hex color | Yes | Heading text color |
text.body | hex color | Yes | Body text color |
text.muted | hex color | No | Secondary / muted text color |
text.onDark | hex color | No | Text color for dark backgrounds |
text.onLight | hex color | No | Text color for light backgrounds |
text.onPrimary | hex color | No | Text color on primary background |
brand | object | No | Additional brand color tokens |
dataViz | object | No | Chart and graph colors |
dataViz.palette | array | No | Chart / graph color palette |
dataViz.positive | hex color | No | Positive indicator color |
dataViz.negative | hex color | No | Negative indicator color |
semantic | object | No | Semantic color tokens (success, warning, error, info) |
typography
Defines font families, size scales, weights, and line heights.
{
"typography": {
"fonts": {
"heading": "Inter, system-ui, sans-serif",
"body": "Source Sans Pro, system-ui, sans-serif",
"mono": "JetBrains Mono, monospace"
},
"scale": {
"hero": "72px",
"h1": "48px",
"h2": "36px",
"h3": "28px",
"body": "18px",
"caption": "14px"
},
"weights": {
"light": 300,
"regular": 400,
"semibold": 600,
"bold": 700
},
"lineHeight": {
"tight": 1.2,
"normal": 1.5,
"relaxed": 1.8
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
fonts.heading | CSS font-family | Yes | Heading font stack |
fonts.body | CSS font-family | Yes | Body font stack |
fonts.mono | CSS font-family | No | Monospace font stack |
scale.hero | CSS size | Yes | Largest display size |
scale.h1 | CSS size | Yes | Primary heading |
scale.h2 | CSS size | Yes | Secondary heading |
scale.h3 | CSS size | Yes | Tertiary heading |
scale.body | CSS size | Yes | Body text |
scale.caption | CSS size | Yes | Small text / captions |
weights.* | number | Yes (at least one) | Font weight values |
lineHeight | object | No | Line height scale |
shapes
Defines border radius, box shadow, and border style scales.
{
"shapes": {
"borderRadius": {
"none": "0",
"small": "4px",
"medium": "8px",
"large": "16px",
"full": "9999px"
},
"shadow": {
"small": "0 1px 2px rgba(0,0,0,0.05)",
"medium": "0 4px 6px rgba(0,0,0,0.1)",
"large": "0 10px 15px rgba(0,0,0,0.15)"
},
"border": {
"thin": "1px solid #E5E7EB",
"medium": "2px solid #D1D5DB"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
borderRadius | object | Yes (at least one entry) | Border radius scale |
borderRadius.none | string | No | No rounding (typically "0") |
borderRadius.small | string | No | Small rounding |
borderRadius.medium | string | No | Medium rounding |
borderRadius.large | string | No | Large rounding |
borderRadius.full | string | No | Full rounding (circle / pill) |
shadow | object | Yes (at least one entry) | Box shadow scale |
shadow.small | string | No | Subtle shadow |
shadow.medium | string | No | Medium shadow |
shadow.large | string | No | Prominent shadow |
border | object | Yes (at least one entry) | Border style scale |
border.thin | string | No | Thin border |
border.medium | string | No | Medium border |
components
Defines style presets for reusable slide components. This section can be an empty object {} if no component presets are needed.
{
"components": {
"box": {
"default": { "background": "#F3F4F6", "border": "1px solid #E5E7EB", "radius": "8px" },
"outlined": { "background": "transparent", "border": "2px solid #1E40AF", "radius": "8px" },
"callout": { "background": "#EFF6FF", "border": "none", "radius": "12px" }
},
"arrow": {
"default": { "color": "#6B7280", "strokeWidth": "2px" }
},
"button": {
"primary": { "background": "#1E40AF", "color": "#FFFFFF", "radius": "8px" },
"secondary": { "background": "transparent", "color": "#1E40AF", "radius": "8px" }
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
components | object | Yes (can be {}) | Component style presets |
box | object | No | Box / container component styles |
arrow | object | No | Arrow / connector component styles |
icon | object | No | Icon component styles |
button | object | No | Button component styles |
Each component type can have multiple named variants (e.g., default, outlined, primary).
slides
Defines slide dimensions and named layout definitions.
{
"slides": {
"dimensions": {
"width": 1920,
"height": 1080,
"aspectRatio": "16:9"
},
"layouts": {
"title": { },
"content": { },
"split": { },
"data": { }
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
slides | object | No | Slide configuration |
dimensions | object | No | Slide dimensions |
dimensions.width | number | No | Slide width in pixels |
dimensions.height | number | No | Slide height in pixels |
dimensions.aspectRatio | string | No | Display aspect ratio (e.g., "16:9") |
layouts | object | No | Named layout definitions |
gradients
Defines named gradient values that can be referenced in slide generation.
{
"gradients": {
"brandFade": "linear-gradient(135deg, #1E40AF 0%, #0D9488 100%)",
"darkOverlay": "linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.7) 100%)",
"lightAccent": "linear-gradient(90deg, #F3F4F6 0%, #EFF6FF 100%)"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
gradients | object | No | Named gradient definitions |
gradients.* | CSS gradient | No | Any named gradient value |
workflowRules
Defines rules that influence how AI workflows generate slides. These rules provide constraints and preferences for the generation process.
{
"workflowRules": {
"maxBulletsPerSlide": 4,
"preferDarkMode": false,
"defaultTone": "professional",
"alwaysIncludeTagline": true
}
}
| Field | Type | Required | Description |
|---|---|---|---|
workflowRules | object | No | Workflow-specific generation rules |
This is a flexible object. Any key-value pairs are accepted and consumed by workflows during slide generation.
personality
Classifies the brand personality to guide tone and style decisions during slide generation.
{
"personality": {
"classification": "bold",
"traits": ["innovative", "confident", "forward-thinking"],
"guidance": {
"do": ["Use strong action verbs", "Lead with data"],
"dont": ["Avoid passive voice", "Skip generic stock imagery"]
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
personality | object | No | Brand personality profile |
classification | enum | No | Primary personality type: bold, minimal, playful, or corporate |
traits | array | No | Descriptive characteristics |
guidance.do | array | No | Recommended design and content approaches |
guidance.dont | array | No | Approaches to avoid |
meta
Stores metadata about how the theme was created, including extraction sources and confidence levels.
{
"meta": {
"extractedFrom": {
"website": "https://example.com",
"reference": "Brand guidelines PDF"
},
"brandDescription": "Enterprise SaaS platform for customer engagement",
"confidence": 0.85,
"locked": false,
"changeNotes": [
"Initial extraction from website",
"Adjusted typography per user feedback"
]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
meta | object | No | Theme extraction metadata |
extractedFrom.website | URL | No | Source website used for extraction |
extractedFrom.reference | string | No | Other source references |
brandDescription | string | No | Brief brand summary |
confidence | number (0-1) | No | Extraction confidence score |
locked | boolean | No | When true, prevents automated modifications |
changeNotes | array | No | History of changes to the theme |
brandContext
Stores unstructured brand context data that informs AI-driven slide generation. This is an open-ended object — any keys and value types are accepted.
{
"brandContext": {
"voice": "Professional but approachable",
"designPhilosophy": "Clean, modern minimalism with strategic accent color use",
"colorUsage": "Primary blue for headlines and CTAs only. Secondary teal for data accents.",
"typographyNotes": "Inter for headings, Source Sans Pro for body text.",
"customInstructions": [
"Always include the company tagline on title slides",
"Limit bullet points to 4 per slide maximum"
]
}
}
| Field | Type | Required | Description |
|---|---|---|---|
brandContext | object | No | Unstructured brand context data |
voice | string | No | Brand voice and tone description |
designPhilosophy | string | No | Core design principles and visual approach |
colorUsage | string or object | No | Guidelines for brand color usage |
typographyNotes | string | No | Typography choices, pairing rationale, and usage guidelines |
customInstructions | string or array | No | Additional AI instructions for brand-aware slide generation |
The fields listed above are common conventions but are not enforced by the schema. Custom keys are fully supported.
How brandContext is populated: Brand context data is typically generated during the /pitchsmith:setup workflow, where brand assets and user input are analyzed. It can also be manually edited in the theme.json file.
How brandContext is consumed: Slide generation workflows use brand context fields to produce brand-aware content, ensuring consistent voice, color usage, and design alignment across generated presentations.
Complete theme.json example
{
"name": "Acme Corp",
"version": "1.0.0",
"colors": {
"primary": "#1E40AF",
"secondary": "#0D9488",
"accent": "#F59E0B",
"background": {
"default": "#FFFFFF",
"alt": "#F3F4F6",
"dark": "#111827",
"light": "#F9FAFB",
"darkAlt": "#1F2937"
},
"text": {
"heading": "#111827",
"body": "#374151",
"muted": "#6B7280",
"onDark": "#F9FAFB",
"onPrimary": "#FFFFFF"
}
},
"typography": {
"fonts": {
"heading": "Inter, system-ui, sans-serif",
"body": "Source Sans Pro, system-ui, sans-serif"
},
"scale": {
"hero": "72px",
"h1": "48px",
"h2": "36px",
"h3": "28px",
"body": "18px",
"caption": "14px"
},
"weights": {
"regular": 400,
"semibold": 600,
"bold": 700
}
},
"shapes": {
"borderRadius": {
"small": "4px",
"medium": "8px",
"large": "16px"
},
"shadow": {
"small": "0 1px 2px rgba(0,0,0,0.05)",
"medium": "0 4px 6px rgba(0,0,0,0.1)"
},
"border": {
"thin": "1px solid #E5E7EB"
}
},
"components": {},
"personality": {
"classification": "corporate",
"traits": ["professional", "trustworthy", "modern"],
"guidance": {
"do": ["Use data to support claims", "Maintain visual hierarchy"],
"dont": ["Avoid overly casual language", "Skip decorative elements"]
}
},
"brandContext": {
"voice": "Professional but approachable. Use active voice.",
"designPhilosophy": "Clean minimalism with strategic use of brand blue."
}
}