by zarazhangrui
Create beautiful slides on the web using Claude's frontend skills
# Add to your Claude Code skills
git clone https://github.com/zarazhangrui/frontend-slidesCreate zero-dependency, animation-rich HTML presentations that run entirely in the browser.
You tend to converge toward generic, "on distribution" outputs. In frontend design, this creates what users call the "AI slop" aesthetic. Avoid this: make creative, distinctive frontends that surprise and delight.
Focus on:
Avoid generic AI-generated aesthetics:
Interpret creatively and make unexpected choices that feel genuinely designed for the context. Vary between light and dark themes, different fonts, different aesthetics. You still tend to converge on common choices (Space Grotesk, for example) across generations. Avoid this: it is critical that you think outside the box!
These invariants apply to EVERY slide in EVERY presentation:
.slide must have height: 100vh; height: 100dvh; overflow: hidden;clamp(min, preferred, max) — never fixed px/remmax-height constraintsmax-height: min(50vh, 400px)prefers-reduced-motion support-clamp(), -min(), -max() are silently ignored) — use calc(-1 * clamp(...)) insteadWhen generating, read viewport-base.css and include its full contents in every presentation.
| Slide Type | Maximum Content | | ------------- | --------------------------------------------------------- | | Title slide | 1 heading + 1 subtitle + optional tagline | | Content slide | 1 heading + 4-6 bullet points OR 1 heading + 2 paragraphs | | Feature grid | 1 heading + 6 cards maximum (2x3 or 3x2) | | Code slide | 1 heading + 8-10 lines of code | | Quote slide | 1 quote (max 3 lines) + attribution | | Image slide | 1 heading + 1 image (max 60vh height) |
Content exceeds limits? Split into multiple slides. Never cram, never scroll.
Determine what the user wants:
When enhancing existing presentations, viewport fitting is the biggest risk:
max-height: min(50vh, 400px). If slide already has max content, split into two slides.slide has overflow: hidden, new elements use clamp(), images have viewport-relative max-height, content fits at 1280x720When adding images to existing slides: Move image to new slide or reduce other content first. Never add images without checking if existing content already fills the viewport.
Ask ALL questions in a single AskUserQuestion call so the user fills everything out at once:
Question 1 — Purpose (header: "Purpose"): What is this presentation for? Options: Pitch deck / Teaching-Tutorial / Conference talk / Internal presentation
Question 2 — Length (header: "Length"): Approximately how many slides? Options: Short 5-10 / Medium 10-20 / Long 20+
Question 3 — Content (header: "Content"): Do you have content ready? Options: All content ready / Rough notes / Topic only
Question 4 — Inline Editing (header: "Editing"): Do you need to edit text directly in the browser after generation? Options:
Remember the user's editing choice — it determines whether edit-related code is included in Phase 3.
If user has content, ask them to share it.
If user selected "No images" → skip to Phase 2.
If user provides an image folder:
Logo in previews: If a usable logo was identified, embed it (base64) into each style preview in Phase 2 — the user sees their brand styled three different ways.
This is the "show, don't tell" phase. Most people can't articulate design preferences in words.
Ask how they want to choose (header: "Style"):
If direct selection: Show preset picker and skip to Phase 3. Available presets are defined in STYLE_PRESETS.md.
Ask (header: "Vibe", multiSelect: true, max 2): What feeling should the audience have? Options:
Based on mood, generate 3 distinct single-slide HTML previews showing typography, colors, animation, and overall aesthetic. Read STYLE_PRESETS.md for available presets and their specifications.
| Mood | Suggested Presets | | ------------------- | -------------------------------------------------- | | Impressed/Confident | Bold Signal, Electric Studio, Dark Botanical | | Excited/Energized | Creative Voltage, Neon Cyber, Split Pastel | | Calm/Focused | Notebook Tabs, Paper & Ink, Swiss Modern | | Inspired/Moved | Dark Botanical, Vintage Editorial, Pastel Geometry |
Save previews to .claude-design/slide-previews/ (style-a.html, style-b.html, style-c.html). Each should be self-contained, ~50-100 lines, showing one animated title slide.
Open each preview automatically for the user.
Ask (header: "Style"): Which style preview do you prefer? Options: Style A: [Name] / Style B: [Name] / Style C: [Name] / Mix elements
If "Mix elements", ask for specifics.
Generate the full presentation using content from Phase 1 (text, or text + curated images) and style from Phase 2.
If images were provided, the slide outline already incorporates them from Step 1.2. If not, CSS-generated visuals (gradients, shapes, patterns) provide visual interest — this is a fully supported first-class path.
Before generating, read these supporting files:
Key requirements:
<style> block/* === SECTION NAME === */ comment blockWhen converting PowerPoint files:
python scripts/extract-pptx.py <input.pptx> <output_dir> (install python-pptx if needed: pip install python-pptx).claude-design/slide-previews/ if it existsopen [filename].html to launch in browser:root CSS variables for colors, font link for typography, .reveal class for animationsAfter delivery, ask the user: "Would you like to share this presentation? I can deploy it to a live URL (works on any device including phones) or export it as a PDF."
Options:
If the user declines, stop here. If they choose one or both, proceed below.
This deploys the presentation to Vercel — a free hosting platform. The link works on any device (phones, tablets, laptops) and stays live until the user takes it down.
If the user has never deployed before, guide them step by step:
Check if Vercel CLI is installed — Run npx vercel --version. If not found, install Node.js first (brew install node on macOS, or download from https://nodejs.org).
Check if user is logged in — Run npx vercel whoami.
vercel login and follow the prompts (it opens a browser window to authorize)vercel whoamiDeploy — Run the deploy script:
bash scripts/deploy.sh <path-to-presentation>
The script accepts either a folder (with index.html) or a single HTML file.
Share the URL — Tell the user:
⚠ Deployment gotchas:
src="..." in the HTML and bundles them. But if the presentation references files via CSS background-image or unusual paths, those may be missed. Before deploying, verify: open the deployed URL and check that all images load. If any are broken, the safest fix is to put the HTML and all its assets into a single folder and deploy the folder instead of a standalone HTML file.my-deck/index.html + my-deck/logo.png), deploy the folder directly: bash scripts/deploy.sh ./my-deck/. This is more reliable than deploying a single HTML file because the entire folder contents are uploaded as-is.%20. If possible, avoid spaces in image filenames. If the user's images have spaces, the script handles it — but if images still break, renaming files to use hyphens instead of spaces is the fix.This captures each slide as a screenshot and combines them into a PDF. Perfect for email attachments, embedding in documents, or printing.
Note: Animations and interactivity are not preserved — the PDF is a static snapshot. This is normal and expected; mention it to the user so they're not surprised.
Run the export script:
bash scripts/export-pdf.sh <path-to-html> [output.pdf]
If no output path is given, the PDF is saved next to the HTML file.
What happens behind the scenes (explain briefly to the user):
If Playwright installation fails:
npx playwright install chromiumDeliver the PDF — The script auto-opens it. Tell the user:
⚠ PDF export gotchas:
class="slide". The export script finds slides by querying .slide elements. If the presentation uses a different class name, the script will report "0 slides found" and fail. All presentations generated by this skill use .slide, so this only matters for externally-created HTML.src="/Users/name/photo.png") instead of relative paths (e.g., src="photo.png"), they won't load. Generated presentations always use relative paths, but converted or user-provided decks might not — check and fix if needed.src="photo.png" resolve correctly — including filenames with spaces. If images still don't appear, check: (1) the image files actually exist at the referenced path, (2) the paths are relative, not absolute filesystem paths like /Users/name/photo.png.--compact flag:
bash scripts/export-pdf.sh <path-to-html> [output.pdf] --compact
This renders at 1280×720 instead of 1920×1080, typically cutting file size by 50-70% with minimal visual difference.| File | Purpose | When to Read | | -------------------------------------------------- | -------------------------------------------------------------------- | ------------------------- | | STYLE_PRESETS.md | 12 curated visual presets with colors, fonts, and signature elements | Phase 2 (style selection) | | viewport-base.css | Mandatory responsive CSS — copy into every presentation | Phase 3 (generation) | | html-template.md | HTML structure, JS features, code quality standards | Phase 3 (generation) | | animation-patterns.md | CSS/JS animation snippets and effect-to-feeling guide | Phase 3 (generation) | | scripts/extract-pptx.py | Python script for PPT content extraction | Phase 4 (conversion) | | scripts/deploy.sh | Deploy slides to Vercel for instant sharing | Phase 6 (sharing) | | scripts/export-pdf.sh | Export slides to PDF | Phase 6 (sharing) |
Last scanned: 4/25/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-04-25T05:48:18.657Z",
"semgrepRan": false,
"npmAuditRan": true,
"pipAuditRan": true
}A Claude Code skill for creating stunning, animation-rich HTML presentations — from scratch or by converting PowerPoint files.
Frontend Slides helps non-designers create beautiful web presentations without knowing CSS or JavaScript. It uses a "show, don't tell" approach: instead of asking you to describe your aesthetic preferences in words, it generates visual previews and lets you pick what you like.
Here is a deck about the skill, made through the skill:
https://github.com/user-attachments/assets/ef57333e-f879-432a-afb9-180388982478
Install directly from Claude Code in two commands:
/plugin marketplace add zarazhangrui/frontend-slides
/plugin install frontend-slides@frontend-slides
Then use it by typing /frontend-slides in Claude Code.
Copy the skill files to your Claude Code skills directory:
# Create the skill directory
mkdir -p ~/.claude/skills/frontend-slides/scripts
# Copy all files (or clone this repo directly)
cp SKILL.md STYLE_PRESETS.md viewport-base.css html-template.md animation-patterns.md ~/.claude/skills/frontend-slides/
cp scripts/extract-pptx.py ~/.claude/skills/frontend-slides/scripts/
Or clone directly:
git clone https://github.com/zarazhangrui/frontend-slides.git ~/.claude/skills/frontend-slides
Then use it by typing /frontend-slides in Claude Code.
/frontend-slides
> "I want to create a pitch deck for my AI startup"
The skill will:
/frontend-slides
> "Convert my presentation.pptx to a web slideshow"
The skill will:
This skill uses progressive disclosure — the main SKILL.md is a concise map (~180 lines), with supporting files loaded on-demand only when needed:
| File | Purpose | Loaded When |
| ------------------------- | ------------------------------ | ------------------------- |
| SKILL.md | Core workflow and rules | Always (skill invocation) |
| STYLE_PRESETS.md | 12 curated visual presets | Phase 2 (style selection) |
| viewport-base.css | Mandatory responsive CSS | Phase 3 (generation) |
| html-template.md | HTML structure and JS features | Phase 3 (generation) |
| animation-patterns.md | CSS/JS animation reference | Phase 3 (generation) |
| scripts/extract-pptx.py | PPT content extraction | Phase 4 (conversion) |
| scripts/deploy.sh | Deploy to Vercel | Phase 6 (sharing) |
| scripts/export-pdf.sh | Export slides to PDF | Phase 6 (sharing) |
This design follows OpenAI's harness engineering principle: "give the agent a map, not a 1,000-page instruction manual."
This skill was born from the belief that:
You don't need to be a designer to make beautiful things. You just need to react to what you see.
Dependencies are debt. A single HTML file will work in 10 years. A React project from 2019? Good luck.
Generic is forgettable. Every presentation should feel custom-crafted, not template-generated.
Comments are kindness. Code should explain itself to future-you (or anyone else who opens it).
After creating a presentation, the skill offers two ways to share it:
One command deploys your slides to a permanent, shareable URL that works on any device — phones, tablets, laptops:
bash scripts/deploy.sh ./my-deck/
# or
bash scripts/deploy.sh ./presentation.html
Uses Vercel (free tier). The skill walks you through signup and login if it's your first time.
Convert your slides to a PDF for email, Slack, Notion, or printing:
bash scripts/export-pdf.sh ./my-deck/index.html
bash scripts/export-pdf.sh ./presentation.html ./output.pdf
Uses Playwright to screenshot each slide at 1920×1080 and combine into a PDF. Installs automatically if needed. Animations are not preserved (it's a static snapshot).
python-pptx libraryCreated by @zarazhangrui with Claude Code.
Inspired by the "Vibe Coding" philosophy — building beautiful things without being a traditional software engineer.
MIT — Use it, modify it, share it.
No comments yet. Be the first to share your thoughts!