diff --git a/AGENTS.md b/AGENTS.md index 8fd784c..89b7878 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,7 +55,7 @@ OpenHands uses an **extended AgentSkills standard**: - **Compatible with the AgentSkills specification** (https://agentskills.io/specification) - **Extended with optional `triggers:` frontmatter** for keyword-based activation -When editing or adding skills in this repo, follow these rules (and add new skills to `.plugin/marketplace.json`): +When editing or adding skills in this repo, follow these rules (and register new skills in `marketplaces/default.json` and `.claude-plugin/marketplace.json`): 1. **One skill per directory** - Create `skills//SKILL.md`. diff --git a/marketplaces/default.json b/marketplaces/default.json index 1120ee8..32bbf8f 100644 --- a/marketplaces/default.json +++ b/marketplaces/default.json @@ -179,6 +179,21 @@ "css" ] }, + { + "name": "frontend-slides", + "source": "./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.", + "category": "design", + "keywords": [ + "slides", + "presentation", + "ppt", + "pptx", + "html", + "css", + "animation" + ] + }, { "name": "github", "source": "./github", diff --git a/skills/frontend-slides/LICENSE.txt b/skills/frontend-slides/LICENSE.txt new file mode 100644 index 0000000..746da68 --- /dev/null +++ b/skills/frontend-slides/LICENSE.txt @@ -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. diff --git a/skills/frontend-slides/README.md b/skills/frontend-slides/README.md new file mode 100644 index 0000000..6512d9e --- /dev/null +++ b/skills/frontend-slides/README.md @@ -0,0 +1,178 @@ +# Frontend Slides + +An [Agent Skills](https://agentskills.io/) skill for creating stunning, animation-rich HTML presentations — from scratch or by converting PowerPoint files. + +This skill is published in the OpenHands extensions registry and can be used by OpenHands (CLI/GUI/Cloud) and other AgentSkills-compatible runtimes. + +## 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 + +### OpenHands (CLI / Local GUI) + +This skill uses the AgentSkills directory format. The **directory name must be `frontend-slides/`** and it must contain `SKILL.md` (plus the `references/` folder). + +- **Repository-level (recommended):** `.agents/skills/frontend-slides/` +- **User-level:** `~/.agents/skills/frontend-slides/` + +```bash +# Repository-level +mkdir -p .agents/skills +cp -R frontend-slides .agents/skills/frontend-slides + +# User-level +mkdir -p ~/.agents/skills +cp -R frontend-slides ~/.agents/skills/frontend-slides +``` + +### OpenHands Software Agent SDK + +- To auto-load skills from the public registry (https://github.com/OpenHands/extensions): + +```python +from openhands.sdk import AgentContext + +agent_context = AgentContext(load_public_skills=True) +``` + +- To load this skill from a local directory (for example, `.agents/skills/`): + +```python +from openhands.sdk import AgentContext +from openhands.sdk.context.skills import load_skills_from_dir + +_, _, agent_skills = load_skills_from_dir(".agents/skills") +agent_context = AgentContext(skills=list(agent_skills.values())) +``` + +References: https://docs.openhands.dev/overview/skills and https://docs.openhands.dev/sdk/guides/skill + +## Usage + +### Create a New Presentation + +``` +Create a pitch deck for my AI startup. + +Use the frontend-slides skill. +``` + +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 + +``` +Convert my presentation.pptx to a web slideshow (HTML). Preserve text, images, and speaker notes. + +Use the frontend-slides skill. +``` + +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 + + + + + + +
+

Your Title

+
+ +
+

Slide Content

+
+ + + + + +``` + +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` | Skill definition (AgentSkills format) | +| `references/STYLE_PRESETS.md` | Reference file with curated visual styles | + +## Requirements + +- OpenHands (CLI/GUI/Cloud) or the OpenHands Software Agent SDK (AgentSkills-compatible runtime) +- For PPT conversion: Python with `python-pptx` library + +## Credits + +Originally created by [@zarazhangrui](https://github.com/zarazhangrui). + +Inspired by the "Vibe Coding" philosophy — building beautiful things without being a traditional software engineer. + +## License + +MIT — Use it, modify it, share it. diff --git a/skills/frontend-slides/SKILL.md b/skills/frontend-slides/SKILL.md new file mode 100644 index 0000000..c237715 --- /dev/null +++ b/skills/frontend-slides/SKILL.md @@ -0,0 +1,42 @@ +--- +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. +license: MIT (see LICENSE.txt) +compatibility: For PPT/PPTX conversion requires Python and the python-pptx package. +--- + +# Frontend Slides Skill + +Create **zero-dependency**, animation-rich HTML presentations that run entirely in the browser. + +## Non-negotiables + +- **Single-file output:** generate a self-contained `.html` with inline CSS/JS (no npm, no build tools). +- **Distinctive design:** avoid generic, templated “AI slop” aesthetics. +- **Viewport fitting (CRITICAL):** every slide must fit exactly in the viewport; **no scrolling within slides**. + - Details + mandatory base CSS: see [references/VIEWPORT_FITTING.md](references/VIEWPORT_FITTING.md). + +## How to use (choose a mode) + +1. **New presentation** (from scratch) + - Use the structured workflow in [references/WORKFLOW.md](references/WORKFLOW.md). + - Use the style index in [references/STYLE_PRESETS.md](references/STYLE_PRESETS.md) and load the chosen preset from `references/presets/`. + +2. **PPT/PPTX conversion** + - Extract content + images with the workflow in [references/PPT_CONVERSION.md](references/PPT_CONVERSION.md). + +3. **Enhance an existing HTML presentation** + - Read the existing HTML/CSS/JS, preserve the content structure, then apply the same constraints: + - viewport fitting + - accessibility + - performance + - distinctive visuals + +## Design + animation references + +- Effect → feeling mapping: [references/STYLE_EFFECT_MAPPING.md](references/STYLE_EFFECT_MAPPING.md) +- Animation patterns (CSS/JS snippets): [references/ANIMATION_PATTERNS.md](references/ANIMATION_PATTERNS.md) + +## Troubleshooting + +See [references/TROUBLESHOOTING.md](references/TROUBLESHOOTING.md). diff --git a/skills/frontend-slides/references/ANIMATION_PATTERNS.md b/skills/frontend-slides/references/ANIMATION_PATTERNS.md new file mode 100644 index 0000000..16b8758 --- /dev/null +++ b/skills/frontend-slides/references/ANIMATION_PATTERNS.md @@ -0,0 +1,103 @@ +## 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)'; + }); + } +} + +// Usage: +document.querySelectorAll('.card').forEach((card) => { + new TiltEffect(card); +}); +``` + +--- + diff --git a/skills/frontend-slides/references/PPT_CONVERSION.md b/skills/frontend-slides/references/PPT_CONVERSION.md new file mode 100644 index 0000000..1b40c1c --- /dev/null +++ b/skills/frontend-slides/references/PPT_CONVERSION.md @@ -0,0 +1,121 @@ +## 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.enum.shapes import MSO_SHAPE_TYPE +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 == MSO_SHAPE_TYPE.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) + +--- + +## 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 diff --git a/skills/frontend-slides/references/STYLE_EFFECT_MAPPING.md b/skills/frontend-slides/references/STYLE_EFFECT_MAPPING.md new file mode 100644 index 0000000..b261d82 --- /dev/null +++ b/skills/frontend-slides/references/STYLE_EFFECT_MAPPING.md @@ -0,0 +1,52 @@ +## 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 + +--- + diff --git a/skills/frontend-slides/references/STYLE_PRESETS.md b/skills/frontend-slides/references/STYLE_PRESETS.md new file mode 100644 index 0000000..4ce1459 --- /dev/null +++ b/skills/frontend-slides/references/STYLE_PRESETS.md @@ -0,0 +1,89 @@ +# Style Presets Reference + +Curated visual styles for Frontend Slides. Each preset is inspired by real design references—no generic “AI slop” aesthetics. + +**Rule:** abstract / geometric shapes only (no illustrations). + +--- + +## CRITICAL: Viewport Fitting (Non-Negotiable) + +Every slide MUST fit exactly in the viewport. No scrolling within slides, ever. + +- Mandatory base CSS + breakpoints: see [VIEWPORT_FITTING.md](VIEWPORT_FITTING.md). + +### Content Density Limits Per Slide + +| Slide Type | Maximum Content | +|------------|-----------------| +| Title slide | 1 heading + 1 subtitle | +| Content slide | 1 heading + 4-6 bullets (max 2 lines each) | +| Feature grid | 1 heading + 6 cards (2x3 or 3x2) | +| Code slide | 1 heading + 8-10 lines of code | +| Quote slide | 1 quote (max 3 lines) + attribution | + +Too much content? Split into multiple slides. Never scroll. + +--- + +## Presets (load only what you need) + +Each preset lives in its own file so agents can load just the chosen style: + +### Dark themes + +- **Bold Signal** — Confident, bold, modern, high-impact ([presets/bold-signal.md](presets/bold-signal.md)) +- **Electric Studio** — Bold, clean, professional, high contrast ([presets/electric-studio.md](presets/electric-studio.md)) +- **Creative Voltage** — Energetic retro-modern ([presets/creative-voltage.md](presets/creative-voltage.md)) +- **Dark Botanical** — Elegant, premium, artistic ([presets/dark-botanical.md](presets/dark-botanical.md)) + +### Light themes + +- **Notebook Tabs** — Editorial, organized, tactile ([presets/notebook-tabs.md](presets/notebook-tabs.md)) +- **Pastel Geometry** — Friendly, modern, approachable ([presets/pastel-geometry.md](presets/pastel-geometry.md)) +- **Split Pastel** — Playful, creative ([presets/split-pastel.md](presets/split-pastel.md)) +- **Vintage Editorial** — Personality-driven editorial ([presets/vintage-editorial.md](presets/vintage-editorial.md)) + +### Specialty themes + +- **Neon Cyber** — Futuristic, techy, confident ([presets/neon-cyber.md](presets/neon-cyber.md)) +- **Terminal Green** — Developer-focused, hacker aesthetic ([presets/terminal-green.md](presets/terminal-green.md)) +- **Swiss Modern** — Bauhaus-inspired precision ([presets/swiss-modern.md](presets/swiss-modern.md)) +- **Paper & Ink** — Literary editorial ([presets/paper-ink.md](presets/paper-ink.md)) + +--- + +## Font Pairing Quick Reference + +| Preset | Display Font | Body Font | Source | +|--------|--------------|-----------|--------| +| Bold Signal | Archivo Black | Space Grotesk | Google | +| Electric Studio | Manrope | Manrope | Google | +| Creative Voltage | Syne | Space Mono | Google | +| Dark Botanical | Cormorant | IBM Plex Sans | Google | +| Notebook Tabs | Bodoni Moda | DM Sans | Google | +| Pastel Geometry | Plus Jakarta Sans | Plus Jakarta Sans | Google | +| Split Pastel | Outfit | Outfit | Google | +| Vintage Editorial | Fraunces | Work Sans | Google | +| Neon Cyber | Clash Display | Satoshi | Fontshare | +| Terminal Green | JetBrains Mono | JetBrains Mono | JetBrains | +| Swiss Modern | Archivo | Nunito | Google | +| Paper & Ink | Cormorant Garamond | Source Serif 4 | Google | + +--- + +## DO NOT USE (Generic AI Patterns) + +- Fonts: Inter, Roboto, Arial, system fonts as display +- Colors: `#6366f1` (generic indigo), purple gradients on white +- Layouts: everything centered, generic hero sections, identical card grids +- Decorations: realistic illustrations, gratuitous glassmorphism, purposeless shadows + +--- + +## Troubleshooting + +If you hit viewport overflow / scaling issues, see: + +- [VIEWPORT_FITTING.md](VIEWPORT_FITTING.md) +- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) diff --git a/skills/frontend-slides/references/TROUBLESHOOTING.md b/skills/frontend-slides/references/TROUBLESHOOTING.md new file mode 100644 index 0000000..df6e6e5 --- /dev/null +++ b/skills/frontend-slides/references/TROUBLESHOOTING.md @@ -0,0 +1,28 @@ +## 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 + +--- + diff --git a/skills/frontend-slides/references/VIEWPORT_FITTING.md b/skills/frontend-slides/references/VIEWPORT_FITTING.md new file mode 100644 index 0000000..0548105 --- /dev/null +++ b/skills/frontend-slides/references/VIEWPORT_FITTING.md @@ -0,0 +1,228 @@ +## CRITICAL: Viewport Fitting Requirements + +**This section is mandatory for ALL presentations. Every slide must be fully visible without scrolling on any screen size.** + +### The Golden Rule + +``` +Each slide = exactly one viewport height (100vh/100dvh) +Content overflows? → Split into multiple slides or reduce content +Never scroll within a slide. +``` + +### Content Density Limits + +To guarantee viewport fitting, enforce these limits per slide: + +| Slide Type | Maximum Content | +|------------|-----------------| +| Title slide | 1 heading + 1 subtitle + optional tagline | +| Content slide | 1 heading + 4-6 bullet points OR 1 heading + 2 paragraphs | +| Feature grid | 1 heading + 6 cards maximum (2x3 or 3x2 grid) | +| Code slide | 1 heading + 8-10 lines of code maximum | +| Quote slide | 1 quote (max 3 lines) + attribution | +| Image slide | 1 heading + 1 image (max 60vh height) | + +**If content exceeds these limits → Split into multiple slides** + +### Required CSS Architecture + +Every presentation MUST include this base CSS for viewport fitting: + +```css +/* =========================================== + VIEWPORT FITTING: MANDATORY BASE STYLES + These styles MUST be included in every presentation. + They ensure slides fit exactly in the viewport. + =========================================== */ + +/* 1. Lock html/body to viewport */ +html, body { + height: 100%; + overflow-x: hidden; +} + +html { + scroll-snap-type: y mandatory; + scroll-behavior: smooth; +} + +/* 2. Each slide = exact viewport height */ +.slide { + width: 100vw; + height: 100vh; + height: 100dvh; /* Dynamic viewport height for mobile browsers */ + overflow: hidden; /* CRITICAL: Prevent ANY overflow */ + scroll-snap-align: start; + display: flex; + flex-direction: column; + position: relative; +} + +/* 3. Content container with flex for centering */ +.slide-content { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + max-height: 100%; + overflow: hidden; /* Double-protection against overflow */ + padding: var(--slide-padding); +} + +/* 4. ALL typography uses clamp() for responsive scaling */ +:root { + /* Titles scale from mobile to desktop */ + --title-size: clamp(1.5rem, 5vw, 4rem); + --h2-size: clamp(1.25rem, 3.5vw, 2.5rem); + --h3-size: clamp(1rem, 2.5vw, 1.75rem); + + /* Body text */ + --body-size: clamp(0.75rem, 1.5vw, 1.125rem); + --small-size: clamp(0.65rem, 1vw, 0.875rem); + + /* Spacing scales with viewport */ + --slide-padding: clamp(1rem, 4vw, 4rem); + --content-gap: clamp(0.5rem, 2vw, 2rem); + --element-gap: clamp(0.25rem, 1vw, 1rem); +} + +/* 5. Cards/containers use viewport-relative max sizes */ +.card, .container, .content-box { + max-width: min(90vw, 1000px); + max-height: min(80vh, 700px); +} + +/* 6. Lists auto-scale with viewport */ +.feature-list, .bullet-list { + gap: clamp(0.4rem, 1vh, 1rem); +} + +.feature-list li, .bullet-list li { + font-size: var(--body-size); + line-height: 1.4; +} + +/* 7. Grids adapt to available space */ +.grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); + gap: clamp(0.5rem, 1.5vw, 1rem); +} + +/* 8. Images constrained to viewport */ +img, .image-container { + max-width: 100%; + max-height: min(50vh, 400px); + object-fit: contain; +} + +/* =========================================== + RESPONSIVE BREAKPOINTS + Aggressive scaling for smaller viewports + =========================================== */ + +/* Short viewports (< 700px height) */ +@media (max-height: 700px) { + :root { + --slide-padding: clamp(0.75rem, 3vw, 2rem); + --content-gap: clamp(0.4rem, 1.5vw, 1rem); + --title-size: clamp(1.25rem, 4.5vw, 2.5rem); + --h2-size: clamp(1rem, 3vw, 1.75rem); + } +} + +/* Very short viewports (< 600px height) */ +@media (max-height: 600px) { + :root { + --slide-padding: clamp(0.5rem, 2.5vw, 1.5rem); + --content-gap: clamp(0.3rem, 1vw, 0.75rem); + --title-size: clamp(1.1rem, 4vw, 2rem); + --body-size: clamp(0.7rem, 1.2vw, 0.95rem); + } + + /* Hide non-essential elements */ + .nav-dots, .keyboard-hint, .decorative { + display: none; + } +} + +/* Extremely short (landscape phones, < 500px height) */ +@media (max-height: 500px) { + :root { + --slide-padding: clamp(0.4rem, 2vw, 1rem); + --title-size: clamp(1rem, 3.5vw, 1.5rem); + --h2-size: clamp(0.9rem, 2.5vw, 1.25rem); + --body-size: clamp(0.65rem, 1vw, 0.85rem); + } +} + +/* Narrow viewports (< 600px width) */ +@media (max-width: 600px) { + :root { + --title-size: clamp(1.25rem, 7vw, 2.5rem); + } + + /* Stack grids vertically */ + .grid { + grid-template-columns: 1fr; + } +} + +/* =========================================== + REDUCED MOTION + Respect user preferences + =========================================== */ +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.01ms !important; + transition-duration: 0.2s !important; + } + + html { + scroll-behavior: auto; + } +} +``` + +### Overflow Prevention Checklist + +Before generating any presentation, mentally verify: + +1. ✅ Every `.slide` has `height: 100vh; height: 100dvh; overflow: hidden;` +2. ✅ All font sizes use `clamp(min, preferred, max)` +3. ✅ All spacing uses `clamp()` or viewport units +4. ✅ Content containers have `max-height` constraints +5. ✅ Images have `max-height: min(50vh, 400px)` or similar +6. ✅ Grids use `auto-fit` with `minmax()` for responsive columns +7. ✅ Breakpoints exist for heights: 700px, 600px, 500px +8. ✅ No fixed pixel heights on content elements +9. ✅ Content per slide respects density limits + +### When Content Doesn't Fit + +If you find yourself with too much content: + +**DO:** +- Split into multiple slides +- Reduce bullet points (max 5-6 per slide) +- Shorten text (aim for 1-2 lines per bullet) +- Use smaller code snippets +- Create a "continued" slide + +**DON'T:** +- Reduce font size below readable limits +- Remove padding/spacing entirely +- Allow any scrolling +- Cram content to fit + +### Testing Viewport Fit + +After generating, recommend the user test at these sizes: +- Desktop: 1920×1080, 1440×900, 1280×720 +- Tablet: 1024×768, 768×1024 (portrait) +- Mobile: 375×667, 414×896 +- Landscape phone: 667×375, 896×414 + +--- + diff --git a/skills/frontend-slides/references/WORKFLOW.md b/skills/frontend-slides/references/WORKFLOW.md new file mode 100644 index 0000000..f0cd660 --- /dev/null +++ b/skills/frontend-slides/references/WORKFLOW.md @@ -0,0 +1,35 @@ +# Workflow (Index) + +This file is a lightweight index for the Frontend Slides workflow (split for progressive disclosure). + +## What to load + +- **New presentation (from scratch)** → [WORKFLOW_NEW_PRESENTATION.md](WORKFLOW_NEW_PRESENTATION.md) → [WORKFLOW_BUILD_PRESENTATION.md](WORKFLOW_BUILD_PRESENTATION.md) → [WORKFLOW_DELIVERY.md](WORKFLOW_DELIVERY.md) +- **PPT/PPTX conversion** → [PPT_CONVERSION.md](PPT_CONVERSION.md) → [WORKFLOW_BUILD_PRESENTATION.md](WORKFLOW_BUILD_PRESENTATION.md) → [WORKFLOW_DELIVERY.md](WORKFLOW_DELIVERY.md) +- **Enhance existing HTML** → [WORKFLOW_ENHANCEMENT.md](WORKFLOW_ENHANCEMENT.md) + +## Phase 0: Detect Mode + +First, determine what the user wants: + +**Mode A: New Presentation** +- User wants to create slides from scratch +- Load: [WORKFLOW_NEW_PRESENTATION.md](WORKFLOW_NEW_PRESENTATION.md) +- Then: [WORKFLOW_BUILD_PRESENTATION.md](WORKFLOW_BUILD_PRESENTATION.md) → [WORKFLOW_DELIVERY.md](WORKFLOW_DELIVERY.md) + +**Mode B: PPT/PPTX Conversion** +- User has a PowerPoint file (.ppt, .pptx) to convert +- Load: [PPT_CONVERSION.md](PPT_CONVERSION.md) +- Then: [WORKFLOW_BUILD_PRESENTATION.md](WORKFLOW_BUILD_PRESENTATION.md) → [WORKFLOW_DELIVERY.md](WORKFLOW_DELIVERY.md) + +**Mode C: Existing Presentation Enhancement** +- User has an HTML presentation and wants to improve it +- Load: [WORKFLOW_ENHANCEMENT.md](WORKFLOW_ENHANCEMENT.md) + +--- + + +## Next steps (common) + +- Build/generation checklist: [WORKFLOW_BUILD_PRESENTATION.md](WORKFLOW_BUILD_PRESENTATION.md) +- Delivery checklist: [WORKFLOW_DELIVERY.md](WORKFLOW_DELIVERY.md) diff --git a/skills/frontend-slides/references/WORKFLOW_BUILD_PRESENTATION.md b/skills/frontend-slides/references/WORKFLOW_BUILD_PRESENTATION.md new file mode 100644 index 0000000..71b7707 --- /dev/null +++ b/skills/frontend-slides/references/WORKFLOW_BUILD_PRESENTATION.md @@ -0,0 +1,288 @@ +# Workflow: Build Presentation + +Split from [WORKFLOW.md](WORKFLOW.md). Use after you have content + a chosen style. + +## 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 + + + + + + Presentation Title + + + + + + + + +
+ + + + + +
+

Presentation Title

+

Subtitle or author

+
+ +
+

Slide Title

+

Content...

+
+ + + + + + +``` + +### 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 (`
`, `