Back to catalog

create-presentation

Create or update presentation notebooks with embedded HTML and JavaScript in markdown cells using EDS blocks. Convert executable code cells to informative text. Build presentations, slides, demos, showcases with accordion, cards, tabs, hero, grid, table blocks. No runnable JavaScript cells - only visual markdown with inline scripts for presentation mode.

  • Category: discovered
  • Tags: github, community
  • Version: 1.0.0
  • Author: walid
  • Downloads: 0
  • Updated: 2025-11-22

Download the latest version (v1.0.0) from this page.

SKILL.md

---
name: create-presentation
description: Create or update presentation notebooks with embedded HTML and JavaScript in markdown cells using EDS blocks. Convert executable code cells to informative text. Build presentations, slides, demos, showcases with accordion, cards, tabs, hero, grid, table blocks. No runnable JavaScript cells - only visual markdown with inline scripts for presentation mode.
---

# Create Presentation Skill

## Purpose

Transform Jupyter notebooks into beautiful presentation-mode experiences using embedded HTML and JavaScript within markdown cells. Leverages EDS blocks for visual appeal while preventing code execution by users.

## When to Use

- Creating presentation notebooks
- Building interactive demos without executable code
- Converting educational notebooks to presentation format
- Creating showcases, tutorials, or product demos
- Building slide-like experiences with EDS blocks
- Updating existing notebooks to presentation mode
- Applying inline HTML styling for beautiful, consistent appearance

## Key Concepts

### Presentation Mode vs Interactive Mode vs Educational Mode vs Navigation Mode

**Interactive Notebooks** (e.g., test.ipynb):
- Users can run JavaScript code cells
- Code cells have "Run" buttons
- For developers and testing

**Educational Notebooks** (e.g., tutorial.ipynb):
- Runnable code cells for learning
- Can use auto-wrapping in notebook mode (pure markdown)
- 60% markdown, 40% code
- For teaching and explaining
- See `jupyter-educational-notebook` skill

**Presentation Notebooks** (e.g., demo.ipynb):
- No executable code cells
- All interactivity via inline scripts in markdown
- Can use auto-wrapping (notebook mode) OR manual HTML (all modes)
- For end users, clients, presentations
- Beautiful visual layouts with EDS blocks

**Navigation Notebooks** (e.g., docs-navigation.ipynb):
- No executable code cells (pure navigation)
- 100% markdown with action cards
- Multi-paradigm navigation (role, task, workflow, category)
- For complex documentation systems (20+ documents)
- Progressive disclosure with part summaries
- See template: `docs/for-ai/templates/ipynb/navigation-template.ipynb`

### Core Approach

1. **All content in markdown cells** - No code cells with executable JavaScript
2. **Inline scripts in markdown** - Use `<script>` tags within markdown for interactivity
3. **EDS blocks via HTML** - Embed block HTML directly in markdown
4. **Conversion of existing code cells** - Transform to informative markdown text
5. **Choose styling approach**:
   - **Auto-wrapping** (pure markdown) - When displayed in notebook mode
   - **Manual HTML** (inline styles) - When displayed in other modes or needing custom styling

## Available EDS Blocks

See [resources/blocks-reference.md](resources/blocks-reference.md) for complete details on all blocks.

**Visual Layout Blocks:**
- `accordion` - Collapsible sections
- `cards` - Card grid layouts
- `tabs` - Tabbed content
- `grid` - Flexible grid layouts
- `hero` - Hero banners
- `table` - Data tables

**Content Blocks:**
- `quote` - Pull quotes
- `columns` - Multi-column layouts
- `modal` - Dialog overlays
- `video` - Embedded videos

**Interactive Blocks:**
- `code-expander` - Expandable code snippets
- `counter` - Animated counters
- `floating-alert` - Dismissible alerts

## Quick Start

### Creating a New Presentation

```markdown
Use /create-presentation command with:
- Topic or title
- Key sections/topics
- Desired blocks (accordion, cards, tabs, etc.)
```

**Example:**
```
/create-presentation "Product Demo" with sections: Features, Benefits, Pricing
Use cards for features, accordion for benefits, table for pricing
```

### Converting Existing Notebook

```markdown
Use /create-presentation with path to existing .ipynb file
All code cells will be converted to informative markdown
```

**Example:**
```
/create-presentation convert education.ipynb
Keep structure but make it presentation-only
```

## Structure Pattern

### Metadata Setup

Every presentation notebook should have:

```json
{
  "metadata": {
    "title": "Presentation Title",
    "description": "Brief description",
    "author": "Author Name",
    "date": "2025-01-19",
    "category": "presentation",
    "repo": "https://github.com/username/repo",
    "manual-path": "docs/for-ai/your-documentation.md"
  }
}
```

**Key Fields:**

- **`title`** - Main presentation title (required)
- **`description`** - One-line summary (optional)
- **`author`** - Author name (optional)
- **`date`** - Publication date (optional)
- **`category`** - Content category, e.g., "presentation" (optional)
- **`repo`** - Repository URL for linking .md files (optional)
- **`manual-path`** - Path to documentation for "Read the Manual" button (optional)
  - **REQUIRED for button:** Button only appears if `manual-path` is provided
  - With `repo` and plain .md: Creates GitHub link `{repo}/blob/main/{manual-path}`
  - Absolute path (`/...`): Used as-is
  - Relative path: Made absolute from root
  - Full URL: Used as-is
  - **No default:** If omitted, button will not appear

### Cell Structure

**Important:** Do NOT automatically include a Table of Contents. The presentation template does not include a TOC by default. Only add navigation if explicitly requested by the user.

**Typical structure:**

**Title Cell (Markdown):**
```markdown
# 🎯 Presentation Title

**Subtitle or tagline**

---

## Overview

Brief introduction to the presentation
```

**Content Cells (Markdown with Embedded Blocks):**
```markdown
## Section Title

<div class="accordion block">
  <div>
    <div>Feature 1</div>
    <div>Description of feature 1 with details...</div>
  </div>
  <div>
    <div>Feature 2</div>
    <div>Description of feature 2 with details...</div>
  </div>
</div>

<script type="module">
  // Initialize block
  const block = document.querySelector('.accordion.block');
  const module = await import('/blocks/accordion/accordion.js');
  await module.default(block);
</script>
```

**Navigation Cell (Markdown):**
```markdown
---

## 📋 Table of Contents

- [Section 1](#section-1)
- [Section 2](#section-2)
- [Conclusion](#conclusion)
```

## Block Usage Patterns

### Accordion Block (Collapsible Sections)

**Best For:** FAQs, feature lists, detailed explanations

```markdown
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

<h2 style="color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;">Section Title</h2>

<div class="accordion block">
  <div>
    <div>Question or Title</div>
    <div>Answer or detailed content here...</div>
  </div>
</div>

<script type="module">
  const block = document.querySelector('.accordion.block');
  const module = await import('/blocks/accordion/accordion.js');
  await module.default(block);
</script>

</div>
```

### Cards Block (Grid Layout)

**Best For:** Features, team members, product showcase

```markdown
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

<h2 style="color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;">Section Title</h2>

<div class="cards block">
  <div>
    <div><strong>📊 Card Title</strong></div>
    <div>Card content with description...</div>
  </div>
  <div>
    <div><strong>🚀 Another Card</strong></div>
    <div>More content here...</div>
  </div>
</div>

<script type="module">
  const block = document.querySelector('.cards.block');
  const module = await import('/blocks/cards/cards.js');
  await module.default(block);
</script>

</div>
```

### Tabs Block (Tabbed Content)

**Best For:** Organizing related information, code examples, comparisons

```markdown
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

<h2 style="color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;">Section Title</h2>

<div class="tabs block">
  <div>
    <div>Tab 1</div>
    <div>Content for tab 1...</div>
  </div>
  <div>
    <div>Tab 2</div>
    <div>Content for tab 2...</div>
  </div>
</div>

<script type="module">
  const block = document.querySelector('.tabs.block');
  const module = await import('/blocks/tabs/tabs.js');
  await module.default(block);
</script>

</div>
```

See [resources/blocks-reference.md](resources/blocks-reference.md) for all block patterns.

## Visual Consistency Standards

**CRITICAL: All presentations must follow these exact styling standards for consistency.**

### Typography Standards

- **H1 (Hero Title)**: `font-size: 48px; font-weight: 800`
- **H2 (Major Sections)**: `color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;`
  - H2 emoji size: `32px`
- **H3 (Subsections)**: `color: #0d47a1; font-size: 26px; font-weight: 700; margin-bottom: 20px;`
  - H3 emoji size: `28px`
  - Use flexbox pattern: `display: flex; align-items: center; gap: 12px;`
- **Body text**: `font-size: 16px; line-height: 1.8; color: #212121;`
- **List item emojis**: `20px`
- **TOC/Navigation links**: `font-size: 18px; font-weight: 500`
- **IMPORTANT**: Use HTML headings with explicit styling, NOT markdown syntax (`##`, `###`)
- Markdown headings render with default grey colors - always use HTML

### Background Standards

- **Standard gradient**: `background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);`
- **All content divs MUST include**: `color: #212121;` to prevent text fading
- **Margin**: `margin: 0 0;` (no vertical gaps that expose dark ipynb-viewer background)
- **Border radius**: `border-radius: 12px;`
- **Padding**: `padding: 32px;`

### Border Hierarchy

- **H2 major sections**: `border-left: 6px solid #0288d1;` (thick border for major parts)
- **H3 subsections**: `border-left: 4px solid #0288d1;` (thinner border for content within sections)
- **Hero cells**: No border (full-width hero styling)
- **Transition cells**: `border-left: 4px solid #0288d1;` (matches subsection weight)

### Standard Container Patterns

**H2 Major Section (NO section tag):**

```html
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

  <h2 style="color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;">🎯 Section Title</h2>

  <p style="font-size: 16px; line-height: 1.8;">Body text content here...</p>

</div>
```

**IMPORTANT:** Do NOT wrap cells in `<section>` tags - they cause overlay jumping between slides.

**H3 Subsection (standalone):**

```html
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 4px solid #0288d1; color: #212121;">

  <h3 style="color: #0d47a1; font-size: 26px; font-weight: 700; margin-bottom: 20px; display: flex; align-items: center; gap: 12px;">
    <span style="font-size: 28px;">✨</span>
    Subsection Title
  </h3>

  <p style="font-size: 16px; line-height: 1.8;">Body text content here...</p>

</div>
```

**Hero Cell (title page):**

```html
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); color: white; border-radius: 16px; padding: 48px; text-align: center; margin: 0 0; box-shadow: 0 8px 20px rgba(0,0,0,0.25); color: #212121;">
  <h1 style="font-size: 48px; font-weight: 800; margin: 0 0 16px 0; display: flex; align-items: center; justify-content: center; gap: 16px;">
    <span style="font-size: 56px;">🎯</span>
    <span>Presentation Title</span>
  </h1>
  <p style="font-size: 20px; margin: 16px 0; opacity: 0.95; font-weight: 300;">
    Compelling subtitle or tagline
  </p>
</div>
```

### Block Wrapping Pattern

**CRITICAL**: All EDS blocks MUST be wrapped INSIDE styled divs, not as siblings.

Blocks inherit dark background from ipynb-viewer if not properly wrapped:

```html
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

  <h2 style="color: #0d47a1; font-size: 28px; font-weight: 700; margin-bottom: 24px;">Section Title</h2>

  <!-- Optional explanation box -->
  <div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 20px; margin: 0 0 24px 0; border-left: 4px solid #0288d1; color: #212121;">
    Explanation text about the block demonstration
  </div>

  <!-- Block INSIDE the container -->
  <div class="block-name block">
    <!-- block content -->
  </div>

  <script type="module">
    const block = document.querySelector('.block-name.block');
    const module = await import('/blocks/block-name/block-name.js');
    await module.default(block);
  </script>

</div> <!-- Close container AFTER block -->
```

### Common Mistakes to Avoid

1. ❌ Using markdown headings (`##`, `###`) - they render grey
2. ❌ Using `<section>` tags to wrap cells - causes overlay jumping between slides
3. ❌ Placing blocks as siblings to styled divs - they inherit dark background
4. ❌ Forgetting `color: #212121;` on gradient divs - text fades
5. ❌ Using vertical margins (`margin: 32px 0;`) - creates black gaps
6. ❌ Inconsistent H3 margin-bottom (always use 20px, not 24px)
7. ❌ Inconsistent colors across cells

## Inline HTML Styling

### Design System

Apply consistent inline HTML styling to all markdown cells for professional presentation:

**Standard Color Palette:**
```javascript
{
  heading: '#0d47a1',      // Dark Blue (all headings)
  text: '#212121',         // Dark Gray (all body text)
  border: '#0288d1',       // Blue (left borders)
  gradient_start: '#e3f2fd', // Light Blue (gradient start)
  gradient_end: '#bbdefb',   // Medium Blue (gradient end)

  // Legacy/optional colors:
  primary: '#1976d2',      // Material Blue
  secondary: '#dc004e',    // Material Pink
  success: '#2e7d32',      // Green
  warning: '#ed6c02',      // Orange
  background: '#f5f5f5',   // Light Gray
  surface: '#ffffff'       // White
}
```

### Styling Patterns

**Hero Header:**
```html
<div style="background: linear-gradient(135deg, #1976d2 0%, #1565c0 100%); color: white; border-radius: 16px; padding: 48px; text-align: center; margin: 32px 0; box-shadow: 0 8px 16px rgba(0,0,0,0.2);">
<h1 style="font-size: 48px; font-weight: 800; margin: 0 0 16px 0;">
🗺️ Presentation Title
</h1>
<p style="font-size: 20px; margin: 16px 0; opacity: 0.95;">
Your compelling subtitle or tagline
</p>
</div>
```

**Content Card:**
```html
<div style="background: white; border-radius: 12px; padding: 28px; margin: 20px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
<h3 style="color: #1976d2; font-size: 24px; font-weight: 700; margin-bottom: 20px;">Section Title</h3>
<div style="color: #212121; line-height: 1.8; font-size: 16px;">
Your content here with proper typography
</div>
</div>
```

**Block Wrapper (for EDS blocks):**
```html
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

<h3 style="color: #0d47a1; font-size: 26px; font-weight: 700; margin-bottom: 16px;">What this demonstrates</h3>

<p>Explanatory text before the EDS block</p>

<div class="cards block">
  <!-- Block HTML here -->
</div>

<script type="module">
  const block = document.querySelector('.cards.block');
  const module = await import('/blocks/cards/cards.js');
  await module.default(block);
</script>

</div>
```

**List with Icons (Compact Spacing):**
```html
<ul style="list-style: none; padding: 0; margin: 0;">
  <li style="padding: 12px 0; border-bottom: 1px solid rgba(0,0,0,0.08); font-size: 16px; display: flex; align-items: center; gap: 12px;">
    <span style="font-size: 20px;">✅</span>
    <span>List item text</span>
  </li>
  <!-- Remove border-bottom from last item -->
  <li style="padding: 12px 0; font-size: 16px; display: flex; align-items: center; gap: 12px;">
    <span style="font-size: 20px;">✅</span>
    <span>Last list item</span>
  </li>
</ul>
```

### Typography Scale

- **H1 (Hero Title)**: 48px, font-weight: 800, emoji: 56px
- **H2 (Major Sections)**: 28px, font-weight: 700, emoji: 32px
- **H3 (Subsections)**: 26px, font-weight: 700, emoji: 28px
- **Body Text**: 16px, line-height: 1.8
- **TOC Links**: 18px, font-weight: 500
- **List Icons**: 20px (emojis)
- **Code**: Courier New, monospace

### Spacing System

- **Container Padding**: 32px (all content containers)
- **Hero Padding**: 48px (title cells)
- **H2 Margin-bottom**: 24px
- **H3 Margin-bottom**: 20px
- **Paragraph Margin-bottom**: 16px-24px
- **List Item Padding**: 12px vertical, with border separators
- **TOC Item Padding**: 10px vertical, 8px 12px for links
- **Flexbox Gap**: 12px (heading emoji spacing)
- **Border Radius**: 12px (standard), 16px (hero cells)

### Interactive Elements

**Hover Effects:**
- Background transitions on links
- Color changes on buttons
- Shadow depth changes on cards

**Best Practices:**
- ✅ **Use CSS `:hover` pseudo-class** - Inline JavaScript event handlers (`onmouseover`, `onmouseout`) are blocked by browser security
- ✅ **Use `<style>` tags with classes** - Define reusable classes for hover states
- ✅ **Apply `transition`** - For smooth animations (e.g., `transition: background 0.2s`)
- ✅ **Maintain accessibility** - Proper contrast ratios and focus states

**Security Note:**
Browsers block inline JavaScript event handlers when content is inserted via `innerHTML` (which ipynb-viewer uses). Always use CSS `:hover` instead of `onmouseover`/`onmouseout`.

## Converting Code Cells

### Original Code Cell

```javascript
const { testBlock } = await import('/scripts/ipynb-helpers.js');
const block = await testBlock('accordion', content);
return block.outerHTML;
```

### Converted to Markdown

```markdown
<div style="background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%); border-radius: 12px; padding: 32px; margin: 0 0; border-left: 6px solid #0288d1; color: #212121;">

<h3 style="color: #0d47a1; font-size: 26px; font-weight: 700; margin-bottom: 16px;">Code Example: Testing Accordion Block</h3>

<p>This example demonstrates how to test the accordion block programmatically:</p>

**Original code:**
\```javascript
const { testBlock } = await import('/scripts/ipynb-helpers.js');
const block = await testBlock('accordion', content);
return block.outerHTML;
\```

**What it does:**
1. Imports the testBlock helper function
2. Tests the accordion block with provided content
3. Returns the rendered HTML

**Result:** The accordion block is decorated and ready for display.

---

**Note:** In presentation mode, code is shown for reference only. See the live accordion demonstration below:

<div class="accordion block">
  <!-- Actual working accordion here -->
</div>

<script type="module">
  const block = document.querySelector('.accordion.block');
  const module = await import('/blocks/accordion/accordion.js');
  await module.default(block);
</script>

</div>
```

### Conversion Rules

1. **Show the code** - Display original code in fenced code block
2. **Explain the purpose** - What does this code do?
3. **Describe the result** - What was the expected outcome?
4. **Provide alternative** - Show the working result via embedded block

## Best Practices

### Visual Design

- Use emojis for section headers (🎯, 📊, 🚀, ✨, 💡)
- Break content into digestible chunks
- Use blocks for interactive elements
- Add horizontal rules (`---`) between major sections
- Use **bold** and *italic* for emphasis

### Choosing Between Auto-Wrapping and Manual HTML

Both presentation (non-interactive) and educational (interactive) notebooks can use either approach.

**Auto-wrapping (pure markdown):**
- ✅ 90% less code to write
- ✅ Fast content creation
- ✅ Consistent default styling
- ❌ **ONLY works in not