@troshab/slidev-theme-troshab 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 (168) hide show
  1. package/CLAUDE.md +537 -0
  2. package/LICENSE +134 -0
  3. package/README.md +168 -0
  4. package/SKILL.md +414 -0
  5. package/components/AnimatedCounter.vue +35 -0
  6. package/components/Background.vue +204 -0
  7. package/components/Callout.vue +135 -0
  8. package/components/Card.vue +75 -0
  9. package/components/CardGrid.vue +67 -0
  10. package/components/CaseStudy.vue +66 -0
  11. package/components/CodeDiff.vue +229 -0
  12. package/components/CodeHighlight.vue +337 -0
  13. package/components/ColorSwatch.vue +114 -0
  14. package/components/Confetti.vue +292 -0
  15. package/components/Conversation.vue +405 -0
  16. package/components/Countdown.vue +476 -0
  17. package/components/Definition.vue +59 -0
  18. package/components/DeviceMockup.vue +392 -0
  19. package/components/Funnel.vue +87 -0
  20. package/components/Icon.vue +73 -0
  21. package/components/Iframe.vue +38 -0
  22. package/components/Image.vue +69 -0
  23. package/components/ImageCompare.vue +436 -0
  24. package/components/MatrixGrid.vue +85 -0
  25. package/components/MermaidChart.vue +299 -0
  26. package/components/Metric.vue +161 -0
  27. package/components/PersonCard.vue +165 -0
  28. package/components/PricingTable.vue +144 -0
  29. package/components/Progress.vue +100 -0
  30. package/components/Pyramid.vue +81 -0
  31. package/components/QRCode.vue +137 -0
  32. package/components/QuoteBlock.vue +101 -0
  33. package/components/SpeechBubble.vue +169 -0
  34. package/components/Stepper.vue +542 -0
  35. package/components/StyledList.vue +156 -0
  36. package/components/StyledText.vue +275 -0
  37. package/components/SwotGrid.vue +99 -0
  38. package/components/Tags.vue +20 -0
  39. package/components/Testimonial.vue +243 -0
  40. package/components/Typewriter.vue +181 -0
  41. package/components_base/AnimatedCounter.vue +208 -0
  42. package/components_base/CodeHighlight.vue +364 -0
  43. package/composables/useColors.ts +101 -0
  44. package/composables/useShiki.ts +81 -0
  45. package/example_content.md +371 -0
  46. package/example_dark.md +10 -0
  47. package/example_slides/001-cover.md +15 -0
  48. package/example_slides/002-agenda.md +25 -0
  49. package/example_slides/003-section-layouts.md +14 -0
  50. package/example_slides/004-fullscreen-centered.md +7 -0
  51. package/example_slides/005-fullscreen-align-bottom.md +14 -0
  52. package/example_slides/006-fullscreen-no-padding.md +14 -0
  53. package/example_slides/007-fullscreen-bg-image-dark.md +13 -0
  54. package/example_slides/008-fullscreen-bg-image-light.md +13 -0
  55. package/example_slides/009-fullscreen-bg-gradient.md +15 -0
  56. package/example_slides/010-fullscreen-bg-color.md +13 -0
  57. package/example_slides/011-split-basic.md +17 -0
  58. package/example_slides/012-split-image-text.md +18 -0
  59. package/example_slides/013-split-contrast.md +22 -0
  60. package/example_slides/014-columns-basic.md +13 -0
  61. package/example_slides/015-columns-two.md +26 -0
  62. package/example_slides/016-columns-ratios.md +22 -0
  63. package/example_slides/017-columns-three.md +31 -0
  64. package/example_slides/018-columns-four.md +22 -0
  65. package/example_slides/019-columns-alignment.md +23 -0
  66. package/example_slides/020-columns-styled.md +21 -0
  67. package/example_slides/021-footnote-prop.md +16 -0
  68. package/example_slides/022-iframe-fullscreen.md +8 -0
  69. package/example_slides/023-iframe-split.md +18 -0
  70. package/example_slides/024-section-components.md +14 -0
  71. package/example_slides/025-styled-text.md +9 -0
  72. package/example_slides/026-styled-text.md +15 -0
  73. package/example_slides/027-text-formatting.md +28 -0
  74. package/example_slides/028-text-spoiler.md +15 -0
  75. package/example_slides/029-icon-component.md +47 -0
  76. package/example_slides/030-metric-component.md +29 -0
  77. package/example_slides/031-person-card.md +33 -0
  78. package/example_slides/032-styled-list.md +50 -0
  79. package/example_slides/033-color-swatch.md +35 -0
  80. package/example_slides/034-code-highlight.md +9 -0
  81. package/example_slides/035-iframe-component.md +9 -0
  82. package/example_slides/036-callout.md +15 -0
  83. package/example_slides/037-card-grid.md +27 -0
  84. package/example_slides/038-stepper-variants.md +18 -0
  85. package/example_slides/039-stepper-clicks.md +49 -0
  86. package/example_slides/040-stepper-interactive.md +28 -0
  87. package/example_slides/041-tags-progress.md +21 -0
  88. package/example_slides/042-speech-bubble.md +30 -0
  89. package/example_slides/043-conversation.md +13 -0
  90. package/example_slides/044-device-iphone.md +26 -0
  91. package/example_slides/045-device-browser.md +7 -0
  92. package/example_slides/046-qrcode.md +26 -0
  93. package/example_slides/047-countdown.md +14 -0
  94. package/example_slides/048-typewriter.md +8 -0
  95. package/example_slides/049-confetti.md +16 -0
  96. package/example_slides/050-image-compare.md +13 -0
  97. package/example_slides/051-code-diff.md +24 -0
  98. package/example_slides/052-quote-block.md +8 -0
  99. package/example_slides/053-testimonial.md +26 -0
  100. package/example_slides/054-testimonial-featured.md +16 -0
  101. package/example_slides/055-funnel.md +12 -0
  102. package/example_slides/056-pyramid.md +13 -0
  103. package/example_slides/057-pricing-table.md +9 -0
  104. package/example_slides/058-swot-grid.md +12 -0
  105. package/example_slides/059-matrix-grid.md +12 -0
  106. package/example_slides/060-case-study.md +11 -0
  107. package/example_slides/061-definition.md +15 -0
  108. package/example_slides/062-mermaid-intro.md +34 -0
  109. package/example_slides/063-mermaid-flowchart.md +19 -0
  110. package/example_slides/064-mermaid-sequence.md +17 -0
  111. package/example_slides/065-mermaid-xy-chart.md +16 -0
  112. package/example_slides/066-mermaid-pie.md +17 -0
  113. package/example_slides/067-mermaid-class.md +19 -0
  114. package/example_slides/068-mermaid-state.md +19 -0
  115. package/example_slides/069-mermaid-er.md +22 -0
  116. package/example_slides/070-mermaid-gantt.md +24 -0
  117. package/example_slides/071-mermaid-timeline.md +17 -0
  118. package/example_slides/072-mermaid-mindmap.md +21 -0
  119. package/example_slides/073-mermaid-gitgraph.md +20 -0
  120. package/example_slides/074-mermaid-split.md +30 -0
  121. package/example_slides/075-mermaid-columns.md +32 -0
  122. package/example_slides/076-section-addons.md +14 -0
  123. package/example_slides/077-asciinema.md +27 -0
  124. package/example_slides/078-fancyarrow.md +31 -0
  125. package/example_slides/079-fancyarrow-demo.md +23 -0
  126. package/example_slides/080-section-theme.md +14 -0
  127. package/example_slides/081-color-architecture.md +22 -0
  128. package/example_slides/082-semantic-text-colors.md +25 -0
  129. package/example_slides/083-typography.md +16 -0
  130. package/example_slides/084-typography-rationale.md +22 -0
  131. package/example_slides/085-icons.md +24 -0
  132. package/example_slides/086-tables.md +14 -0
  133. package/example_slides/087-code-blocks.md +18 -0
  134. package/example_slides/088-motion-modes.md +35 -0
  135. package/example_slides/089-slide-transitions.md +31 -0
  136. package/example_slides/090-v-click-reveals.md +40 -0
  137. package/example_slides/091-accessibility.md +27 -0
  138. package/example_slides/092-safe-zone.md +17 -0
  139. package/example_slides/093-questions.md +8 -0
  140. package/example_white.md +10 -0
  141. package/fonts/IBMPlexMono-Medium.woff2 +1449 -0
  142. package/fonts/IBMPlexMono-Regular.woff2 +1449 -0
  143. package/fonts/IBMPlexSans-Bold.woff2 +1449 -0
  144. package/fonts/IBMPlexSans-Medium.woff2 +1449 -0
  145. package/fonts/IBMPlexSans-Regular.woff2 +1449 -0
  146. package/fonts/IBMPlexSans-SemiBold.woff2 +1449 -0
  147. package/fonts/LICENSE.txt +93 -0
  148. package/layouts/slide.vue +251 -0
  149. package/package.json +62 -0
  150. package/public/avatars/alice.png +0 -0
  151. package/public/avatars/bob.png +0 -0
  152. package/public/avatars/carol.png +0 -0
  153. package/scripts/chart-audit.mjs +216 -0
  154. package/scripts/contrast-audit.mjs +299 -0
  155. package/scripts/generate-palette.mjs +395 -0
  156. package/scripts/integrity-audit.mjs +357 -0
  157. package/scripts/shared/css-utils.mjs +216 -0
  158. package/scripts/shiki-audit.mjs +300 -0
  159. package/scripts/typography-audit.mjs +300 -0
  160. package/setup/main.ts +107 -0
  161. package/setup/mermaid.ts +237 -0
  162. package/setup/shiki.ts +40 -0
  163. package/snippets/demo.ts +26 -0
  164. package/styles/base.css +1053 -0
  165. package/styles/colors.css +422 -0
  166. package/styles/index.css +12 -0
  167. package/styles/motion.css +486 -0
  168. package/uno.config.ts +67 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,537 @@
1
+ # slidev-theme-troshab
2
+
3
+ > **This file must be written in English only.**
4
+
5
+ Minimal universal Slidev theme with flexible layouts and a library of ready-made slides.
6
+
7
+ ---
8
+
9
+ ## Development Rules
10
+
11
+ ### Styling Principles
12
+
13
+ 1. **All styling via CSS classes** — never use inline styles (`style="..."`)
14
+ 2. **Semantic class names** — classes should describe component purpose, not appearance
15
+ - Good: `.btn-primary`, `.link-button`, `.card-metric`
16
+ - Bad: `.text-white`, `.bg-blue-500` (only use utility classes from UnoCSS when necessary)
17
+ 3. **All custom classes in `styles/base.css`** — component styles must be centralized
18
+ 4. **Type-specific variations** — use modifier classes like `.block-info`, `.block-warning`
19
+ 5. **Dark theme support** — use `color-mix(in srgb, var(--color-X) N%, transparent)` instead of `.dark` overrides; CSS variables auto-adapt
20
+
21
+ ### File Organization
22
+
23
+ - `styles/colors.css` — color variables only (no component styles) **← SOURCE OF TRUTH**
24
+ - `styles/base.css` — typography, spacing, and component styles
25
+ - `styles/motion.css` — motion system (transitions, animations, v-click)
26
+ - `uno.config.ts` — grid utilities and UnoCSS configuration
27
+ - `setup/mermaid.ts` — Mermaid theme configuration (reads CSS variables at runtime)
28
+ - `setup/shiki.ts` — Shiki syntax highlighting theme + lang-label transformer
29
+ - `composables/useColors.ts` — shared color types and CSS var maps (single source of truth)
30
+
31
+ ### Component Documentation Sync
32
+
33
+ > Component docs live in the plugin skill directory: `~/troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/`
34
+
35
+ - Every component in `components/` has a matching `.md` in `plugin/components/{Name}.md`
36
+ - The layout has `plugin/layouts/slide.md` with full mode/prop/slot documentation
37
+ - **When creating or modifying a component:** update (or create) the corresponding `.md` in the plugin skill directory
38
+ - **When deleting a component:** delete its `.md` from the plugin skill directory
39
+ - MD files use a standard format: `# Name`, `## Props` (table), `## Slots` (table, if any), `## Usage` (examples), `## Notes` (gotchas, if any)
40
+
41
+ ### Slide Numbering
42
+
43
+ - Slides in `example_slides/` use 3-digit prefix: `001-name.md`, `002-name.md`, ...
44
+ - When adding or removing slides, **renumber all subsequent files** to maintain continuous sequence
45
+ - Update `example_content.md` to match the new file names
46
+ - 4 sections: Layouts (003-023), Components (024-075), Addons (076-079), Theme Features (080-092), Q&A (093)
47
+
48
+ ---
49
+
50
+ ## Project Structure
51
+
52
+ ```
53
+ slidev-theme-troshab/
54
+ ├── package.json
55
+ ├── uno.config.ts # UnoCSS: grid, utilities
56
+ ├── styles/
57
+ │ ├── index.css # CSS entry point (auto-detected by Slidev)
58
+ │ ├── base.css # Typography, spacing, component styles
59
+ │ ├── colors.css # Color system (light/dark) ← SOURCE OF TRUTH
60
+ │ └── motion.css # Motion system (transitions, animations)
61
+ ├── setup/
62
+ │ ├── main.ts # App setup (image preloading)
63
+ │ ├── mermaid.ts # Mermaid theme (reads CSS vars at runtime)
64
+ │ └── shiki.ts # Shiki syntax highlighting
65
+ ├── composables/
66
+ │ └── useColors.ts # Shared color types + CSS var maps
67
+ ├── fonts/ # IBM Plex Sans/Mono (woff2)
68
+ ├── layouts/ # 1 universal layout (slide.vue)
69
+ ├── components/ # 11 primitives + 26 widgets
70
+ ├── snippets/ # Code snippets for import demos
71
+ ├── example_content.md # 92 slides (all content, no theme config)
72
+ ├── example_white.md # Light theme wrapper (src: example_content.md)
73
+ ├── example_dark.md # Dark theme wrapper (src: example_content.md)
74
+ └── slides-export/ # Visual testing reference
75
+ ├── white/ # Light theme PNG exports
76
+ └── black/ # Dark theme PNG exports
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Development Servers
82
+
83
+ ```bash
84
+ npx slidev example_dark.md --port 30303 # Dark: http://localhost:30303
85
+ npx slidev example_white.md --port 31313 # Light: http://localhost:31313
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Visual Testing
91
+
92
+ ```bash
93
+ npx slidev export example_white.md --format png --output ./slides-export/white
94
+ npx slidev export example_dark.md --format png --output ./slides-export/black
95
+ ```
96
+
97
+ ## THE UNIVERSAL LAYOUT
98
+
99
+ See @../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/layouts/slide.md for full documentation (modes, props, slots, background slots, edge-to-edge rules).
100
+
101
+ All slides use `layout: slide` with `mode: fullscreen | split | columns` (default: columns).
102
+
103
+ ---
104
+
105
+ ## INCLUDED ADDONS
106
+
107
+ ### Preload Images
108
+
109
+ Automatic image preloading. Config: `preloadImages: { enabled: true, ahead: 3 }` in frontmatter. Strategy: preload current + ahead slides on startup, then background-load the rest.
110
+
111
+ ### Asciinema
112
+
113
+ Terminal recordings: `<Asciinema src="/casts/demo.cast" :rows="24" :cols="80" autoplay />`. Props: `src` (required), `rows`, `cols`, `autoplay`, `loop`, `speed`.
114
+
115
+ ### FancyArrow
116
+
117
+ Hand-drawn arrows: `<FancyArrow x1="100" y1="100" x2="300" y2="200" color="red" :width="3" />`. Props: `x1/y1/x2/y2` (required), `color`, `width`, `two-way`.
118
+
119
+ ---
120
+
121
+ ## PRIMITIVE COMPONENTS (10)
122
+
123
+ Semantic building blocks. Full API (props, slots, usage) in `plugin/components/{Name}.md`.
124
+
125
+ | Component | Description |
126
+ |-----------|-------------|
127
+ | Background | Bg slot wrapper: color, gradient, image, overlay (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Background.md) |
128
+ | StyledText | Universal text: heading/block/inline, color, spoiler v-click (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/StyledText.md) |
129
+ | Image | Content image with caption, border, sizing (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Image.md) |
130
+ | Icon | Phosphor icon with size and color (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Icon.md) |
131
+ | Metric | KPI display with count-up animation (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Metric.md) |
132
+ | PersonCard | Speaker/member card with avatar (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/PersonCard.md) |
133
+ | Iframe | External content embed (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Iframe.md) |
134
+ | ColorSwatch | Theme color display with resolved value (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/ColorSwatch.md) |
135
+ | StyledList | Themed list markers (check/arrow/star/number) (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/StyledList.md) |
136
+ | CodeHighlight | Syntax-highlighted code block (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/CodeHighlight.md) |
137
+
138
+ ---
139
+
140
+ ## WIDGET COMPONENTS (26)
141
+
142
+ Full API (props, slots, usage) in `plugin/components/{Name}.md`.
143
+
144
+ | Component | Description |
145
+ |-----------|-------------|
146
+ | Stepper | Steps/timeline/progress with dots/numbers/arrows (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Stepper.md) |
147
+ | Callout | Admonition: info, tip, warning, danger, note (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Callout.md) |
148
+ | Card / CardGrid | Feature cards in responsive grid (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Card.md, @components/CardGrid.md) |
149
+ | QRCode | Theme-aware SVG QR code (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/QRCode.md) |
150
+ | Tags | Tag pills (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Tags.md) |
151
+ | Progress | Presentation progress bar (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Progress.md) |
152
+ | SpeechBubble | Speech/thought bubbles (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/SpeechBubble.md) |
153
+ | Conversation | iMessage-style chat with v-click (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Conversation.md) |
154
+ | DeviceMockup | Device frames: iPhone, MacBook, browser, tablet (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/DeviceMockup.md) |
155
+ | Countdown | Animated timer with v-click (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Countdown.md) |
156
+ | AnimatedCounter | Count-up number animation (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/AnimatedCounter.md) |
157
+ | Typewriter | Text typing animation (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Typewriter.md) |
158
+ | Confetti | Celebration particles for bg slot (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Confetti.md) |
159
+ | ImageCompare | Before/after image slider (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/ImageCompare.md) |
160
+ | CodeDiff | Code comparison: split or unified (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/CodeDiff.md) |
161
+ | Testimonial | Customer quote card with rating (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Testimonial.md) |
162
+ | QuoteBlock | Large centered quote (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/QuoteBlock.md) |
163
+ | Funnel | Conversion funnel (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Funnel.md) |
164
+ | Pyramid | Hierarchical levels (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Pyramid.md) |
165
+ | PricingTable | Pricing tier cards (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/PricingTable.md) |
166
+ | MatrixGrid | 2x2 quadrant grid (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/MatrixGrid.md) |
167
+ | SwotGrid | SWOT analysis (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/SwotGrid.md) |
168
+ | CaseStudy | Multi-section case study (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/CaseStudy.md) |
169
+ | Definition | Term definition card (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/Definition.md) |
170
+ | MermaidChart | Mermaid diagram wrapper (@../troshab-own-claude-code/plugins/troshab-own/skills/slidev-visualise-content/components/MermaidChart.md) |
171
+
172
+ ---
173
+
174
+ ## MERMAID DIAGRAMS
175
+
176
+ Theme automatically applies matching colors via `setup/mermaid.ts` (reads CSS vars at runtime). Theme detection happens at page load — toggle requires reload.
177
+
178
+ ### Rules
179
+
180
+ 1. **Short labels** — max 8-10 chars per node
181
+ 2. **Limit nodes** — max 6-8 for flowcharts
182
+ 3. **No titles in xychart** — causes overflow
183
+ 4. **Use abbreviations** — `LB` not `Load Balancer`
184
+
185
+ ### Limits by type
186
+
187
+ - **Flowchart:** max 8 nodes, 2-8 char labels, use `TD` or `LR`
188
+ - **XY Chart:** no `title`, max 6-8 x-axis labels (3-char), short y-axis label
189
+ - **Sequence:** max 4 participants (2-6 chars), max 6-8 messages
190
+ - **Pie:** max 5 segments, max 12-char labels
191
+
192
+ If too complex: split slides, use `cols: 2`, create external SVG, or simplify.
193
+
194
+ ---
195
+
196
+ ## CODE BLOCKS
197
+
198
+ ### Limits to Avoid Overflow
199
+
200
+ | Context | Max lines | Max width |
201
+ |---------|-----------|-----------|
202
+ | Full-width slide (1 col) | 12-15 lines | 80 chars |
203
+ | Two-column (`cols: 2`) | 8-10 lines | 40 chars |
204
+ | Inline with text | 6-8 lines | 60 chars |
205
+
206
+ ### Best Practices
207
+
208
+ 1. **Remove comments** — `// Usage`, `// Example` take space
209
+ 2. **Shorten error messages** — `throw new Error('HTTP error')` not full status
210
+ 3. **Omit obvious types** — TypeScript can infer many types
211
+ 4. **Split long code** — use multiple slides or `cols: 2` for before/after
212
+ 5. **Use highlights** — `{1,3-5}` to focus on key lines instead of showing all
213
+
214
+ ---
215
+
216
+ ## SLIDE EXAMPLES
217
+
218
+ ### Cover / section divider
219
+
220
+ ```md
221
+ ---
222
+ layout: slide
223
+ mode: fullscreen
224
+ ---
225
+
226
+ ::bg::
227
+ <Background :gradient="'section'" />
228
+
229
+ ::default::
230
+ # Section Title
231
+ ```
232
+
233
+ ### Image with overlay
234
+
235
+ ```md
236
+ ---
237
+ layout: slide
238
+ mode: fullscreen
239
+ ---
240
+
241
+ ::bg::
242
+ <Background src="/hero.jpg" bgOverlay="dark" />
243
+
244
+ ::default::
245
+ # Title Over Image
246
+ ```
247
+
248
+ ### Two columns
249
+
250
+ ```md
251
+ ---
252
+ layout: slide
253
+ cols: 2
254
+ ---
255
+
256
+ # Title
257
+
258
+ ::col1::
259
+ Left content
260
+
261
+ ::col2::
262
+ Right content
263
+ ```
264
+
265
+ ### Split with image
266
+
267
+ ```md
268
+ ---
269
+ layout: slide
270
+ mode: split
271
+ split: [5, 7]
272
+ ---
273
+
274
+ ::left-bg::
275
+ <Background src="/photo.jpg" />
276
+
277
+ ::right::
278
+ # Content
279
+ ```
280
+
281
+ ### Simple text
282
+
283
+ ```md
284
+ ---
285
+ layout: slide
286
+ ---
287
+
288
+ # Title
289
+
290
+ Content here
291
+ ```
292
+
293
+ ---
294
+
295
+ ## V-CLICK AUTO-INTEGRATION
296
+
297
+ Components can auto-register with Slidev's click system so users don't need `<v-click>` wrappers or `clicks:` frontmatter. The slide's total clicks are computed dynamically from all registered elements.
298
+
299
+ ### How it works
300
+
301
+ Inject `$$slidev-clicks-context` (a `Ref<ClicksContext>`). On mount, call `ctx.calculate('+1')` to claim the next click slot, then `ctx.register(el, info)` to register. On unmount, call `ctx.unregister(el)`.
302
+
303
+ **ClicksContext API** (from `@slidev/client/composables/useClicks.ts`):
304
+ - `ctx.calculate(at)` - returns `ClicksInfo` with `{ start, end, max, delta, isActive, isCurrent }`. `at` values: `'+1'` (relative next), `'+2'`, or absolute number `0`, `1`, `2`.
305
+ - `ctx.register(el, info)` - registers element in click system. `el` = DOM element (used as Map key). Must be called in `onMounted` (before parent slide's `isMounted`).
306
+ - `ctx.unregister(el)` - removes element from click system.
307
+ - `ctx.current` - current click index (reactive getter, clamped to `[clicksStart, total]`).
308
+ - `ctx.total` - max click index (dynamically computed from all registered elements' `max` values).
309
+ - `info.isActive` - `computed(() => current >= start)` - tracks forward/backward.
310
+ - `info.isCurrent` - `computed(() => current === start)` - true only at exact click.
311
+
312
+ ### Pattern for auto v-click components
313
+
314
+ ```typescript
315
+ const rootEl = ref<HTMLElement | null>(null)
316
+ const clicksContext = inject<Ref<any>>('$$slidev-clicks-context', ref(null))
317
+
318
+ onMounted(() => {
319
+ const ctx = clicksContext.value
320
+ if (ctx?.calculate && rootEl.value) {
321
+ const info = ctx.calculate('+1') // Claim next click slot
322
+ if (info) {
323
+ ctx.register(rootEl.value, info)
324
+ // IMPORTANT: watchEffect MUST be inside onMounted — info is not reactive,
325
+ // so a watchEffect created before onMounted would never re-run.
326
+ // info.isActive is a computed ref that tracks forward/backward navigation.
327
+ watchEffect(() => {
328
+ isRevealed.value = info.isActive.value
329
+ })
330
+ }
331
+ }
332
+ })
333
+
334
+ onUnmounted(() => {
335
+ if (clicksContext.value?.unregister && rootEl.value)
336
+ clicksContext.value.unregister(rootEl.value)
337
+ })
338
+ ```
339
+
340
+ ### `at` prop pattern (explicit click index)
341
+
342
+ For components with `at` prop (AnimatedCounter, Countdown, Confetti, ImageCompare, Metric):
343
+
344
+ ```typescript
345
+ const clicksContext = inject<Ref<{current: number}>>('$$slidev-clicks-context', ref({current: 0}))
346
+
347
+ // Watch click counter manually
348
+ watch(() => clicksContext.value.current, (cur) => {
349
+ if (cur >= props.at && !hasTriggered) trigger()
350
+ if (cur < props.at && hasTriggered) reset()
351
+ })
352
+ ```
353
+
354
+ ### Components with v-click integration
355
+
356
+ | Component | Type | Behavior |
357
+ |-----------|------|----------|
358
+ | StyledText (spoiler) | Auto `+1` | Registers next click, blurs/unblurs |
359
+ | AnimatedCounter | `at` prop (0) | Count-up on click, reset on backward |
360
+ | Countdown | `at` prop (-1) | Start timer on click |
361
+ | Confetti | `at` prop (0) | Fire particles on click |
362
+ | ImageCompare | `at` prop (-1) | Animate slider on click |
363
+ | Metric | Pass-through | Forwards `at` to AnimatedCounter |
364
+
365
+ ---
366
+
367
+ ## UnoCSS Utilities
368
+
369
+ Theme includes:
370
+ - 12-column grid (`col-span-3` ... `col-span-9`)
371
+ - Semantic aliases (`is-half`, `is-one-third`, `is-two-thirds`, `is-one-quarter`, `is-three-quarters`)
372
+ - Styles for Block/Theorem components
373
+
374
+ ---
375
+
376
+ ## When to Use Which Mode + Component
377
+
378
+ | Situation | Mode | Component |
379
+ |-----------|------|-----------|
380
+ | Regular slide with text/list | columns (default) | — |
381
+ | Title/cover slide | fullscreen | `<StyledText tag="h1">` + `<StyledText color="secondary">` |
382
+ | Section divider | fullscreen | `<Background :gradient="'section'">` in ::bg:: |
383
+ | Centered statement | fullscreen | `<StyledText tag="h1" align="center">` |
384
+ | Quote | fullscreen | `<QuoteBlock>` |
385
+ | Large number/KPI | fullscreen | `<Metric size="lg" gradient>` |
386
+ | Hero with background image | fullscreen | `<Background src="..." bgOverlay="dark">` |
387
+ | Full-screen iframe/media | fullscreen | `padding: false` |
388
+ | Image + text side by side | split | `<Background>` in bg slot |
389
+ | Before/after comparison | split | `colAlign: center` prop |
390
+ | Two columns | columns | `cols: 2` |
391
+ | Three columns | columns | `cols: 3` |
392
+ | Four columns | columns | `cols: 4` |
393
+ | Meeting agenda | columns | `<StyledList marker="number">` |
394
+ | Key takeaways | columns | `<StyledList marker="check" color="success">` |
395
+ | Styled bullet points | columns | `<StyledList marker="arrow">` |
396
+ | Content with footnotes | columns | `footnote: true` prop |
397
+ | Speaker introduction | columns | `<PersonCard>` |
398
+ | Team members grid | columns | `<PersonCard size="sm">` in grid |
399
+ | KPIs dashboard | columns | `<Metric>` components |
400
+ | Pricing table | columns | `<PricingTable>` |
401
+ | Customer testimonial | fullscreen | `<Testimonial variant="featured">` |
402
+ | Chat dialog, Q&A | columns | `<Conversation>` |
403
+ | Call to action | fullscreen | `<StyledText tag="h1">` + `<StyledText>` |
404
+ | Case study | columns | `<CaseStudy>` |
405
+ | Step-by-step workflow | columns | `<Stepper variant="numbers">` |
406
+ | Project milestones | columns | `<Stepper variant="dots" direction="vertical">` |
407
+ | Sales/conversion funnel | columns | `<Funnel>` |
408
+ | Hierarchical pyramid | columns | `<Pyramid>` |
409
+ | SWOT analysis | columns | `<SwotGrid>` |
410
+ | Impact/effort matrix | columns | `<MatrixGrid>` |
411
+ | Key insight, focus point | fullscreen | `<StyledText tag="h1" color="primary">` |
412
+ | Term definition | columns | `<Definition>` |
413
+ | Bibliography/references | columns | `<StyledList indent="hanging">` |
414
+ | Attribution credits | columns | `<StyledList marker="none" columns="2">` |
415
+ | Q&A, thank you | fullscreen | `<StyledText tag="h1" align="center">` |
416
+ | Mermaid diagrams (all types) | any | `<MermaidChart type="...">` wrapper with ` ```mermaid ` inside |
417
+
418
+ ---
419
+
420
+ ## TYPOGRAPHY
421
+
422
+ ### Fonts
423
+
424
+ | Role | Font | Weights |
425
+ |------|------|---------|
426
+ | Text + headings | **IBM Plex Sans** | 400, 500, 600, 700 |
427
+ | Code | **IBM Plex Mono** | 400, 500 |
428
+
429
+ ### Font Sizes (4 variables)
430
+
431
+ `--font-size-h1`: 57px, `--font-size-h2`: 43px (also h3), `--font-size-base`: 24px, `--font-size-small`: 18px (captions, labels, code)
432
+
433
+ ### Formatting Rules
434
+
435
+ - **Alignment:** left for multi-line text, center only for single-line headings
436
+ - **Italic:** only for book titles/terms, NOT for emphasis
437
+ - **ALL CAPS:** only for short labels
438
+ - **Underline:** only for links
439
+ - **Justified text:** forbidden
440
+ - **Light/thin weights:** forbidden (fade on projector)
441
+
442
+ ### Accessibility
443
+
444
+ - Contrast ratio >= 4.5:1 for all text (AA), target 7:1 (AAA)
445
+ - WCAG 2.2 keyboard focus styles (3px primary outline)
446
+ - BDA-compliant spacing: word-spacing 0.08em, letter-spacing 0.02em (4.0x ratio, BDA min 3.5x)
447
+ - Safe zone: 5% padding on all sides (`--safe-inset-x`, `--safe-inset-y`)
448
+
449
+ ---
450
+
451
+ ## COLORS
452
+
453
+ **Source of truth:** `styles/colors.css`. Shared types in `composables/useColors.ts`.
454
+
455
+ ### Architecture (3-layer Dracula/Alucard palette)
456
+
457
+ 1. **Layer 1 (Palette):** `--color-{family}-{shade}` in `:root` — ONLY place hex values exist. 11 families (drac-bg, drac-fg, alu-bg, drac-comment, drac-cyan, drac-green, drac-orange, drac-pink, drac-purple, drac-red, drac-yellow) x 11 shades. Generated via `scripts/generate-palette.mjs` (OKLCH shade ramps).
458
+ 2. **Layer 2 (Semantic):** `--color-primary: var(--color-drac-purple-700)` — only `var()` refs to palette.
459
+ 3. **Layer 3 (Usage):** Components use ONLY semantic vars. NO hex anywhere in components/slides.
460
+
461
+ ### Key principles
462
+
463
+ - Light (Alucard): alu-bg-50 bg, drac-fg-900 text, drac-purple-700 primary, drac-pink-700 accent
464
+ - Dark (Dracula): drac-bg-900 bg, drac-fg-50 text, drac-cyan-300 primary, drac-purple-200 accent
465
+ - Tint vars (`--color-X-tint`) use opaque palette shades, NOT `color-mix()`
466
+ - `color-mix()` ONLY for true alpha: shadows, image overlays
467
+ - Every `--color-{name}` has matching `--color-{name}-foreground` for readable text
468
+ - Borders: light drac-comment-500/600, dark drac-comment-300/200 (all 3:1+ non-text contrast)
469
+ - Chart palette: 8 colors per theme with varied shade levels for grayscale spread
470
+ - Components accepting colors use semantic names (primary, success, accent) mapped to `--color-{name}`
471
+ - 5 audits: contrast, shiki, chart, typography, integrity — all must exit 0
472
+
473
+ ### Gradient system
474
+
475
+ **CSS vars** (defined in `colors.css`): `--gradient-{color}` for each semantic color + accent. Primary is a special cross-color gradient (purple→pink); others go from `--color-{name}` to `--color-{name}-fade`.
476
+
477
+ **JS utility** (in `composables/useColors.ts`): `gradientVar` map (`Record<ExtendedColor, string>`). Components use it instead of building template literals:
478
+
479
+ ```typescript
480
+ import { gradientVar } from '../composables/useColors'
481
+ // In component: gradientVar[props.color] → 'var(--gradient-primary)'
482
+ ```
483
+
484
+ **Pattern for components with `color` prop + gradient:**
485
+ - Inline style sets a CSS custom property: `:style="{ '--metric-gradient': gradientVar[color] }"`
486
+ - CSS uses it with fallback: `background: var(--metric-gradient, var(--gradient-primary))`
487
+ - Components without `color` prop use `var(--gradient-primary)` directly in CSS (decorative)
488
+
489
+ ---
490
+
491
+ ## MOTION SYSTEM
492
+
493
+ **Source of truth:** `styles/motion.css`. Tokens based on IBM Carbon.
494
+
495
+ ### Design Principles
496
+
497
+ 1. Motion explains, not decorates — animations show causality
498
+ 2. 1-2 properties max — only `opacity + transform` (GPU-friendly)
499
+ 3. Exit faster than enter (~20% shorter)
500
+ 4. Desktop prefers shorter (150-300ms typical)
501
+ 5. Stagger <= 6 items (longer lists skip stagger)
502
+ 6. Reduced motion: WCAG 2.1 via `prefers-reduced-motion` (currently TODO)
503
+
504
+ ### Motion Modes
505
+
506
+ | Mode | Class | Duration | Use |
507
+ |------|-------|----------|-----|
508
+ | Calm | (default) | 240ms | Standard presentations |
509
+ | Crisp | `motion-crisp` | 150ms | Technical demos |
510
+ | Expressive | `motion-expressive` | 400ms | Creative presentations |
511
+
512
+ ### Slide Transitions
513
+
514
+ Content slides use `slide-left` (page-turn), accent slides use `fade`. Set global default in first slide's frontmatter (`transition: slide-left`), override per slide.
515
+
516
+ Available: `slide-left`, `slide-right`, `slide-up`, `slide-down`, `fade`, `none`.
517
+
518
+ ### v-click Reveal Styles
519
+
520
+ Default = fade + rise. Override per slide: `reveal-fade` (opacity only), `reveal-slide` (from right), `reveal-pop` (scale up). Theme auto-detects content type (code/tables = fade, lists = slide from left, large text = pop).
521
+
522
+ ### Entrance Animations
523
+
524
+ Automatic per layout — headings fall from above, content rises from below, two columns slide from opposite sides, grids rise together. No configuration needed.
525
+
526
+ ---
527
+
528
+ ## ICONS
529
+
530
+ Phosphor Icons via Iconify (`@iconify-json/ph`). Use via `<Icon>` component:
531
+
532
+ ```md
533
+ <Icon name="ph-check-circle" size="xl" color="success" />
534
+ <Icon name="ph-github-logo-bold" />
535
+ ```
536
+
537
+ Weight suffixes: (none) = regular, `-bold`, `-fill`, `-duotone`, `-thin`, `-light`.
package/LICENSE ADDED
@@ -0,0 +1,134 @@
1
+ # PolyForm Noncommercial License 1.0.0
2
+
3
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
4
+
5
+ ## Acceptance
6
+
7
+ In order to get any license under these terms, you must agree
8
+ to them as both strict obligations and conditions to all your
9
+ licenses.
10
+
11
+ ## Copyright License
12
+
13
+ The licensor grants you a copyright license for the software
14
+ to do everything you might do with the software that would
15
+ otherwise infringe the licensor's copyright in it for any
16
+ permitted purpose. However, you may only distribute the
17
+ software according to [Distribution License](#distribution-license)
18
+ and make changes or new works based on the software according
19
+ to [Changes and New Works License](#changes-and-new-works-license).
20
+
21
+ ## Distribution License
22
+
23
+ The licensor grants you an additional copyright license to
24
+ distribute copies of the software. Your license to distribute
25
+ covers distributing the software with changes and new works
26
+ permitted by [Changes and New Works License](#changes-and-new-works-license).
27
+
28
+ ## Notices
29
+
30
+ You must ensure that anyone who gets a copy of any part of
31
+ the software from you also gets a copy of these terms or the
32
+ URL for them above, as well as copies of any plain-text lines
33
+ beginning with `Required Notice:` that the licensor provided
34
+ with the software. For example:
35
+
36
+ > Required Notice: Copyright (c) 2024-2026 troshab
37
+ > (https://github.com/troshab)
38
+
39
+ ## Changes and New Works License
40
+
41
+ The licensor grants you an additional copyright license to
42
+ make changes and new works based on the software for any
43
+ permitted purpose.
44
+
45
+ ## Patent License
46
+
47
+ The licensor grants you a patent license for the software
48
+ that covers patent claims the licensor can license, or
49
+ becomes able to license, that you would infringe by using
50
+ the software.
51
+
52
+ ## Noncommercial Purposes
53
+
54
+ Any noncommercial purpose is a permitted purpose.
55
+
56
+ ## Personal Uses
57
+
58
+ Personal use for research, experiment, and testing for
59
+ the benefit of public knowledge, personal study, private
60
+ entertainment, hobby projects, amateur pursuits, or
61
+ religious observance, without any anticipated commercial
62
+ application, is use for a permitted purpose.
63
+
64
+ ## Noncommercial Organizations
65
+
66
+ Use by any charitable organization, educational institution,
67
+ public research organization, public safety or health
68
+ organization, environmental protection organization, or
69
+ government institution is use for a permitted purpose
70
+ regardless of the source of funding or obligations resulting
71
+ from the funding.
72
+
73
+ ## Fair Use
74
+
75
+ You may have "fair use" rights for the software under the
76
+ law. These terms do not limit them.
77
+
78
+ ## No Other Rights
79
+
80
+ These terms do not allow you to sublicense or transfer any
81
+ of your licenses to anyone else, or prevent the licensor
82
+ from granting licenses to anyone else. These terms do not
83
+ imply any other licenses.
84
+
85
+ ## Patent Defense
86
+
87
+ If you make any written claim that the software infringes
88
+ or contributes to infringement of any patent, your patent
89
+ license for the software granted under these terms ends
90
+ immediately. If your company makes such a claim, your
91
+ patent license ends immediately for work on behalf of your
92
+ company.
93
+
94
+ ## Violations
95
+
96
+ The first time you are notified in writing that you have
97
+ violated any of these terms, or done anything with the
98
+ software not covered by your licenses, your licenses can
99
+ nonetheless continue if you come into full compliance with
100
+ these terms, and take practical steps to correct past
101
+ violations, within 32 days of receiving notice. Otherwise,
102
+ all your licenses end immediately.
103
+
104
+ ## No Liability
105
+
106
+ As far as the law allows, the software comes as is, without
107
+ any warranty or condition, and the licensor will not be
108
+ liable to you for any damages arising out of these terms or
109
+ the use or nature of the software, under any kind of legal
110
+ claim.
111
+
112
+ ## Definitions
113
+
114
+ The **licensor** is the individual or entity offering these
115
+ terms, and the **software** is the software the licensor
116
+ makes available under these terms.
117
+
118
+ **You** refers to the individual or entity agreeing to these
119
+ terms.
120
+
121
+ **Your company** is any legal entity, sole proprietorship,
122
+ or other kind of organization that you work for, plus all
123
+ organizations that have control over, are under the control
124
+ of, or are under common control with that organization.
125
+ Control means ownership of substantially all the assets of
126
+ an entity, or the power to direct its management and policies
127
+ by vote, contract, or otherwise. Control can be direct or
128
+ indirect.
129
+
130
+ **Your licenses** are all the licenses granted to you for
131
+ the software under these terms.
132
+
133
+ **Use** means anything you do with the software requiring
134
+ one of your licenses.