Install
$ agentstack add skill-crealwork-ai-marketing-kit-ppt-slide-generator ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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 Used
- ✓ 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →About
PPT Slide Generator (프레젠테이션 슬라이드 자동 생성기)
This skill creates professional HTML-based presentation slides (1920x1080, 16:9) through a complete pipeline: theme selection, topic confirmation, deep research, 2-stage content review, AI image generation, and HTML generation with PDF download.
> Output format fork — decide FIRST: > - Default deliverable (HTML → PDF): follow the steps below. > - Editable Google Slides deck requested (구글 슬라이드, Google Slides, > collaborative deck, redesigning an existing Slides deck): read > google-slides-export.md in this skill folder and build with python-pptx > instead of HTML. Content/research/review steps (0-3.5) still apply; > Step 4 (HTML) and the download button do not. > - Redesigning an existing deck from a PDF: skip research/outline gates — > extract content + page renders with PyMuPDF (fitz), keep copy 1:1, > redesign the template only. > - Both at once (PDF redesign → Google Slides): PDF-redesign rules govern > content (skip gates, copy 1:1); Google Slides rules govern build/delivery.
Step 0: Theme Selection + Topic Confirmation
First, check available themes:
- Read the list of
.mdfiles in thethemes/folder (relative to this SKILL.md) - Present the available themes to the user and ask them to select one
- Read the selected theme file to load the design system
Then confirm:
- Topic — What is the presentation about?
- Purpose — Business presentation or educational/lecture material?
- Slide count preference — Short (5-8) / Normal (10-15) / Deep (16-25)
- Presenter info — Name, date, contact (for cover and ending slides)
Don't over-interview. Get the topic confirmed and move to research quickly.
Step 1: Deep Research
Once topic is confirmed, do thorough web research. Research quality directly determines whether the presentation is valuable or just looks nice.
What to search for (5-10 searches)
- Key statistics and recent numbers
- Latest trends and market changes
- Comparable data points for before/after or vs. comparisons
- Visualizable data (percentages, growth rates, rankings)
- Real examples or quotable insights
- Source-backed facts (not vague claims)
Organize your research
After researching, compile:
Topic summary (1 line)
Key data points (5-8)
Chart-ready data (numbers that can become visuals)
Memorable example or quote
Key takeaways (3-5)
Step 1.5: Narrative Strategy
Design the presentation arc before writing the outline.
Opening (slides 1-3) must:
- Hook the audience — a bold claim, surprising statistic, or provocative question
- Establish the problem/opportunity clearly
- Preview the value — "by the end of this presentation, you will..."
Middle (core slides):
- Build logical progression — each slide sets up the next
- Alternate between data/evidence slides and insight/implication slides
- Place the strongest data point at the climax, not the beginning
Closing (last 2-3 slides):
- Summarize key takeaways (no new information)
- Clear call-to-action or next steps
- End with impact — not a whimper
Step 2: Outline Review (Gate 1)
Present the slide outline to the user for review:
Slide 1 [Cover]: Title — "..."
Slide 2 [Agenda]: 3 sections
Slide 3 [Section Divider]: Section 1 — "..."
Slide 4 [Body-Text]: Key message — "..."
Slide 5 [Body-Data]: Chart — "..."
...
Slide N [Ending]: Thank you + contact
Revision loop: Wait for explicit approval before proceeding.
- If the user requests changes: apply revisions and re-present the updated outline
- Repeat until the user approves
- If the user wants to change the topic direction significantly, go back to Step 1
Only proceed to Gate 2 after explicit approval.
Step 3: Detailed Content Review (Gate 2)
Present full text/data for each slide:
Slide 4 [Body-Text]
Title: "AI 마케팅 도입률 현황"
Bullet 1: "2026년 기준 글로벌 기업 72%가 ..."
Bullet 2: "한국 시장은 ..."
Source: McKinsey 2026 Report
Present ALL slides with their complete content. Wait for explicit approval.
Revision loop:
- If the user requests changes: apply revisions to specific slides and re-present only the changed slides
- Repeat until the user approves
- If structural changes are needed (add/remove/reorder slides), go back to Gate 1
Only proceed to image generation after explicit approval.
Step 3.5: Image Generation (Optional)
After content approval, before HTML generation:
- Analyze each slide and identify where images would enhance the presentation
- Present image prompt proposals to the user:
`` Slide 1 [Cover]: Background — "Professional abstract geometric pattern in navy and gold tones" Slide 6 [Quote]: Illustration — "Business team collaborating with AI dashboard" → Approve / Edit prompt / Skip all images ``
- For approved prompts, generate images using Gemini API
- Embed generated images as base64
data:image/png;base64,...in the HTML
Gemini API Call
Model: gemini-3.1-flash-image-preview
Authentication: Uses GOOGLE_AI_API_KEY from global environment.
API pattern:
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents="Create a professional presentation background: [prompt]",
config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE'],
image_config=types.ImageConfig(
aspect_ratio="16:9", # for slide backgrounds
image_size="2K"
)
)
)
for part in response.parts:
if part.inline_data is not None:
image = part.as_image()
image.save("slide-bg.png")
Aspect ratios:
- Slide backgrounds:
16:9 - Inline illustrations:
4:3or1:1
Error Handling
All image generation failures are non-blocking:
- API timeout → skip image, log warning
- Rate limit → wait 5s, retry once, then skip
- Invalid response → skip, proceed without image
- User can skip image generation entirely
If any image fails, note which slides were intended to have images so the user can retry later.
Step 4: HTML Generation
Read the selected theme file and generate a single HTML file containing all slides.
Critical Rules
Rule 1: Static HTML only for slides. Every ` must exist directly in the `. Never generate slides with JavaScript. JS-generated slides won't render in preview.
Rule 2: JavaScript is only for the download button and slide navigator. No JS for slide rendering.
Rule 3: Use Pretendard font via CDN.
:root {
--font-main: 'Pretendard Variable', 'Pretendard', 'Apple SD Gothic Neo',
'Malgun Gothic', 'NanumGothic', sans-serif;
}
* {
word-break: keep-all;
overflow-wrap: break-word;
}
word-break: keep-all is mandatory for Korean. Without it, the browser breaks lines in the middle of words (character by character), which looks broken. keep-all forces line breaks only at spaces, keeping Korean phrases intact.
Rule 4: Deliver the HTML file directly. One HTML file, no separate viewer.
Rule 5: Photos and headshots — use ` with object-fit` (vector-first path).
The PRIMARY export path is now Playwright (vector PDF, see Rule 6). Playwright honors object-fit: cover perfectly. The html2canvas raster path is fallback-only.
Use `` for photos that need to fit a fixed-ratio container:
.speaker-photo { width:520px; height:680px; overflow:hidden; }
.headshot { width:100%; height:100%; object-fit:cover; object-position:center top; }
Why not background-image: Chrome's Ctrl+P "Background graphics" checkbox is OFF by default — ` with background-image disappears from the printed PDF. ` always renders. This was a real Dave Kim deck bug.
The old html2canvas-friendly background-image pattern is still acceptable as a fallback only if you can't move to Playwright export.
Rule 6: Use Playwright for PDF export — html2canvas/Ctrl+P are fallbacks.
Playwright page.pdf({width:'1920px', height:'1080px'}) is the only method that guarantees exact 16:9 page size regardless of user environment. Chrome's Ctrl+P UI ignores @page CSS when user picks Letter/Legal manually. Always create render-pdf.py alongside the deck HTML:
"""Render the deck to a 1920×1080 landscape PDF via Playwright."""
import asyncio
from pathlib import Path
from playwright.async_api import async_playwright
HERE = Path(__file__).parent
HTML = HERE / "deck.html" # adjust to actual filename
OUT = Path.home() / "Downloads" / "deck.pdf" # adjust
async def main():
async with async_playwright() as pw:
browser = await pw.chromium.launch()
ctx = await browser.new_context(viewport={"width": 1920, "height": 1080})
page = await ctx.new_page()
await page.goto(HTML.as_uri(), wait_until="networkidle")
await page.evaluate("document.fonts.ready") # wait for web fonts (FOUT guard)
await page.pdf(
path=str(OUT), width="1920px", height="1080px",
print_background=True,
margin={"top":"0","right":"0","bottom":"0","left":"0"},
prefer_css_page_size=False,
)
await browser.close()
print(f"PDF written to {OUT} ({OUT.stat().st_size:,} bytes)")
asyncio.run(main())
Auto-open after creation/modification (MANDATORY): After running render-pdf.py, always chain start "" "" so the user sees the result immediately. Same for the source HTML during iteration:
python render-pdf.py && start "" "%USERPROFILE%\Downloads\deck.pdf"
If the PDF is locked by an open viewer (PermissionError), fall back to V{N+1}.pdf naming (e.g., V4 → V5).
Print CSS still required for the rare Ctrl+P fallback path:
@media print {
@page { size: 1920px 1080px; margin: 0; }
html, body {
background: #fff !important; margin: 0; padding: 0;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
.slide-nav, .download-section { display: none !important; }
.deck { padding: 0 !important; }
.slide {
margin: 0 !important; box-shadow: none !important;
page-break-after: always; page-break-inside: avoid; break-after: page;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
.slide:last-child { page-break-after: auto; break-after: auto; }
}
print-color-adjust:exact prevents Chrome's ink-saver from stripping accent colors. The html2canvas download button stays as a tertiary fallback in the download section.
Slide Dimensions
Each slide: width: 1920px; height: 1080px (16:9 ratio).
.slide {
width: 1920px;
height: 1080px;
padding: 80px 100px;
display: flex;
flex-direction: column;
justify-content: center;
box-sizing: border-box;
overflow: hidden;
position: relative;
}
position: relative is required so that absolutely-positioned children (slide-number, slide-footer) are positioned relative to the slide, not the viewport.
Font Size Minimums
| Element | Size | Weight | |---------|------|--------| | Slide title | 48px ~ 64px | 800 | | Subtitle / section heading | 36px ~ 44px | 700 | | Body text | 28px ~ 34px | 400-500 | | Number callouts | 72px ~ 120px | 900 | | Caption / source | 20px ~ 24px | 400 | | Slide number | 18px ~ 20px | 400 |
These are MINIMUM sizes. If a slide has less content, scale UP the font sizes to fill the space rather than leaving empty areas.
Heading Letter Spacing
All headings (h1, h2) must have letter-spacing: 0.02em to prevent tight kerning at large sizes. Add this as a global CSS rule:
h1, h2 { letter-spacing: 0.02em; }
Spacing Rules
- Slide padding:
80px ~ 100px - Content block gap:
40px+ - Bullet point spacing:
32px+
Data Visualization
For stable PNG rendering, do NOT use external chart libraries (Chart.js, etc.).
Allowed methods:
- Inline SVG
- HTML/CSS div-based charts (width percentages, flexbox bars, etc.)
Recommended chart types (mix at least 2-3 per presentation):
- Donut/pie charts (SVG)
- Bar charts (CSS divs)
- Comparison bars (side-by-side CSS)
- Progress bars
- Big number + label blocks
- Timeline/process flow (CSS flexbox)
Checklist:
- Numbers in the chart match the text
- Percentages add up correctly
- Sources are attributed
- Each data slide focuses on one insight
Slide Numbering
All slides except Cover and Ending/CTA display a slide number. Position: bottom-right. Format: N / Total (e.g., 3 / 15).
Slide Navigator (Browser Preview)
Since 1920x1080 slides are larger than typical browser viewports, add a navigation helper at the top of the HTML:
Slide Navigator
1 2 ...
Each slide gets id="slide-N". The nav bar is fixed at top and is NOT inside any .slide element, so it's automatically excluded from PNG capture.
.slide-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #333;
color: #fff;
padding: 8px 16px;
z-index: 100000;
display: flex;
gap: 8px;
align-items: center;
font-family: var(--font-main);
font-size: 14px;
}
.slide-nav a {
color: #fff;
background: #555;
padding: 4px 10px;
border-radius: 4px;
text-decoration: none;
}
.slide-nav a:hover { background: #777; }
Year References
Always use the current year. Never hardcode a specific year.
Download Button (PDF)
Add a download section at the bottom of the HTML (after all slides, before ``).
Libraries (EXACT CDN URLs — copy exactly, do NOT change versions):
CRITICAL:
- Use html2canvas
@1.4.1+ jsPDF@2.5.2. Access jsPDF viawindow.jspdf.jsPDF. - Do NOT use dom-to-image-more — it depends on viewport size and breaks in web/narrow
browser environments where viewport 0) pdf.addPage([1920, 1080], 'landscape'); pdf.addImage(imgData, 'JPEG', 0, 0, 1920, 1080); }
status.textContent = 'PDF 저장 중...'; pdf.save('{topic}-presentation.pdf'); status.textContent = '✓ 다운로드 완료!'; } catch (error) { console.error('Download failed:', error); status.textContent = '오류: ' + error.message; } finally { btn.disabled = false; } });
Replace `'{topic}-presentation.pdf'` with the actual sanitized topic name
(lowercase, hyphens, no special characters). Example: `'ai-marketing-presentation.pdf'`
**File naming:** `{topic}-presentation.pdf`
**Download Section UI (MANDATORY pattern):**
The download area must prominently promote **Ctrl/Cmd+P** as the best-quality path.
The html2canvas download button is shown as a smaller, de-emphasized fallback next
to it. Never lead with the rasterized button.
```html
★ Recommended — Best Quality
Press Ctrl+P → “Save as PDF”
Windows: Ctrl+P · Mac: Cmd+PText stays vector-perfect. Use this option.
Or — rasterized fallback
Download PDF
.download-section {
max-width: 1400px; margin: 60px auto 80px; text-align: center;
color: #fff; font-family: var(--font-main, 'Inter', sans-serif);
display: flex; gap: 24px; align-items: stretch; justify-content: center;
flex-wrap: wrap;
}
.best-option {
flex: 1 1 520px; max-width: 680px;
background: #1a1a1a; border: 2px solid var(--accent, #3B82F6);
padding: 36px 44px; border-radius: 10px;
display: flex; flex-direction: column; justify-content: center;
}
.best-label {
color: var(--accent, #3B82F6); font-size: 12px; font-weight: 700;
letter-spacing: 4px; text-transform: uppercase; margin-bottom: 14px;
}
.best-title {
color: #fff; font-size: 30px; font-weight: 600;
margin-bottom: 10px; line-height: 1.2;
}
.best-title kbd {
background: #fff; color: #000; padding: 6px 14px;
border-radius: 6px; font-family: 'SF Mono', 'Monaco', monospace;
font-size: 22px; margin: 0 4px; font-weight: 700;
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.35);
}
.best-note { color: #bbb;
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [crealwork](https://github.com/crealwork)
- **Source:** [crealwork/ai-marketing-kit](https://github.com/crealwork/ai-marketing-kit)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.