Claude
Skills
Sign in
Back

slides

Included with Lifetime
$97 forever

Transform markdown to beautiful Apple-like presentation slides using Marp. Use this skill when the user says "create slides", "make presentation", "markdown to slides", "generate deck", or "create powerpoint".

Writing & Docs

What this skill does


# Slides - Markdown to Beautiful Presentations

Transform markdown content into stunning, Apple Keynote-inspired presentation slides using Marp with AI-enhanced content generation.

## Quick Start

```bash
# Install Marp CLI globally
bun add -g @marp-team/marp-cli

# Or install locally in project
bun add @marp-team/marp-cli
```

## What Gets Created

| Skill File | Target Project Path | Description |
|------------|---------------------|-------------|
| `lib/slides.ts` | `src/lib/slides.ts` | Core slides generation library |
| `lib/slides-theme.css` | `src/lib/slides-theme.css` | Apple-inspired Marp theme |
| (embedded) | `src/lib/ai/tools/slides-tool.ts` | AI tool for slide generation |
| (embedded) | `src/app/api/slides/route.ts` | API endpoint for slides |

## Apple-Inspired Theme

The theme features:

- **Typography**: SF Pro-inspired clean sans-serif fonts
- **Colors**: Neutral grays with vibrant accent colors
- **Spacing**: Generous whitespace, elegant margins
- **Layout**: Centered content, minimal visual noise
- **Animations**: Subtle fade transitions

## Installation

```bash
bun add @marp-team/marp-cli puppeteer-core ai zod
```

## Environment Variables

```env
# Optional: Custom Chromium path for PDF/PPTX export
PUPPETEER_EXECUTABLE_PATH=/path/to/chromium
```

## Theme CSS

Create `src/lib/slides-theme.css`:

```css
/* Apple-Inspired Marp Theme */
/* @theme apple */

@import 'default';

:root {
  /* Apple-like color palette */
  --color-background: #ffffff;
  --color-foreground: #1d1d1f;
  --color-muted: #86868b;
  --color-accent: #0071e3;
  --color-accent-light: #147ce5;

  /* Typography */
  --font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-mono: 'SF Mono', ui-monospace, SFMono-Regular, 'Cascadia Code', Menlo, monospace;

  /* Sizing */
  --slide-width: 1920px;
  --slide-height: 1080px;
}

section {
  font-family: var(--font-family);
  font-size: 40px;
  font-weight: 400;
  color: var(--color-foreground);
  background: var(--color-background);
  padding: 80px 120px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Title Slides */
section.title {
  text-align: center;
  justify-content: center;
  align-items: center;
}

section.title h1 {
  font-size: 96px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-bottom: 24px;
  background: linear-gradient(135deg, #1d1d1f 0%, #424245 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

section.title h2 {
  font-size: 48px;
  font-weight: 400;
  color: var(--color-muted);
  margin: 0;
}

/* Content Slides */
h1 {
  font-size: 72px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 40px 0;
  color: var(--color-foreground);
}

h2 {
  font-size: 56px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 32px 0;
  color: var(--color-foreground);
}

h3 {
  font-size: 44px;
  font-weight: 600;
  margin: 0 0 24px 0;
  color: var(--color-muted);
}

p {
  font-size: 36px;
  line-height: 1.6;
  margin: 0 0 24px 0;
  color: var(--color-foreground);
}

/* Lists */
ul, ol {
  margin: 0;
  padding-left: 48px;
}

li {
  font-size: 36px;
  line-height: 1.6;
  margin-bottom: 16px;
  color: var(--color-foreground);
}

li::marker {
  color: var(--color-accent);
}

/* Code */
code {
  font-family: var(--font-mono);
  font-size: 32px;
  background: #f5f5f7;
  border-radius: 8px;
  padding: 4px 12px;
}

pre {
  background: #1d1d1f;
  border-radius: 16px;
  padding: 32px 40px;
  overflow: hidden;
}

pre code {
  background: transparent;
  color: #f5f5f7;
  font-size: 28px;
  line-height: 1.5;
  padding: 0;
}

/* Blockquotes */
blockquote {
  border-left: 6px solid var(--color-accent);
  padding-left: 32px;
  margin: 32px 0;
  font-style: italic;
  color: var(--color-muted);
}

/* Images */
img {
  max-width: 100%;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12);
}

/* Links */
a {
  color: var(--color-accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Dark Mode */
section.dark {
  background: #1d1d1f;
  color: #f5f5f7;
}

section.dark h1,
section.dark h2,
section.dark p,
section.dark li {
  color: #f5f5f7;
}

section.dark h3 {
  color: #a1a1a6;
}

section.dark code {
  background: #2d2d30;
  color: #f5f5f7;
}

/* Gradient Backgrounds */
section.gradient-blue {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

section.gradient-blue h1,
section.gradient-blue h2,
section.gradient-blue p,
section.gradient-blue li {
  color: white;
}

section.gradient-orange {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  color: white;
}

section.gradient-green {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  color: #1d1d1f;
}

/* Two Column Layout */
section.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
}

/* Center Layout */
section.center {
  text-align: center;
  align-items: center;
}

/* Page Numbers */
section::after {
  content: attr(data-marpit-pagination) ' / ' attr(data-marpit-pagination-total);
  position: absolute;
  bottom: 40px;
  right: 60px;
  font-size: 24px;
  color: var(--color-muted);
}

/* Hide pagination on title slides */
section.title::after {
  display: none;
}

/* Transitions */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

section > * {
  animation: fadeIn 0.6s ease-out forwards;
}
```

## Slides Library

Create `src/lib/slides.ts`:

```typescript
import { spawn } from "child_process";
import { writeFile, readFile, unlink, mkdir } from "fs/promises";
import { join } from "path";
import { tmpdir } from "os";
import { randomUUID } from "crypto";

type SlideTheme = "apple" | "default" | "gaia" | "uncover";
type ExportFormat = "html" | "pdf" | "pptx" | "png" | "jpeg";

type SlidesConfig = {
  theme?: SlideTheme;
  format?: ExportFormat;
  width?: number;
  height?: number;
  allowLocalFiles?: boolean;
};

type SlidesResult = {
  success: boolean;
  filePath?: string;
  buffer?: Buffer;
  error?: string;
};

const APPLE_THEME_PATH = join(process.cwd(), "src/lib/slides-theme.css");

/**
 * Convert markdown to slides using Marp CLI
 */
export async function convertMarkdownToSlides(
  markdown: string,
  config: SlidesConfig = {}
): Promise<SlidesResult> {
  const {
    theme = "apple",
    format = "html",
    width = 1920,
    height = 1080,
    allowLocalFiles = false,
  } = config;

  const tempDir = join(tmpdir(), "marp-slides");
  const sessionId = randomUUID();
  const inputPath = join(tempDir, `${sessionId}.md`);
  const outputPath = join(tempDir, `${sessionId}.${format}`);

  try {
    // Ensure temp directory exists
    await mkdir(tempDir, { recursive: true });

    // Prepare markdown with frontmatter
    const frontmatter = [
      "---",
      "marp: true",
      theme === "apple" ? `theme: apple` : `theme: ${theme}`,
      "paginate: true",
      `size: ${width}x${height}`,
      "---",
      "",
    ].join("\n");

    const fullMarkdown = frontmatter + markdown;
    await writeFile(inputPath, fullMarkdown, "utf-8");

    // Build Marp CLI arguments
    const args: string[] = [inputPath, "-o", outputPath];

    // Add theme CSS if using custom Apple theme
    if (theme === "apple") {
      args.push("--theme", APPLE_THEME_PATH);
    }

    // Format-specific options
    if (format === "pptx" || format === "pdf") {
      args.push("--allow-local-files");
    }

    if (format === "png" || format === "jpeg") {
      args.push("--images", format);
    }

    if (allowLocalFiles) {
      args.push("--allow-local-files");
    }

    // Execute Marp CLI
    await new Promise<void>((resolve, reject) => {
      const marp = spawn("npx", ["@marp-team/marp-cli", ...args], {
        cwd: process.cwd(),
        shell: true,
      });
Files: 1
Size: 19.8 KB
Complexity: 29/100
Category: Writing & Docs

Related in Writing & Docs