Browse Source

Initial release: Frontend Slides skill for Claude Code

A skill for creating stunning, animation-rich HTML presentations from scratch
or by converting PowerPoint files. Features visual style discovery ("show,
don't tell"), 10 curated design presets, and zero-dependency output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Zara Zhang 4 months ago
commit
84d16176ed
4 changed files with 1469 additions and 0 deletions
  1. 21 0
      LICENSE
  2. 158 0
      README.md
  3. 768 0
      SKILL.md
  4. 522 0
      STYLE_PRESETS.md

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Zara Zhang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 158 - 0
README.md

@@ -0,0 +1,158 @@
+# Frontend Slides
+
+A Claude Code skill for creating stunning, animation-rich HTML presentations — from scratch or by converting PowerPoint files.
+
+## What This Does
+
+**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.
+
+### Key Features
+
+- **Zero Dependencies** — Single HTML files with inline CSS/JS. No npm, no build tools, no frameworks.
+- **Visual Style Discovery** — Can't articulate design preferences? No problem. Pick from generated visual previews.
+- **PPT Conversion** — Convert existing PowerPoint files to web, preserving all images and content.
+- **Anti-AI-Slop** — Curated distinctive styles that avoid generic AI aesthetics (bye-bye, purple gradients on white).
+- **Production Quality** — Accessible, responsive, well-commented code you can customize.
+
+## Installation
+
+### For Claude Code Users
+
+Copy the skill files to your Claude Code skills directory:
+
+```bash
+# Create the skill directory
+mkdir -p ~/.claude/skills/frontend-slides
+
+# Copy the files (or download from this repo)
+cp SKILL.md ~/.claude/skills/frontend-slides/
+cp STYLE_PRESETS.md ~/.claude/skills/frontend-slides/
+```
+
+Then use it by typing `/frontend-slides` in Claude Code.
+
+### Manual Download
+
+1. Download `SKILL.md` and `STYLE_PRESETS.md` from this repo
+2. Place them in `~/.claude/skills/frontend-slides/`
+3. Restart Claude Code
+
+## Usage
+
+### Create a New Presentation
+
+```
+/frontend-slides
+
+> "I want to create a pitch deck for my AI startup"
+```
+
+The skill will:
+1. Ask about your content (slides, messages, images)
+2. Ask about the feeling you want (impressed? excited? calm?)
+3. Generate 3 visual style previews for you to compare
+4. Create the full presentation in your chosen style
+5. Open it in your browser
+
+### Convert a PowerPoint
+
+```
+/frontend-slides
+
+> "Convert my presentation.pptx to a web slideshow"
+```
+
+The skill will:
+1. Extract all text, images, and notes from your PPT
+2. Show you the extracted content for confirmation
+3. Let you pick a visual style
+4. Generate an HTML presentation with all your original assets
+
+## Included Styles
+
+### Dark Themes
+- **Neon Cyber** — Futuristic, techy, particle effects
+- **Midnight Executive** — Premium, corporate, trustworthy
+- **Deep Space** — Cinematic, inspiring, vast
+- **Terminal Green** — Developer-focused, hacker aesthetic
+
+### Light Themes
+- **Paper & Ink** — Editorial, literary, refined
+- **Swiss Modern** — Clean, Bauhaus-inspired, geometric
+- **Soft Pastel** — Friendly, playful, creative
+- **Warm Editorial** — Magazine-style, photographic
+
+### Specialty
+- **Brutalist** — Raw, bold, attention-grabbing
+- **Gradient Wave** — Modern SaaS aesthetic
+
+## Output Example
+
+Each presentation is a single, self-contained HTML file:
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <!-- Fonts, CSS variables, all styles inline -->
+</head>
+<body>
+    <section class="slide title-slide">
+        <h1 class="reveal">Your Title</h1>
+    </section>
+
+    <section class="slide">
+        <h2 class="reveal">Slide Content</h2>
+    </section>
+
+    <!-- Navigation: Arrow keys, scroll, swipe, or click dots -->
+    <script>
+        // SlidePresentation controller, animations, interactions
+    </script>
+</body>
+</html>
+```
+
+Features included:
+- Keyboard navigation (arrows, space)
+- Touch/swipe support
+- Mouse wheel scrolling
+- Progress bar
+- Navigation dots
+- Scroll-triggered animations
+- Responsive design
+- Reduced motion support
+
+## Philosophy
+
+This skill was born from the belief that:
+
+1. **You don't need to be a designer to make beautiful things.** You just need to react to what you see.
+
+2. **Dependencies are debt.** A single HTML file will work in 10 years. A React project from 2019? Good luck.
+
+3. **Generic is forgettable.** Every presentation should feel custom-crafted, not template-generated.
+
+4. **Comments are kindness.** Code should explain itself to future-you (or anyone else who opens it).
+
+## Files
+
+| File | Purpose |
+|------|---------|
+| `SKILL.md` | Main skill instructions for Claude Code |
+| `STYLE_PRESETS.md` | Reference file with 10 curated visual styles |
+
+## Requirements
+
+- [Claude Code](https://claude.ai/claude-code) CLI
+- For PPT conversion: Python with `python-pptx` library
+
+## Credits
+
+Created by [@zarazhangrui](https://github.com/zarazhangrui) with Claude Code.
+
+Inspired by the "Vibe Coding" philosophy — building beautiful things without being a traditional software engineer.
+
+## License
+
+MIT — Use it, modify it, share it.

+ 768 - 0
SKILL.md

@@ -0,0 +1,768 @@
+---
+name: frontend-slides
+description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
+---
+
+# Frontend Slides 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.
+
+## 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.
+
+---
+
+## Phase 0: Detect Mode
+
+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
+
+---
+
+## Phase 1: Content Discovery (New Presentations)
+
+Before designing, understand the content. Ask via AskUserQuestion:
+
+### Step 1.1: Presentation Context
+
+**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.).
+
+---
+
+## Phase 2: Style Discovery (Visual Exploration)
+
+**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
+
+**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)
+
+### Step 2.2: Generate Style Previews
+
+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):**
+
+| Mood | Style 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
+
+### Step 2.3: Present Previews
+
+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.
+
+---
+
+## Phase 3: Generate Presentation
+
+Now generate the full presentation based on:
+- Content from Phase 1
+- Style from Phase 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/
+```
+
+### HTML Architecture
+
+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>
+```
+
+### Required JavaScript Features
+
+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
+
+### 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;
+    }
+}
+```
+
+---
+
+## Phase 4: PPT Conversion
+
+When converting PowerPoint files:
+
+### Step 4.1: Extract Content
+
+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
+```
+
+### Step 4.2: Confirm Content Structure
+
+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?
+```
+
+### Step 4.3: Style Selection
+
+Proceed to Phase 2 (Style Discovery) with the extracted content in mind.
+
+### Step 4.4: Generate 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)
+
+---
+
+## Phase 5: Delivery
+
+### 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?
+```
+
+---
+
+## 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
+
+### 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
+
+### 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
+
+### 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);
+}
+```
+
+### 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;
+}
+```
+
+### 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)';
+        });
+    }
+}
+```
+
+---
+
+## 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
+
+---
+
+## Related Skills
+
+- **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
+
+---
+
+## 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
+
+---
+
+## 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

+ 522 - 0
STYLE_PRESETS.md

@@ -0,0 +1,522 @@
+# Style Presets Reference
+
+Curated visual styles for Frontend Slides. Each preset includes specific font choices, color palettes, and animation approaches to ensure distinctive, non-generic designs.
+
+---
+
+## Dark Themes
+
+### 1. Neon Cyber
+
+**Vibe:** Futuristic, techy, confident, cutting-edge
+
+**Typography:**
+- Display: `Clash Display` (700) — Bold, geometric, modern
+- Body: `Satoshi` (400/500) — Clean, technical, readable
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #0a0f1c;
+    --bg-secondary: #111827;
+    --text-primary: #ffffff;
+    --text-secondary: #94a3b8;
+    --accent: #00ffcc;
+    --accent-secondary: #ff00aa;
+    --glow: rgba(0, 255, 204, 0.4);
+}
+```
+
+**Signature Elements:**
+- Particle system background (canvas)
+- Neon glow on accent elements
+- Custom cursor with trail
+- Grid pattern overlay
+- Glitch text effect on titles
+
+**Animation Style:**
+- Medium speed (0.5-0.8s)
+- Slide up + fade entrances
+- Staggered reveals
+
+---
+
+### 2. Midnight Executive
+
+**Vibe:** Premium, trustworthy, sophisticated, corporate
+
+**Typography:**
+- Display: `Libre Baskerville` (700) — Classic, authoritative
+- Body: `Source Sans 3` (400/600) — Professional, highly readable
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #0f172a;
+    --bg-secondary: #1e293b;
+    --text-primary: #f8fafc;
+    --text-secondary: #94a3b8;
+    --accent: #3b82f6;
+    --accent-secondary: #818cf8;
+    --gold: #fbbf24;
+}
+```
+
+**Signature Elements:**
+- Subtle gradient backgrounds
+- Thin gold accent lines
+- Data visualizations
+- Minimal decorative elements
+- Focus on whitespace
+
+**Animation Style:**
+- Fast, subtle (0.3-0.5s)
+- Fade only, minimal movement
+- Professional restraint
+
+---
+
+### 3. Deep Space
+
+**Vibe:** Inspiring, vast, contemplative, visionary
+
+**Typography:**
+- Display: `Space Grotesk` (700) — Geometric, space-age
+- Body: `DM Sans` (400/500) — Modern, friendly
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #030712;
+    --bg-secondary: #111827;
+    --text-primary: #f9fafb;
+    --text-secondary: #6b7280;
+    --accent: #818cf8;
+    --accent-secondary: #c084fc;
+    --stars: rgba(255, 255, 255, 0.1);
+}
+```
+
+**Signature Elements:**
+- Starfield background (CSS or canvas)
+- Radial gradient "spotlight" effects
+- Floating elements
+- Large, impactful typography
+- Generous vertical spacing
+
+**Animation Style:**
+- Slow, cinematic (0.8-1.2s)
+- Scale + fade entrances
+- Parallax scrolling
+
+---
+
+### 4. Terminal Green
+
+**Vibe:** Developer-focused, hacker aesthetic, retro-tech
+
+**Typography:**
+- Display: `JetBrains Mono` (700) — Monospace, code-like
+- Body: `JetBrains Mono` (400) — Consistent monospace
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #0d1117;
+    --bg-secondary: #161b22;
+    --text-primary: #c9d1d9;
+    --text-secondary: #8b949e;
+    --accent: #39d353;
+    --accent-dim: rgba(57, 211, 83, 0.2);
+    --border: #30363d;
+}
+```
+
+**Signature Elements:**
+- Scan line overlay effect
+- Blinking cursor
+- Code blocks and syntax highlighting
+- ASCII art decorations
+- Terminal-style borders
+
+**Animation Style:**
+- Typewriter text reveals
+- Quick, snappy transitions (0.2-0.3s)
+- Character-by-character reveals
+
+---
+
+## Light Themes
+
+### 5. Paper & Ink
+
+**Vibe:** Editorial, literary, thoughtful, refined
+
+**Typography:**
+- Display: `Cormorant Garamond` (700) — Elegant, editorial
+- Body: `Source Serif 4` (400) — Classic, readable
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #faf9f7;
+    --bg-secondary: #f5f3ef;
+    --text-primary: #1a1a1a;
+    --text-secondary: #666666;
+    --accent: #c41e3a;
+    --border: #e5e2db;
+}
+```
+
+**Signature Elements:**
+- Drop caps on opening paragraphs
+- Pull quotes
+- Subtle paper texture
+- Elegant horizontal rules
+- Classic column layouts
+
+**Animation Style:**
+- Gentle fades (0.4-0.6s)
+- No dramatic movements
+- Refined, understated
+
+---
+
+### 6. Swiss Modern
+
+**Vibe:** Clean, precise, Bauhaus-inspired, geometric
+
+**Typography:**
+- Display: `Archivo` (800) — Strong, geometric
+- Body: `Nunito` (400/600) — Friendly, rounded
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #ffffff;
+    --bg-secondary: #f7f7f7;
+    --text-primary: #000000;
+    --text-secondary: #555555;
+    --accent: #ff3300;
+    --grid: rgba(0, 0, 0, 0.05);
+}
+```
+
+**Signature Elements:**
+- Visible grid system
+- Asymmetric layouts
+- Red accent sparingly
+- Bold black typography
+- Geometric shapes
+
+**Animation Style:**
+- Precise, mechanical (0.3-0.4s)
+- Linear or ease-out easing
+- Grid-aligned movements
+
+---
+
+### 7. Soft Pastel
+
+**Vibe:** Friendly, approachable, creative, playful
+
+**Typography:**
+- Display: `Nunito` (800) — Rounded, warm
+- Body: `Nunito` (400/500) — Consistent warmth
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #fef3f2;
+    --bg-secondary: #fef9f5;
+    --text-primary: #374151;
+    --text-secondary: #6b7280;
+    --accent: #f472b6;
+    --accent-secondary: #a78bfa;
+    --accent-tertiary: #34d399;
+}
+```
+
+**Signature Elements:**
+- Rounded corners everywhere
+- Blob shapes in background
+- Multiple pastel accents
+- Soft shadows
+- Illustrated icons
+
+**Animation Style:**
+- Bouncy spring physics
+- Playful overshoots
+- Floating/bobbing elements
+
+---
+
+### 8. Warm Editorial
+
+**Vibe:** Human, storytelling, photographic, magazine
+
+**Typography:**
+- Display: `Playfair Display` (700) — Elegant, serif headlines
+- Body: `Work Sans` (400) — Modern, readable
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #fffbf5;
+    --bg-secondary: #f5efe6;
+    --text-primary: #2d2a24;
+    --text-secondary: #78716c;
+    --accent: #b45309;
+    --accent-secondary: #0369a1;
+}
+```
+
+**Signature Elements:**
+- Large hero images
+- Image overlays with text
+- Warm photography
+- Pull quotes in accent color
+- Handwritten accent fonts
+
+**Animation Style:**
+- Cinematic crossfades
+- Ken Burns effect on images
+- Slow, emotional transitions (0.8-1s)
+
+---
+
+## Specialty Themes
+
+### 9. Brutalist
+
+**Vibe:** Raw, bold, unconventional, attention-grabbing
+
+**Typography:**
+- Display: `Anton` or `Bebas Neue` (900) — Massive, compressed
+- Body: `IBM Plex Mono` (400) — Industrial
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #ffffff;
+    --text-primary: #000000;
+    --accent: #ff0000;
+    --border: #000000;
+}
+```
+
+**Signature Elements:**
+- Thick black borders
+- Asymmetric, chaotic layouts
+- Oversized typography
+- Raw, unpolished look
+- High contrast
+
+**Animation Style:**
+- Instant or very fast
+- Hard cuts, no easing
+- Jarring transitions
+
+---
+
+### 10. Gradient Wave
+
+**Vibe:** Modern SaaS, energetic, approachable tech
+
+**Typography:**
+- Display: `Cabinet Grotesk` (800) — Modern, confident
+- Body: `Inter` (400/500) — Only allowed for this style
+
+**Colors:**
+```css
+:root {
+    --bg-primary: #0f0f1a;
+    --gradient-1: #667eea;
+    --gradient-2: #764ba2;
+    --gradient-3: #f472b6;
+    --text-primary: #ffffff;
+    --text-secondary: #a1a1aa;
+}
+```
+
+**Signature Elements:**
+- Animated gradient meshes
+- Blob shapes with blur
+- Glass-morphism cards
+- Floating orbs
+- Smooth curves
+
+**Animation Style:**
+- Smooth, flowing (0.5-0.7s)
+- Continuous subtle animations
+- Hover reveals
+
+---
+
+## Font Pairing Quick Reference
+
+| Vibe | Display Font | Body Font | Source |
+|------|--------------|-----------|--------|
+| Techy/Modern | Clash Display | Satoshi | Fontshare |
+| Professional | Libre Baskerville | Source Sans 3 | Google |
+| Space/Future | Space Grotesk | DM Sans | Google |
+| Developer | JetBrains Mono | JetBrains Mono | JetBrains |
+| Editorial | Cormorant Garamond | Source Serif 4 | Google |
+| Swiss/Minimal | Archivo | Nunito | Google |
+| Playful | Nunito | Nunito | Google |
+| Magazine | Playfair Display | Work Sans | Google |
+| Brutalist | Anton | IBM Plex Mono | Google |
+| SaaS Modern | Cabinet Grotesk | Inter | Fontshare/Google |
+
+---
+
+## Animation Easing Reference
+
+```css
+:root {
+    /* Standard curves */
+    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
+    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
+    --ease-out-cubic: cubic-bezier(0.33, 1, 0.68, 1);
+
+    /* Bouncy */
+    --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
+    --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
+
+    /* Smooth */
+    --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
+
+    /* Snappy */
+    --ease-snappy: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+}
+```
+
+---
+
+## Background Effect Snippets
+
+### Particle Field (Canvas)
+
+```javascript
+class ParticleSystem {
+    constructor(canvas) {
+        this.canvas = canvas;
+        this.ctx = canvas.getContext('2d');
+        this.particles = [];
+        this.init();
+    }
+
+    init() {
+        this.resize();
+        for (let i = 0; i < 50; i++) {
+            this.particles.push({
+                x: Math.random() * this.canvas.width,
+                y: Math.random() * this.canvas.height,
+                vx: (Math.random() - 0.5) * 0.5,
+                vy: (Math.random() - 0.5) * 0.5,
+                radius: Math.random() * 2 + 1
+            });
+        }
+        this.animate();
+    }
+
+    animate() {
+        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+        this.particles.forEach(p => {
+            p.x += p.vx;
+            p.y += p.vy;
+            // Wrap around edges
+            if (p.x < 0) p.x = this.canvas.width;
+            if (p.x > this.canvas.width) p.x = 0;
+            if (p.y < 0) p.y = this.canvas.height;
+            if (p.y > this.canvas.height) p.y = 0;
+            // Draw
+            this.ctx.beginPath();
+            this.ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
+            this.ctx.fillStyle = 'rgba(0, 255, 204, 0.5)';
+            this.ctx.fill();
+        });
+        requestAnimationFrame(() => this.animate());
+    }
+}
+```
+
+### Gradient Mesh (CSS)
+
+```css
+.gradient-mesh {
+    background:
+        radial-gradient(at 40% 20%, hsla(280, 100%, 70%, 0.3) 0px, transparent 50%),
+        radial-gradient(at 80% 0%, hsla(200, 100%, 60%, 0.3) 0px, transparent 50%),
+        radial-gradient(at 0% 50%, hsla(340, 100%, 70%, 0.3) 0px, transparent 50%),
+        radial-gradient(at 80% 50%, hsla(180, 100%, 50%, 0.2) 0px, transparent 50%),
+        radial-gradient(at 0% 100%, hsla(250, 100%, 60%, 0.3) 0px, transparent 50%),
+        radial-gradient(at 80% 100%, hsla(20, 100%, 60%, 0.2) 0px, transparent 50%),
+        var(--bg-primary);
+}
+```
+
+### Animated Starfield (CSS)
+
+```css
+.starfield {
+    background-image:
+        radial-gradient(2px 2px at 20% 30%, white 0%, transparent 50%),
+        radial-gradient(2px 2px at 40% 70%, white 0%, transparent 50%),
+        radial-gradient(1px 1px at 50% 40%, white 0%, transparent 50%),
+        radial-gradient(1px 1px at 60% 60%, white 0%, transparent 50%),
+        radial-gradient(2px 2px at 90% 10%, white 0%, transparent 50%);
+    background-size: 200% 200%;
+    animation: twinkle 15s ease-in-out infinite;
+}
+
+@keyframes twinkle {
+    0%, 100% { background-position: 0% 0%; }
+    50% { background-position: 100% 100%; }
+}
+```
+
+### Noise Texture (SVG Data URI)
+
+```css
+.noise {
+    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+    opacity: 0.05;
+}
+```
+
+---
+
+## DO NOT USE (Generic AI Patterns)
+
+Avoid these overused patterns that create "AI slop":
+
+**Fonts:**
+- Inter (except in Gradient Wave style)
+- Roboto
+- Arial / Helvetica
+- System font stacks as display fonts
+
+**Colors:**
+- `#6366f1` (generic indigo)
+- Purple/violet gradients on white
+- Generic blue primary buttons
+- Equal distribution of accent colors
+
+**Layouts:**
+- Centered everything
+- Generic hero with text left, image right
+- Standard 3-column features grid
+- Rounded rectangle cards with shadows
+
+**Animations:**
+- Identical timing on all elements
+- No stagger on children
+- Linear easing everywhere
+- Excessive bounce
+
+**Effects:**
+- Drop shadows without intention
+- Gratuitous glassmorphism
+- Blurs that don't add meaning
+- Gradients for no reason