---
name: web-deck
description: "Build CoinFund-branded web presentations as self-contained HTML files. Supports static (print/PDF) and dynamic (keyboard nav, transitions) modes. Outputs a single versionable HTML file with optional PDF export via Puppeteer. Trigger on: 'web deck', 'web slides', 'html presentation', 'web presentation', or any request for a browser-based slide deck."
---
# Web Deck — CoinFund Web Presentation Builder
Build minimalist, CoinFund-branded slide decks as self-contained HTML files. Each deck is a single `.html` file — no build step, no dependencies, trivially versionable in Git.
## When to Use
Any time the user wants a **web-based** slide deck (HTML/CSS/JS). For `.pptx` output, use the `jake-deck` skill instead. This skill is for browser-native presentations that can also export to PDF.
The user specifies:
1. **Mode**: `static` (print-optimized, no JS) or `dynamic` (keyboard navigation, slide transitions). Default: `dynamic`.
2. **Content**: Slide titles and content, as an outline or bullet points.
## Design System
### Color Palette (CSS Custom Properties)
```css
:root {
--bg: #F7F3EE; /* Warm cream — all slide backgrounds */
--text: #1A1A1A; /* Near-black — headings, primary body text */
--gray: #7A7A7A; /* Secondary text, labels */
--ltgray: #C8C2BA; /* Divider rules, subtle borders */
--white: #FFFFFF; /* Title slide background, table headers */
--red: #C0392B; /* Warnings, risks, negative indicators */
--green: #27AE60; /* Positive indicators, "ready" status */
--blue: #2C3E50; /* Section headers, callout boxes */
}
```
### Typography
All text uses **Nunito** (loaded from Google Fonts, with system-font fallback for offline use).
| Element | Size | Weight | Color |
|------------------|--------|--------|------------|
| Slide title | 28px | 700 | `--blue` |
| Section header | 16px | 700 | `--text` |
| Body text | 13px | 400 | `--text` |
| Labels/secondary | 11px | 400 | `--gray` |
| Footnotes | 10-11px| 400 | `--red` or `--gray` |
### Layout
Slides are **16:9** aspect ratio (960px x 540px base, scaled to fill viewport).
```
┌──────────────────────────────────────────────┐
│ padding-left: 76px (~0.8" equivalent) │
│ ┌─ Title zone: top 50px ──────────────────┐ │
│ │ │ │
│ ├─ Content zone: top 110px ───────────────┤ │
│ │ width: 808px (~8.4" equivalent) │ │
│ │ │ │
│ ├─ Footnote zone: bottom 30px ────────────┤ │
│ └──────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
```
## Required Slides
### Title Slide (always first)
- Background: `--white` (#FFFFFF), not cream
- CoinFund logo: text wordmark "CoinFund" in 52px Arial bold, color `--text`, centered
- Thin divider line below wordmark: 240px wide, `--text`, centered
- Deck title: 28px Nunito bold, color `--blue`, centered below divider
- Subtitle/date: 14px Nunito, color `--gray`, centered
```html
CoinFund
Deck Title Here
March 2026
```
### End Slide (always last)
- Background: `--bg` (cream)
- "CoinFund" in 36px Nunito bold, color `--blue`, centered
- Gray divider rule centered
- "coinfund.io" in 13px Nunito, color `--gray`, centered
```html
```
## Content Slide Patterns
Every content slide follows this HTML structure:
```html
```
### Pattern 1: Header + Body Blocks (default, most common)
For slides with 3-5 topics, each with bold header and description.
```html
Gray body description text.
```
### Pattern 2: Label-Value Grid
Two-column layout: gray labels left, text values right.
```html
```
### Pattern 3: Table
Blue header row with white text, alternating cream/white body rows.
```html
| Column A | Column B | Column C |
| Data | Data | Data |
| Data | Data | Data |
```
### Pattern 4: Numbered List
Blue number + bold label + body inline.
```html
-
Item name
Description text explaining the item.
```
### Pattern 5: Callout Box
Light blue-gray fill with left border accent.
```html
Key insight or important note goes here.
```
## Entrance Animations
In dynamic mode, add `class="reveal"` to any element that should animate in when its slide becomes active. Elements fade up with staggered timing based on their position among siblings.
```html
Title animates first
This block animates third
This one fourth (0.08s delay)
```
In static mode, `reveal` has no effect — elements render normally.
## Static vs. Dynamic Mode
### Static Mode (`data-mode="static"`)
- No JavaScript whatsoever
- All slides visible in sequence, separated by CSS page breaks
- Optimized for `Cmd+P` / `Ctrl+P` browser print or Puppeteer PDF export
- Each `` gets `page-break-after: always`
### Dynamic Mode (`data-mode="dynamic"`)
- Keyboard navigation: Arrow keys, Space, Page Up/Down
- Touch/swipe navigation on mobile and tablet
- Current slide indicator (e.g., "3 / 12") in bottom-right
- Blue progress bar at top of viewport
- Subtle fade transitions between slides (CSS `opacity` + `transition`)
- Staggered entrance animations on `.reveal` elements
- URL hash updates per slide (`#slide-3`) for deep linking
- Press `F` for fullscreen, `Esc` to exit
- Press `P` to toggle overview mode (shows all slides, click to jump)
- `prefers-reduced-motion` automatically disables animations
## HTML Template
The file `template.html` (in the same directory as this SKILL.md) is the complete, working boilerplate for every deck. It includes all CSS (design tokens, patterns 1-5, animations, static/dynamic modes, print styles) and all JS (keyboard/touch nav, overview mode, fullscreen, progress bar, hash deep linking).
### Creating a new deck
Copy the template to start every new deck:
```bash
cp /template.html deck.html
```
Then:
1. Set `data-mode` on `` to `"dynamic"` or `"static"`
2. Replace `DECK_TITLE_HERE` in `` and `.slide__deck-title`
3. Replace `MONTH YEAR` in `.slide__subtitle`
4. Add content slides between the title and end slides, using the content patterns documented above
**Do not regenerate the boilerplate from memory.** Always copy the template file.
## Live Development Server (MANDATORY)
**ALWAYS serve decks through the dev server.** Never open deck files directly via `file://` — the server provides live reload, the hamburger overlay menu, and PDF export. Without it, the user gets a static file with no interactivity tools.
The dev server is at `serve-deck.mjs` (same directory as this SKILL.md). Zero npm dependencies (Puppeteer auto-installed on first PDF export).
### Starting the server
```bash
node /path/to/skills/web-deck/serve-deck.mjs 3333 /path/to/deck/directory
```
Then open the browser:
```bash
open http://localhost:3333/deck.html
```
**Start the server BEFORE opening the browser.** Use `run_in_background: true` so it persists across edits.
### What the server provides
1. **Live reload** — SSE-based, auto-reloads the browser on every file save. The user sees changes instantly as you edit slides.
2. **Hamburger overlay menu** — always-visible hamburger icon (☰) in the top-right corner with:
- **Download as PDF** — Puppeteer renders the deck server-side at 960×540px per slide, producing a faithful PDF with all fonts and styles intact. Auto-installs Puppeteer on first use.
- **⌘P hint** — reminder that browser print also works
3. **Static file serving** — serves the deck and any local assets (images, fonts)
The overlay menu and reload client are **injected at serve time** — they do not exist in the `deck.html` file itself. The deck stays clean and self-contained. This is why the server is mandatory: without it, no hamburger menu, no PDF export, no live reload.
### Workflow
1. User provides outline (slide titles + content bullets) and mode preference (static/dynamic)
2. Copy the template: `cp /template.html deck.html`
3. Set the mode, title, and subtitle in the copied file
4. Choose the right content pattern for each slide and add content slides
5. **Start the server** (background, one time): `node /serve-deck.mjs 3333 .` with `run_in_background: true`
6. **Open in browser** (one time): `open http://localhost:3333/deck.html`
7. **Iterate** — use the Edit tool to modify slides. The browser auto-reloads on every save.
8. User clicks the **hamburger menu → Download as PDF** when ready.
### Important: keep the server running
- Start the server with `run_in_background: true` so it persists across edits
- The second argument is the directory to serve (defaults to `.`)
- The server stays alive for the session — no auto-shutdown
- When the session ends or user is done, kill the server: `pkill -f serve-deck` or let it die naturally
## Style Principles
The CoinFund deck style is defined by restraint:
1. **No gradients, drop shadows, or decorative elements.** The CSS `box-shadow` on slides is only for the browser viewport framing, not part of the slide content itself.
2. **Color is semantic.** Blue for structure, red for risk/warnings, green for readiness/positive. Never decorative.
3. **Whitespace does the heavy lifting.** Generous padding, clear spacing between blocks. If it feels crowded, split into two slides.
4. **Max 4-5 content blocks per slide.** Prevents overflow and keeps slides scannable.
5. **Footnotes sit below main content** with a clear gap. Use `slide__footnote` positioned at the bottom.
6. **One accent line per slide.** The short `slide__accent` `
` separates title from content. That's the only decoration.
7. **Terse over verbose.** Bullets should be 1-2 sentences max. The deck is a conversation starter, not a whitepaper.
8. **Uniform style changes.** When the user makes a visual or stylistic change to one slide, apply that change consistently across all slides in the deck.
## Incremental Editing
The live server makes editing feel like a REPL — edit the file, see the result immediately.
Because the deck is a single HTML file:
- **Git-friendly**: each slide is a `` block, so diffs are clean and meaningful
- **Add slides**: insert new `` blocks between existing ones
- **Reorder**: cut/paste `` blocks
- **Edit content**: modify text within existing sections
- **Style tweaks**: adjust CSS custom properties in `:root` for global changes
When the user asks to edit specific slides, use the Edit tool to modify just the relevant `` blocks. Do not regenerate the entire file for small changes. The live server will auto-reload on every save.
## Overflow Prevention
- **5 blocks max** per slide (Pattern 1)
- **6 rows max** per label-value grid (Pattern 2)
- **7 table rows max** (including header)
- **Footnotes** anchored to `bottom: 20px` via absolute positioning
- If content won't fit, **split into two slides** — never shrink fonts below 10px