frontend-slides

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Frontend Slides Skill

前端幻灯片制作Skill

Create zero-dependency, animation-rich HTML presentations that run entirely in the browser. This skill helps non-designers discover their preferred aesthetic through visual exploration ("show, don't tell"), then generates production-quality slide decks.
创建零依赖、富含动画效果的HTML演示文稿,可直接在浏览器中运行。本Skill帮助非设计人员通过视觉探索(“展示而非说教”)找到自己偏好的美学风格,随后生成可投入生产使用的幻灯片。

Core Philosophy

核心理念

  1. Zero Dependencies — Single HTML files with inline CSS/JS. No npm, no build tools.
  2. Show, Don't Tell — People don't know what they want until they see it. Generate visual previews, not abstract choices.
  3. Distinctive Design — Avoid generic "AI slop" aesthetics. Every presentation should feel custom-crafted.
  4. Production Quality — Code should be well-commented, accessible, and performant.

  1. 零依赖 — 单个内嵌CSS/JS的HTML文件,无需npm,无需构建工具。
  2. 展示而非说教 — 人们在看到实际效果前不知道自己想要什么。生成视觉预览,而非提供抽象选项。
  3. 独特设计 — 避免千篇一律的“AI通用风格”。每个演示文稿都应具有定制感。
  4. 生产级质量 — 代码应注释清晰、易于访问且性能优异。

Phase 0: Detect Mode

阶段0:模式检测

First, determine what the user wants:
Mode A: New Presentation
  • User wants to create slides from scratch
  • Proceed to Phase 1 (Content Discovery)
Mode B: PPT Conversion
  • User has a PowerPoint file (.ppt, .pptx) to convert
  • Proceed to Phase 4 (PPT Extraction)
Mode C: Existing Presentation Enhancement
  • User has an HTML presentation and wants to improve it
  • Read the existing file, understand the structure, then enhance

首先确定用户的需求:
模式A:新建演示文稿
  • 用户想要从零开始创建幻灯片
  • 进入阶段1(内容探索)
模式B:PPT转换
  • 用户有PowerPoint文件(.ppt, .pptx)需要转换
  • 进入阶段4(PPT内容提取)
模式C:现有演示文稿优化
  • 用户已有HTML演示文稿并希望对其进行改进
  • 读取现有文件,理解其结构后进行优化

Phase 1: Content Discovery (New Presentations)

阶段1:内容探索(新建演示文稿)

Before designing, understand the content. Ask via AskUserQuestion:
在设计前,先明确内容。通过AskUserQuestion询问以下问题:

Step 1.1: Presentation Context

步骤1.1:演示文稿背景

Question 1: Purpose
  • Header: "Purpose"
  • Question: "What is this presentation for?"
  • Options:
    • "Pitch deck" — Selling an idea, product, or company to investors/clients
    • "Teaching/Tutorial" — Explaining concepts, how-to guides, educational content
    • "Conference talk" — Speaking at an event, tech talk, keynote
    • "Internal presentation" — Team updates, strategy meetings, company updates
Question 2: Slide Count
  • Header: "Length"
  • Question: "Approximately how many slides?"
  • Options:
    • "Short (5-10)" — Quick pitch, lightning talk
    • "Medium (10-20)" — Standard presentation
    • "Long (20+)" — Deep dive, comprehensive talk
Question 3: Content
  • Header: "Content"
  • Question: "Do you have the content ready, or do you need help structuring it?"
  • Options:
    • "I have all content ready" — Just need to design the presentation
    • "I have rough notes" — Need help organizing into slides
    • "I have a topic only" — Need help creating the full outline
If user has content, ask them to share it (text, bullet points, images, etc.).

问题1:用途
  • 标题:“用途”
  • 问题:“此演示文稿的用途是什么?”
  • 选项:
    • “路演PPT” — 向投资者/客户推销创意、产品或公司
    • “教学/教程” — 讲解概念、操作指南、教育内容
    • 会议演讲 — 在活动、技术分享、主题演讲中使用
    • “内部演示” — 团队更新、战略会议、公司通报
问题2:幻灯片数量
  • 标题:“长度”
  • 问题:“大约需要多少张幻灯片?”
  • 选项:
    • “简短(5-10张)” — 快速路演、闪电演讲
    • “中等(10-20张)” — 标准演示文稿
    • “长篇(20张以上)” — 深度讲解、全面分享
问题3:内容准备情况
  • 标题:“内容”
  • 问题:“你是否已准备好内容,还是需要帮助梳理结构?”
  • 选项:
    • “我已准备好所有内容” — 仅需要设计演示文稿
    • “我有大致的笔记” — 需要帮助整理成幻灯片
    • “我只有主题” — 需要帮助创建完整大纲
如果用户已有内容,请他们分享(文本、要点、图片等)。

Phase 2: Style Discovery (Visual Exploration)

阶段2:风格探索(视觉探索)

CRITICAL: This is the "show, don't tell" phase.
Most people can't articulate design preferences in words. Instead of asking "do you want minimalist or bold?", we generate mini-previews and let them react.
关键:这是“展示而非说教”的阶段。
大多数人无法用语言清晰表达设计偏好。与其问“你想要极简风格还是大胆风格?”,不如生成迷你预览让用户做出选择。

Step 2.1: Mood Selection

步骤2.1:氛围选择

Question 1: Feeling
  • Header: "Vibe"
  • Question: "What feeling should the audience have when viewing your slides?"
  • Options:
    • "Impressed/Confident" — Professional, trustworthy, this team knows what they're doing
    • "Excited/Energized" — Innovative, bold, this is the future
    • "Calm/Focused" — Clear, thoughtful, easy to follow
    • "Inspired/Moved" — Emotional, storytelling, memorable
  • multiSelect: true (can choose up to 2)
问题1:感受
  • 标题:“氛围”
  • 问题:“观众观看你的幻灯片时应产生何种感受?”
  • 选项:
    • “印象深刻/充满信心” — 专业、值得信赖,团队对业务驾轻就熟
    • “兴奋/充满活力” — 创新、大胆,代表未来趋势
    • “平静/专注” — 清晰、深思熟虑,易于理解
    • “受启发/被打动” — 富有情感、注重叙事、令人难忘
  • 多选:是(最多可选2个)

Step 2.2: Generate Style Previews

步骤2.2:生成风格预览

Based on their mood selection, generate 3 distinct style previews as mini HTML files in a temporary directory. Each preview should be a single title slide showing:
  • Typography (font choices, heading/body hierarchy)
  • Color palette (background, accent, text colors)
  • Animation style (how elements enter)
  • Overall aesthetic feel
Preview Styles to Consider (pick 3 based on mood):
MoodStyle Options
Impressed/Confident"Corporate Elegant", "Dark Executive", "Clean Minimal"
Excited/Energized"Neon Cyber", "Bold Gradients", "Kinetic Motion"
Calm/Focused"Paper & Ink", "Soft Muted", "Swiss Minimal"
Inspired/Moved"Cinematic Dark", "Warm Editorial", "Atmospheric"
IMPORTANT: Never use these generic patterns:
  • Purple gradients on white backgrounds
  • Inter, Roboto, or system fonts
  • Standard blue primary colors
  • Predictable hero layouts
Instead, use distinctive choices:
  • Unique font pairings (Clash Display, Satoshi, Cormorant Garamond, DM Sans, etc.)
  • Cohesive color themes with personality
  • Atmospheric backgrounds (gradients, subtle patterns, depth)
  • Signature animation moments
根据用户选择的氛围,在临时目录中生成3种不同的风格预览,作为迷你HTML文件。每个预览应为单个标题幻灯片,展示:
  • 排版(字体选择、标题/正文层级)
  • 调色板(背景色、强调色、文字颜色)
  • 动画风格(元素入场方式)
  • 整体美学感受
可参考的预览风格(根据氛围选择3种):
氛围风格选项
印象深刻/充满信心“企业典雅风”、“深色高管风”、“简洁极简风”
兴奋/充满活力“霓虹赛博风”、“大胆渐变风”、“动态动能风”
平静/专注“纸墨风”、“柔和低饱和风”、“瑞士极简风”
受启发/被打动“电影暗黑风”、“温暖编辑风”、“氛围感风”
重要提示:切勿使用以下通用模板:
  • 白色背景搭配紫色渐变
  • Inter、Roboto或系统字体
  • 标准蓝色主色调
  • predictable hero layouts(可预测的主视觉布局)
相反,请使用独特的选择:
  • 独特的字体组合(Clash Display、Satoshi、Cormorant Garamond、DM Sans等)
  • 具有个性的统一配色主题
  • 氛围感背景(渐变、微妙图案、层次感)
  • 标志性动画效果

Step 2.3: Present Previews

步骤2.3:展示预览

Create the previews in:
.claude-design/slide-previews/
.claude-design/slide-previews/
├── style-a.html   # First style option
├── style-b.html   # Second style option
├── style-c.html   # Third style option
└── assets/        # Any shared assets
Each preview file should be:
  • Self-contained (inline CSS/JS)
  • A single "title slide" showing the aesthetic
  • Animated to demonstrate motion style
  • ~50-100 lines, not a full presentation
Present to user:
I've created 3 style previews for you to compare:

**Style A: [Name]** — [1 sentence description]
**Style B: [Name]** — [1 sentence description]
**Style C: [Name]** — [1 sentence description]

Open each file to see them in action:
- .claude-design/slide-previews/style-a.html
- .claude-design/slide-previews/style-b.html
- .claude-design/slide-previews/style-c.html

Take a look and tell me:
1. Which style resonates most?
2. What do you like about it?
3. Anything you'd change?
Then use AskUserQuestion:
Question: Pick Your Style
  • Header: "Style"
  • Question: "Which style preview do you prefer?"
  • Options:
    • "Style A: [Name]" — [Brief description]
    • "Style B: [Name]" — [Brief description]
    • "Style C: [Name]" — [Brief description]
    • "Mix elements" — Combine aspects from different styles
If "Mix elements", ask for specifics.

在以下路径创建预览:
.claude-design/slide-previews/
.claude-design/slide-previews/
├── style-a.html   # 第一种风格选项
├── style-b.html   # 第二种风格选项
├── style-c.html   # 第三种风格选项
└── assets/        # 共享资源
每个预览文件应满足:
  • 自包含(内嵌CSS/JS)
  • 单个展示美学风格的“标题幻灯片”
  • 带有动画以展示运动风格
  • 约50-100行代码,而非完整演示文稿
向用户展示:
我为你创建了3种风格预览以供对比:

**风格A:[名称]** — [1句话描述]
**风格B:[名称]** — [1句话描述]
**风格C:[名称]** — [1句话描述]

打开以下文件查看实际效果:
- .claude-design/slide-previews/style-a.html
- .claude-design/slide-previews/style-b.html
- .claude-design/slide-previews/style-c.html

请查看并告诉我:
1. 哪种风格最符合你的喜好?
2. 你喜欢它的哪些方面?
3. 有什么需要调整的地方?
然后使用AskUserQuestion:
问题:选择你的风格
  • 标题:“风格”
  • 问题:“你偏好哪种风格预览?”
  • 选项:
    • “风格A:[名称]” — [简要描述]
    • “风格B:[名称]” — [简要描述]
    • “风格C:[名称]” — [简要描述]
    • “混合元素” — 结合不同风格的特点
如果用户选择“混合元素”,请询问具体细节。

Phase 3: Generate Presentation

阶段3:生成演示文稿

Now generate the full presentation based on:
  • Content from Phase 1
  • Style from Phase 2
现在根据以下内容生成完整的演示文稿:
  • 阶段1获取的内容
  • 阶段2确定的风格

File Structure

文件结构

For single presentations:
presentation.html    # Self-contained presentation
assets/              # Images, if any
For projects with multiple presentations:
[presentation-name].html
[presentation-name]-assets/
单个演示文稿:
presentation.html    # 自包含的演示文稿
assets/              # 图片(如有)
包含多个演示文稿的项目:
[presentation-name].html
[presentation-name]-assets/

HTML Architecture

HTML架构

Follow this structure for all presentations:
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Presentation Title</title>

    <!-- Fonts (use Fontshare or Google Fonts) -->
    <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">

    <style>
        /* ===========================================
           CSS CUSTOM PROPERTIES (THEME)
           Easy to modify: change these to change the whole look
           =========================================== */
        :root {
            /* Colors */
            --bg-primary: #0a0f1c;
            --bg-secondary: #111827;
            --text-primary: #ffffff;
            --text-secondary: #9ca3af;
            --accent: #00ffcc;
            --accent-glow: rgba(0, 255, 204, 0.3);

            /* Typography */
            --font-display: 'Clash Display', sans-serif;
            --font-body: 'Satoshi', sans-serif;

            /* Spacing */
            --slide-padding: clamp(2rem, 5vw, 4rem);

            /* Animation */
            --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
            --duration-normal: 0.6s;
        }

        /* ===========================================
           BASE STYLES
           =========================================== */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        html {
            scroll-behavior: smooth;
            scroll-snap-type: y mandatory;
        }

        body {
            font-family: var(--font-body);
            background: var(--bg-primary);
            color: var(--text-primary);
            overflow-x: hidden;
        }

        /* ===========================================
           SLIDE CONTAINER
           Each section is one slide
           =========================================== */
        .slide {
            min-height: 100vh;
            padding: var(--slide-padding);
            scroll-snap-align: start;
            display: flex;
            flex-direction: column;
            justify-content: center;
            position: relative;
            overflow: hidden;
        }

        /* ===========================================
           ANIMATIONS
           Trigger via .visible class (added by JS on scroll)
           =========================================== */
        .reveal {
            opacity: 0;
            transform: translateY(30px);
            transition: opacity var(--duration-normal) var(--ease-out-expo),
                        transform var(--duration-normal) var(--ease-out-expo);
        }

        .slide.visible .reveal {
            opacity: 1;
            transform: translateY(0);
        }

        /* Stagger children */
        .reveal:nth-child(1) { transition-delay: 0.1s; }
        .reveal:nth-child(2) { transition-delay: 0.2s; }
        .reveal:nth-child(3) { transition-delay: 0.3s; }
        .reveal:nth-child(4) { transition-delay: 0.4s; }

        /* ... more styles ... */
    </style>
</head>
<body>
    <!-- Progress bar (optional) -->
    <div class="progress-bar"></div>

    <!-- Navigation dots (optional) -->
    <nav class="nav-dots">
        <!-- Generated by JS -->
    </nav>

    <!-- Slides -->
    <section class="slide title-slide">
        <h1 class="reveal">Presentation Title</h1>
        <p class="reveal">Subtitle or author</p>
    </section>

    <section class="slide">
        <h2 class="reveal">Slide Title</h2>
        <p class="reveal">Content...</p>
    </section>

    <!-- More slides... -->

    <script>
        /* ===========================================
           SLIDE PRESENTATION CONTROLLER
           Handles navigation, animations, and interactions
           =========================================== */

        class SlidePresentation {
            constructor() {
                // ... initialization
            }

            // ... methods
        }

        // Initialize
        new SlidePresentation();
    </script>
</body>
</html>
所有演示文稿均遵循以下结构:
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Presentation Title</title>

    <!-- Fonts (use Fontshare or Google Fonts) -->
    <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">

    <style>
        /* ===========================================
           CSS CUSTOM PROPERTIES (THEME)
           Easy to modify: change these to change the whole look
           =========================================== */
        :root {
            /* Colors */
            --bg-primary: #0a0f1c;
            --bg-secondary: #111827;
            --text-primary: #ffffff;
            --text-secondary: #9ca3af;
            --accent: #00ffcc;
            --accent-glow: rgba(0, 255, 204, 0.3);

            /* Typography */
            --font-display: 'Clash Display', sans-serif;
            --font-body: 'Satoshi', sans-serif;

            /* Spacing */
            --slide-padding: clamp(2rem, 5vw, 4rem);

            /* Animation */
            --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
            --duration-normal: 0.6s;
        }

        /* ===========================================
           BASE STYLES
           =========================================== */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        html {
            scroll-behavior: smooth;
            scroll-snap-type: y mandatory;
        }

        body {
            font-family: var(--font-body);
            background: var(--bg-primary);
            color: var(--text-primary);
            overflow-x: hidden;
        }

        /* ===========================================
           SLIDE CONTAINER
           Each section is one slide
           =========================================== */
        .slide {
            min-height: 100vh;
            padding: var(--slide-padding);
            scroll-snap-align: start;
            display: flex;
            flex-direction: column;
            justify-content: center;
            position: relative;
            overflow: hidden;
        }

        /* ===========================================
           ANIMATIONS
           Trigger via .visible class (added by JS on scroll)
           =========================================== */
        .reveal {
            opacity: 0;
            transform: translateY(30px);
            transition: opacity var(--duration-normal) var(--ease-out-expo),
                        transform var(--duration-normal) var(--ease-out-expo);
        }

        .slide.visible .reveal {
            opacity: 1;
            transform: translateY(0);
        }

        /* Stagger children */
        .reveal:nth-child(1) { transition-delay: 0.1s; }
        .reveal:nth-child(2) { transition-delay: 0.2s; }
        .reveal:nth-child(3) { transition-delay: 0.3s; }
        .reveal:nth-child(4) { transition-delay: 0.4s; }

        /* ... more styles ... */
    </style>
</head>
<body>
    <!-- Progress bar (optional) -->
    <div class="progress-bar"></div>

    <!-- Navigation dots (optional) -->
    <nav class="nav-dots">
        <!-- Generated by JS -->
    </nav>

    <!-- Slides -->
    <section class="slide title-slide">
        <h1 class="reveal">Presentation Title</h1>
        <p class="reveal">Subtitle or author</p>
    </section>

    <section class="slide">
        <h2 class="reveal">Slide Title</h2>
        <p class="reveal">Content...</p>
    </section>

    <!-- More slides... -->

    <script>
        /* ===========================================
           SLIDE PRESENTATION CONTROLLER
           Handles navigation, animations, and interactions
           =========================================== */

        class SlidePresentation {
            constructor() {
                // ... initialization
            }

            // ... methods
        }

        // Initialize
        new SlidePresentation();
    </script>
</body>
</html>

Required JavaScript Features

必备JavaScript功能

Every presentation should include:
  1. SlidePresentation Class — Main controller
    • Keyboard navigation (arrows, space)
    • Touch/swipe support
    • Mouse wheel navigation
    • Progress bar updates
    • Navigation dots
  2. Intersection Observer — For scroll-triggered animations
    • Add
      .visible
      class when slides enter viewport
    • Trigger CSS animations efficiently
  3. Optional Enhancements (based on style):
    • Custom cursor with trail
    • Particle system background (canvas)
    • Parallax effects
    • 3D tilt on hover
    • Magnetic buttons
    • Counter animations
每个演示文稿应包含:
  1. SlidePresentation类 — 主控制器
    • 键盘导航(方向键、空格键)
    • 触摸/滑动支持
    • 鼠标滚轮导航
    • 进度条更新
    • 导航点
  2. Intersection Observer — 用于滚动触发动画
    • 当幻灯片进入视口时添加
      .visible
    • 高效触发CSS动画
  3. 可选增强功能(根据风格):
    • 带有轨迹的自定义光标
    • 粒子系统背景(canvas)
    • 视差效果
    • 悬停时的3D倾斜效果
    • 磁吸按钮
    • 数字计数动画

Code Quality Requirements

代码质量要求

Comments: Every section should have clear comments explaining:
  • What it does
  • Why it exists
  • How to modify it
javascript
/* ===========================================
   CUSTOM CURSOR
   Creates a stylized cursor that follows mouse with a trail effect.
   - Uses lerp (linear interpolation) for smooth movement
   - Grows larger when hovering over interactive elements
   =========================================== */
class CustomCursor {
    constructor() {
        // ...
    }
}
Accessibility:
  • Semantic HTML (
    <section>
    ,
    <nav>
    ,
    <main>
    )
  • Keyboard navigation works
  • ARIA labels where needed
  • Reduced motion support
css
@media (prefers-reduced-motion: reduce) {
    .reveal {
        transition: opacity 0.3s ease;
        transform: none;
    }
}
Responsive:
  • Mobile-friendly (single column, adjusted spacing)
  • Disable heavy effects on mobile
  • Touch-friendly interactions
css
@media (max-width: 768px) {
    .nav-dots,
    .keyboard-hint {
        display: none;
    }
}

注释: 每个部分都应有清晰的注释,说明:
  • 功能是什么
  • 存在的原因
  • 如何修改
javascript
/* ===========================================
   CUSTOM CURSOR
   Creates a stylized cursor that follows mouse with a trail effect.
   - Uses lerp (linear interpolation) for smooth movement
   - Grows larger when hovering over interactive elements
   =========================================== */
class CustomCursor {
    constructor() {
        // ...
    }
}
可访问性:
  • 语义化HTML(
    <section>
    <nav>
    <main>
  • 键盘导航正常工作
  • 必要时添加ARIA标签
  • 支持减少动画模式
css
@media (prefers-reduced-motion: reduce) {
    .reveal {
        transition: opacity 0.3s ease;
        transform: none;
    }
}
响应式:
  • 移动端友好(单列布局、调整间距)
  • 在移动端禁用重型效果
  • 触摸友好的交互
css
@media (max-width: 768px) {
    .nav-dots,
    .keyboard-hint {
        display: none;
    }
}

Phase 4: PPT Conversion

阶段4:PPT转换

When converting PowerPoint files:
转换PowerPoint文件时:

Step 4.1: Extract Content

步骤4.1:提取内容

Use Python with
python-pptx
to extract:
python
from pptx import Presentation
from pptx.util import Inches, Pt
import json
import os
import base64

def extract_pptx(file_path, output_dir):
    """
    Extract all content from a PowerPoint file.
    Returns a JSON structure with slides, text, and images.
    """
    prs = Presentation(file_path)
    slides_data = []

    # Create assets directory
    assets_dir = os.path.join(output_dir, 'assets')
    os.makedirs(assets_dir, exist_ok=True)

    for slide_num, slide in enumerate(prs.slides):
        slide_data = {
            'number': slide_num + 1,
            'title': '',
            'content': [],
            'images': [],
            'notes': ''
        }

        for shape in slide.shapes:
            # Extract title
            if shape.has_text_frame:
                if shape == slide.shapes.title:
                    slide_data['title'] = shape.text
                else:
                    slide_data['content'].append({
                        'type': 'text',
                        'content': shape.text
                    })

            # Extract images
            if shape.shape_type == 13:  # Picture
                image = shape.image
                image_bytes = image.blob
                image_ext = image.ext
                image_name = f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"
                image_path = os.path.join(assets_dir, image_name)

                with open(image_path, 'wb') as f:
                    f.write(image_bytes)

                slide_data['images'].append({
                    'path': f"assets/{image_name}",
                    'width': shape.width,
                    'height': shape.height
                })

        # Extract notes
        if slide.has_notes_slide:
            notes_frame = slide.notes_slide.notes_text_frame
            slide_data['notes'] = notes_frame.text

        slides_data.append(slide_data)

    return slides_data
使用Python和
python-pptx
提取内容:
python
from pptx import Presentation
from pptx.util import Inches, Pt
import json
import os
import base64

def extract_pptx(file_path, output_dir):
    """
    Extract all content from a PowerPoint file.
    Returns a JSON structure with slides, text, and images.
    """
    prs = Presentation(file_path)
    slides_data = []

    # Create assets directory
    assets_dir = os.path.join(output_dir, 'assets')
    os.makedirs(assets_dir, exist_ok=True)

    for slide_num, slide in enumerate(prs.slides):
        slide_data = {
            'number': slide_num + 1,
            'title': '',
            'content': [],
            'images': [],
            'notes': ''
        }

        for shape in slide.shapes:
            # Extract title
            if shape.has_text_frame:
                if shape == slide.shapes.title:
                    slide_data['title'] = shape.text
                else:
                    slide_data['content'].append({
                        'type': 'text',
                        'content': shape.text
                    })

            # Extract images
            if shape.shape_type == 13:  # Picture
                image = shape.image
                image_bytes = image.blob
                image_ext = image.ext
                image_name = f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"
                image_path = os.path.join(assets_dir, image_name)

                with open(image_path, 'wb') as f:
                    f.write(image_bytes)

                slide_data['images'].append({
                    'path': f"assets/{image_name}",
                    'width': shape.width,
                    'height': shape.height
                })

        # Extract notes
        if slide.has_notes_slide:
            notes_frame = slide.notes_slide.notes_text_frame
            slide_data['notes'] = notes_frame.text

        slides_data.append(slide_data)

    return slides_data

Step 4.2: Confirm Content Structure

步骤4.2:确认内容结构

Present the extracted content to the user:
I've extracted the following from your PowerPoint:

**Slide 1: [Title]**
- [Content summary]
- Images: [count]

**Slide 2: [Title]**
- [Content summary]
- Images: [count]

...

All images have been saved to the assets folder.

Does this look correct? Should I proceed with style selection?
向用户展示提取的内容:
我已从你的PowerPoint文件中提取了以下内容:

**幻灯片1:[标题]**
- [内容摘要]
- 图片:[数量]

**幻灯片2:[标题]**
- [内容摘要]
- 图片:[数量]

...

所有图片已保存到assets文件夹中。

内容是否正确?是否可以进入风格选择阶段?

Step 4.3: Style Selection

步骤4.3:风格选择

Proceed to Phase 2 (Style Discovery) with the extracted content in mind.
结合提取的内容,进入阶段2(风格探索)。

Step 4.4: Generate HTML

步骤4.4:生成HTML

Convert the extracted content into the chosen style, preserving:
  • All text content
  • All images (referenced from assets folder)
  • Slide order
  • Any speaker notes (as HTML comments or separate file)

将提取的内容转换为选定的风格,保留:
  • 所有文本内容
  • 所有图片(从assets文件夹引用)
  • 幻灯片顺序
  • 所有演讲备注(作为HTML注释或单独文件)

Phase 5: Delivery

阶段5:交付

Final Output

最终输出

When the presentation is complete:
  1. Clean up temporary files
    • Delete
      .claude-design/slide-previews/
      if it exists
  2. Open the presentation
    • Use
      open [filename].html
      to launch in browser
  3. Provide summary
Your presentation is ready!

📁 File: [filename].html
🎨 Style: [Style Name]
📊 Slides: [count]

**Navigation:**
- Arrow keys (← →) or Space to navigate
- Scroll/swipe also works
- Click the dots on the right to jump to a slide

**To customize:**
- Colors: Look for `:root` CSS variables at the top
- Fonts: Change the Fontshare/Google Fonts link
- Animations: Modify `.reveal` class timings

Would you like me to make any adjustments?

演示文稿完成后:
  1. 清理临时文件
    • 如果存在,删除
      .claude-design/slide-previews/
  2. 打开演示文稿
    • 使用
      open [filename].html
      在浏览器中打开
  3. 提供摘要
你的演示文稿已准备就绪!

📁 文件:[filename].html
🎨 风格:[风格名称]
📊 幻灯片数量:[数量]

**导航方式:**
- 方向键(← →)或空格键导航
- 滚动/滑动也可操作
- 点击右侧的点可跳转到对应幻灯片

**自定义方法:**
- 颜色:修改顶部的`:root` CSS变量
- 字体:更改Fontshare/Google Fonts链接
- 动画:调整`.reveal`类的时间设置

需要我进行任何调整吗?

Style Reference: Effect → Feeling Mapping

风格参考:效果→感受映射

Use this guide to match animations to intended feelings:
使用本指南匹配动画与预期感受:

Dramatic / Cinematic

戏剧性/电影感

  • Slow fade-ins (1-1.5s)
  • Large scale transitions (0.9 → 1)
  • Dark backgrounds with spotlight effects
  • Parallax scrolling
  • Full-bleed images
  • 缓慢淡入(1-1.5秒)
  • 大尺度过渡(0.9 → 1)
  • 深色背景搭配聚光灯效果
  • 视差滚动
  • 全屏图片

Techy / Futuristic

科技感/未来感

  • Neon glow effects (box-shadow with accent color)
  • Particle systems (canvas background)
  • Grid patterns
  • Monospace fonts for accents
  • Glitch or scramble text effects
  • Cyan, magenta, electric blue palette
  • 霓虹发光效果(使用强调色的box-shadow)
  • 粒子系统(canvas背景)
  • 网格图案
  • 等宽字体用于强调
  • 故障或文字打乱效果
  • 青色、品红色、电光蓝调色板

Playful / Friendly

趣味性/友好感

  • Bouncy easing (spring physics)
  • Rounded corners (large radius)
  • Pastel or bright colors
  • Floating/bobbing animations
  • Hand-drawn or illustrated elements
  • 弹性缓动(弹簧物理效果)
  • 圆角(大半径)
  • 柔和或明亮的颜色
  • 漂浮/晃动动画
  • 手绘或插画元素

Professional / Corporate

专业感/企业感

  • Subtle, fast animations (200-300ms)
  • Clean sans-serif fonts
  • Navy, slate, or charcoal backgrounds
  • Precise spacing and alignment
  • Minimal decorative elements
  • Data visualization focus
  • 微妙、快速的动画(200-300毫秒)
  • 简洁的无衬线字体
  • 海军蓝、石板灰、炭灰色背景
  • 精确的间距和对齐
  • 极少的装饰元素
  • 注重数据可视化

Calm / Minimal

平静感/极简风

  • Very slow, subtle motion
  • High whitespace
  • Muted color palette
  • Serif typography
  • Generous padding
  • Content-focused, no distractions
  • 非常缓慢、微妙的动效
  • 高留白
  • 低饱和调色板
  • 衬线字体
  • 充足的内边距
  • 以内容为核心,无干扰元素

Editorial / Magazine

编辑感/杂志风

  • Strong typography hierarchy
  • Pull quotes and callouts
  • Image-text interplay
  • Grid-breaking layouts
  • Serif headlines, sans-serif body
  • Black and white with one accent

  • 强烈的排版层级
  • 引言和标注
  • 图文结合
  • 打破网格的布局
  • 衬线标题、无衬线正文
  • 黑白搭配一种强调色

Animation Patterns Reference

动画模式参考

Entrance Animations

入场动画

css
/* Fade + Slide Up (most common) */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s var(--ease-out-expo),
                transform 0.6s var(--ease-out-expo);
}

.visible .reveal {
    opacity: 1;
    transform: translateY(0);
}

/* Scale In */
.reveal-scale {
    opacity: 0;
    transform: scale(0.9);
    transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}

/* Slide from Left */
.reveal-left {
    opacity: 0;
    transform: translateX(-50px);
    transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}

/* Blur In */
.reveal-blur {
    opacity: 0;
    filter: blur(10px);
    transition: opacity 0.8s, filter 0.8s var(--ease-out-expo);
}
css
/* 淡入+向上滑动(最常用) */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s var(--ease-out-expo),
                transform 0.6s var(--ease-out-expo);
}

.visible .reveal {
    opacity: 1;
    transform: translateY(0);
}

/* 缩放入场 */
.reveal-scale {
    opacity: 0;
    transform: scale(0.9);
    transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}

/* 从左侧滑入 */
.reveal-left {
    opacity: 0;
    transform: translateX(-50px);
    transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}

/* 模糊入场 */
.reveal-blur {
    opacity: 0;
    filter: blur(10px);
    transition: opacity 0.8s, filter 0.8s var(--ease-out-expo);
}

Background Effects

背景效果

css
/* Gradient Mesh */
.gradient-bg {
    background:
        radial-gradient(ellipse at 20% 80%, rgba(120, 0, 255, 0.3) 0%, transparent 50%),
        radial-gradient(ellipse at 80% 20%, rgba(0, 255, 200, 0.2) 0%, transparent 50%),
        var(--bg-primary);
}

/* Noise Texture */
.noise-bg {
    background-image: url("data:image/svg+xml,..."); /* Inline SVG noise */
}

/* Grid Pattern */
.grid-bg {
    background-image:
        linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
    background-size: 50px 50px;
}
css
/* 渐变网格 */
.gradient-bg {
    background:
        radial-gradient(ellipse at 20% 80%, rgba(120, 0, 255, 0.3) 0%, transparent 50%),
        radial-gradient(ellipse at 80% 20%, rgba(0, 255, 200, 0.2) 0%, transparent 50%),
        var(--bg-primary);
}

/* 噪点纹理 */
.noise-bg {
    background-image: url("data:image/svg+xml,..."); /* Inline SVG noise */
}

/* 网格图案 */
.grid-bg {
    background-image:
        linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
    background-size: 50px 50px;
}

Interactive Effects

交互效果

javascript
/* 3D Tilt on Hover */
class TiltEffect {
    constructor(element) {
        this.element = element;
        this.element.style.transformStyle = 'preserve-3d';
        this.element.style.perspective = '1000px';
        this.bindEvents();
    }

    bindEvents() {
        this.element.addEventListener('mousemove', (e) => {
            const rect = this.element.getBoundingClientRect();
            const x = (e.clientX - rect.left) / rect.width - 0.5;
            const y = (e.clientY - rect.top) / rect.height - 0.5;

            this.element.style.transform = `
                rotateY(${x * 10}deg)
                rotateX(${-y * 10}deg)
            `;
        });

        this.element.addEventListener('mouseleave', () => {
            this.element.style.transform = 'rotateY(0) rotateX(0)';
        });
    }
}

javascript
/* 悬停时的3D倾斜效果 */
class TiltEffect {
    constructor(element) {
        this.element = element;
        this.element.style.transformStyle = 'preserve-3d';
        this.element.style.perspective = '1000px';
        this.bindEvents();
    }

    bindEvents() {
        this.element.addEventListener('mousemove', (e) => {
            const rect = this.element.getBoundingClientRect();
            const x = (e.clientX - rect.left) / rect.width - 0.5;
            const y = (e.clientY - rect.top) / rect.height - 0.5;

            this.element.style.transform = `
                rotateY(${x * 10}deg)
                rotateX(${-y * 10}deg)
            `;
        });

        this.element.addEventListener('mouseleave', () => {
            this.element.style.transform = 'rotateY(0) rotateX(0)';
        });
    }
}

Troubleshooting

故障排除

Common Issues

常见问题

Fonts not loading:
  • Check Fontshare/Google Fonts URL
  • Ensure font names match in CSS
Animations not triggering:
  • Verify Intersection Observer is running
  • Check that
    .visible
    class is being added
Scroll snap not working:
  • Ensure
    scroll-snap-type
    on html/body
  • Each slide needs
    scroll-snap-align: start
Mobile issues:
  • Disable heavy effects at 768px breakpoint
  • Test touch events
  • Reduce particle count or disable canvas
Performance issues:
  • Use
    will-change
    sparingly
  • Prefer
    transform
    and
    opacity
    animations
  • Throttle scroll/mousemove handlers

字体未加载:
  • 检查Fontshare/Google Fonts链接
  • 确保CSS中的字体名称匹配
动画未触发:
  • 验证Intersection Observer是否在运行
  • 检查是否添加了
    .visible
滚动吸附不工作:
  • 确保html/body上设置了
    scroll-snap-type
  • 每个幻灯片需要设置
    scroll-snap-align: start
移动端问题:
  • 在768px断点处禁用重型效果
  • 测试触摸事件
  • 减少粒子数量或禁用canvas
性能问题:
  • 谨慎使用
    will-change
  • 优先使用
    transform
    opacity
    动画
  • 对滚动/鼠标移动事件处理函数进行节流

Related Skills

相关Skill

  • learn — Generate FORZARA.md documentation for the presentation
  • frontend-design — For more complex interactive pages beyond slides
  • design-and-refine:design-lab — For iterating on component designs

  • learn — 为演示文稿生成FORZARA.md文档
  • frontend-design — 用于创建幻灯片之外更复杂的交互式页面
  • design-and-refine:design-lab — 用于迭代组件设计

Example Session Flow

示例会话流程

  1. User: "I want to create a pitch deck for my AI startup"
  2. Skill asks about purpose, length, content
  3. User shares their bullet points and key messages
  4. Skill asks about desired feeling (Impressed + Excited)
  5. Skill generates 3 style previews
  6. User picks Style B (Neon Cyber), asks for darker background
  7. Skill generates full presentation with all slides
  8. Skill opens the presentation in browser
  9. User requests tweaks to specific slides
  10. Final presentation delivered

  1. 用户:“我想为我的AI创业公司创建一份路演PPT”
  2. Skill询问用途、长度、内容情况
  3. 用户分享要点和关键信息
  4. Skill询问期望的感受(印象深刻+兴奋)
  5. Skill生成3种风格预览
  6. 用户选择风格B(霓虹赛博风),要求背景更深色
  7. Skill生成包含所有幻灯片的完整演示文稿
  8. Skill在浏览器中打开演示文稿
  9. 用户请求调整特定幻灯片
  10. 交付最终演示文稿

Conversion Session Flow

转换会话流程

  1. User: "Convert my slides.pptx to a web presentation"
  2. Skill extracts content and images from PPT
  3. Skill confirms extracted content with user
  4. Skill asks about desired feeling/style
  5. Skill generates style previews
  6. User picks a style
  7. Skill generates HTML presentation with preserved assets
  8. Final presentation delivered
  1. 用户:“把我的slides.pptx转换成网页演示文稿”
  2. Skill从PPT中提取内容和图片
  3. Skill与用户确认提取的内容
  4. Skill询问期望的感受/风格
  5. Skill生成风格预览
  6. 用户选择一种风格
  7. Skill生成包含保留资源的HTML演示文稿
  8. 交付最终演示文稿 ",