OPF
SpecAuthoring schema referenceView source

Theme

Schema for theme records. Each theme is a small, named bundle that pairs a color scheme, a font scheme, a default theme-controlled background, and a slide size. Documents reference a theme from design.theme; design.colorScheme, design.fontScheme, design.background and design.dimensions take precedence over the resolved theme. The theme's own colorScheme and fontScheme references resolve in the theme's group first, so a catalog's theme finds that catalog's schemes. A document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.

Schema $id
https://openpresentation.org/schema/opf-theme/v1
Type
object
Source
spec/schemas/theme.schema.json
Fields
13 · 3 required

Field index

FieldTypeReq.DefaultDescription
$schemaconstyes—Identifies a published record file as a theme record. Required in a published file; an embedded copy omits it.
$schema · Allowed values
"https://openpresentation.org/schema/opf-theme/v1"
idstringyes—The theme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.
namestringyes—Human-readable theme name shown in pickers.
summarystring——One-sentence positioning of the theme — when to reach for it.
descriptionstring——Longer prose describing what the theme looks and feels like and the kinds of decks it suits.
colorSchemestring——The theme's default colour scheme: a reference (a bare id or 'name:id') resolved like design.colorScheme, but in the theme's own catalogs group first.
fontSchemestring——The theme's default font scheme: a reference (a bare id or 'name:id') resolved like design.fontScheme, but in the theme's own catalogs group first.
backgroundref:ThemeBackground——
variantsarray<ref:ThemeVariant>——The color variants the theme offers (OPF 0.23), for example light, light-alt, dark and dark-alt: named values of design.variant over the theme's one color scheme, so a dark deck is a variant of a theme and not a theme of its own. A picker lists them by name; choosing one sets design.variant (or a slide's design.variant) to the entry's 'variant'. A document stores that value and never the id, so a variant needs no record and the theme does not change when its variants do. The entry ids are unique within a theme.
dimensionsenum——Default slide size for this theme. Accepts the same preset values as design.dimensions.preset.
dimensions · Allowed values
"16:9""4:3""16:10""1:1""4:5""9:16""letter""a4""widescreen""standard"
designobject——The theme's design defaults (OPF 0.19), so a house style such as boxed content or centred titles is set once: the keys and values of the deck's design for titleAlignment, contentAlignment, contentBox, contentDirection, imageFit and listBullet. Per key the slide's design wins, then the deck's design, then this, then the layout record's design, then the engine default.
tagsarray<string>——Free-form labels for filtering and search.
previewobject——Visual previews of the record, used by picker UIs and inline rendering. All sub-fields are optional; engines fall back gracefully when previews aren't available.

$schema

typeconstrequiredyesdefault—

Identifies a published record file as a theme record. Required in a published file; an embedded copy omits it.

$schema · Allowed values
"https://openpresentation.org/schema/opf-theme/v1"
$schema.json
{
  "$schema": "https://openpresentation.org/schema/opf-theme/v1"
}

id

typestringrequiredyesdefault—pattern^[a-z][a-z0-9-]*$

The theme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.

id.json
{
  "id": "minimal"
}

name

typestringrequiredyesdefault—

Human-readable theme name shown in pickers.

name.json
{
  "name": "Minimal"
}

summary

typestringrequirednodefault—

One-sentence positioning of the theme — when to reach for it.

summary.json
{
  "summary": "A clean, minimalist theme for professional, straightforward presentations."
}

description

typestringrequirednodefault—

Longer prose describing what the theme looks and feels like and the kinds of decks it suits.

description.json
{
  "description": "A clean, minimalistic theme with a focus on simplicity and readability. Ideal for professional, straightforward presentations."
}

colorScheme

typestringrequirednodefault—pattern^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$

The theme's default colour scheme: a reference (a bare id or 'name:id') resolved like design.colorScheme, but in the theme's own catalogs group first.

colorScheme.json
{
  "colorScheme": "cool-horizon"
}

fontScheme

typestringrequirednodefault—pattern^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$

The theme's default font scheme: a reference (a bare id or 'name:id') resolved like design.fontScheme, but in the theme's own catalogs group first.

fontScheme.json
{
  "fontScheme": "aptos"
}

background

typeref:ThemeBackgroundrequirednodefault—

background.type · Allowed values
"theme"
background.slot · Allowed values
"light1""light2""dark1""dark2"

variants

typearray<ref:ThemeVariant>requirednodefault—

The color variants the theme offers (OPF 0.23), for example light, light-alt, dark and dark-alt: named values of design.variant over the theme's one color scheme, so a dark deck is a variant of a theme and not a theme of its own. A picker lists them by name; choosing one sets design.variant (or a slide's design.variant) to the entry's 'variant'. A document stores that value and never the id, so a variant needs no record and the theme does not change when its variants do. The entry ids are unique within a theme.

variants[].variant · Named choices (see schema for other values and constraints)
"light1""light2""dark1""dark2"
variants[].variant (oneOf 2).background · Allowed values
"light1""light2""dark1""dark2"
variants[].variant (oneOf 2).accents[] · Allowed values
"accent1""accent2""accent3""accent4""accent5""accent6"
variants.json
{
  "variants": [
    {
      "id": "light",
      "name": "Light",
      "variant": "light1"
    },
    {
      "id": "dark",
      "name": "Dark",
      "variant": "dark1"
    },
    {
      "id": "dark-alt",
      "name": "Dark alt",
      "variant": {
        "background": "dark1",
        "accents": [
          "accent2",
          "accent1",
          "accent3",
          "accent4",
          "accent5",
          "accent6"
        ]
      }
    }
  ]
}

dimensions

typeenumrequirednodefault—

Default slide size for this theme. Accepts the same preset values as design.dimensions.preset.

dimensions · Allowed values
"16:9""4:3""16:10""1:1""4:5""9:16""letter""a4""widescreen""standard"
dimensions.json
{
  "dimensions": "16:9"
}

design

typeobjectrequirednodefault—

The theme's design defaults (OPF 0.19), so a house style such as boxed content or centred titles is set once: the keys and values of the deck's design for titleAlignment, contentAlignment, contentBox, contentDirection, imageFit and listBullet. Per key the slide's design wins, then the deck's design, then this, then the layout record's design, then the engine default.

design.titleAlignment · Allowed values
"left""center""right"
design.contentAlignment · Allowed values
"left""center""right"
design.contentDirection · Allowed values
"horizontal""vertical"
design.imageFit · Allowed values
"cover""contain""stretch"
design.listBullet · Allowed values
"character""image""none"
design.json
{
  "design": {
    "contentBox": true,
    "titleAlignment": "left"
  }
}

tags

typearray<string>requirednodefault—

Free-form labels for filtering and search.

tags.json
{
  "tags": [
    "minimal",
    "professional"
  ]
}

preview

typeobjectrequirednodefault—

Visual previews of the record, used by picker UIs and inline rendering. All sub-fields are optional; engines fall back gracefully when previews aren't available.

Complete definition constraints
Schema constraints
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openpresentation.org/schema/opf-theme/v1",
  "$comment": "The v1 in the $id is the pre-1.0 line, not a frozen contract: this schema may change in any 0.x minor release. The release that produced this copy is the version of the @openpresentation/opf package it came from (opf --version; opf schemas lists it next to each id). See docs/schema-versioning.md.",
  "title": "Theme",
  "description": "Schema for theme records. Each theme is a small, named bundle that pairs a color scheme, a font scheme, a default theme-controlled background, and a slide size. Documents reference a theme from design.theme; design.colorScheme, design.fontScheme, design.background and design.dimensions take precedence over the resolved theme. The theme's own colorScheme and fontScheme references resolve in the theme's group first, so a catalog's theme finds that catalog's schemes.\n\nA document references a record as a bare id or 'name:id' and resolves it in its own catalogs groups first, then in the catalog the host registered for the group's source; engines never fetch a catalog. A published record file carries '$schema' and 'id'; the copy a document embeds under catalogs.<group>.<kind>.<id> carries neither (the key is the id) and no 'x-*' display metadata.",
  "type": "object",
  "required": [
    "$schema",
    "id",
    "name"
  ],
  "properties": {
    "$schema": {
      "type": "string",
      "const": "https://openpresentation.org/schema/opf-theme/v1",
      "description": "Identifies a published record file as a theme record. Required in a published file; an embedded copy omits it."
    },
    "id": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*$",
      "description": "The theme's id in its catalog, lowercase kebab-case. Required in a published record file; a document references the record by it (a bare id, or 'name:id' for a named group) and embeds it keyed by it, without this field.",
      "examples": [
        "minimal",
        "classic",
        "bold"
      ]
    },
    "name": {
      "type": "string",
      "description": "Human-readable theme name shown in pickers.",
      "examples": [
        "Minimal",
        "Classic",
        "Bold"
      ]
    },
    "summary": {
      "type": "string",
      "description": "One-sentence positioning of the theme — when to reach for it.",
      "examples": [
        "A clean, minimalist theme for professional, straightforward presentations.",
        "A vibrant, high-energy theme with bold colors for presentations that need to stand out."
      ]
    },
    "description": {
      "type": "string",
      "description": "Longer prose describing what the theme looks and feels like and the kinds of decks it suits.",
      "examples": [
        "A clean, minimalistic theme with a focus on simplicity and readability. Ideal for professional, straightforward presentations."
      ]
    },
    "colorScheme": {
      "type": "string",
      "pattern": "^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$",
      "description": "The theme's default colour scheme: a reference (a bare id or 'name:id') resolved like design.colorScheme, but in the theme's own catalogs group first.",
      "examples": [
        "cool-horizon",
        "boost",
        "burnt-orange"
      ]
    },
    "fontScheme": {
      "type": "string",
      "pattern": "^(?:[a-z][a-z0-9-]*:)?[a-z][a-z0-9-]*$",
      "description": "The theme's default font scheme: a reference (a bare id or 'name:id') resolved like design.fontScheme, but in the theme's own catalogs group first.",
      "examples": [
        "aptos",
        "tenorite",
        "seaford",
        "impact"
      ]
    },
    "background": {
      "$ref": "#/$defs/ThemeBackground"
    },
    "variants": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/ThemeVariant"
      },
      "description": "The color variants the theme offers (OPF 0.23), for example light, light-alt, dark and dark-alt: named values of design.variant over the theme's one color scheme, so a dark deck is a variant of a theme and not a theme of its own. A picker lists them by name; choosing one sets design.variant (or a slide's design.variant) to the entry's 'variant'. A document stores that value and never the id, so a variant needs no record and the theme does not change when its variants do. The entry ids are unique within a theme.",
      "examples": [
        [
          {
            "id": "light",
            "name": "Light",
            "variant": "light1"
          },
          {
            "id": "dark",
            "name": "Dark",
            "variant": "dark1"
          },
          {
            "id": "dark-alt",
            "name": "Dark alt",
            "variant": {
              "background": "dark1",
              "accents": [
                "accent2",
                "accent1",
                "accent3",
                "accent4",
                "accent5",
                "accent6"
              ]
            }
          }
        ]
      ]
    },
    "dimensions": {
      "type": "string",
      "enum": [
        "16:9",
        "4:3",
        "16:10",
        "1:1",
        "4:5",
        "9:16",
        "letter",
        "a4",
        "widescreen",
        "standard"
      ],
      "description": "Default slide size for this theme. Accepts the same preset values as design.dimensions.preset.",
      "examples": [
        "16:9",
        "4:3",
        "16:10",
        "1:1",
        "4:5",
        "9:16",
        "letter",
        "a4",
        "widescreen",
        "standard"
      ]
    },
    "design": {
      "type": "object",
      "additionalProperties": false,
      "description": "The theme's design defaults (OPF 0.19), so a house style such as boxed content or centred titles is set once: the keys and values of the deck's design for titleAlignment, contentAlignment, contentBox, contentDirection, imageFit and listBullet. Per key the slide's design wins, then the deck's design, then this, then the layout record's design, then the engine default.",
      "properties": {
        "titleAlignment": {
          "type": "string",
          "enum": [
            "left",
            "center",
            "right"
          ],
          "description": "As design.titleAlignment of a deck."
        },
        "contentAlignment": {
          "type": "string",
          "enum": [
            "left",
            "center",
            "right"
          ],
          "description": "As design.contentAlignment of a deck."
        },
        "contentBox": {
          "type": "boolean",
          "description": "As design.contentBox of a deck."
        },
        "contentDirection": {
          "type": "string",
          "enum": [
            "horizontal",
            "vertical"
          ],
          "description": "As design.contentDirection of a deck."
        },
        "imageFit": {
          "type": "string",
          "enum": [
            "cover",
            "contain",
            "stretch"
          ],
          "description": "As design.imageFit of a deck."
        },
        "listBullet": {
          "type": "string",
          "enum": [
            "character",
            "image",
            "none"
          ],
          "description": "As design.listBullet of a deck."
        }
      },
      "examples": [
        {
          "contentBox": true,
          "titleAlignment": "left"
        }
      ]
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Free-form labels for filtering and search.",
      "examples": [
        [
          "minimal",
          "professional"
        ],
        [
          "bold",
          "high-impact"
        ]
      ]
    },
    "preview": {
      "type": "object",
      "description": "Visual previews of the record, used by picker UIs and inline rendering. All sub-fields are optional; engines fall back gracefully when previews aren't available.",
      "properties": {
        "src": {
          "type": "string",
          "format": "uri",
          "description": "Main preview image (PNG/JPG). Used as the primary visual in picker UIs and previews of the record.",
          "examples": [
            "https://www.pptx.gallery/themes/minimal.png"
          ]
        },
        "thumbnailSrc": {
          "type": "string",
          "format": "uri",
          "description": "Smaller thumbnail preview suited to dense grid views.",
          "examples": [
            "https://www.pptx.gallery/themes/minimal.thumbnail.png"
          ]
        },
        "vectorSrc": {
          "type": "string",
          "format": "uri",
          "description": "SVG / vector preview for crisp scaling at any size.",
          "examples": [
            "https://www.pptx.gallery/themes/minimal.svg"
          ]
        }
      }
    }
  },
  "$defs": {
    "ThemeVariant": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "name",
        "variant"
      ],
      "description": "One named color variant of a theme.",
      "properties": {
        "id": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9-]*$",
          "description": "The variant's id within the theme, lowercase kebab-case.",
          "examples": [
            "light",
            "light-alt",
            "dark",
            "dark-alt"
          ]
        },
        "name": {
          "type": "string",
          "description": "Human-readable variant name shown in pickers.",
          "examples": [
            "Light",
            "Light alt",
            "Dark",
            "Dark alt"
          ]
        },
        "variant": {
          "description": "The value design.variant takes when the variant is chosen: a background slot ('light1', 'light2', 'dark1', 'dark2'; the same as { background: slot }) or the ColorVariant object of opf.schema.json, which adds an accent order.",
          "oneOf": [
            {
              "$ref": "#/$defs/ThemeBackgroundSlot"
            },
            {
              "$ref": "https://openpresentation.org/schema/opf/v1#/$defs/ColorVariant"
            }
          ],
          "examples": [
            "dark1",
            {
              "background": "light1",
              "accents": [
                "accent6",
                "accent5",
                "accent4",
                "accent1",
                "accent3",
                "accent2"
              ]
            }
          ]
        }
      }
    },
    "ThemeBackgroundSlot": {
      "type": "string",
      "description": "PowerPoint theme-controlled slide background slot from the active color scheme. These are slots, not assumptions about actual colors: light1 is usually white and dark1 is usually black by convention, but the color scheme controls the real values.",
      "enum": [
        "light1",
        "light2",
        "dark1",
        "dark2"
      ]
    },
    "ThemeBackground": {
      "type": "object",
      "description": "Theme-controlled PowerPoint slide background. The slot is resolved through the active color scheme and remains theme-aware.",
      "required": [
        "type",
        "slot"
      ],
      "properties": {
        "type": {
          "type": "string",
          "const": "theme",
          "description": "Theme-controlled background fill."
        },
        "slot": {
          "$ref": "#/$defs/ThemeBackgroundSlot"
        }
      }
    }
  }
}

Definition choices

Values declared by this schema and its nested definitions. Paths ending in [] describe array items; * describes each dictionary entry. Variant paths apply within the named schema branch.

$defs.ThemeVariant.variant · Named choices (see schema for other values and constraints)
"light1""light2""dark1""dark2"
$defs.ThemeBackgroundSlot · Allowed values
"light1""light2""dark1""dark2"
$defs.ThemeBackground.type · Allowed values
"theme"
$defs.ThemeBackground.slot · Allowed values
"light1""light2""dark1""dark2"