All skills
zarazhangrui avatar

/frontend-slides

@fb5b037
by Zara Zhangzarazhangrui/frontend-slides30k stars
2,348

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.

Use this Skill: https://skilld.dev/gh/zarazhangrui/frontend-slides/frontend-slides

This session only. Nothing lands on disk.

html-template.md

≈2.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

HTML Presentation Template

Reference architecture for generating slide presentations. Every presentation follows a fixed 16:9 stage model: slides are authored at 1920×1080 and the whole stage scales to fit the browser window.

Base HTML Structure

<!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 — never system fonts -->
    <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">

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

            /* Typography — authored at 1920×1080 stage size */
            --font-display: 'Clash Display', sans-serif;
            --font-body: 'Satoshi', sans-serif;
            --title-size: 112px;
            --subtitle-size: 34px;
            --body-size: 28px;

            /* Spacing — authored at 1920×1080 stage size */
            --slide-padding: 72px;
            --content-gap: 32px;

            /* 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; }

        /* --- PASTE viewport-base.css CONTENTS HERE --- */

        /* ===========================================
           ANIMATIONS
           Trigger via .visible class on the active slide
           =========================================== */
        .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 for sequential reveal */
        .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; }

        /* ... preset-specific styles ... */
    </style>
</head>
<body>
    <div class="deck-viewport">
        <main class="deck-stage" id="deckStage">
            <section class="slide title-slide active">
                <h1 class="reveal">Presentation Title</h1>
                <p class="reveal">Subtitle or author</p>
            </section>

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

            <!-- More slides... -->
        </main>
    </div>

    <script>
        /* ===========================================
           SLIDE PRESENTATION CONTROLLER
           =========================================== */
        class SlidePresentation {
            constructor() {
                this.slides = document.querySelectorAll('.slide');
                this.currentSlide = 0;
                this.stage = document.getElementById('deckStage');
                this.setupStageScale();
                this.setupKeyboardNav();
                this.setupTouchNav();
                this.showSlide(0);
            }

            setupStageScale() {
                const scale = () => {
                    const factor = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
                    const x = (window.innerWidth - 1920 * factor) / 2;
                    const y = (window.innerHeight - 1080 * factor) / 2;
                    this.stage.style.transform = `translate(${x}px, ${y}px) scale(${factor})`;
                };
                scale();
                window.addEventListener('resize', scale);
            }

            setupKeyboardNav() {
                // Arrow keys, Space, Page Up/Down
            }

            setupTouchNav() {
                // Touch/swipe support for mobile
            }

            showSlide(index) {
                this.currentSlide = Math.max(0, Math.min(index, this.slides.length - 1));
                this.slides.forEach((slide, i) => {
                    slide.classList.toggle('active', i === this.currentSlide);
                    slide.classList.toggle('visible', i === this.currentSlide);
                });
            }
        }

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

Required JavaScript Features

Every presentation must include:

  1. SlidePresentation Class — Main controller with:

    • Keyboard navigation (arrows, space, page up/down)
    • Touch/swipe support
    • Mouse wheel navigation
    • Optional progress indicator or page count, kept outside the slide stage
  2. Stage Scaling — For fixed 16:9 presentation behavior:

    • Keep all slides at 1920×1080 inside .deck-stage
    • Scale the whole stage with one transform
    • Letterbox/pillarbox as needed; never reflow slide content per device
  3. Optional Enhancements (match to chosen style):

    • Custom cursor with trail
    • Particle system background (canvas)
    • Parallax effects
    • 3D tilt on hover
    • Magnetic buttons
    • Counter animations
  4. Inline Editing (included by default after draft generation):

    • Edit toggle button (hidden by default, revealed via hover hotzone or E key)
    • Auto-save to localStorage
    • Export/save file functionality
    • See "Inline Editing Implementation" section below

Inline Editing Implementation

Inline editing is a lightweight post-draft affordance. Do not ask the user whether they want it during the pre-generation Q&A. Include it by default unless the user explicitly asks for a locked/export-only presentation or no editing controls.

Do NOT use CSS ~ sibling selector for hover-based show/hide. The CSS-only approach (edit-hotzone:hover ~ .edit-toggle) fails because pointer-events: none on the toggle button breaks the hover chain: user hovers hotzone -> button becomes visible -> mouse moves toward button -> leaves hotzone -> button disappears before click.

Required approach: JS-based hover with 400ms delay timeout.

HTML:

<div class="edit-hotzone"></div>
<button class="edit-toggle" id="editToggle" title="Edit mode (E)">✏️</button>

CSS (visibility controlled by JS classes only):

/* Do NOT use CSS ~ sibling selector for this!
   pointer-events: none breaks the hover chain.
   Must use JS with delay timeout. */
.edit-hotzone {
    position: fixed; top: 0; left: 0;
    width: 80px; height: 80px;
    z-index: 10000;
    cursor: pointer;
}
.edit-toggle {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    z-index: 10001;
}
.edit-toggle.show,
.edit-toggle.active {
    opacity: 1;
    pointer-events: auto;
}

JS (three interaction methods):

// 1. Click handler on the toggle button
document.getElementById('editToggle').addEventListener('click', () => {
    editor.toggleEditMode();
});

// 2. Hotzone hover with 400ms grace period
const hotzone = document.querySelector('.edit-hotzone');
const editToggle = document.getElementById('editToggle');
let hideTimeout = null;

hotzone.addEventListener('mouseenter', () => {
    clearTimeout(hideTimeout);
    editToggle.classList.add('show');
});
hotzone.addEventListener('mouseleave', () => {
    hideTimeout = setTimeout(() => {
        if (!editor.isActive) editToggle.classList.remove('show');
    }, 400);
});
editToggle.addEventListener('mouseenter', () => {
    clearTimeout(hideTimeout);
});
editToggle.addEventListener('mouseleave', () => {
    hideTimeout = setTimeout(() => {
        if (!editor.isActive) editToggle.classList.remove('show');
    }, 400);
});

// 3. Hotzone direct click
hotzone.addEventListener('click', () => {
    editor.toggleEditMode();
});

// 4. Keyboard shortcut (E key, skip when editing text)
document.addEventListener('keydown', (e) => {
    if ((e.key === 'e' || e.key === 'E') && !e.target.getAttribute('contenteditable')) {
        editor.toggleEditMode();
    }
});

Image Pipeline (Skip If No Images)

If user chose "No images" in Phase 1, skip this entirely. If images were provided, process them before generating HTML.

Dependency: pip install Pillow

Image Processing

from PIL import Image, ImageDraw

# Circular crop (for logos on modern/clean styles)
def crop_circle(input_path, output_path):
    img = Image.open(input_path).convert('RGBA')
    w, h = img.size
    size = min(w, h)
    left, top = (w - size) // 2, (h - size) // 2
    img = img.crop((left, top, left + size, top + size))
    mask = Image.new('L', (size, size), 0)
    ImageDraw.Draw(mask).ellipse([0, 0, size, size], fill=255)
    img.putalpha(mask)
    img.save(output_path, 'PNG')

# Resize (for oversized images that inflate HTML)
def resize_max(input_path, output_path, max_dim=1200):
    img = Image.open(input_path)
    img.thumbnail((max_dim, max_dim), Image.LANCZOS)
    img.save(output_path, quality=85)
Situation Operation
Square logo on rounded aesthetic crop_circle()
Image > 1MB resize_max(max_dim=1200)
Wrong aspect ratio Manual crop with img.crop()

Save processed images with _processed suffix. Never overwrite originals.

Image Placement

Use direct file paths (not base64) — presentations are viewed locally:

<img src="assets/logo_round.png" alt="Logo" class="slide-image logo">
<img src="assets/screenshot.png" alt="Screenshot" class="slide-image screenshot">
.slide-image {
    max-width: 100%;
    max-height: min(50vh, 400px);
    object-fit: contain;
    border-radius: 8px;
}
.slide-image.screenshot {
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.slide-image.logo {
    max-height: min(30vh, 200px);
}

Adapt border/shadow colors to match the chosen style's accent. Never repeat the same image on multiple slides (except logos on title + closing).

Placement patterns: Logo centered on title slide. Screenshots in two-column layouts with text. Full-bleed images as slide backgrounds with text overlay (use sparingly).


Code Quality

Comments: Every section needs clear comments explaining what it does and how to modify it.

Accessibility:

  • Semantic HTML (<section>, <nav>, <main>)
  • Keyboard navigation works fully
  • ARIA labels where needed
  • prefers-reduced-motion support (included in viewport-base.css)

File Structure

Single presentations:

presentation.html    # Self-contained, all CSS/JS inline
assets/              # Images only, if any

Multiple presentations in one project:

[name].html
[name]-assets/

Source: SKILL.md on GitHub

2 warnings3mo5 checks · Risk SAFE
  • Gen Agent Trust Hub3mo

    The Frontend Slides skill is a comprehensive tool for creating and sharing HTML presentations. It includes automation scripts for PowerPoint conversion, PDF export, and web deployment via Vercel. A thorough security analysis of the provided code and instructions revealed no evidence of malicious behavior, unauthorized data exfiltration, or prompt injection attempts. All external dependencies and network operations are associated with well-known, reputable services such as Vercel, Microsoft (Playwright), and Google Fonts.

  • Socket3mo

    No alerts

  • Snyk3mo

    Risk: MEDIUM · 1 issue

  • Runlayer7mo

    4 files scanned · No issues

  • ZeroLeaks5mo

    Scan incomplete

Signed by skilld at fb5b037. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 months ago.

Steadyupdated 4 months ago
  • html
  • presentations
  • slides
  • animations
  • css
  • pptx
  • conversion
  • web-design
  • typography

README badge

README badge for zarazhangrui/frontend-slides

Generates zero-dependency, animation-rich HTML presentations with a fixed 16:9 stage that scales to any viewport. Converts PowerPoint files to web-based decks or creates new presentations from scratch with visual style discovery and distinctive design aesthetics tailored to talks, pitches, or internal docs.

Generated from the current SKILL.md.

Does this skill convert PowerPoint files to HTML?
Yes. The skill can convert .pptx files to zero-dependency HTML presentations that run in the browser. It also creates presentations from scratch or enhances existing HTML decks.
What happens if my content is too long for a slide?
The skill enforces a fixed 1920×1080 slide canvas and will split content across multiple slides rather than allow overflow. It respects content density modes (speaker-led or reading-first) and will automatically reorganize to keep slides readable.
Do I need build tools or npm to use these presentations?
No. Every presentation is a zero-dependency single HTML file with inline CSS and JavaScript. They run entirely in the browser with no build step.
Will the slides work on phones and tablets?
Yes, but they maintain a fixed 16:9 aspect ratio and do not reflow. Slides letterbox or pillarbox to fit the viewport while preserving their 1920×1080 design.
Can I add animations to slides?
Yes. The skill generates CSS-based animations for effects and micro-interactions, with support for reduced-motion preferences. It emphasizes high-impact moments like page-load reveals over scattered effects.

Generated from the current SKILL.md. These answers refresh after source changes.