promptslide 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/index.d.ts +377 -0
  2. package/dist/index.js +963 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +65 -0
  5. package/src/commands/build.mjs +73 -0
  6. package/src/commands/create.mjs +197 -0
  7. package/src/commands/preview.mjs +22 -0
  8. package/src/commands/studio.mjs +27 -0
  9. package/src/core/animated.tsx +153 -0
  10. package/src/core/animation-config.ts +98 -0
  11. package/src/core/animation-context.tsx +54 -0
  12. package/src/core/index.ts +73 -0
  13. package/src/core/layouts/shared-footer.tsx +43 -0
  14. package/src/core/morph.tsx +153 -0
  15. package/src/core/slide-deck.tsx +430 -0
  16. package/src/core/slide-error-boundary.tsx +50 -0
  17. package/src/core/theme-context.tsx +48 -0
  18. package/src/core/transitions.ts +200 -0
  19. package/src/core/types.ts +136 -0
  20. package/src/core/use-slide-navigation.ts +142 -0
  21. package/src/core/utils.ts +8 -0
  22. package/src/index.mjs +70 -0
  23. package/src/utils/ansi.mjs +5 -0
  24. package/src/utils/colors.mjs +44 -0
  25. package/src/utils/prompts.mjs +50 -0
  26. package/src/utils/tsconfig.mjs +35 -0
  27. package/src/vite/config.mjs +40 -0
  28. package/src/vite/plugin.mjs +66 -0
  29. package/templates/default/AGENTS.md +453 -0
  30. package/templates/default/README.md +35 -0
  31. package/templates/default/package.json +26 -0
  32. package/templates/default/public/logo.svg +7 -0
  33. package/templates/default/src/App.tsx +11 -0
  34. package/templates/default/src/deck-config.ts +8 -0
  35. package/templates/default/src/globals.css +157 -0
  36. package/templates/default/src/layouts/slide-layout-centered.tsx +59 -0
  37. package/templates/default/src/slides/slide-example.tsx +53 -0
  38. package/templates/default/src/slides/slide-title.tsx +27 -0
  39. package/templates/default/src/theme.ts +8 -0
@@ -0,0 +1,40 @@
1
+ import { createRequire } from "node:module"
2
+ import { resolve, dirname } from "node:path"
3
+ import { fileURLToPath } from "node:url"
4
+
5
+ import tailwindcss from "@tailwindcss/postcss"
6
+ import react from "@vitejs/plugin-react"
7
+
8
+ import { promptslidePlugin } from "./plugin.mjs"
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url))
11
+ const require = createRequire(import.meta.url)
12
+
13
+ // Resolve tailwindcss from CLI's deps so @import "tailwindcss" in user CSS works
14
+ // even when the user's project doesn't have tailwindcss as a direct dependency.
15
+ const tailwindPath = resolve(dirname(require.resolve("tailwindcss")), "..")
16
+
17
+ // Resolve promptslide core from source so Vite uses TS directly without a build step
18
+ const promptslidePath = resolve(__dirname, "../core/index.ts")
19
+
20
+ export function createViteConfig({ cwd, mode = "development" }) {
21
+ return {
22
+ configFile: false,
23
+ root: cwd,
24
+ mode,
25
+ plugins: [react(), promptslidePlugin()],
26
+ resolve: {
27
+ alias: {
28
+ "@": resolve(cwd, "src"),
29
+ promptslide: promptslidePath,
30
+ // CSS @import "tailwindcss" → resolved from CLI package
31
+ tailwindcss: tailwindPath
32
+ }
33
+ },
34
+ css: {
35
+ postcss: {
36
+ plugins: [tailwindcss()]
37
+ }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,66 @@
1
+ const VIRTUAL_ENTRY_ID = "virtual:promptslide-entry"
2
+ const RESOLVED_VIRTUAL_ENTRY_ID = "\0" + VIRTUAL_ENTRY_ID
3
+
4
+ function getHtmlTemplate() {
5
+ return `<!doctype html>
6
+ <html lang="en" class="dark">
7
+ <head>
8
+ <meta charset="UTF-8" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
+ <title>PromptSlide</title>
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ <script type="module" src="/@id/${VIRTUAL_ENTRY_ID}"></script>
15
+ </body>
16
+ </html>`
17
+ }
18
+
19
+ function getEntryModule() {
20
+ return `
21
+ import { StrictMode, createElement } from "react"
22
+ import { createRoot } from "react-dom/client"
23
+ import "./src/globals.css"
24
+ import App from "./src/App"
25
+
26
+ createRoot(document.getElementById("root")).render(
27
+ createElement(StrictMode, null, createElement(App))
28
+ )
29
+ `
30
+ }
31
+
32
+ export function promptslidePlugin() {
33
+ return {
34
+ name: "promptslide",
35
+ enforce: "pre",
36
+
37
+ resolveId(id) {
38
+ if (id === VIRTUAL_ENTRY_ID) {
39
+ return RESOLVED_VIRTUAL_ENTRY_ID
40
+ }
41
+ },
42
+
43
+ load(id) {
44
+ if (id === RESOLVED_VIRTUAL_ENTRY_ID) {
45
+ return getEntryModule()
46
+ }
47
+ },
48
+
49
+ configureServer(server) {
50
+ return () => {
51
+ server.middlewares.use(async (req, res, next) => {
52
+ if (req.url === "/" || req.url === "/index.html") {
53
+ const html = await server.transformIndexHtml(req.url, getHtmlTemplate())
54
+ res.setHeader("Content-Type", "text/html")
55
+ res.statusCode = 200
56
+ res.end(html)
57
+ return
58
+ }
59
+ next()
60
+ })
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ export { VIRTUAL_ENTRY_ID, getHtmlTemplate }
@@ -0,0 +1,453 @@
1
+ # PromptSlide — Agent Documentation
2
+
3
+ This file documents the slide presentation framework for coding agents (Claude Code, Cursor, Windsurf, etc.). Read this before creating or modifying slides.
4
+
5
+ ## Quick Start
6
+
7
+ To create a new slide:
8
+
9
+ 1. Create a file in `src/slides/` (e.g., `src/slides/slide-market.tsx`)
10
+ 2. Import from `promptslide` and `@/layouts/slide-layout-centered`
11
+ 3. Add it to `src/deck-config.ts`
12
+
13
+ ```tsx
14
+ // src/slides/slide-market.tsx
15
+ import type { SlideProps } from "promptslide";
16
+ import { SlideLayoutCentered } from "@/layouts/slide-layout-centered";
17
+
18
+ export function SlideMarket({ slideNumber, totalSlides }: SlideProps) {
19
+ return (
20
+ <SlideLayoutCentered
21
+ slideNumber={slideNumber}
22
+ totalSlides={totalSlides}
23
+ eyebrow="MARKET OPPORTUNITY"
24
+ title="$50B Total Addressable Market"
25
+ >
26
+ <div className="flex h-full flex-col justify-center">
27
+ <p className="text-muted-foreground text-lg">Your content here</p>
28
+ </div>
29
+ </SlideLayoutCentered>
30
+ );
31
+ }
32
+ ```
33
+
34
+ ```ts
35
+ // src/deck-config.ts
36
+ import type { SlideConfig } from "promptslide";
37
+ import { SlideTitle } from "@/slides/slide-title";
38
+ import { SlideMarket } from "@/slides/slide-market";
39
+
40
+ export const slides: SlideConfig[] = [
41
+ { component: SlideTitle, steps: 0 },
42
+ { component: SlideMarket, steps: 0 },
43
+ ];
44
+ ```
45
+
46
+ Vite will hot-reload — the new slide appears instantly in the browser.
47
+
48
+ ---
49
+
50
+ ## Architecture
51
+
52
+ ```
53
+ src/
54
+ ├── layouts/ # Slide layouts (customizable)
55
+ │ └── slide-layout-centered.tsx # Base centered layout with header/footer
56
+
57
+ ├── slides/ # YOUR SLIDES GO HERE
58
+ │ └── slide-title.tsx # Example starter slide
59
+
60
+ ├── theme.ts # Theme config (brand, colors, fonts, assets)
61
+ ├── deck-config.ts # Slide order + step counts (modify this)
62
+ ├── App.tsx # Root component (theme provider)
63
+ └── globals.css # Theme colors (customize here)
64
+
65
+ promptslide (npm package) # CLI + slide engine — stable, upgradeable
66
+ ├── Animated, AnimatedGroup # Step animations (click-to-reveal)
67
+ ├── Morph, MorphGroup, MorphItem # Shared element transitions
68
+ ├── SlideDeck # Presentation viewer/controller
69
+ ├── SlideThemeProvider # Theme context (colors, logos, fonts, assets)
70
+ ├── useSlideNavigation # Navigation state machine
71
+ ├── SlideProps, SlideConfig # TypeScript types
72
+ ├── ThemeConfig # Theme configuration type
73
+ └── Layouts # ContentLayout, TitleLayout, SectionLayout,
74
+ # TwoColumnLayout, ImageLayout, QuoteLayout
75
+ ```
76
+
77
+ **Key principle**: The presentation engine and CLI live in `promptslide` (stable, upgradeable via npm). Layouts and slides are local files you customize freely.
78
+
79
+ ---
80
+
81
+ ## Animation System
82
+
83
+ The framework provides three types of animations:
84
+
85
+ | Type | Purpose | Import |
86
+ | --------------------- | ------------------------------------------------ | ----------------------------------- |
87
+ | **Slide Transitions** | Animations between slides (fade, slide, zoom) | `promptslide` |
88
+ | **Step Animations** | Within-slide reveal animations (click to reveal) | `Animated` from `promptslide` |
89
+ | **Morph Animations** | Shared element transitions across slides | `Morph` from `promptslide` |
90
+
91
+ ---
92
+
93
+ ## 1. SlideLayoutCentered Component
94
+
95
+ Every slide should use `SlideLayoutCentered` as its wrapper. It provides consistent padding, header, and footer.
96
+
97
+ ```tsx
98
+ import { SlideLayoutCentered } from "@/layouts/slide-layout-centered";
99
+
100
+ <SlideLayoutCentered
101
+ slideNumber={slideNumber}
102
+ totalSlides={totalSlides}
103
+ eyebrow="CATEGORY" // Optional small label above title
104
+ title="Slide Title" // Optional main heading
105
+ subtitle="Description" // Optional subtitle
106
+ hideFooter // Optional: hide footer with logo + slide number
107
+ >
108
+ {/* Your slide content */}
109
+ </SlideLayoutCentered>;
110
+ ```
111
+
112
+ **Slide dimensions**: 1280x720 (16:9 aspect ratio). Design content for this size — it will be scaled to fit the viewport in presentation mode.
113
+
114
+ ---
115
+
116
+ ## 2. Step Animations (click-to-reveal)
117
+
118
+ Use `<Animated>` to reveal content on clicks:
119
+
120
+ ```tsx
121
+ import { Animated } from "promptslide"
122
+
123
+ // Always visible content (no wrapper needed)
124
+ <h2>Main Title</h2>
125
+
126
+ // Appears on first click
127
+ <Animated step={1} animation="fade">
128
+ <p>First point</p>
129
+ </Animated>
130
+
131
+ // Appears on second click
132
+ <Animated step={2} animation="slide-up">
133
+ <p>Second point</p>
134
+ </Animated>
135
+ ```
136
+
137
+ **Animation types**: `fade`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `scale`
138
+
139
+ **Props:**
140
+ | Prop | Type | Default | Description |
141
+ |------|------|---------|-------------|
142
+ | `step` | number | required | Which click reveals this (1-indexed) |
143
+ | `animation` | AnimationType | `"slide-up"` | Animation style |
144
+ | `duration` | number | `0.4` | Duration in seconds |
145
+ | `delay` | number | `0` | Delay after trigger |
146
+ | `className` | string | — | Additional CSS classes |
147
+
148
+ ### AnimatedGroup (staggered children)
149
+
150
+ ```tsx
151
+ import { AnimatedGroup } from "promptslide";
152
+
153
+ <AnimatedGroup startStep={1} animation="slide-up" staggerDelay={0.1}>
154
+ <Card>First</Card>
155
+ <Card>Second</Card>
156
+ <Card>Third</Card>
157
+ </AnimatedGroup>;
158
+ ```
159
+
160
+ ### Step Count Rules
161
+
162
+ - Steps are **1-indexed** (step 1 = first click)
163
+ - Multiple elements can share the same step (appear together)
164
+ - **Critical**: The `steps` value in `deck-config.ts` must equal the highest step number used
165
+
166
+ ```ts
167
+ // If your slide uses step={1} and step={2}:
168
+ { component: MySlide, steps: 2 }
169
+
170
+ // If your slide has no animations:
171
+ { component: MySlide, steps: 0 }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 3. Morph Animations
177
+
178
+ Morph animations smoothly transition shared elements between consecutive slides.
179
+
180
+ ```tsx
181
+ import { Morph, MorphText } from "promptslide"
182
+
183
+ // Slide 1 - Large version
184
+ <Morph layoutId="hero-title">
185
+ <h1 className="text-6xl">Title</h1>
186
+ </Morph>
187
+
188
+ // Slide 2 - Small version (same layoutId = morphs between them)
189
+ <Morph layoutId="hero-title">
190
+ <h1 className="text-2xl">Title</h1>
191
+ </Morph>
192
+ ```
193
+
194
+ **Note**: Morph is currently disabled in fullscreen presentation mode due to CSS transform conflicts with Framer Motion's layoutId calculations.
195
+
196
+ ### MorphGroup + MorphItem
197
+
198
+ ```tsx
199
+ import { MorphGroup, MorphItem } from "promptslide";
200
+
201
+ <MorphGroup groupId="card">
202
+ <MorphItem id="icon">
203
+ <Icon />
204
+ </MorphItem>
205
+ <MorphItem id="title">
206
+ <h2>Title</h2>
207
+ </MorphItem>
208
+ </MorphGroup>;
209
+ // Generates layoutIds: "card-icon", "card-title"
210
+ ```
211
+
212
+ ---
213
+
214
+ ## 4. Deck Configuration (`deck-config.ts`)
215
+
216
+ This file controls which slides appear and in what order.
217
+
218
+ ```ts
219
+ import type { SlideConfig } from "promptslide";
220
+ import { SlideTitle } from "@/slides/slide-title";
221
+ import { SlideProblem } from "@/slides/slide-problem";
222
+ import { SlideSolution } from "@/slides/slide-solution";
223
+
224
+ export const slides: SlideConfig[] = [
225
+ { component: SlideTitle, steps: 0 },
226
+ { component: SlideProblem, steps: 2 }, // Has 2 click-to-reveal steps
227
+ { component: SlideSolution, steps: 0 },
228
+ ];
229
+ ```
230
+
231
+ ### Enriched SlideConfig (optional)
232
+
233
+ Each slide config supports optional metadata fields:
234
+
235
+ ```ts
236
+ {
237
+ component: SlideProblem,
238
+ steps: 2,
239
+ title: "The Problem", // Grid view labels, navigation
240
+ section: "Introduction", // Chapter grouping in grid view
241
+ transition: "zoom", // Per-slide transition override
242
+ notes: "Talk about market gap", // Speaker notes (future)
243
+ }
244
+ ```
245
+
246
+ ### Managing slides
247
+
248
+ - **Add a slide**: Import it and add to the array
249
+ - **Remove a slide**: Remove from the array (keep the file if you want it later)
250
+ - **Reorder**: Change position in the array
251
+ - **The `steps` value** must match the highest `step` number in `<Animated>` components
252
+
253
+ ---
254
+
255
+ ## 5. Theme Customization (`globals.css`)
256
+
257
+ Colors use OKLCH format in CSS variables. Edit `src/globals.css` to change the theme.
258
+
259
+ **Change your brand color** by modifying `--primary`:
260
+
261
+ ```css
262
+ :root {
263
+ /* Blue brand (default) */
264
+ --primary: oklch(0.55 0.2 250);
265
+
266
+ /* Orange brand */
267
+ /* --primary: oklch(0.661 0.201 41.38); */
268
+
269
+ /* Green brand */
270
+ /* --primary: oklch(0.6 0.2 145); */
271
+
272
+ /* Purple brand */
273
+ /* --primary: oklch(0.55 0.2 300); */
274
+ }
275
+ ```
276
+
277
+ OKLCH format: `oklch(lightness chroma hue)`
278
+
279
+ - **Lightness**: 0 (black) to 1 (white)
280
+ - **Chroma**: 0 (gray) to ~0.4 (vivid)
281
+ - **Hue**: 0–360 (color wheel: 0=red, 120=green, 250=blue)
282
+
283
+ ---
284
+
285
+ ## 6. Theme & Branding (`theme.ts`)
286
+
287
+ Configure your brand identity in `src/theme.ts`:
288
+
289
+ ```ts
290
+ import type { ThemeConfig } from "promptslide";
291
+
292
+ export const theme: ThemeConfig = {
293
+ name: "Acme Inc",
294
+ logo: {
295
+ full: "/logo.svg", // Footer logo
296
+ icon: "/icon.svg", // Compact variant (title slides)
297
+ fullLight: "/logo-white.svg", // For dark backgrounds
298
+ },
299
+ colors: {
300
+ primary: "oklch(0.55 0.2 250)",
301
+ },
302
+ fonts: {
303
+ heading: "Inter",
304
+ body: "Inter",
305
+ },
306
+ };
307
+ ```
308
+
309
+ Everything is optional except `name`. Omitted values fall back to `globals.css` defaults. Logo files go in `public/`.
310
+
311
+ ---
312
+
313
+ ## 7. Slide Transitions
314
+
315
+ The `SlideDeck` component accepts a `transition` prop:
316
+
317
+ ```tsx
318
+ <SlideDeck
319
+ slides={slides}
320
+ transition="slide-left" // Transition type
321
+ directionalTransition={true} // Reverse on back navigation
322
+ />
323
+ ```
324
+
325
+ **Available transitions**: `fade` (default), `slide-left`, `slide-right`, `slide-up`, `slide-down`, `zoom`, `zoom-fade`, `none`
326
+
327
+ Per-slide transitions can also be set in `deck-config.ts` via the `transition` field on individual slide configs.
328
+
329
+ ---
330
+
331
+ ## 8. Keyboard Shortcuts
332
+
333
+ | Key | Action |
334
+ | -------------- | ----------------------------------------- |
335
+ | `→` or `Space` | Advance (next step or next slide) |
336
+ | `←` | Go back (previous step or previous slide) |
337
+ | `F` | Toggle fullscreen presentation mode |
338
+ | `G` | Toggle grid view |
339
+ | `Escape` | Exit fullscreen |
340
+
341
+ ---
342
+
343
+ ## 9. View Modes
344
+
345
+ 1. **Slide view** (default): Single slide with navigation controls
346
+ 2. **Grid view**: Thumbnail overview — click any slide to jump to it
347
+ 3. **List view**: Vertical scroll — optimized for PDF export via browser print
348
+
349
+ ---
350
+
351
+ ## 10. Design Best Practices
352
+
353
+ ### Layout tips
354
+
355
+ - Use `flex h-full` on content containers to fill available space
356
+ - Use Tailwind's responsive classes (`md:`, `lg:`) for adaptive layouts
357
+ - Content should look good at 1280x720 — it's scaled in presentation mode
358
+
359
+ ### Preserve layout with className
360
+
361
+ ```tsx
362
+ // BAD — animation wrapper breaks flex centering
363
+ <div className="flex justify-center">
364
+ <Animated step={1}>
365
+ <Content />
366
+ </Animated>
367
+ </div>
368
+
369
+ // GOOD — pass layout classes to Animated
370
+ <Animated step={1} className="flex justify-center">
371
+ <Content />
372
+ </Animated>
373
+ ```
374
+
375
+ ### Color classes
376
+
377
+ Use semantic color classes from the theme:
378
+
379
+ - `text-foreground` — primary text
380
+ - `text-muted-foreground` — secondary text
381
+ - `text-primary` — brand color text
382
+ - `bg-background` — page background
383
+ - `bg-card` — card backgrounds
384
+ - `border-border` — borders
385
+
386
+ ### Visual Variety Checklist
387
+
388
+ Before generating a multi-slide deck, plan visual diversity. Aim for:
389
+
390
+ - At least 2 different background treatments across the deck (plain, gradient mesh, split solid, spotlight)
391
+ - At least 2 different card/panel styles (not all `rounded-xl border border-border bg-card`)
392
+ - At least 3 different animation types used (not all `slide-up`)
393
+ - At least 1 slide using `AnimatedGroup` instead of manual `Animated` stagger
394
+ - At least 1 asymmetric layout (not all equal-column grids)
395
+ - At least 1 typography-driven slide (where text IS the visual, no cards)
396
+ - No two consecutive slides using the same layout pattern
397
+
398
+ ### Layout & Card Recipes
399
+
400
+ Refer to `references/slide-patterns.md` for ready-to-use recipes including:
401
+
402
+ - **Backgrounds:** Gradient mesh, split screen, spotlight vignette
403
+ - **Card styles:** Glass (`backdrop-blur-md`), gradient, elevated (shadow), accent-border
404
+ - **Layouts:** Bento grid, vertical timeline, comparison/before-after, asymmetric columns
405
+ - **Data viz:** Big numbers + progress bars, CSS bar charts, SVG donut rings
406
+ - **Typography:** Large quotes, headline-only with accent word
407
+
408
+ ### Animation Selection Guide
409
+
410
+ Match animation types to layout styles:
411
+
412
+ | Layout | Animation | Why |
413
+ | ------------ | ---------------------------- | ------------------------- |
414
+ | Hero/Title | `scale` or `fade` | Dramatic, non-directional |
415
+ | Split Screen | `slide-right` + `slide-left` | Panels enter from edges |
416
+ | Card Grids | `AnimatedGroup` + `scale` | Uniform pop-in |
417
+ | Timeline | `fade` | Clean, no movement |
418
+ | Comparison | `slide-right` + `slide-left` | Opposing directions |
419
+ | Metrics | `slide-up` | Vertical reveal |
420
+ | Quote | `fade` | Let words speak |
421
+
422
+ **Prefer `AnimatedGroup`** over manually wrapping each child in `<Animated>` for grids and collections — it's cleaner and produces better stagger timing.
423
+
424
+ ---
425
+
426
+ ## 11. Animation Configuration Constants
427
+
428
+ From `promptslide`:
429
+
430
+ ```ts
431
+ SLIDE_TRANSITION_DURATION = 0.3; // Between slides
432
+ MORPH_DURATION = 0.8; // Layout morphs
433
+ STEP_ANIMATION_DURATION = 0.4; // Within-slide steps
434
+ STAGGER_DELAY = 0.1; // Group stagger
435
+
436
+ SPRING_SNAPPY = { stiffness: 300, damping: 30 };
437
+ SPRING_SMOOTH = { stiffness: 200, damping: 25 };
438
+ SPRING_BOUNCY = { stiffness: 400, damping: 20 };
439
+
440
+ SLIDE_DIMENSIONS = { width: 1280, height: 720 };
441
+ ```
442
+
443
+ ---
444
+
445
+ ## 12. Available Icon Library
446
+
447
+ [Lucide React](https://lucide.dev) is included. Import icons directly:
448
+
449
+ ```tsx
450
+ import { ArrowRight, CheckCircle, TrendingUp } from "lucide-react";
451
+
452
+ <TrendingUp className="h-6 w-6 text-primary" />;
453
+ ```
@@ -0,0 +1,35 @@
1
+ # {{PROJECT_NAME}}
2
+
3
+ A slide deck built with [PromptSlide](https://github.com/prompticeu/promptslide) — React + Tailwind + Framer Motion.
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ bun install
9
+ bun run dev
10
+ ```
11
+
12
+ Then open your coding agent (Claude Code, Cursor, Windsurf, etc.) and say:
13
+
14
+ > "Create me a 10-slide pitch deck for [your topic]"
15
+
16
+ The agent reads `AGENTS.md`, generates slide files in `src/slides/`, and Vite hot-reloads them instantly.
17
+
18
+ ## Customization
19
+
20
+ - **Brand color**: Edit `--primary` in `src/globals.css`
21
+ - **Company name**: Edit branding in `src/App.tsx`
22
+ - **Logo**: Replace `public/logo.svg`
23
+
24
+ ## Keyboard Shortcuts
25
+
26
+ | Key | Action |
27
+ | ------------- | ---------------------- |
28
+ | `→` / `Space` | Next step or slide |
29
+ | `←` | Previous step or slide |
30
+ | `F` | Toggle fullscreen |
31
+ | `G` | Toggle grid view |
32
+
33
+ ## Learn More
34
+
35
+ See `AGENTS.md` for full framework documentation.
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "{{PROJECT_SLUG}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "promptslide studio",
8
+ "build": "promptslide build",
9
+ "preview": "promptslide preview"
10
+ },
11
+ "dependencies": {
12
+ "promptslide": "^0.2.0",
13
+ "clsx": "^2.1.1",
14
+ "framer-motion": "^12.23.22",
15
+ "lucide-react": "^0.552.0",
16
+ "react": "^19.2.4",
17
+ "react-dom": "^19.2.4",
18
+ "tailwind-merge": "^3.3.1",
19
+ "tw-animate-css": "^1.4.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^19.0.0",
23
+ "@types/react-dom": "^19.0.0",
24
+ "typescript": "^5.9.2"
25
+ }
26
+ }
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
2
+ <rect width="32" height="32" rx="6" fill="currentColor" opacity="0.1"/>
3
+ <rect x="6" y="8" width="20" height="14" rx="2" stroke="currentColor" stroke-width="2" fill="none"/>
4
+ <line x1="6" y1="25" x2="26" y2="25" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
5
+ <rect x="10" y="12" width="8" height="2" rx="1" fill="currentColor" opacity="0.6"/>
6
+ <rect x="10" y="16" width="12" height="1.5" rx="0.75" fill="currentColor" opacity="0.3"/>
7
+ </svg>
@@ -0,0 +1,11 @@
1
+ import { SlideThemeProvider, SlideDeck } from "promptslide";
2
+ import { slides } from "@/deck-config";
3
+ import { theme } from "@/theme";
4
+
5
+ export default function App() {
6
+ return (
7
+ <SlideThemeProvider theme={theme}>
8
+ <SlideDeck slides={slides} />
9
+ </SlideThemeProvider>
10
+ );
11
+ }
@@ -0,0 +1,8 @@
1
+ import type { SlideConfig } from "promptslide";
2
+ import { SlideTitle } from "@/slides/slide-title";
3
+ import { SlideExample } from "@/slides/slide-example";
4
+
5
+ export const slides: SlideConfig[] = [
6
+ { component: SlideTitle, steps: 0 },
7
+ { component: SlideExample, steps: 2 },
8
+ ];