AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Pro Deck Builder

skill-thatrebeccarae-claude-marketing-pro-deck-builder · by thatrebeccarae

Create polished HTML slide decks and PDF-ready documents for consulting deliverables. Uses the RRBC design system with warm light mode, dark mode cover pages, Lora/Inter/Roboto Mono typography, and data visualization palette. Trigger on 'deck', 'slides', 'presentation', 'pitch deck', 'keynote', 'report', or 'PDF'.

— No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-thatrebeccarae-claude-marketing-pro-deck-builder

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-thatrebeccarae-claude-marketing-pro-deck-builder)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
○ 4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Pro Deck Builder? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Presentation Designer

VC-backed SaaS design quality for PowerPoint. Think Linear, Attio, Vercel, Raycast — not corporate clip art.

Install

git clone https://github.com/thatrebeccarae/claude-marketing.git && cp -r claude-marketing/skills/pro-deck-builder ~/.claude/skills/

Quick Reference

| Task | Approach | |------|----------| | Create from scratch | Read [REFERENCE.md](REFERENCE.md), use PptxGenJS | | Edit existing / use template | Read [editing.md](editing.md) | | Read/extract content | python -m markitdown presentation.pptx | | Visual overview | python scripts/thumbnail.py presentation.pptx |


Before You Start (Required Steps)

Step 1: Ask the User

Before writing any code, ask:

  1. Light or dark mode? Dark = premium/keynote feel. Light = reports/data-heavy decks.
  2. Palette preference? Show the palette table below, or ask if they have brand colors.
  3. Logo? Ask if they have a logo file to include (PNG/SVG path).

Step 2: Discover Fonts

Check what's installed — premium fonts make a massive difference:

# macOS — list all installed font families
fc-list : family | sort -u

# Search for premium fonts first
fc-list : family | grep -iE "inter|dm.sans|poppins|avenir|futura|geist|sf.pro|sf.mono|jetbrains|fira.code|montserrat|playfair|source.sans"

# Check macOS Font Book directories directly
ls ~/Library/Fonts/ /Library/Fonts/ /System/Library/Fonts/Supplemental/ 2>/dev/null

Priority order for font selection:

  1. Inter — the gold standard for SaaS UI (if installed, use it for everything)
  2. DM Sans — geometric, startup-friendly
  3. Poppins — rounded, approachable
  4. Avenir / Avenir Next — ships with macOS, Apple-adjacent elegance
  5. Calibri — safe fallback, always available

For data/mono: JetBrains Mono > Fira Code > SF Mono > Consolas


Design Language: VC-Backed SaaS

Aesthetic Principles

  1. Depth through layering — Surfaces float above backgrounds. Cards and panels have subtle elevation via shadows and fine borders, not flat colored boxes.
  2. Bold typography, minimal decoration — Let type hierarchy do the work. No accent lines, no decorative shapes, no clip art.
  3. Restrained color — One accent color used sparingly (10%). Mostly neutrals. Color = signal, not decoration.
  4. Generous whitespace — Empty space signals confidence. If a slide feels sparse, make the content bigger, don't add more.
  5. Every element earns its place — Before adding anything: what does it communicate? If removing it changes nothing, remove it.

Light vs Dark Mode

The user picks one mode for the entire deck. Never mix modes within a deck.


Color System

Dark Mode (Default — Premium/Keynote)

| Token | Value | Use | |-------|-------|-----| | bg-primary | 0A0A0C | Slide backgrounds (deep space black) | | bg-surface | 17181A | Cards, panels (deep slate) | | bg-elevated | 1E1F23 | Elevated surfaces, hover states | | bg-glass | FFFFFF at 4% opacity | Translucent overlays | | text-primary | FFFFFF | Headlines, key content | | text-secondary | A0A0A0 | Body text, descriptions | | text-muted | 5A5A5E | Captions, metadata, labels | | border-subtle | FFFFFF at 8% opacity | Card borders |

Light Mode (Reports/Data-Heavy)

| Token | Value | Use | |-------|-------|-----| | bg-primary | FFFFFF | Slide backgrounds | | bg-surface | F8F9FA | Cards, panels | | bg-elevated | FFFFFF | Elevated surfaces (use shadow) | | text-primary | 111111 | Headlines, key content | | text-secondary | 555555 | Body text, descriptions | | text-muted | 999999 | Captions, metadata, labels | | border-subtle | E8E8E8 | Card borders |


Palette System

Each palette defines one accent color (used at 10%) plus semantic status colors. The accent is the personality — everything else is neutral.

Built-In Palettes

| Name | Accent | Hex | Best For | |------|--------|-----|----------| | Electric Blue | Intense azure | 0055FF | SaaS, tech, product | | Neon Lime | Acid green | 39FF14 | Dev tools, performance | | Hot Coral | Warm energy | FF6B6B | Marketing, creative | | Indigo | Deep purple | 6366F1 | Startups, AI/ML | | Teal Trust | Cool confidence | 0D9488 | Healthcare, finance | | Amber Signal | Warm authority | F59E0B | Consulting, strategy | | Rose | Refined pink | F43F5E | Design, brand, luxury | | Emerald | Growth green | 10B981 | Sustainability, success | | Cyan Edge | Sharp blue-green | 06B6D4 | Data, analytics | | Violet | Creative depth | 8B5CF6 | Education, innovation | | Slate | No accent | 64748B | Minimal, understated | | Gold Standard | Financial premium | D4AF37 | Investor, board decks |

Custom Palette (User Brand Colors)

If the user provides brand colors, build a custom palette:

const palette = {
  accent: "0055FF",      // primary brand color
  accentMuted: "0055FF" + " at 15% opacity", // for tinted backgrounds
  positive: "10B981",    // good, up, success
  warning: "F59E0B",     // attention, caution
  critical: "EF4444",    // bad, down, error
};

Color Application: 85/10/5 Rule

  • 85% — Backgrounds + neutral text (bg + text tokens from mode)
  • 10% — Accent (key numbers, chart primary, CTAs, active states)
  • 5% — Semantic status (positive/warning/critical in KPIs and data)

Typography

Font Priority

Run font discovery (Step 2 above), then pick:

| Priority | Header | Body | Data/Mono | Vibe | |----------|--------|------|-----------|------| | 1st | Inter 700 | Inter 400 | JetBrains Mono | Linear/Vercel | | 2nd | DM Sans 700 | DM Sans 400 | Fira Code | Geometric startup | | 3rd | Avenir Next Bold | Avenir 400 | SF Mono | Apple-adjacent | | 4th | Poppins 700 | Poppins 400 | JetBrains Mono | Friendly modern | | Safe | Calibri Bold | Calibri | Consolas | Always available |

For editorial/financial decks:

| Header | Body | Vibe | |--------|------|------| | DM Serif Display | DM Sans | Sophisticated editorial | | Playfair Display | Source Sans Pro | Luxury, financial | | Georgia | Calibri | Classic corporate |

Size Scale

| Role | Size | Weight | Use | |------|------|--------|-----| | Hero title | 54-72pt | Bold (700) | Title slide only | | Slide title | 32-40pt | Bold (700) | Every content slide | | Section header | 20-24pt | Semibold (600) | Within-slide sections | | Body text | 14-16pt | Regular (400) | Paragraphs, bullets | | Captions/meta | 10-12pt | Regular (400) | Footnotes, sources | | Big KPI number | 48-72pt | Bold (700) | Dashboard callouts | | KPI label | 9-10pt | Semibold, ALL CAPS, +tracking | Below KPI numbers | | Data/numbers | 11-14pt | Mono regular | Tables, data labels |

Typography Rules

  • Left-align body text and lists — center ONLY titles and KPI values
  • Max 2 font families per deck (+1 mono for data)
  • ALL CAPS + charSpacing only for small labels (KPI labels, category tags)
  • Line height: 1.3x for body, 1.1x for titles
  • Never underline for emphasis — use bold or accent color

Text Fitting (Prevents Overflow)

Big numbers and titles WILL overflow if you use a fixed font size without checking content length. Use these rules:

Big KPI Numbers — scale font to character count:

| Characters | Example | Max Font Size (card) | Max Font Size (standalone) | |------------|---------|---------------------|--------------------------| | 1–4 | $4.2M | 48pt | 72pt | | 5–7 | $5,307K | 36pt | 54pt | | 8–10 | $5,307,540 | 28pt | 44pt | | 11+ | $12,345,678 | 22pt | 36pt |

Rule: prefer abbreviated numbers. $5.3M > $5,307,540. Only use full numbers in tables or footnotes where precision matters.

Slide Titles — max characters before wrapping:

| Font Size | Max Chars (~9" wide) | If Longer | |-----------|---------------------|-----------| | 54pt | ~30 | Reduce to 44pt or rewrite shorter | | 44pt | ~38 | Reduce to 36pt or rewrite shorter | | 36pt | ~46 | Reduce to 32pt or rewrite shorter | | 32pt | ~52 | Use subtitle for overflow |

Rule: count characters before setting fontSize. Never let content slide titles wrap to 2 lines. Section dividers can wrap.

Body Text in Narrow Containers (Insight Panels, Sidebars):

Text overflow in narrow panels (=1000000]"$"#,##0.0,,"M";[>=1000]"$"#,##0.00,"K";"$"#,##0';

values: [2888000, 717734, 425467, 3655], // raw dollar values dataLabelFormatCode: currFmt, // conditional brackets OK here valAxisLabelFormatCode: '"$"#,##0.0,,"M"', // simple format only (no brackets)


```javascript
// ✅ ALSO OK: Pre-scale when all values are same magnitude
values: [2888, 718, 425],  // raw values divided by 1000
dataLabelFormatCode: '"$"#,##0"K"',
valAxisLabelFormatCode: '"$"#,##0"K"',
// ❌ WRONG: Raw values with axis-only format
values: [2888000, 718000, 425000],
valAxisLabelFormatCode: "$#,##0,K",  // axis may format but data labels show 2888000
// ❌ WRONG: numFmt (not a valid PptxGenJS property)

OOXML conditional format reference (use with RAW values):

| Data Range | Format Code | Renders As | |------------|-------------|------------| | Currency (auto-scale) | '[>=1000000]"$"#,##0.0,,"M";[>=1000]"$"#,##0.00,"K";"$"#,##0' | $2.9M, $540.18K, $500 | | Plain number (auto-scale) | '[>=1000000]#,##0.0,,"M";[>=1000]#,##0.00,"K";#,##0' | 2.9M, 540.18K, 500 | | Percentage | '0%' | 50%, 85% |

Format code syntax: OOXML supports up to 2 conditions in brackets + a default: [condition1]format1;[condition2]format2;defaultFormat. Each trailing , divides by 1,000 (so ,, divides by 1M).

IMPORTANT: valAxisLabelFormatCode does NOT support OOXML conditional brackets [>=1000]. Use a simple format for the axis based on the data range:

| Axis Range | valAxisLabelFormatCode | Renders As | |------------|----------------|------------| | Up to ~999K | '"$"#,##0,"K"' | $0K, $100K, $500K | | Up to ~10M+ | '"$"#,##0.0,,"M"' | $0.0M, $0.5M, $1.0M | | Up to ~999 | '"$"#,##0' | $0, $100, $500 |

Use the conditional currFmt for dataLabelFormatCode (which supports brackets), but a simple format for valAxisLabelFormatCode. Always set showValue: true with dataLabelPosition: "outEnd" on bar charts so readers can see exact values without tracing to the axis.


Spacing

| Token | Value | Use | |-------|-------|-----| | xs | 0.125" | Within grouped elements | | sm | 0.25" | Label to value, icon to text | | md | 0.375" | Between sections within a card | | lg | 0.5" | Between cards, major sections | | xl | 0.75" | Between content zones |

Layout Grid (10" × 5.625")

Margins:       0.5" from all edges
Content area:  9.0" wide × ~4.5" tall
Title zone:    y = 0.3"
Content zone:  y = 1.0" to y = 5.0"
Footer zone:   y = 5.2"
Card gap:      0.25" - 0.3"

Logo Placement

Finding Logos

find ~/Desktop ~/Downloads ~/Documents -maxdepth 3 -iname "*logo*" \( -name "*.png" -o -name "*.svg" -o -name "*.jpg" \) 2>/dev/null

Placement Patterns

| Slide Type | Position | Size | Notes | |------------|----------|------|-------| | Title slide (top-left) | x:0.5, y:0.4 | w:1.5, h:0.5 | Subtle brand mark | | Title slide (centered) | x:4.0, y:0.8 | w:2.0, h:0.7 | Above title text | | Content slides | x:8.5, y:0.2 | w:1.0, h:0.35 | Top-right corner, every slide | | Closing slide | x:3.5, y:1.5 | w:3.0, h:1.0 | Centered, hero size |

Logo Rules

  • Always use sizing: { type: "contain", w, h } to preserve aspect ratio
  • Content slides: max 1" wide, don't compete with content
  • Title/closing: up to 3" wide for brand moment
  • Dark mode: use white/light logo variant if available (ask user)
  • Slide master: if logo goes on every slide, add it to a master definition

Icons

Pipeline: react-icons → sharp → PNG → PptxGenJS

npm install -g react-icons react react-dom sharp

Prefer Lucide (react-icons/lu) or Feather (react-icons/fi) — they match the Linear/Vercel icon language.

| Package | Import | Style | |---------|--------|-------| | react-icons/lu | Lucide | Linear-style, clean | | react-icons/fi | Feather | Thin, modern | | react-icons/hi2 | Heroicons v2 | Apple-ish | | react-icons/tb | Tabler | Consistent strokes |

Icon Sizes

| Context | Display Size | Color | |---------|-------------|-------| | KPI card icon | 0.35" × 0.35" | Accent on dark, muted on light | | Feature row icon | 0.4" × 0.4" | White inside accent circle | | Section divider | 0.5" × 0.5" | Accent color | | Inline bullet | 0.25" × 0.25" | text-secondary |


Reusable Components

Bottom Callout Box (Standardized)

Many slides end with a highlighted callout box (recommendation, key insight, total impact). These must be visually identical across all slides:

| Property | Value | Notes | |----------|-------|-------| | Box height | 0.6" | Always 0.6" — never 0.5", 0.7", 0.9" | | Text height | 0.5" | Fits inside 0.6" box with padding | | Font size | 11pt | Always 11pt bold — never 12pt or 13pt | | Font | theme.font.body | Bold, left-aligned, valign: "middle" | | Box x/w | x: 0.5, w: 9.0 | Full content width | | Text x/w | x: 0.7, w: 8.6 | Inset 0.2" from box edges | | Text y offset | box y + 0.05" | Centers text vertically in box | | Corner radius | 0.06" | Consistent across all callouts |

// Standard bottom callout — copy this pattern exactly
s.addShape(pres.shapes.RECTANGLE, {
  x: 0.5, y: calloutY, w: 9.0, h: 0.6,
  fill: { color: "DCFCE7" },  // or theme.accentMuted, "FEF3C7", etc.
  line: { color: theme.status.positive, width: 0.75 },
  rectRadius: 0.06,
});

s.addText("Callout text here.", {
  x: 0.7, y: calloutY + 0.05, w: 8.6, h: 0.5,
  fontSize: 11, fontFace: theme.font.body, bold: true,
  color: "166534", align: "left", valign: "middle",
});

Table + Callout Layout (Prevents Overlap)

Always calculate the table bottom position before placing a callout below it. PptxGenJS tables don't auto-report their height, so you must compute it:

tableBottom = tableY + (rowCount × rowH)
calloutY = tableBottom + 0.15"  // minimum 0.15" gap

**Verify calloutY + 0.6" (callout height) 11pt will overflow.

  • ACCENT LINES: Any thin horizontal bars/lines under titles or headings (must be removed)
  • CHART DATA LABELS: Raw unformatted numbers on data labels (e.g., "2888000" instead of "$2,889K"). This is the #1 chart bug — valAxisLabelFormatCode does NOT format data labels.
  • CHART AXES: Raw unformatted numbers on axes (should be $500K not 500000)
  • Overlapping elements, cramped spacing (<0.3"), insufficient margins (<0.5")
  • Low contrast, text-only slides, repeated layouts, placeholder text
  • Mode inconsistency (light elements on dark or vice versa)
  • Big numbers that should be abbreviated ($5.3M not $5,307,540)
  • CALLOUT INCONSISTENCY: Bottom callout boxes with different heights, font sizes, or padding across slides (all must be h:0.6", fontSize:11)
  • TABLE-CALLOUT OVERLAP: Callout boxes overlapping tables — calculate tableY + (rows × rowH) and verify callout clears it
  • CHART FONT INCONSISTENCY: Different dataLabelFontSize, catAxisLabelFontSize, or valAxisLabelFontSize between charts on different slides

Fix → re-render → inspect → repeat until clean. **Complete at least one fix cycle.**

---

## Dependencies

```bash
npm install -g pptxgenjs                          # Creation
npm install -g react-icons react react-dom sharp  # Icons
pip install "markitdown[pptx]" Pillow             # Reading + QA
# Also: LibreOffice (soffice) + Poppler (pdftoppm) for visual QA

Implementation

Read [REFERENCE.md](REFERENCE.md) for PptxGenJS API patterns and complete slide composition code for both light and dark modes.

Brand Context (Optional)

If brand-profile.json exists in the working directory, read it before building decks. Override the default RRBC palette

…

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.