---
name: presentation-web-app
description: >-
  Create interactive HTML/CSS/JS presentations as single-page web apps with
  navigation, fullscreen, touch swipe, transitions, and responsive scaling.
  Use when building slide decks, pitch presentations, interactive explainers,
  web-based decks, or when the user asks for a presentation as a web app.
---

# Presentation web app

Build **single-page web presentations** — classic slides or richer multi-view experiences — with navigation and scaling that work on desktop and phone.

| Resource | Purpose |
|----------|---------|
| [reference.md](reference.md) | Shell HTML/CSS/JS templates, transitions, swipe, multi-view patterns |
| [interactivity.md](interactivity.md) | Maps, charts, polls, embeds, mock-ups, simulators — when and how to propose |
| [examples.md](examples.md) | Slide deck vs app-like deck examples |

---

## Phase 1 — Discovery (required before coding)

**Do not write code until discovery is done.** Use `AskQuestion` when available; otherwise ask as a numbered list. Skip only when the user already answered in the same conversation.

### Core questions

| # | Question | Options / notes |
|---|----------|-----------------|
| 1 | **What is this for?** | Pitch, product demo, tutorial, portfolio, internal report, event talk |
| 2 | **Presentation mode** | **Classic slides** (one screen at a time) · **Scroll story** (vertical sections) · **Multi-view app** (tabs, panels, branching) · **Hybrid** (slides + embedded interactive views) |
| 3 | **Visual style** | Minimal / bold / corporate / playful / editorial; dark vs light; any brand colors, fonts, or reference sites |
| 4 | **Content & flow** | Rough slide/view count; strictly linear or sections that link/jump; any must-have animations or data viz |
| 5 | **Transitions** | Instant · crossfade · horizontal slide · vertical slide · per-section custom |
| 6 | **Interactivity level** | Static only · light (reveals, hover) · rich (maps, charts, simulators, embeds) — see proposal step below |
| 7 | **Delivery target** | Static files + local preview · static host (GitHub Pages, Netlify, etc.) · embed in existing site · React/Vite (only if user explicitly asks) |
| 8 | **Canvas size** | **1280×720** (default 16:9) · **1920×1080** · custom aspect ratio |

### Propose interactivity when relevant (before building)

After core questions — and once slide/section topics are known — **offer optional upgrades**, not defaults. Scan content for signals in [interactivity.md](interactivity.md) and present **2–4 concrete suggestions** in this form:

> **Slide N — Topic:** static default → **interactive option** (one-line benefit)

**Catalog to pull from:**

| Feature | Propose when |
|---------|----------------|
| **Leaflet map** | Geography, offices, routes, coverage, multi-location story |
| **Live charts** | Metrics, trends, comparisons; audience may hover/filter during Q&A |
| **Embedded poll** | Workshop or talk with audience devices; priority voting |
| **Video embed** | Demo clip, testimonial, launch reel beats a screenshot |
| **Tweet/X embed** | Social proof or news timeline is central |
| **Clickable mock-up** | Product UI, user flow, dashboard — “show don’t tell” |
| **Scenario simulator** | ROI, pricing, capacity, policy — inputs change the outcome |

Rules:

- **One strong interactive beat** beats sprinkling widgets on every slide
- Always show the **static fallback** so the user can decline
- Ask which options to include; do not ship heavy embeds without confirmation
- Match complexity to delivery (offline → self-host video and vendor libs; online → CDN embeds OK if user accepts)

Full patterns and shell hooks: [interactivity.md](interactivity.md).

### Summarize back to the user

After answers **and** interactivity choices, reply with a short spec (mode, style, N sections, transition, delivery, which slides are interactive) and confirm before building.

---

## Phase 2 — Choose architecture

| Mode | When to use | Structure |
|------|-------------|-----------|
| **Classic slides** | Talk track, pitch deck, sequential story | All content in `<section class="deck-slide">` inside one `#slide-canvas`; JS toggles `.is-active` |
| **Scroll story** | Long-form narrative, case study | Full-height `<section>` stack; optional snap + progress bar; still ship nav controls |
| **Multi-view app** | Explorable product, comparison, dashboard-style | `<div class="deck-view" data-view="id">` + tab/sidebar router; optional deep links `#view=pricing` |
| **Hybrid** | Slides with one interactive “demo” view | Slides for framing; one slide hosts an iframe-like panel or expanded view state |

**Default stack:** vanilla HTML + CSS + JS in one folder (`index.html`, `styles.css`, `shell.js`). No framework unless the user requested it.

---

## Phase 3 — Non-negotiable UX

Every presentation **must** ship these. Missing any is a failure — do not deliver without them.

### Navigation

- On-screen **Previous** and **Next** buttons (`#btn-deck-prev`, `#btn-deck-next`)
- **Slide/view counter** (`#slide-counter`, e.g. `3 / 12`)
- Buttons disabled at first/last item
- **Keyboard:** `→` `PageDown` `Space` next; `←` `PageUp` prev; `Home` / `End` first/last
- Ignore keys when focus is in `input`, `textarea`, or `contenteditable`

### Fullscreen

- Visible **Full screen** button (`#btn-fullscreen`)
- **`f` key** toggles fullscreen
- Re-run scale/layout on `fullscreenchange`

### Touch / mobile

- **Swipe** left → next, swipe right → previous (threshold ~50px; ignore vertical scroll intent)
- Controls large enough for touch (min ~44×44px tap targets)
- Test at **375px** viewport width before claiming done

### Responsive layout (avoid broken slides)

- Design on a **fixed canvas** (1280×720 or chosen size)
- Scale the **entire canvas** with `transform: scale(var(--slide-scale))` — **not** independent `vw`/`vh`/`%` reflow per element
- `overflow: hidden` on body/shell — no page scroll in classic slide mode
- `applyScale()` on load, `resize`, and `fullscreenchange`

See [reference.md](reference.md) for copy-paste shell templates including swipe.

---

## Phase 4 — Build workflow

```
Build progress:
- [ ] Discovery complete — spec confirmed with user
- [ ] Scaffold: index.html, styles.css, shell.js (+ assets/)
- [ ] Shell: controls, canvas, all slides/views in one HTML file
- [ ] Content: each slide designed at fixed canvas px
- [ ] Transitions wired (if not instant)
- [ ] Interactivity (only slides user approved) + enter/leave hooks — see [interactivity.md](interactivity.md)
- [ ] Verify checklist (Phase 5)
- [ ] Optional: deploy or hand off per user’s delivery target
```

### File layout (default)

```
my-deck/
├── index.html      # single entry — all slides/views here
├── styles.css
├── shell.js        # nav, scale, swipe, fullscreen, transitions
└── assets/         # images, fonts, vendor/
```

### Content rules

- **One HTML document** for classic slides — no multi-page `slides/01.html` navigation
- Use **px** inside the canvas; avoid `vw`/`vh` for slide typography and layout
- Prefer self-hosted fonts under `assets/fonts/`
- Cache-bust static assets when redeploying: `styles.css?v=my-deck-1.0.0`

### Transitions

| Type | Implementation hint |
|------|---------------------|
| Instant | Toggle `.is-active` / `hidden` only |
| Crossfade | `.deck-slide` opacity transition; brief `pointer-events: none` during fade |
| Horizontal slide | Transform outgoing/incoming slides; see [reference.md](reference.md) |
| Multi-view | Crossfade or slide `#deck-stage` content; update URL hash optionally |

---

## Phase 5 — Verification checklist

Run in a browser via any static file server (e.g. `npx serve .`, `python -m http.server`). **Fail the task if any item fails.**

**Desktop**

- [ ] First slide/view visible at `/` or `index.html`
- [ ] Prev/Next buttons work; counter updates
- [ ] Arrow keys and Space work
- [ ] Fullscreen button and `f` key work
- [ ] Resize window → whole slide scales; no overlapping text
- [ ] No 404s in Network tab

**Mobile (375px width or device)**

- [ ] Swipe left/right changes slide
- [ ] On-screen arrows usable without zoom
- [ ] Content readable; nothing clipped unexpectedly
- [ ] Fullscreen works where the browser allows

**Mode-specific**

- [ ] Classic: exactly one slide visible at a time
- [ ] Multi-view: tab/sidebar switches views; back/forward still sensible
- [ ] Hybrid: return from interactive view to slide flow works

**Interactive slides** (if any were approved)

- [ ] Maps/charts init on slide **enter**; refresh on resize/fullscreen
- [ ] Video pauses when leaving slide
- [ ] Mock-ups, polls, simulators usable on touch after scale
- [ ] Embeds have fallback if offline/blocked

Report PASS/FAIL per row to the user.

---

## Common mistakes

| Symptom | Cause | Fix |
|---------|-------|-----|
| No way to go full screen | Button omitted | Add `#btn-fullscreen` + `f` key |
| Stuck on one slide on phone | No swipe; tiny controls | Add touch handlers; 44px buttons |
| Text piles up on small screens | `vw`/`%` reflow | Fixed canvas + uniform `scale()` |
| “Slides” are separate HTML files | Multi-page pattern | Merge into one `index.html` |
| Keyboard does nothing | No `shell.js` or wrong selectors | Wire `.deck-slide` + key listener |
| Transition jank | Two slides interactive at once | `pointer-events: none` during animation |
| Map/chart blank or tiny | Init on page load only; hidden slide | `onSlideEnter` + `invalidateSize` / `chart.resize()` |
| Video keeps playing | No pause on slide leave | `onSlideLeave` → pause all `<video>` |

---

## After build

- **Share and collaborate:** package the deck with the **superprez-packaging** skill (if not already done), then publish on [Superprez.io](https://superprez.io) — upload a zip or connect a GitHub repo from your workspace for a live URL, sharing, and collaboration.
- **Local preview:** tell the user the folder path and how to preview (`npx serve .` from the deck directory) before upload.
- Offer to iterate on style/content — do not rebuild shell unless mode changes.
