
Officecli Pitch Deck
- 26 installs
- 25.5k repo stars
- Updated August 4, 2026
- iofficeai/officecli
Create professional pitch decks (investor, product-launch, sales) as a .pptx with charts, stat callouts, and speaker notes.
About
Creates professional pitch presentations from scratch such as investor decks, product launches, and sales decks as a single .pptx. A developer uses it to produce a polished non-morph pitch deck with charts, styled tables, stat callouts, and speaker notes.
- Creates investor, product-launch, sales, and business-proposal .pptx decks
- Gradient backgrounds, modern charts, stat callouts, and speaker notes on every slide
Officecli Pitch Deck by the numbers
- 26 all-time installs (skills.sh)
- +5 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #423 of 688 Office & Documents skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/iofficeai/officecli --skill officecli-pitch-deckAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 26 |
|---|---|
| repo stars | ★ 25.5k |
| Last updated | August 4, 2026 |
| Repository | iofficeai/officecli ↗ |
What it does
Create professional pitch decks (investor, product-launch, sales) as a .pptx with charts, stat callouts, and speaker notes.
Files
Pitch Deck Skill
Create professional pitch presentations from scratch -- investor decks, product launches, enterprise sales decks, and business proposals. Output is a single .pptx file with gradient backgrounds, modern charts, styled tables, stat callouts, and speaker notes on every content slide.
---
BEFORE YOU START (CRITICAL)
If `officecli` is not installed:
macOS / Linux
if ! command -v officecli >/dev/null 2>&1; then
curl -fsSL https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.sh | bash
fiWindows (PowerShell)
if (-not (Get-Command officecli -ErrorAction SilentlyContinue)) {
irm https://raw.githubusercontent.com/iOfficeAI/OfficeCLI/main/install.ps1 | iex
}Verify: officecli --version
If officecli is still not found after first install, open a new terminal and run the verify command again.
---
Use When
- User wants to create an investor pitch deck (seed, Series A/B/C)
- User wants a product launch or feature announcement presentation
- User wants an enterprise sales deck or client-facing pitch
- User wants a business proposal or strategy presentation in slides
- User mentions "pitch deck", "investor deck", "sales deck", "fundraising presentation"
Don't Use When
| User Request | Correct Skill |
|---|---|
| Morph-animated or cinematic presentations | morph-ppt |
| Edit/modify an existing .pptx | officecli-pptx (editing.md) |
| Excel dashboard or data report | officecli-data-dashboard |
| Word document | officecli-docx |
| Request is primarily about animation/motion effects | morph-ppt |
pitch-deck vs morph-ppt
| Aspect | pitch-deck (this skill) | morph-ppt |
|---|---|---|
| Core mechanic | Layout diversity + content density | Morph transition + scene actors |
| Slide construction | Build each slide fresh from scratch | Clone + ghost + modify actors |
| Animation | Standard transitions (fade, push) | Morph (shape-matching across slides) |
| Naming convention | No special naming | !!actor + #sN-content |
| Data visualization | Charts, tables, stat callouts | None (text + shapes only) |
| Helper scripts | None needed | morph-helpers.sh required |
---
Hard Rules (Non-Negotiable)
These rules are checked by evaluators and will FAIL the deck if violated. No exceptions beyond the explicit list below.
H-FONT: Body Text Minimum Size + Font Consistency
ALL body text must be ≥ 16pt. This applies to EVERY visible text element unless it falls into the explicit exceptions below.
Elements that MUST be ≥ 16pt (no exceptions):
- Card body copy / card descriptions
- Flow diagram node description text
- Team bio text
- Timeline step labels
- Business model card copy
- Sub-labels under stat callout numbers (e.g., "Total Addressable Market")
- Any paragraph or supporting text block
Permitted exceptions (only these — nothing else):
- Chart axis labels / tick labels: 10pt minimum (e.g.,
axisFont="10:64748B:Calibri") - Chart legend text: 10pt minimum (e.g.,
legendFont="10:64748B:Calibri") - Table header/body rows: 11-12pt minimum (table cells have constrained space)
- Icon badge initials (letters inside avatar ellipses): any size acceptable
If you are unsure whether something is an exception: it is NOT. Set it to 16pt.
Font consistency (enforced across every shape):
The font pairing declared in creating.md Section A.3 (e.g., Georgia for titles, Calibri for body) applies to EVERY text shape in the entire deck without exception. This includes:
- Connector labels (if any)
- Footer shapes
- Page number shapes
- Small caption or source-credit shapes
- Notes callout shapes
❌ BANNED: Using any font not declared in your A.3 pairing (e.g., adding Arial, Helvetica, Times New Roman, or any other font mid-deck) ❌ BANNED: Omitting the font property on any shape and relying on PowerPoint defaults
Before delivery, scan every add command in your script and confirm every shape has an explicit "font" value matching your declared pairing.
H-OVERLAP: No Shape May Overlap Another Shape's Text
After adding connectors and arrows, immediately take a PNG screenshot and verify: 1. Every connector is visible (not missing) 2. No connector or arrow overlaps any text box content
If a connector overlaps text, reposition the connector OR send it behind the text box using --prop zorder=back. See creating.md C.9 for the full connector verification protocol.
H-PALETTE: Color Palette Discipline
Use ONLY colors from your pre-defined palette ($PRIMARY, $SECONDARY, $ACCENT1, $ACCENT2, etc.). Do NOT introduce additional accent colors not defined at the start of the script. If you used purple on Slide 3 but it was not in your initial palette definition, remove it. Every color in the deck must trace back to a named palette variable.
Common traps — these WILL cause a FAIL:
- ❌ BANNED: Red (
FF0000,CC0000,E53935, etc.) to indicate "bad/wrong/competitor weakness" — use your palette's darkest color instead - ❌ BANNED: Green (
00FF00,4CAF50,34A853, etc.) to indicate "good/correct/your advantage" — UNLESS green is explicitly declared as a palette variable (e.g.,ACCENT1="34A853") - ❌ BANNED: Gray (
888888,999999,AAAAAA,CCCCCC, etc.) as a neutral/background color — use a palette light color (e.g.,$LIGHT) instead - ❌ BANNED: Any bare hex color value that does NOT appear in your palette variable block
How to express contrast and status without new colors:
- "Bad/competitor" column or row → use your palette's darkest or most muted shade (e.g.,
$DARK,$DARK2) - "Good/your product" column or row → use your palette's primary or accent color (e.g.,
$PRIMARY,$ACCENT1) - Neutral/disabled state → use a light-opacity version of an existing palette color, not gray
- Tick mark vs cross mark in comparison tables → use the same text color as the column; do NOT switch to red/green
---
Core Concepts
1. Layout-First Construction -- Select a slide pattern from creating.md Section C, then fill with content. Never manually calculate x/y from scratch. 2. Color Palette Upfront -- Define 5-6 hex colors as shell variables before building. All commands reference $PRIMARY, $SECONDARY, etc. 3. Slide Pattern Library -- 11 pre-tested spatial blueprints with positioning tables. See creating.md Section C. 4. Chart Styling is Non-Negotiable -- Every chart uses the modern recipe: plotFill=none, chartFill=none, subtle gridlines, series.outline. 5. Speaker Notes as Checklist Item -- Add 2+ sentence notes after each content slide is complete.
---
Workflow Overview
Phase 1: Understand -- Identify deck type (seed/launch/investor/sales), slide count, data provided, color preference.
Phase 2: Plan -- Select deck structure from creating.md Section A. Define palette as shell variables. Map each slide to a pattern from Section C. Verify no two consecutive slides share the same layout.
Phase 3: Build -- Create file, set metadata, then officecli open for resident mode. Build slide by slide using batch mode (heredoc syntax for 4+ elements). Apply chart/table recipes from Sections D/E. Add speaker notes after each slide. officecli close before QA.
Phase 4: QA & Deliver -- Run officecli validate. Check the QA checklist below. Deliver with note about validation exceptions if cell merge was used.
---
Quick Start -- 6-Slide Seed Pitch
# Setup
officecli create pitch.pptx
officecli set pitch.pptx / --prop title="FitPulse" --prop author="Alex Kim"
officecli open pitch.pptx # Resident mode — all batch operations run in memory
PRIMARY="FF6B35"; SECONDARY="1A1A2E"; ACCENT1="00C9A7"; DARK="16213E"; MUTED="64748B"
# MUTED is declared here so stat sub-label colors use a palette variable, not a bare hex gray
# Slide 1: Title (gradient background, pattern C.1)
cat <<'EOF' | officecli batch pitch.pptx
[
{"command":"add","parent":"/","type":"slide","props":{"layout":"blank","background":"1A1A2E-16213E-180"}},
{"command":"add","parent":"/slide[1]","type":"shape","props":{"text":"FitPulse","x":"2cm","y":"5cm","width":"29.87cm","height":"4cm","font":"Georgia","size":"48","bold":"true","color":"FF6B35","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[1]","type":"shape","props":{"text":"AI That Trains With You","x":"2cm","y":"10cm","width":"29.87cm","height":"2cm","font":"Calibri","size":"22","color":"FFFFFF","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[1]","type":"shape","props":{"text":"Seed Round | $500K","x":"2cm","y":"13cm","width":"29.87cm","height":"1.5cm","font":"Calibri","size":"16","color":"00C9A7","align":"center","fill":"none"}}
]
EOF
officecli set pitch.pptx "/slide[1]" --prop transition=fade
# Slide 2: Market (3-stat callout, pattern C.2)
cat <<'EOF' | officecli batch pitch.pptx
[
{"command":"add","parent":"/","type":"slide","props":{"layout":"blank","background":"FFFFFF"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"A $96B Market","x":"2cm","y":"1cm","width":"29.87cm","height":"3cm","font":"Georgia","size":"36","bold":"true","color":"1A1A2E","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"$96B","x":"2cm","y":"5cm","width":"9cm","height":"4cm","font":"Georgia","size":"64","bold":"true","color":"FF6B35","align":"center","valign":"bottom","fill":"none"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"Total Addressable Market","x":"2cm","y":"9.5cm","width":"9cm","height":"2cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
// ^^^ "64748B" = $MUTED declared above. Use $MUTED in your palette; in heredoc use its literal hex value.
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"$14.7B","x":"12.5cm","y":"5cm","width":"9cm","height":"4cm","font":"Georgia","size":"64","bold":"true","color":"FF6B35","align":"center","valign":"bottom","fill":"none"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"Fitness App Market","x":"12.5cm","y":"9.5cm","width":"9cm","height":"2cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"$320M","x":"23cm","y":"5cm","width":"9cm","height":"4cm","font":"Georgia","size":"64","bold":"true","color":"FF6B35","align":"center","valign":"bottom","fill":"none"}},
{"command":"add","parent":"/slide[2]","type":"shape","props":{"text":"AI Fitness (beachhead)","x":"23cm","y":"9.5cm","width":"9cm","height":"2cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}}
]
EOF
officecli set pitch.pptx "/slide[2]" --prop transition=push-left
officecli add pitch.pptx "/slide[2]" --type notes \
--prop text="The global fitness market is 96 billion. Our beachhead is the 320M AI fitness niche."
# Slide 3: Traction (chart + stats, pattern C.4)
cat <<'EOF' | officecli batch pitch.pptx
[
{"command":"add","parent":"/","type":"slide","props":{"layout":"blank","background":"FFFFFF"}},
{"command":"add","parent":"/slide[3]","type":"shape","props":{"text":"Explosive Early Traction","x":"2cm","y":"1cm","width":"29.87cm","height":"3cm","font":"Georgia","size":"36","bold":"true","color":"1A1A2E","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[3]","type":"chart","props":{"chartType":"areaStacked","categories":"Month 1,Month 2,Month 3","series1":"Casual:8000,14000,19200","series2":"Enthusiast:2500,5200,9600","series3":"Pro:500,1200,3200","x":"2cm","y":"4cm","width":"17cm","height":"13cm","colors":"FF6B35,00C9A7,845EC2","plotFill":"none","chartFill":"none","gridlines":"E2E8F0:0.5","legendFont":"10:64748B:Calibri","legend":"bottom","series.outline":"FFFFFF-0.5"}},
// NOTE: legendFont=10 above is a CHART INTERNAL exception (axis/legend) — allowed.
// All standalone stat sub-labels and body text outside the chart MUST be >= 16pt (Hard Rule H-FONT).
{"command":"add","parent":"/slide[3]","type":"shape","props":{"text":"50K","x":"21cm","y":"4cm","width":"11cm","height":"2.5cm","font":"Georgia","size":"44","bold":"true","color":"FF6B35","align":"center","valign":"bottom","fill":"none"}},
{"command":"add","parent":"/slide[3]","type":"shape","props":{"text":"Downloads","x":"21cm","y":"6.8cm","width":"11cm","height":"1.2cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
// ^^^ "64748B" = $MUTED. Stat sub-label: must be >= 16pt (Hard Rule H-FONT). Do NOT copy 12pt from old examples.
{"command":"add","parent":"/slide[3]","type":"shape","props":{"text":"40%","x":"21cm","y":"8.5cm","width":"11cm","height":"2.5cm","font":"Georgia","size":"44","bold":"true","color":"00C9A7","align":"center","valign":"bottom","fill":"none"}},
{"command":"add","parent":"/slide[3]","type":"shape","props":{"text":"MoM Growth","x":"21cm","y":"11.3cm","width":"11cm","height":"1.2cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}}
// ^^^ "64748B" = $MUTED. Stat sub-label: must be >= 16pt (Hard Rule H-FONT). Do NOT copy 12pt from old examples.
]
EOF
officecli set pitch.pptx "/slide[3]" --prop transition=push-left
officecli add pitch.pptx "/slide[3]" --type notes \
--prop text="50K downloads in 3 months with 40% MoM growth. Premium tier growing fastest."
# Slides 4-5: Team (C.11) + Problem/Solution (C.7) -- use patterns from creating.md
# Slide 6: Closing (C.12) -- gradient matching slide 1, fade transition
# Close and QA
officecli close pitch.pptx
officecli validate pitch.pptx---
QA Checklist
Run before every delivery. See creating.md Section G for the full checklist.
1. officecli validate = 0 errors. Exception: slides with cell merge may report schema warnings that are cosmetic (PowerPoint renders correctly). 2. Every chart is editable (click -> Edit Data appears in PowerPoint) 3. Every table is a native table object (click -> table editing mode) 4. Speaker notes on all content slides (exclude title and closing), >= 2 sentences each 5. No two consecutive slides share the same layout structure 6. Font consistency: every shape in the deck uses only the declared font pairing (Georgia + Calibri). No shape may use an undeclared font (Hard Rule H-FONT). 7. Palette-only colors: scan all fill and color values — no bare hex outside the declared palette block. No red/green/gray introduced for status indicators (Hard Rule H-PALETTE).
---
What This Skill Does NOT Do
- No morph transitions, clone-slide, or
!!naming - No 3D effects, motion paths, or video embedding
- No template merge (
{{key}}patterns) - No custom SVG geometry or WordArt
- No reading/editing existing .pptx (use officecli-pptx)
---
Known Issues
See creating.md Section H for the full list with workarounds. Key issues:
| Issue | Impact |
|---|---|
view issues reports "Slide has no title" for every slide | Expected behavior — safe to ignore. pitch-deck uses layout=blank which has no built-in PowerPoint title placeholder. This is not a bug. |
gap ignored during chart add | Must apply via separate set command |
| Cell merge produces validation errors | PowerPoint renders correctly; note in delivery |
Cell-level color on table cells causes validation errors | Use row-level color instead |
Custom gradient stops (@) fail on slide backgrounds | Use 2-color or 3-color gradients only |
Combo chart requires both comboSplit=1 and secondary=2 | Missing either renders incorrectly |
| Dual-axis scale mismatch makes smaller series invisible | HARD RULE: If ranges differ >10x, MUST split into two separate charts. See creating.md D.4 |
| Stat values wrap at 60pt in 7cm width | HARD RULE: Max 4 chars for $X.YM patterns (wide $+. glyphs); max 5 chars for other values. Use 44-48pt or C.2 (3-stat, 9cm) for longer |
Doughnut chart colors parameter may not apply | CLI accepts without error but PowerPoint renders default colors. No workaround. Verify via screenshot |
Empty table cell c1="" causes validation error | Use c1=" " (space character) instead of empty string |
| Connector arrows may not all render in batch | Add connectors in separate batch after shapes; immediately screenshot to verify each connector is visible (CLI reports success even when rendering fails); if still missing, add one at a time or use --type shape --prop preset=rightArrow as a reliable fallback |
| Empty series values (gaps) not supported | Use 0 for missing data points; produces zero-height bars |
| Background covers text | In batch, background shapes are added before text shapes. Adding bg shapes AFTER text results in bg covering text completely (higher z-order). Always: bg → text, never text → bg |
---
Adjustments After Creation
When the user requests changes after the deck is built:
| Request | Command |
|---|---|
| Swap two slides | officecli swap deck.pptx '/slide[2]' '/slide[4]' |
| Move a slide after another | officecli move deck.pptx '/slide[5]' --after '/slide[2]' |
| Edit shape text | officecli set deck.pptx '/slide[N]/shape[M]' --prop text="..." |
| Change color / style | officecli set deck.pptx '/slide[N]/shape[M]' --prop fill=FF0000 |
| Remove an element | officecli remove deck.pptx '/slide[N]/shape[M]' |
| Find & replace text | officecli set deck.pptx / --prop find=OldText --prop replace=NewText |
After any swap or move, re-query the affected slide with officecli get deck.pptx '/slide[N]' --depth 1 — shape indices shift after reordering.
---
Help System
officecli pptx set # All settable elements and properties
officecli pptx set shape # Shape properties in detail
officecli pptx add # All addable element types
officecli pptx view # All view modes<!-- officecli: v1.0.24 -->
<!-- ============================================================ SESSION PALETTE & FONT — user-tester-1 (LearnFlow EdTech Series A) Date: 2026-04-02 ============================================================ Color Palette (Professional Navy for EdTech): PRIMARY = "0F2B46" (deep navy — slide titles, dark card fills) SECONDARY = "1A73E8" (electric blue — CTAs, accent) ACCENT1 = "34A853" (teal-green — explicitly declared; growth/positive indicators) ACCENT2 = "F9AB00" (amber — callout numbers, key stats) DARK = "0A1628" (darkest navy — gradient start) DARK2 = "0D1F35" (second dark — gradient end) LIGHT = "F0F4F8" (off-white — card backgrounds, light slides) MUTED = "64748B" (slate — sub-labels, secondary text)
Font Pairing (A.3): Titles / Stat numbers : Georgia (bold), 32–44pt titles, 36–64pt stats Body / Labels : Calibri, 16pt minimum (Hard Rule H-FONT) Stat sub-labels : Calibri, 16pt minimum (H-FONT — no exceptions) Chart axis/legend : Calibri, 10pt (chart-internal exception — allowed) Table cells : Calibri, 11–12pt (table-internal exception — allowed) Footer/caption : Calibri, 12pt minimum EVERY shape must have explicit font= — no PowerPoint defaults
H-PALETTE zero-tolerance (R9): ❌ No bare hex outside the 8 variables above ❌ No red for "bad" — use DARK/DARK2 instead ❌ No unregistered green for "good" — use ACCENT1 (34A853, declared above) ❌ No gray (888888, CCCCCC, etc.) — use MUTED (64748B, declared above) ❌ Contrast/status: "without" column → DARK/DARK2; "with" column → SECONDARY/ACCENT1 ============================================================ -->
Creating a Pitch Deck
Complete guide for building professional pitch presentations from scratch. Follow the workflow: decide structure, set up, build slides pattern-by-pattern, polish, QA.
For general pptx building blocks (shapes, pictures, rich text, animations, batch syntax), see pptx creating.md. This document focuses on pitch-deck-specific patterns and recipes.
---
Section A: Decision Logic
A.1 Deck Type Selection
| Deck Type | Slides | When to Use | Recommended Slide Sequence |
|---|---|---|---|
| Seed Pitch | 6 | Pre-seed/seed, < $1M, early metrics | Title, Problem+Solution, Market, Traction, Team, Ask |
| Product Launch | 8 | Feature announcement, product release | Title, Problem, Features, Before/After, Demo, Results, Pricing, CTA |
| Full Investor | 10-12 | Series A+, significant traction | Title, Problem, Solution, Market, Product, Traction, Business Model, Competitive, Roadmap, Team, Financials, Ask |
| Enterprise Sales | 10 | B2B, C-level audience, data-heavy | Title, Threat/Problem, Solution, Architecture, ROI, Case Study, Competitive, Impact, Timeline, Next Steps |
These are starting points. Respect the user's slide count -- never pad to a longer deck. Adapt the sequence to the user's specific request.
A.2 Color Palette Reference
Define palette as shell variables before building. All subsequent commands reference variables.
Professional Navy (investor decks):
PRIMARY="0F2B46"; SECONDARY="1A73E8"; ACCENT1="34A853"; ACCENT2="F9AB00"; DARK="0A1628"; DARK2="0D1F35"; LIGHT="F0F4F8"; MUTED="64748B"Tech Purple (product launches):
PRIMARY="6C2BD9"; SECONDARY="1DB954"; ACCENT1="FF6B35"; ACCENT2="00B4D8"; DARK="1A1A2E"; DARK2="12102A"; LIGHT="F8F7FF"; MUTED="64748B"Dark Premium (enterprise sales):
PRIMARY="0D0D1A"; SECONDARY="00D4AA"; ACCENT1="FF4757"; ACCENT2="FFA502"; ACCENT3="2ED573"; DARK="0D0D1A"; DARK2="1A1A3E"; LIGHT_TEXT="E8E8E8"; MUTED="6B7B8D"Impact/Humanitarian (nonprofit / social impact):
PRIMARY="2E7D32"; SECONDARY="1565C0"; ACCENT1="E65100"; DARK="1B5E20"; DARK2="0D3B6E"; LIGHT="FAFAFA"; TEXT="212121"; MUTED="64748B"If the user provides specific colors, use those. If not, select the closest palette and adapt.
Color Palette Discipline (Hard Rule H-PALETTE): Once defined, use ONLY the named palette variables ($PRIMARY,$SECONDARY,$ACCENT1,$ACCENT2, etc.) throughout the entire deck. Do NOT introduce new accent colors mid-deck. If Slide 3 uses purple (6C2BD9) but that value was not declared in your initial palette block, purple is out-of-palette and must be removed or replaced with an existing palette variable. Every hex color value in the deck must map to a named palette variable. Consistency check: before delivery, scan all shapefillandcolorvalues — any bare hex not in your palette block is a violation.
>
Banned color introductions — common traps that WILL cause a FAIL:
- ❌ Red to indicate "bad/wrong/competitor weakness" — use$DARKor$DARK2instead
- ❌ Green to indicate "good/correct/your advantage" — use$PRIMARYor$ACCENT1instead (unless green is already in your palette)
- ❌ Gray (888888,CCCCCC, etc.) as a neutral or muted-text color — use a declared palette variable; add aMUTEDvariable to your palette block if you need a muted shade
- ❌ Any color not present in your declared palette block, regardless of reason
>
Expressing contrast and status with palette colors only:
- Competitor / "without" column → darker fill from palette (e.g.,$DARK,$DARK2, or a low-opacity$PRIMARY)
- Your product / "with" column → primary or accent fill (e.g.,$PRIMARY,$SECONDARY)
- Comparison table checkmarks vs. crosses → use the same column text color; do NOT switch to red/green
- If you need a muted color for sub-labels, declare it upfront:MUTED="64748B"and reference$MUTEDeverywhere
A.3 Font Pairing
| Element | Font | Size |
|---|---|---|
| Slide title | Georgia, bold | 32-44pt |
| Section header | Georgia or Calibri, bold | 18-24pt |
| Body text | Calibri | 16pt minimum (Hard Rule H-FONT — no exceptions) |
| Stat number | Georgia, bold | 36-64pt |
| Stat label | Calibri | 16pt minimum (Hard Rule H-FONT — stat sub-labels are body text) |
| Chart axis / legend | Calibri | 10pt (chart-internal exception — allowed) |
| Table cell text | Calibri | 11-12pt (table-internal exception — allowed) |
| Caption/footer | Calibri | 12pt minimum |
Font consistency (Hard Rule H-FONT): The pairing above (Georgia + Calibri) applies to EVERY text shape in the deck without exception — including connector labels, footer shapes, page numbers, and any small caption. Do NOT use any other font (Arial, Helvetica, Times New Roman, etc.) anywhere in the deck. Everyaddcommand must include an explicit"font"value; never rely on PowerPoint defaults. Before delivery, scan every shape in your script and confirm only Georgia and Calibri appear.
---
Section B: Setup
B.1 Create File and Set Metadata
officecli create deck.pptx
officecli set deck.pptx / --prop title="Deck Title" --prop author="Author Name"B.2 Define Color Palette
# Example: Professional Navy
PRIMARY="0F2B46"
SECONDARY="1A73E8"
ACCENT1="34A853"
ACCENT2="F9AB00"
DARK="0A1628"
LIGHT="F0F4F8"B.3 Resident Mode (Optional, 3+ Commands)
officecli open deck.pptx # Keep in memory
# ... build slides ...
officecli close deck.pptx # Save and release---
Section C: Slide Patterns
Each pattern includes: visual description, positioning table, and batch template skeleton. Replace placeholder text, colors, and data with scenario content. Add speaker notes after each slide is built. Never use the same pattern on two consecutive slides.
Vertical centering: When a slide has fewer elements than the pattern maximum, adjust y-positions downward by 2-3cm to center the visual weight. The positions in these patterns assume maximum content.
C.1 Title / Cover (Dark Gradient)
3-4 text shapes on gradient background. Slide 1 in all decks. Transition: fade.
| Element | X | Y | Width | Height | Font/Size |
|---|---|---|---|---|---|
| Title | 2cm | 5cm | 29.87cm | 4cm | Georgia bold 44pt |
| Tagline | 2cm | 10cm | 29.87cm | 2cm | Calibri 20pt |
| Footer | 2cm | 13cm | 29.87cm | 1.5cm | Calibri 12pt |
Background: "$DARK-$DARK2-180" (linear gradient, angle 180 = top-to-bottom). DARK2 is the second dark shade defined in the palette (e.g., 0D1F35 for Professional Navy, 12102A for Tech Purple, 1A1A3E for Dark Premium). See SKILL.md Quick Start for full batch template.
C.2 Stat Callout Row (3-Stat)
Title + 3 number/label pairs. Numbers: Georgia bold 64pt. Labels: Calibri 16pt minimum (Hard Rule H-FONT), muted.
| Stat | Number X | Label X | Width | Number Y | Label Y |
|---|---|---|---|---|---|
| 1 | 2cm | 2cm | 9cm | 5cm | 9.5cm |
| 2 | 12.5cm | 12.5cm | 9cm | 5cm | 9.5cm |
| 3 | 23cm | 23cm | 9cm | 5cm | 9.5cm |
Title at y=1cm, height 3cm. Number height 4cm, label height 2cm.
C.3 Stat Callout Row (4-Stat)
Same as C.2 but 4 columns. Numbers: Georgia bold 60pt.
Stat X positions: 1.5cm, 9.5cm, 17.5cm, 25.5cm. Width: 7cm each.
HARD RULE: At 60pt in 7cm width, stat values must be 4 characters or fewer for dollar-amount patterns containing both `$` and `.` (e.g., `$9.4M` is 5 chars but the wide `$` and `.` glyphs in Georgia bold make it effectively 6 — it WILL wrap). Safe dollar patterns: `$9M`, `$96B`, `$4K` (3-4 chars). For non-dollar values, 5 characters is the limit (e.g., "340%", "4.2m", "12.3" are safe). Values of 6+ characters (e.g., "197min", "3 Days") WILL wrap to 2 lines and destroy the stat callout. For longer values: (a) reduce font to 44-48pt, (b) abbreviate (e.g., "197m" instead of "197min", "$9M" instead of "$9.4M"), or (c) use the wider 3-stat layout (C.2, 9cm per stat). Single tokens only — no spaces.
C.4 Chart + Context (Chart Left, Stats Right)
Chart on left 55%, stat callouts stacked on right. Post-batch: officecli set "/slide[N]/chart[1]" --prop gap=80 for column/bar.
| Element | X | Y | Width | Height |
|---|---|---|---|---|
| Title | 2cm | 1cm | 29.87cm | 3cm |
| Chart | 2cm | 4cm | 17cm | 13cm |
| Stats | 21cm | 4cm+ | 11cm | 2.5cm number + 1.5cm label |
Stat spacing: ~3.7cm per pair. For 5 stats, use size=44pt. Stat sub-labels: 16pt minimum (Hard Rule H-FONT).
C.5 Icon-in-Circle Grid (3-Row Vertical)
3 rows at y=4.5cm, 8.5cm, 12.5cm. Each: ellipse 2.5x2.5cm at x=2cm + text overlay (same pos) + label at x=5.5cm (bold 18pt, width 25cm) + description below (16pt minimum, muted). 13 elements total.
C.5b 2×2 Feature Grid (4-Item)
4 feature cards in a 2-column × 2-row grid. Use when you have exactly 4 parallel items (product features, service types, pillars, etc.). Each card: rounded-rect background + icon/emoji ellipse + title + description.
| Element | X | Y | Width | Height | Notes |
|---|---|---|---|---|---|
| Card 1 (top-left) bg | 1.5cm | 4cm | 14.5cm | 7cm | roundRect, fill=card color |
| Card 2 (top-right) bg | 17.5cm | 4cm | 14.5cm | 7cm | |
| Card 3 (bottom-left) bg | 1.5cm | 12cm | 14.5cm | 7cm | |
| Card 4 (bottom-right) bg | 17.5cm | 12cm | 14.5cm | 7cm | |
| Icon ellipse (each card) | card_x+0.5cm | card_y+0.5cm | 2cm | 2cm | centered on left |
| Title (each card) | card_x+3.2cm | card_y+0.6cm | 10.5cm | 1.8cm | bold 16pt |
| Body (each card) | card_x+0.5cm | card_y+3cm | 13cm | 3.5cm | 16pt (Hard Rule H-FONT) |
Slide-level title: Georgia bold 32pt at y=1cm, height=2.5cm.
Z-Order rule: The batch skeleton below already follows the correct order: each card's background shape appears immediately before that card's text shapes. Do NOT reorder — moving any roundRect bg after its text shapes will cause the background to cover the text.Batch skeleton:
cat <<'EOF' | officecli batch deck.pptx
[
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Four Pillars of Our Platform","x":"2cm","y":"1cm","width":"29.87cm","height":"2.5cm","font":"Georgia","size":"32","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"roundRect","x":"1.5cm","y":"4cm","width":"14.5cm","height":"7cm","fill":"F0F4F8","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"2cm","y":"4.5cm","width":"2cm","height":"2cm","fill":"$SECONDARY","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Feature One","x":"4.7cm","y":"4.6cm","width":"10.5cm","height":"1.8cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Brief description of feature one and its core benefit.","x":"2cm","y":"7cm","width":"13cm","height":"3.5cm","font":"Calibri","size":"16","color":"$MUTED_HEX","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"roundRect","x":"17.5cm","y":"4cm","width":"14.5cm","height":"7cm","fill":"F0F4F8","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"18cm","y":"4.5cm","width":"2cm","height":"2cm","fill":"$ACCENT1","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Feature Two","x":"20.7cm","y":"4.6cm","width":"10.5cm","height":"1.8cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Brief description of feature two and its core benefit.","x":"18cm","y":"7cm","width":"13cm","height":"3.5cm","font":"Calibri","size":"16","color":"$MUTED_HEX","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"roundRect","x":"1.5cm","y":"12cm","width":"14.5cm","height":"7cm","fill":"F0F4F8","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"2cm","y":"12.5cm","width":"2cm","height":"2cm","fill":"$ACCENT2","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Feature Three","x":"4.7cm","y":"12.6cm","width":"10.5cm","height":"1.8cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Brief description of feature three and its core benefit.","x":"2cm","y":"15cm","width":"13cm","height":"3.5cm","font":"Calibri","size":"16","color":"$MUTED_HEX","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"roundRect","x":"17.5cm","y":"12cm","width":"14.5cm","height":"7cm","fill":"F0F4F8","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"18cm","y":"12.5cm","width":"2cm","height":"2cm","fill":"$PRIMARY","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Feature Four","x":"20.7cm","y":"12.6cm","width":"10.5cm","height":"1.8cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Brief description of feature four and its core benefit.","x":"18cm","y":"15cm","width":"13cm","height":"3.5cm","font":"Calibri","size":"16","color":"$MUTED_HEX","align":"left","fill":"none"}}
]
EOF`$MUTED_HEX`: Replace with the literal hex value of your declared$MUTEDpalette variable (e.g.,64748B). Variables are not expanded inside heredoc single-quote blocks — you must use the bare hex. Per H-PALETTE, all colors must trace back to a named palette variable; never use444444or any undeclared hex.
For dark-background slides, change card fill to a lighter dark shade (e.g.,fill="1A2540") and text color toFFFFFF/E8E8E8.
C.6 Icon-in-Circle Grid (5-Across Horizontal)
5 icons at x=1.5, 7.5, 13.5, 19.5, 25.5cm. Circle 2x2cm at y=5cm. Label below at y+2.5cm, desc at y+4cm, width 5cm each. 21 elements -- use batch. Post-placement: distribute=horizontal for precision.
C.7 Two-Column Split
Problem+solution, before/after. Card backgrounds (roundRect) first, then text on top.
CRITICAL — Shape Z-Order in Batch:
Background card shapes MUST be added BEFORE text shapes in every batch.
Shapes added later in batch appear on top (higher z-order) and will cover earlier shapes.
Required order: [bg card 1] → [text on card 1] → [bg card 2] → [text on card 2]If you add background shapes AFTER text shapes, the cards will cover all text completely.
| Element | X | Y | Width | Height |
|---|---|---|---|---|
| Left card bg | 2cm | 4.5cm | 14.5cm | 13cm |
| Left header | 3cm | 5cm | 12.5cm | 2cm |
| Left body | 3cm | 7.5cm | 12.5cm | 9cm |
| Right card bg | 17.5cm | 4.5cm | 14.5cm | 13cm |
| Right header | 18.5cm | 5cm | 12.5cm | 2cm |
| Right body | 18.5cm | 7.5cm | 12.5cm | 9cm |
Color guidance for before/after contrast: The two columns MUST be visually distinct. Use contrasting fills — not two shades of the same dark color.
- "Without" (problem) column → dark red/orange tint (e.g.,fill="3D1010"orfill="2D1505"for dark themes;fill="FFF0F0"for light themes). Header accent:ACCENT1red or orange.
- "With" (solution) column → dark green/teal tint (e.g.,fill="0D2D1A"for dark themes;fill="F0FFF4"for light themes). Header accent:ACCENT1green orSECONDARY.
- Test via screenshot: both columns must be immediately distinguishable at a glance.
C.8 Comparison Table (Full-Width)
Title (2cm, 1cm) + table (2cm, 4.5cm, 29.87cm x 13cm). See Section E for construction.
C.9 Flow Diagram (Connectors)
3-node (most common -- e.g., "Install → Monitor → Save"):
| Element | X | Y | Width | Height |
|---|---|---|---|---|
| Node 1 (left) | 1cm | 9cm | 7cm | 4cm |
| Arrow 1→2 | 8.5cm | 10.5cm | 3cm | 1cm |
| Node 2 (center) | 12cm | 9cm | 7cm | 4cm |
| Arrow 2→3 | 19.5cm | 10.5cm | 3cm | 1cm |
| Node 3 (right) | 23cm | 9cm | 7cm | 4cm |
(slide width = 33.87cm; nodes are vertically centered at y=9cm)
4-node: x=1, 8.5, 16, 23.5cm. Width 6cm, y=8cm, height 3cm. 5-node: x=0.5, 7, 13.5, 20, 26.5cm. Width 5.5cm.
Title = shape[1]. Flow shapes start at shape[2]. Add all shapes BEFORE connectors. Connectors work within the same batch.
Node text color rule (H-11 enforcement):
Node cards on dark-background slides use dark fills (e.g.,$PRIMARY,$DARK2). All text on these nodes — both the title text and the description text below the node — MUST use light colors.
- Node title text:"color":"FFFFFF"or"color":"$LIGHT_TEXT"
- Node description text:"color":"E8E8E8"or"color":"FFFFFF"— never use `MUTED` (6B7B8D) on dark node backgrounds; it is too dark to read
- Only useMUTEDor"color":"333333"when the node card has a light fill.
Connector reliability: Add connectors in a separate batch AFTER all node shapes are created. Verify each connector is visible. If batch connectors are unreliable, add them one at a time with individual add commands.MANDATORY CONNECTOR VERIFICATION (PNG only):
Do NOT use officecli view slides.pptx svg to verify connectors — SVG rendering may disagree with LibreOffice.You MUST verify connectors via the authoritative screenshot pipeline:
screenshot.mjs → PDF → PNG>
After generating the PNG, verify ALL of the following — both checks are required:
1. Every connector is visible (not missing or transparent)
2. No connector overlaps or obscures any text shape — zoom into each node label in the PNG and confirm the connector line/arrow does not cross over any text content
>
If a connector is missing in the PNG screenshot:
- Fall back to a visible rightArrow shape instead of connector: {"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"rightArrow","x":"...","y":"...","width":"1.5cm","height":"0.8cm","fill":"ACCENT_COLOR","line":"none"}}- rightArrow shapes render reliably in all viewers.
>
If a connector overlaps text in the PNG screenshot:
- Add 0.5cm of padding to the connector's start or end point by adjustingstartX/startY/endX/endYto move the endpoint away from the text region; OR
- Use --prop zorder=back on the connector to send it behind the text shape; OR- Replace with a rightArrow fallback (see above) positioned to avoid the text box.Coordinate tip for precise connectors: Before specifying startX/startY/endX/endY, confirm adjacent node positions with:```bash
officecli get deck.pptx "/slide[N]" --depth 1 --json
```
Use the returnedx,y,width,heightvalues to calculate exact connector endpoints (e.g.,startX = nodeX + nodeWidth,startY = nodeY + nodeHeight/2).
C.10 Timeline / Roadmap (Horizontal)
Spine: connector at y=10cm, full width. 4 milestones (3x3cm circles) at x=4, 12, 20, 28cm, y=8.5cm. Alternating above/below labels: odd at y=5.5cm/7cm, even at y=12cm/13.5cm. ~19 elements -- single batch (reliable).
Add the spine connector first:
officecli add deck.pptx "/slide[N]" --type connector --prop preset=straight --prop startX=2cm --prop startY=10cm --prop endX=32cm --prop endY=10cm --prop line=$SECONDARY --prop lineWidth=2ptC.11 Avatar Grid
2-person (centered, symmetric):
| Element | X | Y | Width | Height |
|---|---|---|---|---|
| Person 1 avatar | 7cm | 6cm | 8cm | 5cm |
| Person 2 avatar | 18cm | 6cm | 8cm | 5cm |
Name (bold 16pt) + role (16pt) centered below each avatar; use same X and width as avatar.
2x2: circles at (6cm, 4.5cm), (20cm, 4.5cm), (6cm, 12.5cm), (20cm, 12.5cm). Size 3.5x3.5cm. 3-row: circles at x=4.5, 15.5, 26.5cm, y=5cm. Size 3x3cm.
Each member: ellipse + initials overlay + name (bold 16pt) + role (16pt) = 4 elements. Name width 6cm centered.
CRITICAL — 3-person layout: use the batch template below exactly. Each person occupies a fixed column; bio text is pinned to an absolute y-coordinate to prevent overlap. Do NOT shrink height below the values shown.
3-person complete batch example (x=1.5, 12.0, 22.5cm columns; slide width 33.87cm):
cat <<'EOF' | officecli batch deck.pptx
[
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Meet the Team","x":"2cm","y":"1cm","width":"29.87cm","height":"3cm","font":"Georgia","size":"36","bold":"true","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"2.5cm","y":"4.5cm","width":"3cm","height":"3cm","fill":"$SECONDARY","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"AB","x":"2.5cm","y":"4.5cm","width":"3cm","height":"3cm","font":"Georgia","size":"22","bold":"true","color":"FFFFFF","align":"center","valign":"middle","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Alice Brown","x":"1.5cm","y":"8cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"CEO & Co-Founder","x":"1.5cm","y":"9.5cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"10 yrs enterprise SaaS. Ex-Salesforce. Led $50M ARR growth.","x":"1.5cm","y":"11.2cm","width":"9cm","height":"5cm","font":"Calibri","size":"16","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"13.5cm","y":"4.5cm","width":"3cm","height":"3cm","fill":"$ACCENT1","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"CD","x":"13.5cm","y":"4.5cm","width":"3cm","height":"3cm","font":"Georgia","size":"22","bold":"true","color":"FFFFFF","align":"center","valign":"middle","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Carlos Diaz","x":"12.5cm","y":"8cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"CTO & Co-Founder","x":"12.5cm","y":"9.5cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"ML infra at scale. Ex-Google Brain. 3 patents in NLP.","x":"12.5cm","y":"11.2cm","width":"9cm","height":"5cm","font":"Calibri","size":"16","color":"$PRIMARY","align":"left","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"preset":"ellipse","x":"24.5cm","y":"4.5cm","width":"3cm","height":"3cm","fill":"$ACCENT2","line":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"EF","x":"24.5cm","y":"4.5cm","width":"3cm","height":"3cm","font":"Georgia","size":"22","bold":"true","color":"FFFFFF","align":"center","valign":"middle","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"Eva Fischer","x":"23.5cm","y":"8cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","bold":"true","color":"$PRIMARY","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"VP Sales","x":"23.5cm","y":"9.5cm","width":"5cm","height":"1.5cm","font":"Calibri","size":"16","color":"64748B","align":"center","fill":"none"}},
{"command":"add","parent":"/slide[N]","type":"shape","props":{"text":"$30M pipeline closed in 18 months. Ex-HubSpot, AWS.","x":"23.5cm","y":"11.2cm","width":"9cm","height":"5cm","font":"Calibri","size":"16","color":"$PRIMARY","align":"left","fill":"none"}}
]
EOFNo-overlap rule: Each person's column is 11cm wide (gap between columns ≥ 1cm). Avatar at y=4.5cm, name at y=8cm, role at y=9.2cm, bio at y=10.5cm — all three persons share the same y-coordinates. Bio text box height=5.5cm; keep bio text to 2-3 short sentences to avoid overflow.
C.12 Closing / CTA (Dark Gradient)
Mirror slide 1 gradient. Main CTA (44-48pt) at y=4cm, details (16pt) at y=9cm, contact (12pt) at y=15cm. Transition: fade.
---
Section D: Charts
D.0 Chart Styling Baseline (Mandatory)
Apply to EVERY chart. No default PowerPoint styling is acceptable.
Light theme (white/light backgrounds):
plotFill=none, chartFill=none, gridlines="E2E8F0:0.5",
axisFont="10:64748B:Calibri", legendFont="10:64748B:Calibri",
series.outline="FFFFFF-0.5", legend=bottomDark theme (dark backgrounds):
plotFill=none, chartFill=none, gridlines="2A2A4A:0.5",
axisFont="10:6B7B8D:Calibri", legendFont="10:6B7B8D:Calibri",
series.outline="FFFFFF-0.5", legend=bottom`gap` MUST be set via a separate `set` command after chart creation. It is ignored during `add`.
D.1 Column Chart (Single Series)
officecli add deck.pptx "/slide[N]" --type chart \
--prop chartType=column --prop title="Quarterly ARR ($K)" \
--prop categories="Q1,Q2,Q3,Q4" --prop series1="ARR:1400,1720,2060,2400" \
--prop x=2cm --prop y=4cm --prop width=18cm --prop height=13cm \
--prop colors=1A73E8 --prop plotFill=none --prop chartFill=none \
--prop "gridlines=E2E8F0:0.5" --prop dataLabels=value --prop labelPos=outsideEnd \
--prop "labelFont=10:64748B:false" --prop "axisFont=10:64748B:Calibri" \
--prop "legendFont=10:64748B:Calibri" --prop "series.outline=FFFFFF-0.5" --prop legend=bottom
officecli set deck.pptx "/slide[N]/chart[1]" --prop gap=80All subsequent chart recipes include the same D.0 baseline props. Only type-specific differences are noted.
D.2 Multi-Series Column
Same as D.1 but with series1 + series2 and two colors. Post-creation gap=80 required.
Empty series values are not supported. Use0for missing data points:series1="Actual:1400,1720,2060,2400,0,0,0,0"/series2="Projected:0,0,0,0,3000,3800,4700,5800". Note: this produces zero-height bars instead of gaps. For true gap visualization, use separate charts.
D.3 Doughnut
chartType=doughnut, data="Rating:42,38,14,4,2", dataLabels=percent, legend=right. No gap step needed. Use 5 colors from strong to muted.
Known limitation: The `colors` parameter may not apply to doughnut charts. PowerPoint may render doughnut segments in default Office colors instead of specified colors. This is a CLI limitation. Verify colors via screenshot after creation. If colors are wrong, there is currently no workaround.
D.4 Combo Chart (Dual-Axis) -- HIGHEST RISK
BothcomboSplit=1ANDsecondary=2are REQUIRED. Missing either causes incorrect rendering.
HARD RULE: Before creating a combo chart, verify that both series use similar ranges (e.g., both 0-100 or both 0-10). If ranges differ by more than 10x (e.g., $M values vs % values), DO NOT use a combo chart. Instead, create two separate side-by-side charts: a bar chart for the absolute values and a line chart for the percentages. Place them using pattern C.4 (chart left + stats right) or use two 50% width charts.
⚠️ WARNING — Dual-series magnitude mismatch: If one series uses values in the millions (e.g., Revenue $M: 2, 5, 8, 12) and the other uses counts or percentages (e.g., Customer Count: 200, 450, 800, 1200), the smaller-magnitude series will be rendered nearly invisible even withsecondary=2. Examples of dangerous combinations: Revenue ($M) + Customer Count, ARR ($M) + Headcount, Market Share (%) + Absolute Sales. Check the ratio before building: ifmax(series1) / max(series2) > 10ormax(series2) / max(series1) > 10, you MUST split into two separate charts. After building a dual-series chart, always run a screenshot to verify both series are visually legible.
Single combo chart (ONLY when both series have similar ranges):
officecli add deck.pptx "/slide[N]" --type chart \
--prop chartType=combo --prop categories="Year 0,Year 1,Year 2,Year 3" \
--prop "series1=Cost Savings ($M):-0.8,1.2,2.8,3.5" \
--prop "series2=Cumulative ROI (%):-100,50,250,340" \
--prop comboSplit=1 --prop secondary=2 \
--prop colors=00D4AA,FFA502 \
--prop plotFill=none --prop chartFill=none --prop "gridlines=2A2A4A:0.5" \
--prop "axisFont=10:6B7B8D:Calibri" --prop "legendFont=10:6B7B8D:Calibri" \
--prop "series.outline=FFFFFF-0.5" --prop legend=bottom \
--prop x=2cm --prop y=4cm --prop width=29cm --prop height=13cm
officecli set deck.pptx "/slide[N]/chart[1]" --prop gap=80comboSplit=1 = first series as bars, rest as lines. secondary=2 = series 2 on secondary Y-axis.
Two-Chart Alternative (REQUIRED when ranges differ by >10x):
Use two separate charts side by side instead of a single combo chart. This avoids the dual-axis scale mismatch that makes the smaller series invisible.
# Left chart: bar chart for absolute values (55% width)
officecli add deck.pptx "/slide[N]" --type chart \
--prop chartType=column --prop title="Cost Savings ($M)" \
--prop categories="Year 0,Year 1,Year 2,Year 3" \
--prop "series1=Cost Savings:-0.8,1.2,2.8,3.5" \
--prop colors=00D4AA \
--prop plotFill=none --prop chartFill=none --prop "gridlines=2A2A4A:0.5" \
--prop "axisFont=10:6B7B8D:Calibri" --prop "legendFont=10:6B7B8D:Calibri" \
--prop "series.outline=FFFFFF-0.5" --prop legend=bottom \
--prop x=2cm --prop y=4cm --prop width=15cm --prop height=13cm
officecli set deck.pptx "/slide[N]/chart[1]" --prop gap=80
# Right chart: line chart for percentages (45% width)
officecli add deck.pptx "/slide[N]" --type chart \
--prop chartType=line --prop title="Cumulative ROI (%)" \
--prop categories="Year 0,Year 1,Year 2,Year 3" \
--prop "series1=ROI:-100,50,250,340" \
--prop colors=FFA502 \
--prop plotFill=none --prop chartFill=none --prop "gridlines=2A2A4A:0.5" \
--prop "axisFont=10:6B7B8D:Calibri" --prop "legendFont=10:6B7B8D:Calibri" \
--prop "series.outline=FFFFFF-0.5" --prop legend=bottom \
--prop x=18cm --prop y=4cm --prop width=14cm --prop height=13cmD.5 Radar Chart
chartType=radar, 3 series via series1/series2/series3. Position: x=4cm, width=26cm, height=14cm. Include D.0 dark-theme baseline. No gap step needed.
D.6 Stacked Area Chart
chartType=areaStacked, 3 series. Position: x=2cm, width=17cm, height=13cm. Include D.0 light-theme baseline. No gap step needed.
---
Section E: Tables
CONSTRUCTION ORDER (violating this produces inconsistent fonts):
1. Create table (add --type table)2. Populate all rows with set tr[N]3. Set table-levelsize/font/border
4. Apply cell-level styling (fill,boldonly -- NOT cell-levelcolor)
Cell-level `color` produces validation errors. Use row-levelcolorwhen populating rows. For cell-level styling, use onlyfillandbold.
E.1 Comparison Table
H-PALETTE reminder for comparison tables: Do NOT use red to mark competitor weaknesses or green to mark your advantages. Use palette colors only:
- Your product column header →fill=$PRIMARYorfill=$SECONDARY,color=FFFFFF
- Competitor column headers →fill=$DARKorfill=$DARK2,color=FFFFFF(or light palette color on light background)
- "Yes" / checkmark cells in your column →fill=$LIGHT+bold=true(NO green)
- "No" / cross cells in competitor columns → leave default fill or use a subtle dark shade from palette (NO red)
- Cell text for all status values (Yes/No/Partial/✓/✗) → same color as the row; do NOT change individual cell colors to red/greenofficecli add deck.pptx "/slide[N]" --type table \
--prop rows=7 --prop cols=5 --prop x=2cm --prop y=4.5cm --prop width=29.87cm --prop height=13cm
officecli set deck.pptx "/slide[N]/table[1]/tr[1]" \
--prop c1="Feature" --prop c2="DataFlow" --prop c3="Fivetran" --prop c4="Airbyte" --prop c5="Stitch" \
--prop bold=true --prop fill=0F2B46 --prop color=FFFFFF --prop size=12
officecli set deck.pptx "/slide[N]/table[1]/tr[2]" \
--prop c1="No-code setup" --prop c2="Yes" --prop c3="Partial" --prop c4="No" --prop c5="Partial" --prop size=11
# ... populate remaining rows, then table-level font ...
officecli set deck.pptx "/slide[N]/table[1]" --prop size=11 --prop font=Calibri --prop border=E0E0E0
# Highlight "your product" column: cell-level fill + bold only (NO cell-level color, NO green)
officecli set deck.pptx "/slide[N]/table[1]/tr[2]/tc[2]" --prop fill=E8F0FE --prop bold=trueE.2 Pricing Table (3-Tier)
Same create -> populate -> table-level font -> cell-level fill pattern. 6 rows x 4 cols. Header: fill=$PRIMARY, color=FFFFFF, bold, size=14. Recommended column: highlight header cell fill=F9AB00, body cells fill=F0EEFF (fill only, no cell-level color).
E.3 Financial Impact Table (with Cell Merge)
officecli add deck.pptx "/slide[N]" --type table \
--prop rows=10 --prop cols=4 --prop x=2cm --prop y=5cm --prop width=29.87cm --prop height=13cm
# Header
officecli set deck.pptx "/slide[N]/table[1]/tr[1]" \
--prop c1="" --prop c2="Without" --prop c3="With" --prop c4="Improvement" \
--prop bold=true --prop fill=00D4AA --prop color=0D0D1A --prop size=12
# Section header: populate THEN merge
officecli set deck.pptx "/slide[N]/table[1]/tr[2]" \
--prop c1="INCIDENT METRICS" --prop bold=true --prop fill=1A1A3E --prop color=00D4AA --prop size=11
officecli set deck.pptx "/slide[N]/table[1]/tr[2]/tc[1]" --prop merge.right=3
# Data rows, more section headers, then table-level styling...
officecli set deck.pptx "/slide[N]/table[1]" --prop size=11 --prop font=Calibri --prop border=2A2A4Amerge.right=3 merges tc[1] with 3 cells to its right (4-column span). After merge, only set content on tc[1]. See H-5 for validation warning.
---
Section F: Visual Polish
F.1 Gradient Backgrounds
# Linear 2-color with angle
officecli add deck.pptx / --type slide --prop layout=blank --prop "background=0F2B46-0A1628-180"
# Radial gradient
officecli add deck.pptx / --type slide --prop layout=blank --prop "background=radial:0D0D1A-1A1A3E-center"
# Linear 3-color (no custom stops)
officecli set deck.pptx "/slide[N]" --prop "background=1E2761-4472C4-CADCFC"Custom gradient stop positions (`@` syntax) are NOT supported for slide backgrounds. Bothaddandsetfail with "Invalid color value" when usingC1@0-C2@70-C3@100on slide backgrounds. Use simple 2-color or 3-color gradients. The@syntax works only on shapegradientfills (e.g.,--prop "gradient=FF0000@0-FFFF00@50-00FF00@100"on a shape).
F.2 Transitions
# Title and closing slides
officecli set deck.pptx "/slide[1]" --prop transition=fade
officecli set deck.pptx "/slide[N]" --prop transition=fade
# Content slides
officecli set deck.pptx "/slide[2]" --prop transition=push-leftUse at most 2-3 transition types per deck. Dark themes may use fade throughout.
F.3 Entrance Animations (Case Study Reveals Only)
Use sparingly -- only for sequential stat reveals on case study slides.
# First stat: click-triggered
officecli set deck.pptx "/slide[N]/shape[2]" --prop animation=fade-entrance-400-click
# Subsequent stats: auto-after with 200ms delay
officecli set deck.pptx "/slide[N]/shape[3]" --prop animation=fade-entrance-400-after-delay=200
officecli set deck.pptx "/slide[N]/shape[4]" --prop animation=fade-entrance-400-after-delay=200Transitions and animations coexist without conflict.
F.4 z-Order Management
Add background shapes first, content shapes second to avoid z-order changes. If needed: --prop zorder=back / zorder=front. Warning: z-order changes renumber shape indices -- process highest index first.
F.5 Connectors
Add all shapes BEFORE connectors. Title = shape[1], flow shapes start at shape[2]. Connectors can reference shapes from the same batch.
officecli add deck.pptx "/slide[N]" --type connector \
--prop preset=elbow --prop startShape=2 --prop endShape=3 \
--prop line=1A73E8 --prop lineWidth=2pt --prop tailEnd=triangleF.6 Align and Distribute
officecli set deck.pptx "/slide[N]" --prop distribute=horizontal --prop "targets=shape[2],shape[4],shape[6]"
officecli set deck.pptx "/slide[N]" --prop align=bottom --prop "targets=shape[2],shape[4],shape[6]"---
Section G: QA Checklist
Run before every delivery.
Automated
# Must return zero errors (see H-5 for cell merge exception)
officecli validate deck.pptx
# Check for issues
officecli view deck.pptx issues
# NOTE: All slides using layout=blank will report "Slide has no title"
# This is EXPECTED behavior — pitch-deck uses blank layout (no built-in PowerPoint title
# placeholder). This warning is safe to ignore. Not a bug.
# Visual preview per slide (use --start/--end, NOT --slide or --output which do not exist)
officecli view deck.pptx svg --start 1 --end 1 > /tmp/slide1.svg # slide 1
officecli view deck.pptx svg --start 2 --end 2 > /tmp/slide2.svg # slide 2
# For gradient-background slides: SVG renders gradient as white — use html mode for visual QA
officecli view deck.pptx html --browserManual Verification
- [ ]
officecli validate= 0 errors (exception: cell merge slides may report schema warnings) - [ ] Every chart is editable in PowerPoint (click -> Edit Data appears)
- [ ] Every table is a native table object (click -> table editing mode)
- [ ] No two consecutive slides share the same layout structure
- [ ] Speaker notes on every content slide (all except title and closing), >= 2 sentences each
- [ ] All text fully visible (no overflow, no overlap, no off-slide)
- [ ] At least one slide has 3+ stat callouts with number >= 36pt and label <= 16pt
- [ ] Gradient background on both slide 1 and last slide
- [ ] Color palette consistent across all slides (no random/default colors)
- [ ] H-PALETTE: No red/green/gray introduced for status indicators in comparison tables or flow diagrams — all colors trace back to declared palette variables
- [ ] H-FONT font consistency: Every shape has an explicit
fontvalue; only Georgia and Calibri appear across all shapes (no Arial, Helvetica, or default fonts) - [ ] On dark-background slides, verify all text uses light colors (no default black text)
- [ ] Charts use modern styling (plotFill=none, chartFill=none, subtle gridlines)
- [ ] For any slide with connectors: take a screenshot/SVG preview and verify EACH connector is visible before proceeding. CLI may report success even when rendering fails (H-14).
- [ ] For any dual-series chart: verify both series are visible at scale. If one series appears invisible (ranges differ >10x), STOP and split into two charts immediately (D.4 HARD RULE).
- [ ] Layout density check: Content must occupy ≥ 60% of the canvas on every slide. If a slide has large empty zones (more than 40% whitespace), fix it by: (a) adding a supporting stat or data point, (b) adding a visual element (icon, chart, callout box), or (c) increasing the size of existing elements. Slides with only 2-3 small elements and large blank areas below will fail evaluation.
- [ ] Connector overlap check: For any slide with connectors or arrows, confirm in the PNG screenshot that no connector line or arrowhead overlaps a text box. If overlap is found, reposition or use
zorder=backbefore delivery (see C.9).
---
Section H: Known Bugs & Lessons
Read these before building. Each one has caused production failures.
>
HARD RULE items are non-negotiable -- violation produces broken output. WARNING items are strong guidance that should be followed unless you have a specific reason not to. Known limitation items cannot be worked around.
| # | Issue | Workaround |
|---|---|---|
| H-1 | gap ignored during chart add | Apply via officecli set "/slide[N]/chart[1]" --prop gap=80 after creation |
| H-2 | Table font cascade overwritten by row set | Set table-level size/font AFTER all rows populated |
| H-3 | Shell $ in batch JSON or set commands | Batch: use heredoc: `cat <<'EOF' \ |
| H-4 | Combo chart requires both comboSplit=1 AND secondary=2 | Missing either causes incorrect rendering. Always include both |
| H-5 | Cell merge (merge.right=N) produces validation errors | PowerPoint renders correctly. Note in delivery message |
| H-6 | Cell-level color on table cells causes validation errors | Use row-level color instead; cell-level fill + bold only |
| H-7 | Custom gradient stops (@) fail on slide backgrounds | Use 2/3-color gradients. @ syntax works only on shape gradient fills |
| H-8 | Connector shape indices: title = shape[1] | Flow shapes start at shape[2]. Count from first shape on slide |
| H-9 | z-order changes cause shape index renumbering | Process highest index first. Re-query with get --depth 1 if needed |
| H-10 | Chart series count fixed at creation | Include ALL series in add. To add series, delete and recreate |
| H-11 | Dark theme text invisible (defaults to black) | Explicitly set light color on every text shape on dark backgrounds |
| H-12 | zsh glob-expands [N] in paths | Always double-quote: "/slide[1]/chart[1]" |
| H-13 | Batch threshold | Reliable for up to ~20 operations per batch. Split larger batches into groups of 15-20. Heredoc syntax mandatory |
| H-14 | Connector arrows may not all render in batch | Add connectors in separate batch after shapes. If still missing, add one at a time |
| H-15 | Doughnut chart colors parameter may not apply | CLI accepts the parameter without error but PowerPoint renders default colors. No workaround. Verify via screenshot. |
| H-16 | Empty table cell string c1="" causes validation error | Use a space character c1=" " instead of empty string for blank cells |