# How Theme Colors and Default Styling Operate in OfficeCLI for Document Customization

> Discover how OfficeCLI's theme colors and docDefaults manage document styling with a two-tier system for canonical palettes and base properties.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: deep-dive
- Published: 2026-08-08

---

**OfficeCLI manages document styling through a two-tier system: a static canonical color palette for theme colors and document defaults (docDefaults) that provide base paragraph and run properties when no explicit style is set.**

OfficeCLI is an open-source command-line interface for manipulating Office Open XML (OOXML) documents in Word, Excel, and PowerPoint. This guide examines how the project implements **theme colors** and **default styling** to ensure consistent, predictable document appearance across all supported formats.

---

## How Theme Colors Work in OfficeCLI

Theme colors in OfficeCLI are not merely cosmetic—they form a resolution pipeline that bridges user commands to final OOXML output. The system guarantees that every document, even those created from scratch, contains a valid color reference framework.

### The Canonical Palette: OfficeDefaultThemeColors

At the heart of the theme system lies [`OfficeDefaultThemeColors.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OfficeDefaultThemeColors.cs), which defines the **six accent colors**, **two dark/light variants**, and **hyperlink colors** that Word, Excel, and PowerPoint expect.

```csharp
// From src/officecli/Core/OfficeDefaultThemeColors.cs (lines 1-50)
// Colors are stored as 6-character OOXML hex strings without leading #
public static class OfficeDefaultThemeColors
{
    public const string Accent1 = "4472C4";
    public const string Accent2 = "ED7D31";
    // ... Accent3-6, Dark1, Light1, Dark2, Light2, 
    // Hyperlink, FollowedHyperlink
}

```

The class exposes two critical structures:

- **`BuildAliasMap()`** (lines 58-72): Creates a case-insensitive dictionary mapping theme-color names (`accent1`, `tx1`, `bg2`, `dark1`, etc.) to their hex values. This map is consulted whenever the rendering pipeline encounters a `<w:themeColor>` attribute.

- **`DefaultChartSeriesPalette`**: An array that reuses the six accent colors, then provides darker tints (with `lumMod="75000"`) for slots 7-12. Both the OOXML chart builder and SVG preview renderer consume this array.

### Ensuring Theme Part Existence: ThemeHandler

The `ThemeHandler` class in [`src/officecli/Core/ThemeHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThemeHandler.cs) solves a critical OOXML edge case: documents that lack a `<a:theme>` part. When processing such files, the handler injects a minimal `ThemePart` containing an empty `<a:theme>` element. This guarantees that downstream operations—such as `RawXmlHelper.Execute`—can safely replace or modify theme content without null reference failures.

### Resolving Theme Colors: ThemeColorResolver

`ThemeColorResolver` in [`src/officecli/Core/ThemeColorResolver.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThemeColorResolver.cs) performs the final color translation:

1. Looks up the base color in the alias map from `OfficeDefaultThemeColors`
2. Applies **shade** (`themeShade`) or **tint** (`themeTint`) modifiers using `ColorMath` utilities
3. Writes the resolved hex value into the target OOXML element

### The Theme Color Pipeline in Action

When you execute a CLI command with a theme-color selector, this sequence runs:

```bash
officecli set paragraph 1 border top single 2 themeColor=accent2

```

| Step | Component | Action |
|------|-----------|--------|
| Parsing | `ExtractThemeTail` in [`WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.cs) | Splits `single;2;themeColor=accent2` into positional part (`single;2`) and theme dictionary (`{ "themeColor": "accent2" }`) |
| Application | `ApplyBorderTheme` helper | Sets `w:themeColor="accent2"` on the `<w:top>` element |
| Resolution | `ThemeColorResolver` | Converts `accent2` → `ED7D31` at render/save time |
| Persistence | Document save | Theme-color attributes preserved; resolves to concrete color if theme part is missing |

---

## How Default Styling Works in OfficeCLI

Default styling ensures that newly created or minimally styled documents maintain "Office-native" appearance without explicit user configuration.

### Document Defaults: docDefaults

The `WordPageDefaults` class in [`src/officecli/Core/WordPageDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/WordPageDefaults.cs) extracts three critical structures from `StyleDefinitionsPart`:

1. **Run properties default** (`RunPropertiesDefault`): Base font, size, color, and run-level settings
2. **Paragraph properties default**: Spacing, indentation, and alignment baselines
3. **Table defaults**: Default table cell margins and borders

These defaults merge into any style's `RunPropertiesBaseStyle` when computing **effective formatting**.

### Default Paragraph Style Resolution

Within [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs), the handler identifies the default paragraph style by locating the `<w:style>` element with `w:type="paragraph"` and `w:default="1"`. The code then follows the style inheritance chain to resolve all implied properties.

### Blank Document Creation

[`BlankDocCreator.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BlankDocCreator.cs) seeds new documents with a complete styling foundation:

```csharp
// From src/officecli/BlankDocCreator.cs
// Generates minimal theme1.xml with canonical palette
var themePart = document.AddNewPart<ThemePart>();
themePart.FeedData(GenerateDefaultThemeStream());

```

This ensures that `themeColor` references resolve immediately, and that the document's `docDefaults` produce a clean, professional appearance on first open.

### CLI "Default" Keyword Handling

Many `set` commands accept `default` as a magic value. In [`WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.cs) (lines 770-775), this maps to standard document parts:

```bash
officecli set header default  # Maps to /header[1], creates if absent

officecli set footer default  # Maps to /footer[1], creates if absent

```

---

## Practical Examples for Theme Colors and Default Styling

### Example 1: Apply Themed Border to a Paragraph

```bash

# 2pt single top border using Accent 2 (orange)

officecli set paragraph 1 border top single 2 themeColor=accent2

```

**Internal result**: `<w:top w:val="single" w:sz="2" w:themeColor="accent2"/>` → resolves to `ED7D31`

### Example 2: Override Default Theme Color

```bash

# Replace Accent 1 with custom red

officecli set theme accent1=FF0000

```

**Internal result**: `ThemeHandler` ensures theme part exists; `FF0000` written to `<a:accent1>`; all `themeColor="accent1"` references now use red.

### Example 3: Create Document with Full Default Styling

```bash
officecli new word contract.docx

```

**Internal result**: `BlankDocCreator` emits [`theme1.xml`](https://github.com/iOfficeAI/OfficeCLI/blob/main/theme1.xml) with canonical palette + `docDefaults` with standard run/paragraph properties.

---

## Key Source Files for Theme and Default Styling

| File | Purpose | Path |
|------|---------|------|
| [`OfficeDefaultThemeColors.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OfficeDefaultThemeColors.cs) | Canonical palette, alias map, chart series colors | [`src/officecli/Core/OfficeDefaultThemeColors.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/OfficeDefaultThemeColors.cs) |
| [`ThemeHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ThemeHandler.cs) | Guarantees `<a:theme>` part existence | [`src/officecli/Core/ThemeHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThemeHandler.cs) |
| [`ThemeColorResolver.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ThemeColorResolver.cs) | Theme-color name → hex resolution with shade/tint | [`src/officecli/Core/ThemeColorResolver.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThemeColorResolver.cs) |
| [`WordPageDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordPageDefaults.cs) | Reads and exposes `docDefaults` | [`src/officecli/Core/WordPageDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/WordPageDefaults.cs) |
| [`WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.cs) | Parses theme tails, applies to borders/shading/color | [`src/officecli/Handlers/Word/WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/WordHandler.Set.cs) |
| [`BlankDocCreator.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BlankDocCreator.cs) | Generates new documents with seeded theme and defaults | [`src/officecli/BlankDocCreator.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/BlankDocCreator.cs) |

---

## Summary

- **Theme colors** originate from a static canonical palette in [`OfficeDefaultThemeColors.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/OfficeDefaultThemeColors.cs), resolved at runtime via `ThemeColorResolver`, with `ThemeHandler` ensuring every document has a theme part for fallback.

- **Default styling** derives from `docDefaults` and the default paragraph style, accessed through `WordPageDefaults` and merged into effective formatting by `WordHandler`.

- The CLI pipeline (`ExtractThemeTail` → `ApplyBorderTheme`/`ApplyShadingTheme`/`ApplyColorTheme`) bridges user commands to OOXML attributes, preserving theme-color references for round-trip editing.

- New documents automatically receive complete theme and default styling through `BlankDocCreator`, eliminating blank-document appearance issues.

---

## Frequently Asked Questions

### How does OfficeCLI handle documents that have no theme part?

`ThemeHandler` in [`src/officecli/Core/ThemeHandler.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/ThemeHandler.cs) automatically creates a minimal `ThemePart` with an empty `<a:theme>` element. This allows subsequent processing to safely modify or replace theme content without encountering null reference errors.

### Can I use theme colors with tints and shades in CLI commands?

Yes. Include `themeShade` or `themeTint` as key-value pairs: `themeColor=accent1,themeShade=BF`. The `ThemeColorResolver` applies these modifiers using `ColorMath` utilities before writing the final hex value.

### What happens when I specify "default" instead of a specific color or value?

The CLI interprets `default` as a directive to use standard document structures. In [`WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.cs) (lines 770-775), this maps to `/header[1]` or `/footer[1]` with automatic element creation if absent.

### Why do new OfficeCLI documents look like native Office files?

[`BlankDocCreator.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BlankDocCreator.cs) seeds every new document with the full canonical theme palette and `docDefaults` containing standard run and paragraph properties. This design replicates the styling foundation that Microsoft Office applies to blank documents.