@strategicnerds/slide-nerds 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 (101) hide show
  1. package/dist/cli/commands/analytics.d.ts +6 -0
  2. package/dist/cli/commands/analytics.d.ts.map +1 -0
  3. package/dist/cli/commands/analytics.js +44 -0
  4. package/dist/cli/commands/analytics.js.map +1 -0
  5. package/dist/cli/commands/create.d.ts +4 -0
  6. package/dist/cli/commands/create.d.ts.map +1 -0
  7. package/dist/cli/commands/create.js +87 -0
  8. package/dist/cli/commands/create.js.map +1 -0
  9. package/dist/cli/commands/export.d.ts +6 -0
  10. package/dist/cli/commands/export.d.ts.map +1 -0
  11. package/dist/cli/commands/export.js +109 -0
  12. package/dist/cli/commands/export.js.map +1 -0
  13. package/dist/cli/index.d.ts +3 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +12 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/cli/template-path.d.ts +4 -0
  18. package/dist/cli/template-path.d.ts.map +1 -0
  19. package/dist/cli/template-path.js +13 -0
  20. package/dist/cli/template-path.js.map +1 -0
  21. package/dist/runtime/export-api.d.ts +15 -0
  22. package/dist/runtime/export-api.d.ts.map +1 -0
  23. package/dist/runtime/export-api.js +21 -0
  24. package/dist/runtime/export-api.js.map +1 -0
  25. package/dist/runtime/index.d.ts +12 -0
  26. package/dist/runtime/index.d.ts.map +1 -0
  27. package/dist/runtime/index.js +8 -0
  28. package/dist/runtime/index.js.map +1 -0
  29. package/dist/runtime/light-table.d.ts +8 -0
  30. package/dist/runtime/light-table.d.ts.map +1 -0
  31. package/dist/runtime/light-table.js +104 -0
  32. package/dist/runtime/light-table.js.map +1 -0
  33. package/dist/runtime/presenter-view.d.ts +7 -0
  34. package/dist/runtime/presenter-view.d.ts.map +1 -0
  35. package/dist/runtime/presenter-view.js +62 -0
  36. package/dist/runtime/presenter-view.js.map +1 -0
  37. package/dist/runtime/slide-context.d.ts +16 -0
  38. package/dist/runtime/slide-context.d.ts.map +1 -0
  39. package/dist/runtime/slide-context.js +18 -0
  40. package/dist/runtime/slide-context.js.map +1 -0
  41. package/dist/runtime/slide-controls.d.ts +3 -0
  42. package/dist/runtime/slide-controls.d.ts.map +1 -0
  43. package/dist/runtime/slide-controls.js +177 -0
  44. package/dist/runtime/slide-controls.js.map +1 -0
  45. package/dist/runtime/slide-dom.d.ts +17 -0
  46. package/dist/runtime/slide-dom.d.ts.map +1 -0
  47. package/dist/runtime/slide-dom.js +89 -0
  48. package/dist/runtime/slide-dom.js.map +1 -0
  49. package/dist/runtime/slide-runtime.d.ts +7 -0
  50. package/dist/runtime/slide-runtime.d.ts.map +1 -0
  51. package/dist/runtime/slide-runtime.js +125 -0
  52. package/dist/runtime/slide-runtime.js.map +1 -0
  53. package/dist/runtime/slide-shape.d.ts +21 -0
  54. package/dist/runtime/slide-shape.d.ts.map +1 -0
  55. package/dist/runtime/slide-shape.js +115 -0
  56. package/dist/runtime/slide-shape.js.map +1 -0
  57. package/dist/runtime/types.d.ts +150 -0
  58. package/dist/runtime/types.d.ts.map +1 -0
  59. package/dist/runtime/types.js +38 -0
  60. package/dist/runtime/types.js.map +1 -0
  61. package/dist/runtime/use-presenter-mode.d.ts +14 -0
  62. package/dist/runtime/use-presenter-mode.d.ts.map +1 -0
  63. package/dist/runtime/use-presenter-mode.js +52 -0
  64. package/dist/runtime/use-presenter-mode.js.map +1 -0
  65. package/dist/runtime/use-slide-navigation.d.ts +13 -0
  66. package/dist/runtime/use-slide-navigation.d.ts.map +1 -0
  67. package/dist/runtime/use-slide-navigation.js +230 -0
  68. package/dist/runtime/use-slide-navigation.js.map +1 -0
  69. package/package.json +64 -0
  70. package/skills/accessibility/SKILL.md +236 -0
  71. package/skills/advanced-layouts/SKILL.md +429 -0
  72. package/skills/analytics/SKILL.md +97 -0
  73. package/skills/animation/SKILL.md +364 -0
  74. package/skills/brand/SKILL.md +200 -0
  75. package/skills/data-visualization/SKILL.md +533 -0
  76. package/skills/deck-templates/SKILL.md +93 -0
  77. package/skills/diagrams/SKILL.md +395 -0
  78. package/skills/export/SKILL.md +119 -0
  79. package/skills/interactive/SKILL.md +292 -0
  80. package/skills/layout/SKILL.md +178 -0
  81. package/skills/narrative-frameworks/SKILL.md +250 -0
  82. package/skills/react-component-embeds/SKILL.md +73 -0
  83. package/skills/slide-types/SKILL.md +384 -0
  84. package/skills/slidenerds-runtime/SKILL.md +163 -0
  85. package/skills/speaker-notes/SKILL.md +128 -0
  86. package/skills/strategic-frameworks/SKILL.md +392 -0
  87. package/skills/visual-design/SKILL.md +373 -0
  88. package/templates/analytics/custom.tsx.tmpl +20 -0
  89. package/templates/analytics/ga4.tsx.tmpl +15 -0
  90. package/templates/analytics/gtm.tsx.tmpl +9 -0
  91. package/templates/analytics/plausible.tsx.tmpl +10 -0
  92. package/templates/analytics/posthog.tsx.tmpl +14 -0
  93. package/templates/next-app/CLAUDE.md.tmpl +574 -0
  94. package/templates/next-app/README.md.tmpl +35 -0
  95. package/templates/next-app/app/globals.css.tmpl +274 -0
  96. package/templates/next-app/app/layout.tsx.tmpl +31 -0
  97. package/templates/next-app/app/page.tsx.tmpl +38 -0
  98. package/templates/next-app/brand.config.ts.tmpl +32 -0
  99. package/templates/next-app/package.json.tmpl +25 -0
  100. package/templates/next-app/postcss.config.mjs.tmpl +8 -0
  101. package/templates/next-app/tsconfig.json.tmpl +21 -0
@@ -0,0 +1,429 @@
1
+ ---
2
+ name: advanced-layouts
3
+ description: Dashboard, comparison, logo wall, icon grid, before/after, agenda, and other composite slide layouts
4
+ ---
5
+
6
+ # Advanced layouts skill
7
+
8
+ Use this skill for slides that combine multiple content types or need specialized arrangements beyond basic grids. Each pattern here is a complete slide recipe.
9
+
10
+ ## Dashboard slide
11
+
12
+ Use for: board decks, QBRs, metrics reviews. Shows 4-6 KPIs on one slide.
13
+
14
+ ```tsx
15
+ <section data-slide="">
16
+ <div className="flex flex-col w-full"
17
+ style={{ padding: '4rem 6rem' }}>
18
+ <p className="section-label mb-3">Performance</p>
19
+ <h2 className="text-[2.5rem] font-bold mb-4">Q1 dashboard</h2>
20
+ <div className="flex-1 flex items-center justify-center">
21
+ <div className="grid grid-cols-3 gap-4 w-full">
22
+ {[
23
+ { label: 'ARR', value: '$4.2M', delta: '+142%', up: true },
24
+ { label: 'MRR', value: '$350K', delta: '+12%', up: true },
25
+ { label: 'Churn', value: '2.1%', delta: '-0.3%', up: false },
26
+ { label: 'NPS', value: '72', delta: '+8', up: true },
27
+ { label: 'CAC', value: '$148', delta: '-22%', up: false },
28
+ { label: 'LTV:CAC', value: '5.2x', delta: '+0.8', up: true },
29
+ ].map((metric) => (
30
+ <div key={metric.label} data-step="" className="step-fade card-surface p-5">
31
+ <p className="text-xs font-semibold tracking-[0.15em] uppercase"
32
+ style={{ color: 'var(--color-text-tertiary)' }}>{metric.label}</p>
33
+ <p className="text-3xl font-bold mt-2"
34
+ style={{ fontFamily: 'var(--font-heading)' }}>{metric.value}</p>
35
+ <p className="text-sm mt-1"
36
+ style={{ color: metric.up ? '#22c55e' : 'var(--color-accent)' }}>
37
+ {metric.delta}
38
+ </p>
39
+ </div>
40
+ ))}
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </section>
45
+ ```
46
+
47
+ ### Dashboard rules
48
+
49
+ - 6 metrics maximum per slide. More is noise.
50
+ - Use a 3x2 or 2x3 grid. Never 1x6 or 6x1.
51
+ - Each card shows: label (small, uppercase, muted), value (large, bold), delta (small, colored green/red).
52
+ - All cards same height. Use `card-surface` for visual containment.
53
+ - Reveal cards progressively with `data-step` for presentation pacing.
54
+
55
+ ## KPI card with sparkline
56
+
57
+ For dashboard slides that need trend context, pair the number with a tiny chart:
58
+
59
+ ```tsx
60
+ <div className="card-surface p-5 flex items-end justify-between">
61
+ <div>
62
+ <p className="text-xs font-semibold tracking-[0.15em] uppercase"
63
+ style={{ color: 'var(--color-text-tertiary)' }}>Revenue</p>
64
+ <p className="text-3xl font-bold mt-2">$4.2M</p>
65
+ <p className="text-sm mt-1" style={{ color: '#22c55e' }}>+142%</p>
66
+ </div>
67
+ <ResponsiveContainer width={80} height={40}>
68
+ <LineChart data={sparkData}>
69
+ <Line type="monotone" dataKey="v" stroke="var(--color-accent)"
70
+ strokeWidth={1.5} dot={false} />
71
+ </LineChart>
72
+ </ResponsiveContainer>
73
+ </div>
74
+ ```
75
+
76
+ ## Three-option comparison
77
+
78
+ Use for: pricing tiers, plan selection, product editions. The center option is visually highlighted.
79
+
80
+ ```tsx
81
+ <section data-slide="">
82
+ <div className="flex flex-col justify-center items-center w-full min-h-screen"
83
+ style={{ padding: '4rem 6rem' }}>
84
+ <h2 className="text-[2.5rem] font-bold mb-12">Pricing</h2>
85
+ <div className="grid grid-cols-3 gap-6" style={{ maxWidth: 900 }}>
86
+ {[
87
+ { name: 'Starter', price: '$29', features: ['5 users', '10GB storage', 'Email support'], highlighted: false },
88
+ { name: 'Pro', price: '$99', features: ['25 users', '100GB storage', 'Priority support', 'API access'], highlighted: true },
89
+ { name: 'Enterprise', price: 'Custom', features: ['Unlimited users', '1TB storage', 'Dedicated support', 'SSO', 'SLA'], highlighted: false },
90
+ ].map((tier) => (
91
+ <div key={tier.name} data-step="" className="step-move-up"
92
+ style={{
93
+ background: tier.highlighted ? 'var(--color-surface)' : 'transparent',
94
+ border: tier.highlighted ? '2px solid var(--color-accent)' : '1px solid var(--color-border)',
95
+ borderRadius: 14,
96
+ padding: '2rem',
97
+ position: 'relative',
98
+ }}>
99
+ {tier.highlighted && (
100
+ <span className="absolute -top-3 left-1/2 -translate-x-1/2 px-3 py-0.5 rounded-full text-xs font-semibold"
101
+ style={{ background: 'var(--color-accent)', color: 'var(--color-primary)' }}>
102
+ Most popular
103
+ </span>
104
+ )}
105
+ <p className="text-sm font-semibold" style={{ color: 'var(--color-text-tertiary)' }}>{tier.name}</p>
106
+ <p className="text-4xl font-bold mt-2" style={{ fontFamily: 'var(--font-heading)' }}>{tier.price}</p>
107
+ <p className="text-xs mt-1" style={{ color: 'var(--color-text-tertiary)' }}>per month</p>
108
+ <ul className="mt-6 space-y-2">
109
+ {tier.features.map((f) => (
110
+ <li key={f} className="text-sm flex items-center gap-2">
111
+ <span style={{ color: 'var(--color-accent)' }}>&#10003;</span> {f}
112
+ </li>
113
+ ))}
114
+ </ul>
115
+ </div>
116
+ ))}
117
+ </div>
118
+ </div>
119
+ </section>
120
+ ```
121
+
122
+ ### Comparison rules
123
+
124
+ - Always highlight one option (usually the middle one).
125
+ - Use a "Most popular" or "Recommended" badge on the highlighted option.
126
+ - Features list grows top to bottom. Higher tiers include all lower-tier features.
127
+ - Use checkmarks or dots for feature lists, not bullets.
128
+
129
+ ## Before / after split
130
+
131
+ Use for: transformations, product impact, process improvement.
132
+
133
+ ```tsx
134
+ <section data-slide="">
135
+ <div className="grid grid-cols-2 w-full min-h-screen">
136
+ <div className="flex flex-col justify-center"
137
+ style={{ padding: '4rem', background: 'var(--color-primary)' }}>
138
+ <p className="text-xs font-semibold tracking-[0.2em] uppercase mb-4"
139
+ style={{ color: 'var(--color-text-tertiary)' }}>Before</p>
140
+ <h3 className="text-2xl font-bold mb-6">Manual deploys</h3>
141
+ <ul className="space-y-3 text-base" style={{ color: 'var(--color-text-secondary)' }}>
142
+ <li>2-4 week deployment cycles</li>
143
+ <li>3 engineers on deploy duty</li>
144
+ <li>Frequent rollbacks</li>
145
+ </ul>
146
+ </div>
147
+ <div className="flex flex-col justify-center"
148
+ style={{ padding: '4rem', background: 'var(--color-surface)' }}>
149
+ <p className="text-xs font-semibold tracking-[0.2em] uppercase mb-4"
150
+ style={{ color: 'var(--color-accent)' }}>After</p>
151
+ <h3 className="text-2xl font-bold mb-6">Acme CI/CD</h3>
152
+ <ul className="space-y-3 text-base">
153
+ <li>5-minute deploys</li>
154
+ <li>Zero deploy duty</li>
155
+ <li>Automatic canary releases</li>
156
+ </ul>
157
+ </div>
158
+ </div>
159
+ </section>
160
+ ```
161
+
162
+ ### Before/after rules
163
+
164
+ - Use a clear visual divider (background color change or vertical line).
165
+ - "Before" is muted (darker background, secondary text color).
166
+ - "After" is brighter (surface background, primary text, accent label).
167
+ - Keep content parallel (same number of points on each side).
168
+
169
+ ## Icon + text grid
170
+
171
+ Use for: features, benefits, capabilities, service offerings.
172
+
173
+ ```tsx
174
+ <section data-slide="">
175
+ <div className="flex flex-col justify-center w-full min-h-screen"
176
+ style={{ padding: '4rem 6rem' }}>
177
+ <p className="section-label mb-3">Platform</p>
178
+ <h2 className="text-[2.5rem] font-bold mb-12">Key capabilities</h2>
179
+ <div className="grid grid-cols-3 gap-10">
180
+ {[
181
+ { icon: 'hexagon', label: 'Auto-scaling', desc: 'Scale from 0 to 10M requests with zero config' },
182
+ { icon: 'diamond', label: 'Edge network', desc: '42 global regions, sub-20ms latency worldwide' },
183
+ { icon: 'star', label: 'Security', desc: 'SOC 2 Type II, HIPAA, and GDPR compliant' },
184
+ { icon: 'plus', label: 'Integrations', desc: '200+ native integrations with your existing stack' },
185
+ { icon: 'circle', label: 'Observability', desc: 'Built-in metrics, logs, and distributed tracing' },
186
+ { icon: 'rounded-square', label: 'Support', desc: '99.99% SLA with dedicated account management' },
187
+ ].map((item) => (
188
+ <div key={item.label} data-step="" className="step-move-up flex gap-4">
189
+ <SlideShape shape={item.icon as any} size={48}
190
+ fill="var(--color-accent-dim)" stroke="var(--color-accent)" strokeWidth={1} />
191
+ <div>
192
+ <p className="font-semibold text-sm">{item.label}</p>
193
+ <p className="text-xs mt-1" style={{ color: 'var(--color-text-secondary)' }}>{item.desc}</p>
194
+ </div>
195
+ </div>
196
+ ))}
197
+ </div>
198
+ </div>
199
+ </section>
200
+ ```
201
+
202
+ ### Icon grid rules
203
+
204
+ - 6 items maximum (3x2 grid).
205
+ - Each item: shape icon + label + one-line description.
206
+ - Shape icons should use the accent color at low opacity for fill, accent for stroke.
207
+ - All items reveal progressively with `data-step`.
208
+
209
+ ## Logo wall
210
+
211
+ Use for: customer logos, partner logos, technology stack, integration partners.
212
+
213
+ ```tsx
214
+ <section data-slide="">
215
+ <div className="flex flex-col justify-center items-center w-full min-h-screen"
216
+ style={{ padding: '4rem 6rem' }}>
217
+ <p className="section-label mb-3">Customers</p>
218
+ <h2 className="text-[2.5rem] font-bold mb-14">Trusted by industry leaders</h2>
219
+ <div className="grid grid-cols-4 gap-8 items-center justify-items-center"
220
+ style={{ maxWidth: 800, opacity: 0.6 }}>
221
+ {/* Replace with actual logo images */}
222
+ {['TechCorp', 'DataFlow', 'CloudBase', 'NetScale',
223
+ 'AppForge', 'SyncLabs', 'DevStack', 'InfraHub'].map((name) => (
224
+ <div key={name} className="card-surface px-6 py-4 text-center w-full">
225
+ <p className="text-sm font-semibold" style={{ color: 'var(--color-text-secondary)' }}>{name}</p>
226
+ </div>
227
+ ))}
228
+ </div>
229
+ </div>
230
+ </section>
231
+ ```
232
+
233
+ ### Logo wall rules
234
+
235
+ - 8-12 logos maximum. More dilutes the signal.
236
+ - All logos same size container (use `w-full` within grid cells).
237
+ - Reduce opacity to 50-70% so logos don't compete with content.
238
+ - Use `filter: brightness(0) invert(1)` on dark backgrounds to convert colored logos to white.
239
+ - 4 columns for 8 logos, 5 columns for 10-15 logos.
240
+
241
+ ## Numbered list with descriptions
242
+
243
+ Use for: pillars, principles, steps, priorities.
244
+
245
+ ```tsx
246
+ <section data-slide="">
247
+ <div className="flex flex-col justify-center w-full min-h-screen"
248
+ style={{ padding: '4rem 6rem' }}>
249
+ <p className="section-label mb-3">Strategy</p>
250
+ <h2 className="text-[2.5rem] font-bold mb-12">Three pillars</h2>
251
+ <div className="space-y-8" style={{ maxWidth: 700 }}>
252
+ {[
253
+ { n: '01', title: 'Product-led growth', desc: 'Self-serve onboarding that converts without sales intervention.' },
254
+ { n: '02', title: 'Enterprise expansion', desc: 'Land-and-expand motion targeting Fortune 500 accounts.' },
255
+ { n: '03', title: 'Platform ecosystem', desc: 'Marketplace of integrations that increases switching costs.' },
256
+ ].map((item) => (
257
+ <div key={item.n} data-step="" className="step-move-up flex gap-6 items-start">
258
+ <span className="text-3xl font-extrabold"
259
+ style={{ color: 'var(--color-accent)', fontFamily: 'var(--font-heading)', opacity: 0.3, minWidth: 60 }}>
260
+ {item.n}
261
+ </span>
262
+ <div>
263
+ <p className="text-lg font-semibold">{item.title}</p>
264
+ <p className="text-sm mt-1" style={{ color: 'var(--color-text-secondary)' }}>{item.desc}</p>
265
+ </div>
266
+ </div>
267
+ ))}
268
+ </div>
269
+ </div>
270
+ </section>
271
+ ```
272
+
273
+ ## Agenda / table of contents
274
+
275
+ Use for: opening of a long presentation, section navigation.
276
+
277
+ ```tsx
278
+ <section data-slide="">
279
+ <div className="flex flex-col justify-center w-full min-h-screen"
280
+ style={{ padding: '4rem 6rem' }}>
281
+ <h2 className="text-[2.5rem] font-bold mb-14">Agenda</h2>
282
+ <div className="space-y-4" style={{ maxWidth: 600 }}>
283
+ {[
284
+ { n: '01', title: 'Financial performance', time: '5 min' },
285
+ { n: '02', title: 'Product update', time: '5 min' },
286
+ { n: '03', title: 'Growth metrics', time: '5 min' },
287
+ { n: '04', title: 'Roadmap', time: '3 min' },
288
+ { n: '05', title: 'Discussion', time: '10 min' },
289
+ ].map((item) => (
290
+ <div key={item.n} data-step="" className="step-fade
291
+ flex items-center justify-between py-3"
292
+ style={{ borderBottom: '1px solid var(--color-border)' }}>
293
+ <div className="flex items-center gap-4">
294
+ <span className="text-sm font-semibold"
295
+ style={{ color: 'var(--color-accent)', minWidth: 30 }}>{item.n}</span>
296
+ <span className="text-lg">{item.title}</span>
297
+ </div>
298
+ <span className="text-xs" style={{ color: 'var(--color-text-tertiary)' }}>{item.time}</span>
299
+ </div>
300
+ ))}
301
+ </div>
302
+ </div>
303
+ </section>
304
+ ```
305
+
306
+ ## Photo grid / mosaic
307
+
308
+ Use for: culture slides, product screenshots, event photography.
309
+
310
+ ```tsx
311
+ <section data-slide="">
312
+ <div className="grid grid-cols-3 gap-1 w-full min-h-screen">
313
+ {[1, 2, 3, 4, 5, 6].map((i) => (
314
+ <div key={i} className="relative overflow-hidden">
315
+ <img src={`/photos/${i}.jpg`} alt=""
316
+ className="w-full h-full object-cover" />
317
+ </div>
318
+ ))}
319
+ </div>
320
+ </section>
321
+ ```
322
+
323
+ ### Photo grid rules
324
+
325
+ - 4-9 photos. More becomes chaotic.
326
+ - Use `gap-1` for tight mosaic or `gap-2` for breathing room.
327
+ - All images use `object-cover` for consistent sizing.
328
+ - No text overlays on photo grids (put the caption on a separate slide).
329
+
330
+ ## Quote + supporting data
331
+
332
+ Use for: combining a testimonial with the data that backs it up.
333
+
334
+ ```tsx
335
+ <section data-slide="">
336
+ <div className="grid grid-cols-12 gap-8 items-center w-full min-h-screen"
337
+ style={{ padding: '4rem 6rem' }}>
338
+ <div className="col-span-5">
339
+ <div className="text-4xl mb-4" style={{ color: 'var(--color-accent)', opacity: 0.2 }}>&ldquo;</div>
340
+ <blockquote className="text-xl font-light leading-relaxed"
341
+ style={{ fontFamily: 'var(--font-heading)' }}>
342
+ Deployment time dropped from weeks to minutes.
343
+ </blockquote>
344
+ <div className="mt-6">
345
+ <p className="text-sm font-semibold">Sarah Chen</p>
346
+ <p className="text-xs" style={{ color: 'var(--color-text-tertiary)' }}>VP Eng, TechCorp</p>
347
+ </div>
348
+ </div>
349
+ <div className="col-span-7">
350
+ <div className="card-surface p-6">
351
+ {/* Chart showing the improvement */}
352
+ </div>
353
+ </div>
354
+ </div>
355
+ </section>
356
+ ```
357
+
358
+ ### Quote + data rules
359
+
360
+ - Asymmetric split: 5 columns for quote, 7 for data.
361
+ - Quote is text-only. Data side has a chart or stat in a card surface.
362
+ - The quote and data must tell the same story.
363
+
364
+ ## Appendix slide
365
+
366
+ Use for: detailed reference data not meant for live presenting.
367
+
368
+ Appendix slides relax the normal density rules:
369
+ - Font floor drops to 14pt (from 16pt).
370
+ - Whitespace ratio drops to 30% (from 40-60%).
371
+ - Multiple charts or tables per slide are acceptable.
372
+ - Mark clearly with "Appendix" section label.
373
+
374
+ ```tsx
375
+ <section data-slide="">
376
+ <div className="flex flex-col w-full min-h-screen"
377
+ style={{ padding: '2.5rem 4rem' }}>
378
+ <div className="flex items-center justify-between mb-6">
379
+ <div>
380
+ <p className="section-label mb-1">Appendix</p>
381
+ <h2 className="text-xl font-bold">Detailed financials</h2>
382
+ </div>
383
+ <p className="text-xs" style={{ color: 'var(--color-text-tertiary)' }}>Reference only</p>
384
+ </div>
385
+ {/* Dense content: tables, charts, small text */}
386
+ </div>
387
+ </section>
388
+ ```
389
+
390
+ ## Progress tracker
391
+
392
+ Use for: showing "you are here" in a multi-section presentation.
393
+
394
+ ```tsx
395
+ <div className="flex items-center gap-2 mb-12">
396
+ {['Financials', 'Product', 'Growth', 'Roadmap', 'Q&A'].map((section, i) => (
397
+ <React.Fragment key={section}>
398
+ {i > 0 && <div className="w-8 h-px" style={{ background: 'var(--color-border)' }} />}
399
+ <span className={`text-xs font-semibold px-3 py-1 rounded-full ${
400
+ i === currentSection
401
+ ? ''
402
+ : ''
403
+ }`}
404
+ style={{
405
+ background: i === currentSection ? 'var(--color-accent-dim)' : 'transparent',
406
+ color: i === currentSection ? 'var(--color-accent)' : 'var(--color-text-tertiary)',
407
+ }}>
408
+ {section}
409
+ </span>
410
+ </React.Fragment>
411
+ ))}
412
+ </div>
413
+ ```
414
+
415
+ ## Layout selection guide
416
+
417
+ | Need | Layout | Key property |
418
+ |---|---|---|
419
+ | Multiple KPIs | Dashboard (3x2 grid) | Top-left title + centered `grid grid-cols-3` |
420
+ | Pricing / plan options | Three-option comparison | Center card highlighted |
421
+ | Transformation story | Before/after split | `grid grid-cols-2`, different backgrounds |
422
+ | Features / capabilities | Icon + text grid (3x2) | Shape icon + label + description |
423
+ | Social proof | Logo wall (4x2) | Reduced opacity, uniform sizing |
424
+ | Strategic priorities | Numbered list | Large faded number + text |
425
+ | Session overview | Agenda / TOC | Numbered rows with time |
426
+ | Culture / portfolio | Photo grid | `gap-1`, `object-cover` |
427
+ | Testimonial + proof | Quote + data (5:7) | Asymmetric columns |
428
+ | Reference material | Appendix | Relaxed density rules |
429
+ | Navigation aid | Progress tracker | Horizontal pill indicators |
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: analytics
3
+ description: How to add and configure analytics providers in slidenerds decks
4
+ ---
5
+
6
+ # Analytics skill
7
+
8
+ How to add analytics to a slidenerds deck. Each provider has a pre-built component the CLI generates.
9
+
10
+ ## Adding analytics via CLI
11
+
12
+ The fastest way to add analytics:
13
+
14
+ ```bash
15
+ npx slidenerds analytics --gtm GTM-XXXXXX
16
+ npx slidenerds analytics --ga4 G-XXXXXXXXXX
17
+ npx slidenerds analytics --posthog phc_XXXXXXXXXX
18
+ npx slidenerds analytics --plausible yourdomain.com
19
+ npx slidenerds analytics --custom
20
+ ```
21
+
22
+ Each command creates a component in `components/` with the provider ID wired in. Import it in your root layout to activate.
23
+
24
+ ## Component placement
25
+
26
+ Analytics components go in the root layout, inside the `<body>` tag:
27
+
28
+ ```tsx
29
+ import { SlideRuntime } from '@slidenerds/runtime'
30
+ import { GTMAnalytics } from '@/components/gtm-analytics'
31
+
32
+ export default function RootLayout({ children }) {
33
+ return (
34
+ <html lang="en">
35
+ <body>
36
+ <GTMAnalytics />
37
+ <SlideRuntime>{children}</SlideRuntime>
38
+ </body>
39
+ </html>
40
+ )
41
+ }
42
+ ```
43
+
44
+ ## Provider details
45
+
46
+ ### Google Tag Manager (GTM)
47
+
48
+ - ID format: `GTM-XXXXXX`
49
+ - Loads the GTM container script
50
+ - All tracking is configured inside GTM itself
51
+
52
+ ### Google Analytics 4 (GA4)
53
+
54
+ - ID format: `G-XXXXXXXXXX`
55
+ - Loads the gtag.js script and initializes with the measurement ID
56
+ - Automatic page view tracking
57
+
58
+ ### PostHog
59
+
60
+ - ID format: `phc_XXXXXXXXXX`
61
+ - Loads the PostHog array.js script
62
+ - Initializes with the project API key
63
+ - Captures page views and session recordings by default
64
+
65
+ ### Plausible
66
+
67
+ - Domain format: `yourdomain.com`
68
+ - Loads the Plausible script with your domain
69
+ - Privacy-friendly, no cookie consent needed
70
+ - Automatic page view tracking
71
+
72
+ ### Custom
73
+
74
+ - Creates a blank component with comments for manual wiring
75
+ - Use this for any provider not listed above
76
+
77
+ ## Verifying the integration
78
+
79
+ After adding analytics:
80
+
81
+ 1. Run `npm run dev`
82
+ 2. Open the browser developer tools (Network tab)
83
+ 3. Look for requests to the analytics provider's domain:
84
+ - GTM: `googletagmanager.com`
85
+ - GA4: `google-analytics.com`
86
+ - PostHog: `app.posthog.com`
87
+ - Plausible: `plausible.io`
88
+ 4. Check the Console tab for any loading errors
89
+
90
+ ## Platform analytics vs. first-party analytics
91
+
92
+ Slidenerds platform analytics (from slidenerds.com) and first-party analytics (GTM, GA4, etc.) coexist. They measure different things:
93
+
94
+ - **Platform analytics**: How decks perform across audiences (views, completion rate, slide dwell time). Opt-in when connecting a deck to slidenerds.com.
95
+ - **First-party analytics**: Whatever you were already tracking. Page views, user behavior, conversions.
96
+
97
+ Both run independently and don't interfere with each other.