frontend-slides

Generate zero-dependency HTML presentations with keyboard navigation, print CSS, responsive design, and speaker notes. Creates a single self-contained HTML file — no build step, no framework, no CDN. Use when: (1) Creating slide decks or presentations, (2) Building pitch decks, (3) Making technical talks, (4) User asks for slides or a presentation, (5) Quick visual content for meetings.

Best use case

frontend-slides is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Generate zero-dependency HTML presentations with keyboard navigation, print CSS, responsive design, and speaker notes. Creates a single self-contained HTML file — no build step, no framework, no CDN. Use when: (1) Creating slide decks or presentations, (2) Building pitch decks, (3) Making technical talks, (4) User asks for slides or a presentation, (5) Quick visual content for meetings.

Teams using frontend-slides should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/frontend-slides/SKILL.md --create-dirs "https://raw.githubusercontent.com/stevengonsalvez/agents-in-a-box/main/toolkit/packages/skills/frontend-slides/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/frontend-slides/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How frontend-slides Compares

Feature / Agentfrontend-slidesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Generate zero-dependency HTML presentations with keyboard navigation, print CSS, responsive design, and speaker notes. Creates a single self-contained HTML file — no build step, no framework, no CDN. Use when: (1) Creating slide decks or presentations, (2) Building pitch decks, (3) Making technical talks, (4) User asks for slides or a presentation, (5) Quick visual content for meetings.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Frontend Slides — Zero-Dep HTML Presentations

## Quick Start

Generate a single `slides.html` file. Open in browser. Present.

## Slide Structure

Each presentation is a single HTML file with this structure:

```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>
  <style>
    /* All styles inline — zero dependencies */
    {{STYLES}}
  </style>
</head>
<body>
  <div class="slide-deck">
    <div class="slide" id="slide-1">
      <!-- Slide content -->
    </div>
    <div class="slide" id="slide-2">
      <!-- Slide content -->
    </div>
    <!-- ... more slides -->
  </div>

  <div class="progress-bar"><div class="progress-fill"></div></div>
  <div class="slide-counter"></div>

  <script>
    /* All JS inline — keyboard nav, touch, progress */
    {{SCRIPT}}
  </script>
</body>
</html>
```

## Core CSS

```css
* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --bg: #1a1a2e;
  --text: #eee;
  --accent: #e94560;
  --accent2: #0f3460;
  --font: 'system-ui', -apple-system, sans-serif;
  --mono: 'SF Mono', 'Fira Code', monospace;
}

html, body {
  height: 100%;
  overflow: hidden;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
}

.slide-deck { height: 100%; position: relative; }

.slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 5vw;
  opacity: 0;
  transform: translateX(100%);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  text-align: center;
}

.slide.active {
  opacity: 1;
  transform: translateX(0);
}

.slide.prev {
  opacity: 0;
  transform: translateX(-100%);
}

/* Typography */
.slide h1 { font-size: clamp(2rem, 5vw, 4rem); margin-bottom: 1rem; }
.slide h2 { font-size: clamp(1.5rem, 3.5vw, 2.5rem); margin-bottom: 0.75rem; }
.slide p { font-size: clamp(1rem, 2vw, 1.5rem); line-height: 1.6; max-width: 40em; }
.slide ul, .slide ol { font-size: clamp(1rem, 1.8vw, 1.3rem); text-align: left; line-height: 1.8; }
.slide code { font-family: var(--mono); background: rgba(255,255,255,0.1); padding: 0.2em 0.4em; border-radius: 4px; }
.slide pre {
  background: rgba(0,0,0,0.3);
  padding: 1.5em;
  border-radius: 8px;
  overflow-x: auto;
  text-align: left;
  font-size: clamp(0.8rem, 1.4vw, 1.1rem);
  max-width: 90%;
}

/* Progress bar */
.progress-bar {
  position: fixed; bottom: 0; left: 0; right: 0;
  height: 3px; background: rgba(255,255,255,0.1);
}
.progress-fill {
  height: 100%; background: var(--accent);
  transition: width 0.3s ease;
}

/* Slide counter */
.slide-counter {
  position: fixed; bottom: 12px; right: 16px;
  font-size: 0.8rem; opacity: 0.5;
}

/* Speaker notes (hidden in presentation, visible in print) */
.notes { display: none; }

/* Print CSS */
@media print {
  .slide {
    position: relative !important;
    opacity: 1 !important;
    transform: none !important;
    page-break-after: always;
    min-height: 100vh;
  }
  .progress-bar, .slide-counter { display: none; }
  .notes { display: block; border-top: 1px solid #ccc; margin-top: 2em; font-size: 0.9em; color: #666; }
}

/* Responsive */
@media (max-width: 768px) {
  .slide { padding: 8vw 5vw; }
}
```

## Core JavaScript

```javascript
(function() {
  const slides = document.querySelectorAll('.slide');
  const progress = document.querySelector('.progress-fill');
  const counter = document.querySelector('.slide-counter');
  let current = 0;

  function show(index) {
    if (index < 0 || index >= slides.length) return;
    slides[current].classList.remove('active');
    slides[current].classList.add(index > current ? 'prev' : '');
    current = index;
    slides[current].classList.remove('prev');
    slides[current].classList.add('active');

    // Update progress
    progress.style.width = ((current + 1) / slides.length * 100) + '%';
    counter.textContent = (current + 1) + ' / ' + slides.length;

    // Update URL hash
    history.replaceState(null, '', '#slide-' + (current + 1));
  }

  // Keyboard navigation
  document.addEventListener('keydown', e => {
    if (e.key === 'ArrowRight' || e.key === ' ' || e.key === 'Enter') {
      e.preventDefault(); show(current + 1);
    }
    if (e.key === 'ArrowLeft' || e.key === 'Backspace') {
      e.preventDefault(); show(current - 1);
    }
    if (e.key === 'Home') { e.preventDefault(); show(0); }
    if (e.key === 'End') { e.preventDefault(); show(slides.length - 1); }
    // Number keys jump to slide
    if (e.key >= '1' && e.key <= '9') show(parseInt(e.key) - 1);
  });

  // Touch/swipe support
  let touchStart = 0;
  document.addEventListener('touchstart', e => touchStart = e.touches[0].clientX);
  document.addEventListener('touchend', e => {
    const diff = touchStart - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 50) show(current + (diff > 0 ? 1 : -1));
  });

  // Click navigation (left half = back, right half = forward)
  document.addEventListener('click', e => {
    if (e.target.closest('a, button, code, pre')) return;
    show(current + (e.clientX < window.innerWidth / 2 ? -1 : 1));
  });

  // Hash navigation
  const hash = parseInt(location.hash.replace('#slide-', ''));
  show(isNaN(hash) ? 0 : hash - 1);
})();
```

## Slide Templates

### Title Slide
```html
<div class="slide" style="background: linear-gradient(135deg, var(--accent2), var(--bg));">
  <h1>Presentation Title</h1>
  <p style="opacity: 0.7;">Subtitle or tagline</p>
  <p style="margin-top: 2em; font-size: 0.9em; opacity: 0.5;">Author · Date</p>
</div>
```

### Content Slide
```html
<div class="slide">
  <h2>Slide Title</h2>
  <ul>
    <li>Point one with supporting detail</li>
    <li>Point two with <code>inline code</code></li>
    <li>Point three with emphasis</li>
  </ul>
  <div class="notes">Speaker notes go here — visible when printing.</div>
</div>
```

### Code Slide
```html
<div class="slide">
  <h2>Code Example</h2>
  <pre><code>function hello() {
  console.log("Hello, world!");
}</code></pre>
</div>
```

### Image Slide
```html
<div class="slide">
  <h2>Visual</h2>
  <img src="data:image/svg+xml,..." alt="Diagram" style="max-width: 80%; max-height: 60vh;">
</div>
```

### Two-Column Slide
```html
<div class="slide">
  <h2>Comparison</h2>
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2em; text-align: left; width: 100%;">
    <div>
      <h3 style="color: var(--accent);">Before</h3>
      <ul><li>Item</li></ul>
    </div>
    <div>
      <h3 style="color: #4CAF50;">After</h3>
      <ul><li>Item</li></ul>
    </div>
  </div>
</div>
```

### Closing Slide
```html
<div class="slide" style="background: linear-gradient(135deg, var(--bg), var(--accent2));">
  <h1>Thank You</h1>
  <p>Questions?</p>
  <p style="margin-top: 2em; font-size: 0.9em; opacity: 0.5;">contact@example.com</p>
</div>
```

## Color Themes

Override CSS variables for different themes:

```css
/* Dark (default) */
:root { --bg: #1a1a2e; --text: #eee; --accent: #e94560; --accent2: #0f3460; }

/* Light */
:root { --bg: #fafafa; --text: #222; --accent: #e94560; --accent2: #cce5ff; }

/* Corporate */
:root { --bg: #fff; --text: #333; --accent: #0066cc; --accent2: #e8f0fe; }

/* Neon */
:root { --bg: #0a0a0a; --text: #f0f0f0; --accent: #00ff88; --accent2: #1a0033; }
```

## Workflow

1. User describes the presentation topic and audience
2. Generate slide outline (8-15 slides typical)
3. Create the single HTML file with all slides
4. Write to `{topic-slug}-slides.html`
5. Instruct user to open in browser (`open slides.html` on macOS)

## Best Practices

- **Max 6 bullet points per slide** -- Less is more
- **One idea per slide** -- Don't overload
- **Use code slides for technical content** -- Pre-formatted blocks
- **Include speaker notes** -- Hidden in presentation, shown in print
- **Test print** -- Cmd+P should produce clean handouts
- **Keep total slides 8-20** -- Respect attention spans

Related Skills

frontend-design

8
from stevengonsalvez/agents-in-a-box

Frontend design skill for UI/UX implementation - generates distinctive, production-grade interfaces

workflow

8
from stevengonsalvez/agents-in-a-box

Guide through structured delivery workflow with plan, implement, validate phases

webapp-testing

8
from stevengonsalvez/agents-in-a-box

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

validate

8
from stevengonsalvez/agents-in-a-box

Verify implementation against specifications

ui-ux-pro-max

8
from stevengonsalvez/agents-in-a-box

UI/UX design intelligence. 67 styles, 96 palettes, 57 font pairings, 25 charts, 13 stacks (React, Next.js, Vue, Svelte, Astro, Nuxt, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui, Jetpack Compose). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient.

tui-style-guide

8
from stevengonsalvez/agents-in-a-box

TUI style guide for consistent terminal interface design

token-usage

8
from stevengonsalvez/agents-in-a-box

Show Claude Code token usage across sessions — daily, weekly, per-project, and per-session breakdowns. Parses {{HOME_TOOL_DIR}}/projects/**/*.jsonl for consumption data. Use when the user asks about token usage, costs, how many tokens were used, session statistics, or wants a usage report.

tmux-status

8
from stevengonsalvez/agents-in-a-box

Show status of all tmux sessions including dev environments, spawned agents, and running processes

tmux-monitor

8
from stevengonsalvez/agents-in-a-box

Monitor and report status of all tmux sessions including dev environments, spawned agents, and running processes. Uses tmuxwatch for enhanced visibility.

tmux-message

8
from stevengonsalvez/agents-in-a-box

Reliable peer-to-peer message delivery to other Claude Code instances via tmux send-keys. Use as a fallback when claude-peers MCP send_message fails to surface in the receiver's inbox (delivered server-side but receiver never picks it up — observed behaviour). Also use when sending a directive to a known Claude Code TUI session by tmux session name or fuzzy hint, or when injecting a multi-line directive into a peer's prompt and submitting it. Trigger phrases — "claude-peers fallback", "tmux send-keys", "send to peer via tmux", "inject directive", "deliver to nanoclaw/hermes peer", "peer message". Tmux-only — won't reach peers running outside tmux.

test-driven-development

8
from stevengonsalvez/agents-in-a-box

Use when implementing any feature or bugfix, before writing implementation code. Enforces RED-GREEN-REFACTOR cycle with test-first approach.

test-ainb

8
from stevengonsalvez/agents-in-a-box

Run tests for the ainb (agents-in-a-box) Rust workspace via a 5-layer strategy — unit, insta snapshot, mock-plugin compositing, real-plugin spawn, vhs recording. Wraps cargo + insta + vhs into one CLI. Use when Stevie says "/test-ainb", "test ainb", "run ainb tests", "snapshot <component>", "regenerate vhs tapes", or any phrasing about validating ainb test layers. The skill autodetects which ainb-tui worktree the cwd sits in and dispatches to scripts/run.sh.