ThemeConfig Structure
Every PaperDocument can include an optional theme field of type ThemeConfig. The theme controls how scheme color tokens and font references resolve throughout the entire document.
interface ThemeConfig {
name?: string;
colorScheme?: ThemeColorScheme;
fontScheme?: ThemeFontScheme;
}
When no theme is provided, the engine uses OOXML defaults (Office-standard colors and Calibri fonts).
Color Scheme Tokens
The ThemeColorScheme interface defines 12 named slots that map to ECMA-376 theme color tokens:
interface ThemeColorScheme {
dk1?: string; // Dark 1 — typically near-black for body text
lt1?: string; // Light 1 — typically white for backgrounds
dk2?: string; // Dark 2 — secondary dark
lt2?: string; // Light 2 — secondary light / off-white
accent1?: string; // Primary brand accent
accent2?: string;
accent3?: string;
accent4?: string;
accent5?: string;
accent6?: string;
hlink?: string; // Hyperlink color
folHlink?: string; // Followed hyperlink color
}
All values are 6-digit hex strings (e.g., "#2563EB").
Example Color Scheme
{
"colorScheme": {
"dk1": "#0F2540",
"lt1": "#FFFFFF",
"dk2": "#1B3A5C",
"lt2": "#F8FAFC",
"accent1": "#2563EB",
"accent2": "#059669",
"accent3": "#7C3AED",
"accent4": "#EA580C",
"accent5": "#DC2626",
"accent6": "#0891B2",
"hlink": "#2563EB",
"folHlink": "#7C3AED"
}
}
Font Scheme
The ThemeFontScheme defines heading and body typefaces:
interface ThemeFontScheme {
majorLatin?: string; // Headings — e.g., "Aptos Display"
minorLatin?: string; // Body text — e.g., "Aptos"
majorEa?: string; // East Asian heading font
minorEa?: string; // East Asian body font
}
When a node does not specify an explicit fontFamily, the engine resolves to minorLatin for body text and majorLatin for heading-level placeholder text.
Using Scheme Tokens in Nodes
Any ColorValue property can reference a scheme token by name instead of a hex literal:
{
"type": "Text",
"style": {
"color": "accent1",
"backgroundColor": "lt2"
},
"content": "Themed text"
}
This makes the output portable: changing the theme recolors every element that uses tokens without editing individual nodes.
Color Modifiers
For derived colors (lighter tints, darker shades), use a ColorModifier object instead of a plain string:
interface ColorModifier {
scheme: string; // "accent1", "dk1", "lt1", etc.
tint?: number; // 0-100 (percentage white mixed in)
shade?: number; // 0-100 (percentage black mixed in)
lumMod?: number; // Luminance modulation (percentage)
lumOff?: number; // Luminance offset (0-100)
satMod?: number; // Saturation modulation (0-200+)
satOff?: number; // Saturation offset
hueMod?: number; // Hue modulation
hueOff?: number; // Hue offset (degrees * 60000 for OOXML)
comp?: boolean; // Complement color
inv?: boolean; // Inverse color
gray?: boolean; // Convert to grayscale
}
Common Modifier Patterns
// Light tint of the primary accent (40% white)
{ "scheme": "accent1", "tint": 40 }
// Darkened accent (30% black)
{ "scheme": "accent1", "shade": 30 }
// Desaturated dark color at 75% luminance
{ "scheme": "dk1", "lumMod": 75, "satMod": 50 }
// Complementary color
{ "scheme": "accent1", "comp": true }
Theme Cascading
Themes cascade from the document level to all child elements:
PaperDocument.themesets the document-level defaults- Template themes (from
.potxfiles onPaperDocument.template) merge with and can override document-level theme values - Individual node
style.colororstyle.backgroundColorproperties override the cascade
When using scheme tokens, the final resolved hex depends on the active theme at render time. This is what makes decks rebrandable: swap the colorScheme and all token-referencing elements update.
Hosted API: accentColor
When using the V2 API with PresentationSpec, the accentColor field sets accent1 in the generated theme:
{
"version": "2.0",
"title": "Brand Deck",
"accentColor": "#2563EB",
"slides": [...]
}
The protocol compiler generates a full ThemeConfig with the provided accent as accent1 and derives complementary slots for the remaining accents. For full control over all 12 color slots, use the raw PaperDocument format with an explicit theme field.
Full Theme Example
{
"type": "Document",
"meta": { "title": "Themed Deck" },
"theme": {
"name": "Corporate Brand",
"colorScheme": {
"dk1": "#0F172A",
"lt1": "#FFFFFF",
"dk2": "#1E293B",
"lt2": "#F1F5F9",
"accent1": "#2563EB",
"accent2": "#059669",
"accent3": "#7C3AED",
"accent4": "#EA580C",
"accent5": "#DC2626",
"accent6": "#0891B2",
"hlink": "#2563EB",
"folHlink": "#6366F1"
},
"fontScheme": {
"majorLatin": "Aptos Display",
"minorLatin": "Aptos"
}
},
"slides": [
{
"type": "Slide",
"children": [
{
"type": "View",
"style": {
"position": "absolute",
"left": 60, "top": 100, "width": 300, "height": 80,
"backgroundColor": { "scheme": "accent1", "tint": 20 },
"borderColor": "accent1",
"borderWidth": 1
},
"children": [
{ "type": "Text", "style": { "color": "dk1", "fontSize": 14, "padding": 16 }, "content": "Tinted card" }
]
}
]
}
]
}