promptslide 0.2.0 → 0.2.2

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.
@@ -1,49 +1,8 @@
1
- # PromptSlide — Agent Documentation
1
+ # PromptSlide
2
2
 
3
- This file documents the slide presentation framework for coding agents (Claude Code, Cursor, Windsurf, etc.). Read this before creating or modifying slides.
3
+ Slide deck framework: Vite + React 19 + Tailwind v4 + Framer Motion. Each slide is a React component styled with Tailwind CSS.
4
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.
5
+ > **Recommended**: Install the [PromptSlide skill](https://github.com/prompticeu/promptslide) for guided slide authoring, style presets, design recipes, and best practices: `npx skills add prompticeu/promptslide`
47
6
 
48
7
  ---
49
8
 
@@ -51,403 +10,78 @@ Vite will hot-reload — the new slide appears instantly in the browser.
51
10
 
52
11
  ```
53
12
  src/
54
- ├── layouts/ # Slide layouts (customizable)
55
- │ └── slide-layout-centered.tsx # Base centered layout with header/footer
13
+ ├── layouts/ # Slide layouts — your "master themes"
14
+ │ └── slide-layout-centered.tsx # Default layout with header + footer
56
15
 
57
16
  ├── slides/ # YOUR SLIDES GO HERE
58
17
  │ └── slide-title.tsx # Example starter slide
59
18
 
60
- ├── theme.ts # Theme config (brand, colors, fonts, assets)
61
- ├── deck-config.ts # Slide order + step counts (modify this)
19
+ ├── theme.ts # Theme config (brand name, logo, colors, fonts)
20
+ ├── deck-config.ts # Slide order + step counts
62
21
  ├── App.tsx # Root component (theme provider)
63
- └── globals.css # Theme colors (customize here)
22
+ └── globals.css # Theme colors (CSS custom properties)
64
23
 
65
- promptslide (npm package) # CLI + slide engine — stable, upgradeable
24
+ promptslide (npm package) # CLI + slide engine
66
25
  ├── Animated, AnimatedGroup # Step animations (click-to-reveal)
67
26
  ├── Morph, MorphGroup, MorphItem # Shared element transitions
68
27
  ├── SlideDeck # Presentation viewer/controller
69
- ├── SlideThemeProvider # Theme context (colors, logos, fonts, assets)
70
- ├── useSlideNavigation # Navigation state machine
28
+ ├── SlideThemeProvider, useTheme # Theme context
29
+ ├── SlideFooter # Footer with logo + slide number
71
30
  ├── SlideProps, SlideConfig # TypeScript types
72
- ├── ThemeConfig # Theme configuration type
73
31
  └── Layouts # ContentLayout, TitleLayout, SectionLayout,
74
32
  # TwoColumnLayout, ImageLayout, QuoteLayout
75
33
  ```
76
34
 
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
35
  ---
92
36
 
93
- ## 1. SlideLayoutCentered Component
37
+ ## Quick Start
94
38
 
95
- Every slide should use `SlideLayoutCentered` as its wrapper. It provides consistent padding, header, and footer.
39
+ 1. Create a file in `src/slides/` (e.g., `src/slides/slide-market.tsx`)
40
+ 2. Export a React component that receives `SlideProps`
41
+ 3. Register it in `src/deck-config.ts`
96
42
 
97
43
  ```tsx
44
+ // src/slides/slide-market.tsx
45
+ import type { SlideProps } from "promptslide";
98
46
  import { SlideLayoutCentered } from "@/layouts/slide-layout-centered";
99
47
 
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"
48
+ export function SlideMarket({ slideNumber, totalSlides }: SlideProps) {
49
+ return (
50
+ <SlideLayoutCentered
51
+ slideNumber={slideNumber}
52
+ totalSlides={totalSlides}
53
+ eyebrow="MARKET OPPORTUNITY"
54
+ title="$50B Total Addressable Market"
55
+ >
56
+ <div className="flex h-full flex-col justify-center">
57
+ <p className="text-muted-foreground text-lg">Your content here</p>
58
+ </div>
59
+ </SlideLayoutCentered>
60
+ );
61
+ }
210
62
  ```
211
63
 
212
- ---
213
-
214
- ## 4. Deck Configuration (`deck-config.ts`)
215
-
216
- This file controls which slides appear and in what order.
217
-
218
64
  ```ts
65
+ // src/deck-config.ts
219
66
  import type { SlideConfig } from "promptslide";
220
67
  import { SlideTitle } from "@/slides/slide-title";
221
- import { SlideProblem } from "@/slides/slide-problem";
222
- import { SlideSolution } from "@/slides/slide-solution";
68
+ import { SlideMarket } from "@/slides/slide-market";
223
69
 
224
70
  export const slides: SlideConfig[] = [
225
71
  { component: SlideTitle, steps: 0 },
226
- { component: SlideProblem, steps: 2 }, // Has 2 click-to-reveal steps
227
- { component: SlideSolution, steps: 0 },
72
+ { component: SlideMarket, steps: 0 },
228
73
  ];
229
74
  ```
230
75
 
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/`.
76
+ Layouts in `src/layouts/` and theme colors in `src/globals.css` are yours to customize freely — create new layouts, modify existing ones, and adjust CSS variables to make the deck look unique.
310
77
 
311
78
  ---
312
79
 
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.
80
+ ## Key Constraints
328
81
 
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
- ```
82
+ - **Slide dimensions**: 1280×720 (16:9). Content scales automatically in presentation mode.
83
+ - **Semantic colors**: Use `text-foreground`, `text-muted-foreground`, `text-primary`, `bg-background`, `bg-card`, `border-border`.
84
+ - **Icons**: Import from `lucide-react` (e.g., `import { ArrowRight } from "lucide-react"`).
85
+ - **Animations**: Use `<Animated step={n}>` for click-to-reveal. The `steps` value in `deck-config.ts` must equal the highest step number used. Available: `fade`, `slide-up`, `slide-down`, `slide-left`, `slide-right`, `scale`.
86
+ - **PDF compatibility**: No `blur()` or `backdrop-filter` (dropped by Chromium). No gradients (use solid colors with opacity). Keep colored shadows at `/5` max.
87
+ - **Brand color**: Edit `--primary` in `src/globals.css`. Configure logo and fonts in `src/theme.ts`.
@@ -2,7 +2,6 @@
2
2
  @import "tw-animate-css";
3
3
  @source "../node_modules/promptslide/src/core";
4
4
 
5
- @custom-variant dark (&:is(.dark *));
6
5
 
7
6
  @theme inline {
8
7
  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
@@ -62,45 +61,6 @@
62
61
  */
63
62
 
64
63
  :root {
65
- --background: oklch(1 0 0);
66
- --foreground: oklch(0.145 0 0);
67
-
68
- --card: oklch(1 0 0);
69
- --card-foreground: oklch(0.145 0 0);
70
-
71
- --popover: oklch(1 0 0);
72
- --popover-foreground: oklch(0.145 0 0);
73
-
74
- /* Primary brand color — change this to match your brand */
75
- --primary: {{PRIMARY_COLOR}};
76
- --primary-foreground: oklch(0.985 0 0);
77
-
78
- --secondary: oklch(0.97 0 0);
79
- --secondary-foreground: oklch(0.205 0 0);
80
-
81
- --muted: oklch(0.97 0 0);
82
- --muted-foreground: oklch(0.556 0 0);
83
-
84
- --accent: oklch(0.97 0 0);
85
- --accent-foreground: oklch(0.205 0 0);
86
-
87
- --destructive: oklch(0.577 0.245 27.325);
88
- --destructive-foreground: oklch(0.985 0 0);
89
-
90
- --border: oklch(0.922 0 0);
91
- --input: oklch(0.922 0 0);
92
- --ring: oklch(0.708 0 0);
93
-
94
- --radius: 0.625rem;
95
-
96
- --chart-1: {{PRIMARY_COLOR}};
97
- --chart-2: oklch(0.6 0.118 184.704);
98
- --chart-3: oklch(0.398 0.07 227.392);
99
- --chart-4: oklch(0.828 0.189 84.429);
100
- --chart-5: oklch(0.769 0.188 70.08);
101
- }
102
-
103
- .dark {
104
64
  --background: oklch(0.159 0 0);
105
65
  --foreground: oklch(0.985 0 0);
106
66
 
@@ -110,8 +70,8 @@
110
70
  --popover: oklch(0.205 0 0);
111
71
  --popover-foreground: oklch(0.985 0 0);
112
72
 
113
- /* Primary brand color (dark mode) */
114
- --primary: {{PRIMARY_COLOR_DARK}};
73
+ /* Primary brand color change this to match your brand */
74
+ --primary: {{PRIMARY_COLOR}};
115
75
  --primary-foreground: oklch(0.985 0 0);
116
76
 
117
77
  --secondary: oklch(0.985 0 0);
@@ -130,7 +90,9 @@
130
90
  --input: oklch(1 0 0 / 15%);
131
91
  --ring: oklch(0.556 0 0);
132
92
 
133
- --chart-1: oklch(0.488 0.243 264.376);
93
+ --radius: 0.625rem;
94
+
95
+ --chart-1: {{PRIMARY_COLOR}};
134
96
  --chart-2: oklch(0.696 0.17 162.48);
135
97
  --chart-3: oklch(0.769 0.188 70.08);
136
98
  --chart-4: oklch(0.627 0.265 303.9);
@@ -16,11 +16,6 @@ export function SlideTitle({ slideNumber, totalSlides }: SlideProps) {
16
16
  <p className="text-muted-foreground mt-6 max-w-3xl text-xl font-light md:text-2xl">
17
17
  A presentation built with PromptSlide
18
18
  </p>
19
-
20
- <div className="text-muted-foreground mt-16 text-sm">
21
- Press <kbd className="rounded bg-card px-2 py-0.5 font-mono text-xs">Space</kbd> or{" "}
22
- <kbd className="rounded bg-card px-2 py-0.5 font-mono text-xs">&rarr;</kbd> to navigate
23
- </div>
24
19
  </div>
25
20
  </SlideLayoutCentered>
26
21
  );