@honeydeck/honeydeck 0.1.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 (144) hide show
  1. package/AGENTS.md +25 -0
  2. package/DEVELOPMENT.md +522 -0
  3. package/LICENSE +21 -0
  4. package/Readme.md +49 -0
  5. package/SPEC.md +88 -0
  6. package/docs/components.md +63 -0
  7. package/docs/configuration.md +91 -0
  8. package/docs/getting-started.md +116 -0
  9. package/docs/kit-authoring.md +207 -0
  10. package/docs/kits.md +387 -0
  11. package/docs/local-development.md +95 -0
  12. package/docs/mermaid.md +198 -0
  13. package/docs/mobile.md +108 -0
  14. package/docs/navigation.md +93 -0
  15. package/docs/next-steps.md +377 -0
  16. package/docs/pdf-export.md +91 -0
  17. package/docs/presenter-mode.md +104 -0
  18. package/docs/slides.md +130 -0
  19. package/docs/slidev-migration.md +42 -0
  20. package/docs/steps-and-reveals.md +171 -0
  21. package/package.json +134 -0
  22. package/skills/SPEC.md +21 -0
  23. package/skills/honeydeck/SKILL.md +65 -0
  24. package/skills/presentation-writing/SKILL.md +75 -0
  25. package/skills/slidev-migration/SKILL.md +153 -0
  26. package/src/SPEC.md +89 -0
  27. package/src/assets.d.ts +30 -0
  28. package/src/cli/SPEC.md +230 -0
  29. package/src/cli/args.ts +3 -0
  30. package/src/cli/banner.ts +9 -0
  31. package/src/cli/bin.js +5 -0
  32. package/src/cli/build.ts +229 -0
  33. package/src/cli/deck-path.ts +32 -0
  34. package/src/cli/dev.ts +263 -0
  35. package/src/cli/index.ts +126 -0
  36. package/src/cli/init.ts +369 -0
  37. package/src/cli/pdf.ts +923 -0
  38. package/src/cli/skill.ts +75 -0
  39. package/src/cli/templates/SPEC.md +70 -0
  40. package/src/cli/templates/deck-mdx.ts +15 -0
  41. package/src/cli/templates/package-json.ts +36 -0
  42. package/src/cli/templates/sparkle-button.ts +15 -0
  43. package/src/cli/templates/starter/components/SparkleButton.tsx +84 -0
  44. package/src/cli/templates/starter/deck.mdx +153 -0
  45. package/src/cli/templates/starter/styles.css +14 -0
  46. package/src/cli/templates/styles-css.ts +14 -0
  47. package/src/defaults.ts +1 -0
  48. package/src/layouts/ColorModeImage.tsx +55 -0
  49. package/src/layouts/SPEC.md +393 -0
  50. package/src/layouts/SlideFrame.tsx +48 -0
  51. package/src/layouts/bee/Blank.tsx +12 -0
  52. package/src/layouts/bee/Cover.tsx +70 -0
  53. package/src/layouts/bee/Default.tsx +42 -0
  54. package/src/layouts/bee/Image/Image.tsx +151 -0
  55. package/src/layouts/bee/Image/placeholder-dark.webp +0 -0
  56. package/src/layouts/bee/Image/placeholder-vertical-dark.webp +0 -0
  57. package/src/layouts/bee/Image/placeholder-vertical.webp +0 -0
  58. package/src/layouts/bee/Image/placeholder.webp +0 -0
  59. package/src/layouts/bee/ImageLeft.tsx +27 -0
  60. package/src/layouts/bee/ImageRight.tsx +27 -0
  61. package/src/layouts/bee/ImageSide.tsx +107 -0
  62. package/src/layouts/bee/Section.tsx +40 -0
  63. package/src/layouts/bee/TwoCol.tsx +108 -0
  64. package/src/layouts/bee/index.ts +40 -0
  65. package/src/layouts/clean/Blank.tsx +12 -0
  66. package/src/layouts/clean/Cover.tsx +58 -0
  67. package/src/layouts/clean/Default.tsx +33 -0
  68. package/src/layouts/clean/Image/Image.tsx +103 -0
  69. package/src/layouts/clean/ImageLeft.tsx +27 -0
  70. package/src/layouts/clean/ImageRight.tsx +27 -0
  71. package/src/layouts/clean/ImageSide.tsx +113 -0
  72. package/src/layouts/clean/Section.tsx +35 -0
  73. package/src/layouts/clean/TwoCol.tsx +63 -0
  74. package/src/layouts/clean/index.ts +40 -0
  75. package/src/layouts/index.ts +60 -0
  76. package/src/layouts/placeholders.ts +9 -0
  77. package/src/layouts/utils.ts +13 -0
  78. package/src/remark/SPEC.md +49 -0
  79. package/src/remark/h1-extract.ts +124 -0
  80. package/src/remark/index.ts +4 -0
  81. package/src/remark/shiki-code-blocks.ts +325 -0
  82. package/src/remark/step-numbering.ts +412 -0
  83. package/src/runtime/Deck.tsx +533 -0
  84. package/src/runtime/SPEC.md +256 -0
  85. package/src/runtime/SlideCanvas.tsx +95 -0
  86. package/src/runtime/TimelineContext.tsx +122 -0
  87. package/src/runtime/app-shell/index.html +31 -0
  88. package/src/runtime/app-shell/main.tsx +42 -0
  89. package/src/runtime/aspectRatio.ts +34 -0
  90. package/src/runtime/colorMode.ts +23 -0
  91. package/src/runtime/components/BrowserFrame.tsx +233 -0
  92. package/src/runtime/components/Button.tsx +57 -0
  93. package/src/runtime/components/CodeBlock.tsx +210 -0
  94. package/src/runtime/components/ColorModeCycleButton.tsx +59 -0
  95. package/src/runtime/components/ErrorBoundary.tsx +125 -0
  96. package/src/runtime/components/Keyboard.tsx +87 -0
  97. package/src/runtime/components/ListStyle.tsx +203 -0
  98. package/src/runtime/components/NavBar.tsx +223 -0
  99. package/src/runtime/components/NavBarButton.tsx +47 -0
  100. package/src/runtime/components/NavBarDivider.tsx +3 -0
  101. package/src/runtime/components/Notes.tsx +171 -0
  102. package/src/runtime/components/Reveal.tsx +82 -0
  103. package/src/runtime/components/RevealGroup.tsx +193 -0
  104. package/src/runtime/components/SPEC.md +263 -0
  105. package/src/runtime/components/SlideNumberBadge.tsx +11 -0
  106. package/src/runtime/components/TimelineSteps.tsx +115 -0
  107. package/src/runtime/components/index.ts +55 -0
  108. package/src/runtime/index.ts +42 -0
  109. package/src/runtime/inputOwnership.ts +68 -0
  110. package/src/runtime/keyboardTarget.ts +7 -0
  111. package/src/runtime/lastSlideRoute.ts +56 -0
  112. package/src/runtime/navigation.ts +211 -0
  113. package/src/runtime/router.ts +157 -0
  114. package/src/runtime/slideData.ts +137 -0
  115. package/src/runtime/sync.ts +267 -0
  116. package/src/runtime/types.ts +182 -0
  117. package/src/runtime/useKeyboardNav.ts +138 -0
  118. package/src/runtime/useSwipeNav.ts +257 -0
  119. package/src/runtime/views/DocsView.tsx +74 -0
  120. package/src/runtime/views/OverviewView.tsx +386 -0
  121. package/src/runtime/views/PresenterNotesPanel.tsx +76 -0
  122. package/src/runtime/views/PresenterView.tsx +340 -0
  123. package/src/runtime/views/SPEC.md +152 -0
  124. package/src/runtime/views/docs/ComponentsTab.tsx +178 -0
  125. package/src/runtime/views/docs/DocsHeader.tsx +101 -0
  126. package/src/runtime/views/docs/Intro.tsx +20 -0
  127. package/src/runtime/views/docs/LayoutsTab.tsx +324 -0
  128. package/src/runtime/views/docs/ThemeTab.tsx +110 -0
  129. package/src/runtime/views/index.ts +7 -0
  130. package/src/runtime/views/overviewGrid.ts +106 -0
  131. package/src/runtime/views/presenterPreview.ts +27 -0
  132. package/src/runtime/virtual-modules.d.ts +98 -0
  133. package/src/theme/SPEC.md +179 -0
  134. package/src/theme/base.css +623 -0
  135. package/src/theme/bee.css +35 -0
  136. package/src/theme/clean.css +38 -0
  137. package/src/vite-plugin/SPEC.md +114 -0
  138. package/src/vite-plugin/component-doc-crawler.ts +350 -0
  139. package/src/vite-plugin/deck-loader.ts +148 -0
  140. package/src/vite-plugin/index.ts +373 -0
  141. package/src/vite-plugin/layout-demo-crawler.ts +802 -0
  142. package/src/vite-plugin/splitter.ts +353 -0
  143. package/src/vite-plugin/token-manifest.ts +163 -0
  144. package/src/vite-plugin/virtual-modules.ts +587 -0
package/docs/mobile.md ADDED
@@ -0,0 +1,108 @@
1
+ # Mobile and Touch
2
+
3
+ Honeydeck works on phones and tablets, but mobile presentation mode behaves differently from desktop so touch gestures stay reliable.
4
+
5
+ ## What is different from desktop?
6
+
7
+ | Area | Desktop | Mobile / touch |
8
+ |------|---------|----------------|
9
+ | Main input | Keyboard, mouse, trackpad | Tap zones, swipes, pinch, nav bar buttons |
10
+ | Navigation bar | Hidden until hover near bottom edge | Always visible in portrait; hidden by default in landscape until center tap |
11
+ | Text selection | Slide text can be selected normally | Slide text selection is off by default; use the nav bar toggle when you need it |
12
+ | Zoom | Browser/page zoom or normal browser controls | Honeydeck-controlled slide zoom with pinch, up to `5x` |
13
+ | Overview | Keyboard selection and mouse clicks | Responsive fixed two-column grid |
14
+ | Presenter mode | Current slide, next preview, notes, clock | Current slide, notes, navigation buttons; no next preview |
15
+
16
+ ## Tap zones
17
+
18
+ In normal slide view, tapping the slide uses five zones:
19
+
20
+ ```txt
21
+ ┌───────────────┐
22
+ │ Previous slide│
23
+ ├─────┬───┬─────┤
24
+ │Prev │Nav│Next │
25
+ │step │bar│step │
26
+ ├─────┴───┴─────┤
27
+ │ Next slide │
28
+ └───────────────┘
29
+ ```
30
+
31
+ - Left center zone → previous step
32
+ - Right center zone → next step
33
+ - Top zone → previous slide
34
+ - Bottom zone → next slide
35
+ - Center zone → toggle the navigation bar and never navigate slides
36
+
37
+ Landscape mobile uses the center tap zone to show or hide the navigation bar. Portrait mobile keeps the navigation bar visible.
38
+
39
+ ## Swipe navigation
40
+
41
+ Swipe gestures use the dominant movement axis and need roughly 50px movement:
42
+
43
+ - Swipe left → next step
44
+ - Swipe right → previous step
45
+ - Swipe up → next slide
46
+ - Swipe down → previous slide
47
+
48
+ Steps cross slide boundaries. For example, swiping left at the last step moves to the next slide at step 0.
49
+
50
+ ## Pinch zoom and pan
51
+
52
+ Mobile slide zoom is controlled by Honeydeck, not browser page zoom.
53
+
54
+ - Pinch outward zooms the current slide content, up to `5x`.
55
+ - Pinch inward below roughly `1.05x` resets zoom to `1x`.
56
+ - When zoomed in, one-finger dragging pans the slide.
57
+ - While zoomed in, tap-zone navigation and swipe navigation are disabled so dragging does not accidentally change slides.
58
+ - The center tap still toggles the navigation bar, and nav bar buttons still work.
59
+ - Moving to another slide or step resets zoom to `1x`.
60
+
61
+ Use the reset zoom button in the navigation bar when it appears.
62
+
63
+ ## Text selection
64
+
65
+ On touch devices, slide content is not text-selectable by default. This avoids accidental text highlights when tapping, swiping, or panning.
66
+
67
+ When you need to copy text from a slide:
68
+
69
+ 1. Open the navigation bar if needed.
70
+ 2. Tap the text selection button.
71
+ 3. Select or copy slide text normally.
72
+ 4. Tap the same button again to return to presentation gestures.
73
+
74
+ While text selection mode is active, mobile tap/swipe/pinch presentation gestures pause and the navigation bar stays visible so you can turn selection mode off.
75
+
76
+ Desktop slide text remains selectable by default.
77
+
78
+ ## Interactive and scrollable content
79
+
80
+ Honeydeck avoids taking over gestures that start inside interactive or scrollable content.
81
+
82
+ Gestures that start inside buttons, links, inputs, textareas, selects, elements marked with `data-honeydeck-no-swipe`, or scrollable containers are owned by that content instead of slide navigation.
83
+
84
+ This means scrollable demos can scroll without accidentally changing slides, even at their scroll boundaries.
85
+
86
+ ## Overview mode on mobile
87
+
88
+ Overview mode is available from the navigation bar. On mobile it becomes a scrollable responsive fixed two-column grid.
89
+
90
+ Touch scroll belongs to the overview grid and never navigates slides. Tap a slide thumbnail to jump to it.
91
+
92
+ ## Presenter mode on mobile
93
+
94
+ Presenter mode keeps the mobile layout compact:
95
+
96
+ - Current slide preview
97
+ - Speaker notes
98
+ - Navigation buttons
99
+
100
+ The desktop next-slide preview is hidden on mobile because there is not enough space.
101
+
102
+ ## Tips for mobile-friendly decks
103
+
104
+ - Prefer larger text and fewer dense bullets.
105
+ - Avoid content that requires precise hover interactions.
106
+ - Make buttons and links large enough for touch.
107
+ - Test portrait and landscape if people may open the deck on phones.
108
+ - Use pinch zoom for readability, but design important content to be readable at `1x`.
@@ -0,0 +1,93 @@
1
+ # Navigation
2
+
3
+ ## Keyboard Shortcuts
4
+
5
+ | Shortcut | Action |
6
+ |----------|--------|
7
+ | `→` / `d` | Next step (crosses slide boundary) |
8
+ | `←` / `a` | Previous step (crosses slide boundary) |
9
+ | `↓` / `s` | Next slide |
10
+ | `↑` / `w` | Previous slide |
11
+ | `o` | Toggle overview mode |
12
+ | `p` | Open presenter mode (new window) |
13
+ | `f` | Toggle fullscreen |
14
+ | `Escape` | Exit overview / exit fullscreen |
15
+
16
+ ## Navigation Model
17
+
18
+ - **Horizontal** (→/←) = detailed progression through steps. Crosses slide boundaries when no more steps remain.
19
+ - **Vertical** (↓/↑) = slide-level jumps, skipping remaining steps.
20
+
21
+ Boundary behavior:
22
+ - Right at last step → next slide at step 0.
23
+ - Left at step 0 → previous slide at its final step.
24
+
25
+ ## Navigation UI
26
+
27
+ - Hidden by default for clean presentation.
28
+ - Appears on cursor hover near bottom edge.
29
+ - Positioned bottom-left.
30
+ - Contains: current slide number, navigation arrows, overview button, presenter button, fullscreen button, color mode switch (system / dark / light).
31
+ - Built-in controls use `lucide-react` icons, imported from the suffixed `...Icon` exports (for example `ChevronLeftIcon`), not inline SVG paths or unsuffixed aliases.
32
+
33
+ When `showSlideNumbers: true`, the current slide number is also shown as a single viewer overlay aligned to the bottom-right corner of the slide canvas. It is not part of individual slide content, so it does not animate during slide transitions. It renders as themed foreground text without a background container.
34
+
35
+ ```txt
36
+ ┌──────────────────────────────────────┐
37
+ │ │
38
+ │ SLIDE CONTENT │
39
+ │ │
40
+ │ │
41
+ │ ┌──────────────────────────┐ │
42
+ │ │ prev 3 next docs more │ │
43
+ │ └──────────────────────────┘ 3 │
44
+ └──────────────────────────────────────┘
45
+ ```
46
+
47
+ ## Mobile / Touch
48
+
49
+ Mobile uses touch-specific controls. See the full [Mobile and Touch](mobile.md) guide for expectations and desktop differences.
50
+
51
+ - Navigation bar is always visible in portrait.
52
+ - Navigation bar is hidden by default in landscape; tap the center zone to show or hide it.
53
+ - Tap zones navigate previous/next step, previous/next slide, or toggle controls from the center zone.
54
+ - Swipe gestures:
55
+ - Swipe left → next step
56
+ - Swipe right → previous step
57
+ - Swipe up → next slide
58
+ - Swipe down → previous slide
59
+ - Pinch zoom enlarges slide content up to `5x`; dragging pans while zoomed.
60
+ - Slide text selection is off by default on touch devices; the navigation bar includes a toggle to enable selection when needed.
61
+ - Presenter mode on mobile shows only current slide, notes, and navigation buttons (no next slide preview).
62
+
63
+ ## Overview Mode
64
+
65
+ A responsive grid of rendered slide thumbnails. Activated via `o` or the overview button.
66
+
67
+ - Current slide is highlighted.
68
+ - Click a thumbnail to jump to that slide.
69
+ - Future reveal steps are shown at reduced opacity in thumbnails.
70
+ - Arrow keys move selection using the rendered grid columns, including after resizes.
71
+ - Up on the topmost row and Down on the bottommost row keep the current selection and show a short boundary nudge.
72
+ - Enter jumps to selected slide.
73
+ - Escape exits overview.
74
+
75
+ ## URL State
76
+
77
+ Honeydeck uses static-host friendly hash-based URLs:
78
+
79
+ ```txt
80
+ /#/1/0 → slide 1, step 0
81
+ /#/1/1 → slide 1, step 1
82
+ /#/2/0 → slide 2, step 0
83
+ /#/presenter/1/0 → presenter mode
84
+ /#/theme → theme tokens tab
85
+ /#/layouts → layouts tab
86
+ /#/components → components reference tab
87
+ ```
88
+
89
+ - Slides are **1-based** (user-friendly).
90
+ - Steps are **0-based** (step 0 is the initial state).
91
+ - Reloading or sharing the URL restores both slide and step.
92
+
93
+ Hash routing means no server-side routing config needed — works on any static host.
@@ -0,0 +1,377 @@
1
+ # Next steps
2
+
3
+ Use this guide after the quick start when you want to understand the main Honeydeck workflows without jumping straight into every reference page.
4
+
5
+ ## CLI commands
6
+
7
+ ### `honeydeck dev`
8
+
9
+ Starts the Vite development server.
10
+
11
+ ```bash
12
+ honeydeck dev # default port 4200
13
+ honeydeck dev --port 8080 # custom port
14
+ honeydeck dev --open # auto-open browser
15
+ honeydeck dev --deck talk.mdx # custom deck entry file
16
+ ```
17
+
18
+ Typical output:
19
+
20
+ ```text
21
+ Honeydeck v0.1.0
22
+
23
+ Local: http://localhost:4200/
24
+ Network: http://192.168.1.42:4200/
25
+ Theme: http://localhost:4200/#/theme
26
+
27
+ Watching for changes...
28
+ ```
29
+
30
+ ### `honeydeck build`
31
+
32
+ Builds a deployable static SPA to `dist/`.
33
+
34
+ ```bash
35
+ honeydeck build
36
+ honeydeck build --deck talk.mdx
37
+ ```
38
+
39
+ ### `honeydeck pdf`
40
+
41
+ Exports slides to PDF via headless Chromium.
42
+
43
+ ```bash
44
+ honeydeck pdf
45
+ honeydeck pdf -o my-talk.pdf
46
+ honeydeck pdf --steps all
47
+ honeydeck pdf --mode dark
48
+ honeydeck pdf --deck talk.mdx
49
+ ```
50
+
51
+ ### `honeydeck init` and `honeydeck skill`
52
+
53
+ Creates a new Honeydeck project and optionally installs agent skills.
54
+
55
+ ```bash
56
+ honeydeck init
57
+ honeydeck init --name my-talk
58
+ honeydeck init --skip-skill
59
+ honeydeck skill
60
+ ```
61
+
62
+ ## Slide authoring
63
+
64
+ The first `---` block is deck-level frontmatter. Later `---` lines separate slides.
65
+
66
+ ```mdx
67
+ ---
68
+ title: My Talk
69
+ author: Hendrik
70
+ ---
71
+
72
+ # First Slide
73
+
74
+ Content here.
75
+
76
+ ---
77
+
78
+ # Second Slide
79
+
80
+ More content.
81
+ ```
82
+
83
+ Specify a layout per slide in frontmatter:
84
+
85
+ ```mdx
86
+ ---
87
+ layout: Cover
88
+ author: Your Name
89
+ ---
90
+
91
+ # Welcome to My Talk
92
+
93
+ A modern slide framework.
94
+ ```
95
+
96
+ Available layouts: `Blank`, `Default`, `Cover`, `Section`, `TwoCol`, `Image`, `ImageLeft`, and `ImageRight`.
97
+
98
+ For more detail, see [Slides](slides.md).
99
+
100
+ ## Frontmatter
101
+
102
+ Deck-level settings live in the first frontmatter block of the deck entry file.
103
+
104
+ | Property | Type | Default | Description |
105
+ |----------|------|---------|-------------|
106
+ | `title` | `string` | `""` | Deck title |
107
+ | `description` | `string` | `""` | Deck description |
108
+ | `aspectRatio` | `"16:9"` | `"16:9"` | Slide canvas ratio |
109
+ | `colorMode` | `"system" \| "light" \| "dark"` | `"system"` | Color mode |
110
+ | `pdfColorMode` | `"light" \| "dark"` | unset | Optional PDF color mode; falls back to pinned `colorMode`, then `light` |
111
+ | `pdfSteps` | `"final" \| "all"` | `"final"` | PDF step handling |
112
+ | `transition` | `boolean` | `true` | Crossfade between slides |
113
+ | `layouts` | `string` | `""` (built-in) | Custom layout map path |
114
+ | `defaultLayout` | `string` | `"Default"` | Fallback layout |
115
+ | `showSlideNumbers` | `boolean` | `false` | Show slide numbers |
116
+
117
+ Slide-level frontmatter chooses the slide layout and passes layout-specific props.
118
+
119
+ | Property | Type | Description |
120
+ |----------|------|-------------|
121
+ | `layout` | `string` | Layout name in PascalCase |
122
+ | layout props | varies | Layout-specific fields |
123
+
124
+ For the full reference, see [Configuration](configuration.md).
125
+
126
+ ## Core components
127
+
128
+ Core runtime components are explicit imports from `honeydeck`.
129
+
130
+ ```mdx
131
+ import { Reveal, RevealGroup, TimelineSteps, BrowserFrame, Notes } from '@honeydeck/honeydeck'
132
+ ```
133
+
134
+ ### Reveal steps
135
+
136
+ `<Reveal>` reveals content at the next timeline step. Hidden content keeps its layout space so the slide does not jump.
137
+
138
+ ```mdx
139
+ <Reveal>Appears at step 1</Reveal>
140
+ <Reveal>Appears at step 2</Reveal>
141
+ ```
142
+
143
+ `<RevealGroup>` wraps each direct child in a reveal step. Markdown and HTML lists are special: each list item reveals one after another.
144
+
145
+ ```mdx
146
+ <RevealGroup>
147
+ - First point
148
+ - Second point
149
+ - Third point
150
+ </RevealGroup>
151
+ ```
152
+
153
+ `<TimelineSteps>` reserves steps for a custom component, such as an accordion or tab walkthrough. Inside that component, `useTimelineSteps()` returns local step state and `isPdfFinalRender`, which is true only when PDF export captures one final-state page per slide.
154
+
155
+ See [Steps and reveals](steps-and-reveals.md) for examples.
156
+
157
+ ### Browser frames
158
+
159
+ `<BrowserFrame>` shows a live iframe inside a macOS-style browser window frame.
160
+
161
+ ```mdx
162
+ <BrowserFrame
163
+ src="https://example.com"
164
+ addressBar="example.com"
165
+ fallbackImage="/example-fallback-light.png"
166
+ fallbackDarkImage="/example-fallback-dark.png"
167
+ />
168
+ ```
169
+
170
+ Standard iframe attributes such as `allow`, `sandbox`, `loading`, and `referrerPolicy` are forwarded. See [Components](components.md) for props.
171
+
172
+ ### Speaker notes
173
+
174
+ `<Notes>` content is hidden from the audience view and PDF export, then shown in presenter mode.
175
+
176
+ ```mdx
177
+ <Notes>
178
+ # Demo cue
179
+
180
+ - Demo the confetti button.
181
+ - Mention the PDF export path.
182
+ </Notes>
183
+ ```
184
+
185
+ Markdown inside `<Notes>` renders as formatted speaker notes.
186
+
187
+ ## Code and diagrams
188
+
189
+ Honeydeck uses Shiki for build-time syntax highlighting. Add step metadata to a code block with `{...}`:
190
+
191
+ ````mdx
192
+ ```ts {2|4|all}
193
+ const a = 1
194
+ const b = 2
195
+ console.log(a)
196
+ console.log(b)
197
+ ```
198
+ ````
199
+
200
+ - `{2}` highlights line 2 immediately and adds no timeline steps.
201
+ - `{2-3}` highlights lines 2-3 immediately and adds no timeline steps.
202
+ - `{2-3|5|all}` starts with lines 2-3 active, then steps to line 5, then all lines.
203
+ - Highlight groups after the first interleave with `<Reveal>` in document order.
204
+
205
+ ## Navigation, presenting, and PDF
206
+
207
+ Keyboard shortcuts:
208
+
209
+ | Shortcut | Action |
210
+ |----------|--------|
211
+ | `->` / `d` | Next step, wrapping to the next slide |
212
+ | `<-` / `a` | Previous step, wrapping to the previous slide |
213
+ | `down` / `s` | Next slide |
214
+ | `up` / `w` | Previous slide |
215
+ | `o` | Toggle overview mode |
216
+ | `p` | Open presenter mode |
217
+ | `f` | Toggle fullscreen |
218
+ | `Escape` | Exit overview or fullscreen |
219
+
220
+ URL state preserves slide and step position:
221
+
222
+ ```text
223
+ /#/1/0 slide 1, step 0
224
+ /#/2/3 slide 2, step 3
225
+ /#/presenter/2/1 presenter view
226
+ /#/theme theme tokens tab
227
+ /#/layouts layouts tab
228
+ /#/components components tab
229
+ ```
230
+
231
+ On touch devices, swipe left/right for next/previous step and swipe up/down for next/previous slide. The navigation bar is always visible on touch devices.
232
+
233
+ Presenter mode opens with `p` and includes:
234
+
235
+ - current slide and next slide preview
236
+ - speaker notes from `<Notes>`
237
+ - slide/step counter and wall clock
238
+ - an "Open audience view" button
239
+ - audience sync through `BroadcastChannel`
240
+
241
+ See [Navigation](navigation.md), [Mobile and touch](mobile.md), [Presenter mode](presenter-mode.md), and [PDF export](pdf-export.md).
242
+
243
+ ## Theme system
244
+
245
+ Honeydeck uses CSS custom properties with relative `oklch` color derivations. All colors derive from `--honeydeck-primary`.
246
+
247
+ `@honeydeck/honeydeck/theme.css` is the clean black/white/grey default. Override tokens in your CSS:
248
+
249
+ ```css
250
+ @import "tailwindcss";
251
+ @import "@honeydeck/honeydeck/theme.css";
252
+
253
+ [data-honeydeck-color-mode="light"] {
254
+ --honeydeck-primary: oklch(55% 0.25 145);
255
+ }
256
+
257
+ [data-honeydeck-color-mode="dark"] {
258
+ --honeydeck-primary: oklch(70% 0.2 145);
259
+ }
260
+ ```
261
+
262
+ Use the bundled Bee theme by layering it after the base theme:
263
+
264
+ ```css
265
+ @import "tailwindcss";
266
+ @import "@honeydeck/honeydeck/theme.css";
267
+ @import "@honeydeck/honeydeck/themes/bee.css";
268
+ ```
269
+
270
+ Pair it with the Bee layout set:
271
+
272
+ ```yaml
273
+ ---
274
+ layouts: "@honeydeck/honeydeck/layouts/bee"
275
+ ---
276
+ ```
277
+
278
+ All tokens are mapped to Tailwind utilities:
279
+
280
+ ```mdx
281
+ <div className="bg-surface text-surface-foreground border border-border rounded-honeydeck">
282
+ Card content
283
+ </div>
284
+ ```
285
+
286
+ Available color utilities: `primary`, `primary-foreground`, `accent`, `accent-foreground`, `background`, `foreground`, `surface`, `surface-foreground`, and `border`.
287
+
288
+ See [Kits](kits.md) for theme and layout customization.
289
+
290
+ ## Kits
291
+
292
+ A kit is an npm package bundling a theme, layouts, and components.
293
+
294
+ ```mdx
295
+ ---
296
+ layouts: "@company/honeydeck-kit-brand/layouts"
297
+ ---
298
+
299
+ import '@company/honeydeck-kit-brand/theme.css'
300
+ import { Callout } from '@company/honeydeck-kit-brand/components'
301
+
302
+ # Slide with brand kit
303
+ ```
304
+
305
+ Zero config still works: built-in defaults apply without imports. See [Kits](kits.md) and [Kit authoring](kit-authoring.md).
306
+
307
+ ## Runtime reference
308
+
309
+ Navigate to the runtime reference pages during development to see:
310
+
311
+ - `/#/theme` for theme tokens with descriptions and live computed values
312
+ - `/#/layouts` for layout previews with copyable usage snippets
313
+ - `/#/components` for built-in component docs
314
+
315
+ Package Markdown guides live on the Honeydeck docs site and in the package `docs/` directory.
316
+
317
+ ## Architecture overview
318
+
319
+ | Concern | Approach |
320
+ |---------|----------|
321
+ | Slide splitting | Text-level pre-split to virtual modules and independent MDX compilation |
322
+ | HMR | Per-slide invalidation for changed virtual modules |
323
+ | Timeline | Build-time `at={n}` numbering plus React context |
324
+ | DOM strategy | All slides rendered; off-screen slides use `content-visibility: hidden` |
325
+ | Router | Custom hash router with the URL as the single source of truth |
326
+ | Layouts | Runtime dynamic import of the layout map |
327
+ | Tailwind | v4 CSS-first; Honeydeck adds the Vite plugin internally |
328
+ | Shiki | Dual-theme CSS variables with build-time highlighting |
329
+ | Presenter sync | `BroadcastChannel`, unidirectional, no server needed |
330
+ | Scaling | `transform: scale()` from the configured aspect ratio |
331
+ | Build | `tsc` only, ESM, no bundler |
332
+ | Testing | `node:test` plus fixture files |
333
+
334
+ ## Types and exports
335
+
336
+ ```ts
337
+ import { Reveal, RevealGroup, Notes } from '@honeydeck/honeydeck'
338
+ import type { LayoutProps, LayoutMap, LayoutDemo } from '@honeydeck/honeydeck/types'
339
+
340
+ import defaultLayouts from '@honeydeck/honeydeck/layouts'
341
+ import beeLayouts from '@honeydeck/honeydeck/layouts/bee'
342
+
343
+ import { Left, Right } from '@honeydeck/honeydeck/layouts/TwoCol'
344
+ import { Left as BeeLeft, Right as BeeRight } from '@honeydeck/honeydeck/layouts/bee/TwoCol'
345
+
346
+ import '@honeydeck/honeydeck/theme.css'
347
+ import '@honeydeck/honeydeck/themes/bee.css'
348
+ ```
349
+
350
+ `LayoutProps<F>` describes the props passed to layout components:
351
+
352
+ ```ts
353
+ type LayoutProps<F = Record<string, unknown>> = {
354
+ title: ReactNode | null
355
+ children: ReactNode
356
+ rawChildren: ReactNode
357
+ frontmatter: F
358
+ }
359
+ ```
360
+
361
+ ## Agent skills
362
+
363
+ Honeydeck ships optional agent skills:
364
+
365
+ - `honeydeck` for Honeydeck-specific MDX and CLI guidance
366
+ - `presentation-writing` for help writing strong slide narratives
367
+ - `slidev-migration` for moving decks from Slidev to Honeydeck
368
+
369
+ `honeydeck init` can open the same interactive skills installer as `honeydeck skill`.
370
+
371
+ ```bash
372
+ honeydeck skill
373
+ npx skills add <honeydeck-repo-url> --copy
374
+ npx skills add <honeydeck-repo-url> --copy --skill slidev-migration
375
+ ```
376
+
377
+ Coming from Slidev? See the [Slidev migration guide](slidev-migration.md).
@@ -0,0 +1,91 @@
1
+ # PDF Export
2
+
3
+ ## How It Works
4
+
5
+ `honeydeck pdf` renders the deck using Playwright/Chromium. It builds into a temporary directory and starts a temporary local server — no pre-existing build or `dist/` pollution needed.
6
+
7
+ This keeps PDF output on the same rendering path as the browser presentation, so MDX, React components, layouts, themes, and CSS behave consistently.
8
+
9
+ If Chromium is missing or fails to launch after a fresh install, install the
10
+ Playwright browser binary:
11
+
12
+ ```bash
13
+ npx playwright install chromium
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```bash
19
+ honeydeck pdf # → deck.pdf
20
+ honeydeck pdf -o my-talk.pdf # custom filename
21
+ honeydeck pdf --steps all # all step states as separate pages
22
+ honeydeck pdf --mode dark # dark mode PDF
23
+ honeydeck pdf --mode light # explicit light mode
24
+ honeydeck pdf --parallel 6 # capture up to 6 pages at a time
25
+ ```
26
+
27
+ ## Options
28
+
29
+ | Flag | Description | Default |
30
+ |------|-------------|---------|
31
+ | `-o <file>` | Output filename | `deck.pdf` |
32
+ | `--steps <final\|all>` | Override `pdfSteps` frontmatter | `final` |
33
+ | `--mode <light\|dark>` | Override PDF color mode resolution | unset |
34
+ | `--parallel <count>` | Parallel page captures, from `1` to `16` | CPU count, capped at `16` |
35
+
36
+ ## Frontmatter Settings
37
+
38
+ ```yaml
39
+ ---
40
+ pdfColorMode: light # light | dark
41
+ pdfSteps: final # final | all
42
+ ---
43
+ ```
44
+
45
+ - **`pdfColorMode`** — optional PDF color mode. Resolution is CLI `--mode` > `pdfColorMode` > pinned deck `colorMode` (`light`/`dark`) > `light`. `system` is ignored for PDF.
46
+ - **`pdfSteps`** — `final` renders each slide once in its final state. `all` renders every step as a separate PDF page.
47
+
48
+ ## Steps in PDF
49
+
50
+ Honeydeck builds an ordered capture plan before taking screenshots. The final PDF always follows deck order; in `pdfSteps: all`, step pages ascend within each slide. Page screenshots may be captured in parallel, but completion order does not affect PDF page order.
51
+
52
+ When `pdfSteps: all`:
53
+
54
+ - Each `Reveal`/`RevealGroup` step becomes a separate page.
55
+ - Stepped code blocks show their first highlight group on the baseline page; each later code highlight group becomes a separate page.
56
+ - Both use the same underlying timeline.
57
+
58
+ When `pdfSteps: final` (default):
59
+
60
+ - All reveals shown in final (visible) state.
61
+ - Code blocks shown with final highlight applied.
62
+ - `useTimeline()` and `useTimelineSteps()` expose `isPdfFinalRender: true`, so
63
+ custom step-driven components can render an all-open/all-visible PDF state.
64
+
65
+ In `pdfSteps: all`, `isPdfFinalRender` stays false because each step is captured
66
+ with the same timeline state the browser presentation would use.
67
+
68
+ ## Aspect Ratio
69
+
70
+ PDF pages follow the deck's `aspectRatio`. Width stays fixed at 1920 and height is derived from the ratio:
71
+
72
+ ```txt
73
+ 16:9 → 1920×1080
74
+ 4:3 → 1920×1440
75
+ 1:1 → 1920×1920
76
+ ```
77
+
78
+ Invalid or missing ratios fall back to `16:9` / 1920×1080.
79
+
80
+ ## Terminal Output
81
+
82
+ ```txt
83
+ ✨ Honeydeck v0.1.0
84
+
85
+ 🖨️ Exporting PDF...
86
+ 🧵 Capturing 12 pages with N workers...
87
+ 📄 Rendering page 1/12 (slide 1/12)...
88
+ 📄 Rendering page 2/12 (slide 2/12)...
89
+ ...
90
+ ✅ Done! deck.pdf (12 pages)
91
+ ```