@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.
- package/dist/cli/commands/analytics.d.ts +6 -0
- package/dist/cli/commands/analytics.d.ts.map +1 -0
- package/dist/cli/commands/analytics.js +44 -0
- package/dist/cli/commands/analytics.js.map +1 -0
- package/dist/cli/commands/create.d.ts +4 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +87 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/export.d.ts +6 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +109 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +12 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/template-path.d.ts +4 -0
- package/dist/cli/template-path.d.ts.map +1 -0
- package/dist/cli/template-path.js +13 -0
- package/dist/cli/template-path.js.map +1 -0
- package/dist/runtime/export-api.d.ts +15 -0
- package/dist/runtime/export-api.d.ts.map +1 -0
- package/dist/runtime/export-api.js +21 -0
- package/dist/runtime/export-api.js.map +1 -0
- package/dist/runtime/index.d.ts +12 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/light-table.d.ts +8 -0
- package/dist/runtime/light-table.d.ts.map +1 -0
- package/dist/runtime/light-table.js +104 -0
- package/dist/runtime/light-table.js.map +1 -0
- package/dist/runtime/presenter-view.d.ts +7 -0
- package/dist/runtime/presenter-view.d.ts.map +1 -0
- package/dist/runtime/presenter-view.js +62 -0
- package/dist/runtime/presenter-view.js.map +1 -0
- package/dist/runtime/slide-context.d.ts +16 -0
- package/dist/runtime/slide-context.d.ts.map +1 -0
- package/dist/runtime/slide-context.js +18 -0
- package/dist/runtime/slide-context.js.map +1 -0
- package/dist/runtime/slide-controls.d.ts +3 -0
- package/dist/runtime/slide-controls.d.ts.map +1 -0
- package/dist/runtime/slide-controls.js +177 -0
- package/dist/runtime/slide-controls.js.map +1 -0
- package/dist/runtime/slide-dom.d.ts +17 -0
- package/dist/runtime/slide-dom.d.ts.map +1 -0
- package/dist/runtime/slide-dom.js +89 -0
- package/dist/runtime/slide-dom.js.map +1 -0
- package/dist/runtime/slide-runtime.d.ts +7 -0
- package/dist/runtime/slide-runtime.d.ts.map +1 -0
- package/dist/runtime/slide-runtime.js +125 -0
- package/dist/runtime/slide-runtime.js.map +1 -0
- package/dist/runtime/slide-shape.d.ts +21 -0
- package/dist/runtime/slide-shape.d.ts.map +1 -0
- package/dist/runtime/slide-shape.js +115 -0
- package/dist/runtime/slide-shape.js.map +1 -0
- package/dist/runtime/types.d.ts +150 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +38 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/use-presenter-mode.d.ts +14 -0
- package/dist/runtime/use-presenter-mode.d.ts.map +1 -0
- package/dist/runtime/use-presenter-mode.js +52 -0
- package/dist/runtime/use-presenter-mode.js.map +1 -0
- package/dist/runtime/use-slide-navigation.d.ts +13 -0
- package/dist/runtime/use-slide-navigation.d.ts.map +1 -0
- package/dist/runtime/use-slide-navigation.js +230 -0
- package/dist/runtime/use-slide-navigation.js.map +1 -0
- package/package.json +64 -0
- package/skills/accessibility/SKILL.md +236 -0
- package/skills/advanced-layouts/SKILL.md +429 -0
- package/skills/analytics/SKILL.md +97 -0
- package/skills/animation/SKILL.md +364 -0
- package/skills/brand/SKILL.md +200 -0
- package/skills/data-visualization/SKILL.md +533 -0
- package/skills/deck-templates/SKILL.md +93 -0
- package/skills/diagrams/SKILL.md +395 -0
- package/skills/export/SKILL.md +119 -0
- package/skills/interactive/SKILL.md +292 -0
- package/skills/layout/SKILL.md +178 -0
- package/skills/narrative-frameworks/SKILL.md +250 -0
- package/skills/react-component-embeds/SKILL.md +73 -0
- package/skills/slide-types/SKILL.md +384 -0
- package/skills/slidenerds-runtime/SKILL.md +163 -0
- package/skills/speaker-notes/SKILL.md +128 -0
- package/skills/strategic-frameworks/SKILL.md +392 -0
- package/skills/visual-design/SKILL.md +373 -0
- package/templates/analytics/custom.tsx.tmpl +20 -0
- package/templates/analytics/ga4.tsx.tmpl +15 -0
- package/templates/analytics/gtm.tsx.tmpl +9 -0
- package/templates/analytics/plausible.tsx.tmpl +10 -0
- package/templates/analytics/posthog.tsx.tmpl +14 -0
- package/templates/next-app/CLAUDE.md.tmpl +574 -0
- package/templates/next-app/README.md.tmpl +35 -0
- package/templates/next-app/app/globals.css.tmpl +274 -0
- package/templates/next-app/app/layout.tsx.tmpl +31 -0
- package/templates/next-app/app/page.tsx.tmpl +38 -0
- package/templates/next-app/brand.config.ts.tmpl +32 -0
- package/templates/next-app/package.json.tmpl +25 -0
- package/templates/next-app/postcss.config.mjs.tmpl +8 -0
- package/templates/next-app/tsconfig.json.tmpl +21 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: visual-design
|
|
3
|
+
description: Layout, spacing, typography scale, and compositional rules for polished slidenerds slides
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Visual design skill
|
|
7
|
+
|
|
8
|
+
Use this skill whenever building or reviewing slide content. These rules govern layout, spacing, composition, and visual hierarchy. They are independent of color palette and font choice -- users bring their own brand tokens. This skill governs how those tokens are applied spatially.
|
|
9
|
+
|
|
10
|
+
## Canvas and safe zones
|
|
11
|
+
|
|
12
|
+
The canvas is 16:9 (1920x1080 logical pixels). All content must respect two boundaries:
|
|
13
|
+
|
|
14
|
+
- **Action safe**: 3.5% inset from each edge. No content outside this boundary.
|
|
15
|
+
- **Title safe**: 5% inset from each edge. All readable text must stay inside this boundary.
|
|
16
|
+
|
|
17
|
+
For slidenerds, `--slide-padding` controls the outer margin. Set it to 5-8% of the smaller dimension. On a 1080-tall canvas, that is 54-86px, which maps to `3.5rem` to `5.5rem`. The default is `5rem`.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
+-------------------------------------------+
|
|
21
|
+
| 3.5% action safe |
|
|
22
|
+
| +-------------------------------------+ |
|
|
23
|
+
| | 5% title safe | |
|
|
24
|
+
| | | |
|
|
25
|
+
| | Content lives here | |
|
|
26
|
+
| | | |
|
|
27
|
+
| +-------------------------------------+ |
|
|
28
|
+
+-------------------------------------------+
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## The default layout is top-left anchored
|
|
32
|
+
|
|
33
|
+
This is the most important layout rule. The majority of slides in any professional deck anchor content to the top-left corner, with the title at a fixed position and content flowing downward. The bottom portion of the slide is breathing room.
|
|
34
|
+
|
|
35
|
+
**Do NOT vertically center content on most slides.** Vertically centered content is only appropriate for these specific slide types:
|
|
36
|
+
|
|
37
|
+
- **Big stat**: A single number that dominates the slide
|
|
38
|
+
- **Section divider**: A section name between major parts of the deck
|
|
39
|
+
- **Quote**: A blockquote with attribution
|
|
40
|
+
- **Closing**: Contact info or "Questions?"
|
|
41
|
+
|
|
42
|
+
Every other slide type -- charts, tables, text, timelines, dashboards, diagrams, team slides, process flows, comparisons, icon grids -- uses top-left anchored layout. The title starts near the top of the slide at a consistent Y position across all content slides. This consistency is what makes a deck feel like a designed system rather than a collection of individual slides.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
WRONG (everything centered -- looks like a default template):
|
|
46
|
+
+-------------------------------------------+
|
|
47
|
+
| |
|
|
48
|
+
| |
|
|
49
|
+
| Title |
|
|
50
|
+
| Content here |
|
|
51
|
+
| |
|
|
52
|
+
| |
|
|
53
|
+
+-------------------------------------------+
|
|
54
|
+
|
|
55
|
+
RIGHT for text/bullets/tables (anchored below title):
|
|
56
|
+
+-------------------------------------------+
|
|
57
|
+
| SECTION LABEL |
|
|
58
|
+
| Title |
|
|
59
|
+
| |
|
|
60
|
+
| - Bullet point one |
|
|
61
|
+
| - Bullet point two |
|
|
62
|
+
| - Bullet point three |
|
|
63
|
+
| |
|
|
64
|
+
| [breathing room] |
|
|
65
|
+
+-------------------------------------------+
|
|
66
|
+
|
|
67
|
+
RIGHT for diagrams/charts/shapes (title top-left, visual centered):
|
|
68
|
+
+-------------------------------------------+
|
|
69
|
+
| SECTION LABEL |
|
|
70
|
+
| Title |
|
|
71
|
+
| |
|
|
72
|
+
| [diagram or chart centered |
|
|
73
|
+
| in the remaining space] |
|
|
74
|
+
| |
|
|
75
|
+
+-------------------------------------------+
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
There are two sub-patterns for top-left anchored slides:
|
|
79
|
+
|
|
80
|
+
1. **Text content** (bullets, numbered lists, tables, KPI grids): Content flows directly below the title, anchored to the left. The bottom is breathing room.
|
|
81
|
+
2. **Visual content** (diagrams, charts, shapes, process flows, icon grids, team avatars): Title stays top-left. The visual centers both horizontally and vertically in the remaining space below the title. Use `flex-1 flex items-center justify-center` on the visual container.
|
|
82
|
+
|
|
83
|
+
## The one-thing rule
|
|
84
|
+
|
|
85
|
+
Each slide communicates exactly one idea. One stat. One chart. One comparison. One quote. The moment a slide tries to say two things, it stops feeling designed and starts feeling assembled.
|
|
86
|
+
|
|
87
|
+
Ask: "What is the single sentence this slide says?" If you need two sentences, make two slides.
|
|
88
|
+
|
|
89
|
+
## Content density limits
|
|
90
|
+
|
|
91
|
+
| Deck style | Max words per slide | Max content chunks | Whitespace ratio |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| Keynote (Apple, Stripe) | 10-30 | 2 | 60-70% |
|
|
94
|
+
| Board / pitch (Sequoia) | 30-50 | 3-4 | 45-55% |
|
|
95
|
+
| Training / educational | 40-75 | 4 | 35-45% |
|
|
96
|
+
|
|
97
|
+
A "content chunk" is a visually distinct group: a text block, a chart, a stat with its label, an image with caption.
|
|
98
|
+
|
|
99
|
+
Never exceed 3 distinct type sizes on one slide: title, body, and detail. A fourth size signals too much content.
|
|
100
|
+
|
|
101
|
+
## Typography scale
|
|
102
|
+
|
|
103
|
+
Use a modular scale ratio to define type sizes. The two ratios that work for presentations:
|
|
104
|
+
|
|
105
|
+
- **Perfect fourth (1.333)**: body 24 > 32 > 42 > 56. Good for content-heavy slides.
|
|
106
|
+
- **Perfect fifth (1.5)**: body 24 > 36 > 54 > 80. Good for keynote moments.
|
|
107
|
+
|
|
108
|
+
Pick one ratio per deck and use it everywhere.
|
|
109
|
+
|
|
110
|
+
### Size floors for projection
|
|
111
|
+
|
|
112
|
+
| Role | Minimum | Recommended |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| Title / hero | 36pt | 56-80pt |
|
|
115
|
+
| Heading (H2) | 28pt | 36-48pt |
|
|
116
|
+
| Body text | 20pt | 24-32pt |
|
|
117
|
+
| Caption / label | 16pt | 18-20pt |
|
|
118
|
+
|
|
119
|
+
Never set text smaller than 16pt. At projection distance, anything below that disappears.
|
|
120
|
+
|
|
121
|
+
### Line height
|
|
122
|
+
|
|
123
|
+
- Titles: `leading-none` to `leading-tight` (1.0-1.15). Tight title spacing is a core differentiator between polished and amateur decks.
|
|
124
|
+
- Body: `leading-relaxed` (1.35-1.5). Open enough for distance reading.
|
|
125
|
+
- Labels and captions: `leading-snug` (1.2-1.3).
|
|
126
|
+
|
|
127
|
+
### Letter spacing
|
|
128
|
+
|
|
129
|
+
Tight negative tracking on headings creates a confident, editorial feel:
|
|
130
|
+
|
|
131
|
+
- Titles: `tracking-tight` (-0.02em)
|
|
132
|
+
- Body: `tracking-normal` (0)
|
|
133
|
+
- Uppercase labels: `tracking-widest` (0.1-0.2em)
|
|
134
|
+
|
|
135
|
+
## Grid system
|
|
136
|
+
|
|
137
|
+
Use a 12-column conceptual grid for horizontal layout. Twelve divides into halves (6+6), thirds (4+4+4), quarters (3+3+3+3), and asymmetric splits.
|
|
138
|
+
|
|
139
|
+
### Column allocations by slide type
|
|
140
|
+
|
|
141
|
+
| Slide type | Layout | Tailwind |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| Title, big stat, quote | Content centered or left in 8-10 cols | `max-w-4xl mx-auto` or left-aligned |
|
|
144
|
+
| Two-up (text + image) | 5 cols text, 7 cols image (asymmetric) | `grid grid-cols-12`, `col-span-5` / `col-span-7` |
|
|
145
|
+
| Three stats | 4 cols each | `grid grid-cols-3 gap-16` |
|
|
146
|
+
| Chart + annotation | Full width chart, annotation below | Single column, stacked |
|
|
147
|
+
| Table | 10 cols centered | `max-w-4xl mx-auto` |
|
|
148
|
+
|
|
149
|
+
Asymmetric splits (5:7, 4:8) look more designed than symmetric ones (6:6). Use them by default for two-element layouts.
|
|
150
|
+
|
|
151
|
+
## Spacing system
|
|
152
|
+
|
|
153
|
+
### The hierarchy rule
|
|
154
|
+
|
|
155
|
+
Internal spacing (within a group) must always be smaller than external spacing (between groups). The ratio is 1:2.
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
Title
|
|
159
|
+
[0.5x heading height gap]
|
|
160
|
+
Body text paragraph
|
|
161
|
+
[1x body line height gap]
|
|
162
|
+
Body text paragraph
|
|
163
|
+
|
|
164
|
+
[2-3x body line height gap] <-- section break
|
|
165
|
+
|
|
166
|
+
Next group title
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Specific spacing values
|
|
170
|
+
|
|
171
|
+
| Relationship | Spacing | Tailwind |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| Heading to body | 0.5-1x heading line height | `mt-3` to `mt-6` |
|
|
174
|
+
| Between body paragraphs | 0.75-1x body line height | `mt-4` |
|
|
175
|
+
| Between content chunks | 2-3x body line height | `mt-10` to `mt-16` |
|
|
176
|
+
| Between section label and heading | `mt-3` | Small, tight coupling |
|
|
177
|
+
| Chart/image to its caption | `mt-4` to `mt-6` | Visually grouped |
|
|
178
|
+
| Stat number to its label | `mt-2` to `mt-3` | Tight, single unit |
|
|
179
|
+
|
|
180
|
+
### The double-spacing heuristic
|
|
181
|
+
|
|
182
|
+
Whatever spacing looks right at your desk, double it. Slides are viewed from distance. Spacing that feels generous while editing feels normal on a projector. Spacing that feels normal while editing feels cramped projected.
|
|
183
|
+
|
|
184
|
+
## Visual hierarchy through opacity
|
|
185
|
+
|
|
186
|
+
Opacity is more effective than color changes for creating hierarchy on slides. It works with any palette.
|
|
187
|
+
|
|
188
|
+
| Level | Opacity | Use |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| Primary | 100% | Title, hero stat, key data |
|
|
191
|
+
| Secondary | 60-70% | Body text, labels |
|
|
192
|
+
| Tertiary | 40-50% | Captions, attribution, metadata |
|
|
193
|
+
| Decorative | 10-25% | Background elements, dividers |
|
|
194
|
+
|
|
195
|
+
Apply with Tailwind: `opacity-100`, `opacity-60`, `opacity-40`.
|
|
196
|
+
|
|
197
|
+
For text on dark backgrounds, consider `99%` opacity on primary text (not 100%). This is subtle but softens the rendering and reduces harshness.
|
|
198
|
+
|
|
199
|
+
## Compositional patterns
|
|
200
|
+
|
|
201
|
+
### Rule of thirds
|
|
202
|
+
|
|
203
|
+
Divide the slide into a 3x3 grid. Place focal elements at the four intersection points. In a 1920x1080 frame, the power points are at approximately (640, 360), (1280, 360), (640, 720), (1280, 720).
|
|
204
|
+
|
|
205
|
+
Do not center every slide. Reserve centered composition for hero moments (big stat, title, closing). Use rule-of-thirds positioning for content slides.
|
|
206
|
+
|
|
207
|
+
### Asymmetry over symmetry
|
|
208
|
+
|
|
209
|
+
Perfectly centered, symmetric layouts read as "default template." Use asymmetry to create visual tension:
|
|
210
|
+
|
|
211
|
+
- Left-aligned text on a centered slide
|
|
212
|
+
- Content weighted to one side with whitespace on the other
|
|
213
|
+
- Uneven column splits (5:7, 4:8)
|
|
214
|
+
|
|
215
|
+
### Consistent anchor points across slides
|
|
216
|
+
|
|
217
|
+
The single biggest signal of a "designed" deck vs. an "assembled" one: recurring elements occupy the same position on every slide.
|
|
218
|
+
|
|
219
|
+
- Section labels: same x and y on every slide that has one
|
|
220
|
+
- Titles: same y-position (baseline alignment) across all content slides
|
|
221
|
+
- Body text: same x-position (left edge) across all content slides
|
|
222
|
+
- Logo / page indicator: same corner, same size, every slide
|
|
223
|
+
|
|
224
|
+
Define these positions once and reuse them. In slidenerds, this means extracting consistent padding and positioning values.
|
|
225
|
+
|
|
226
|
+
### The left-content, right-atmosphere pattern
|
|
227
|
+
|
|
228
|
+
Used in Apple keynotes and the Supabase re:Invent deck: content occupies the left 50-55% of the slide. The right side is reserved for atmospheric imagery, gradient wash, or intentional emptiness. This creates a strong reading anchor on the left and visual breathing room on the right.
|
|
229
|
+
|
|
230
|
+
## Section structure
|
|
231
|
+
|
|
232
|
+
### Section labels
|
|
233
|
+
|
|
234
|
+
Every content slide (except title and closing) should have a section label -- a small uppercase text above the title that tells the audience where they are in the deck.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
<p className="text-sm font-semibold tracking-[0.2em] uppercase mb-3"
|
|
238
|
+
style={{ color: 'var(--color-accent)' }}>
|
|
239
|
+
Revenue
|
|
240
|
+
</p>
|
|
241
|
+
<h2 className="text-4xl font-bold tracking-tight">
|
|
242
|
+
ARR trajectory
|
|
243
|
+
</h2>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The label uses the accent color, uppercase, wide tracking. The title uses the primary text color, tight tracking. The contrast between the two (small+wide vs. large+tight) creates clear hierarchy.
|
|
247
|
+
|
|
248
|
+
### Section dividers
|
|
249
|
+
|
|
250
|
+
Between major sections, insert a divider slide. It contains only a section number and title, centered. Use the primary/surface background color, not the standard slide background, to create a visual break.
|
|
251
|
+
|
|
252
|
+
## Slide type spacing recipes
|
|
253
|
+
|
|
254
|
+
### Title slide
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
Bottom-aligned layout:
|
|
258
|
+
accent-line (48x3px) at bottom 35%
|
|
259
|
+
title (56-72pt, tight) mt-8 below line
|
|
260
|
+
subtitle (20-24pt, 50% opacity) mt-5
|
|
261
|
+
metadata row (12-14pt, 40% opacity, uppercase tracking) mt-16
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Content gravity is bottom-left. The top 50-60% of the slide is breathing room.
|
|
265
|
+
|
|
266
|
+
### Big stat slide
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
Center-aligned layout:
|
|
270
|
+
stat number (80-160pt, accent color, glow) centered
|
|
271
|
+
label (24-32pt, 60% opacity) mt-2 to mt-4
|
|
272
|
+
context badge (pill shape, accent-dim bg) mt-8 to mt-10
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The stat is optically centered (slightly above true center). The label sits close to the number (they are a single unit). The context badge has more separation.
|
|
276
|
+
|
|
277
|
+
### Chart slide
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
Left-aligned layout:
|
|
281
|
+
section label + title top section
|
|
282
|
+
chart in card surface mt-8 to mt-12, full width up to max-w-4xl
|
|
283
|
+
annotation with bullet dot mt-5 to mt-6 below chart
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Charts sit inside a card surface (subtle border, slightly elevated background) to separate them from the slide background. One chart per slide. The annotation is a single sentence with a small accent-colored dot before it.
|
|
287
|
+
|
|
288
|
+
Charts must use the full available width of the slide -- never constrain them to a narrow `max-width`. Use `flex-1` with `minHeight: 0` so the chart grows to fill available vertical space within the slide padding. The `ResponsiveContainer` should use `height="100%"` not a fixed pixel height.
|
|
289
|
+
|
|
290
|
+
### Comparison table
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
Left-aligned layout:
|
|
294
|
+
section label + title top section
|
|
295
|
+
table in card surface mt-8, full width up to max-w-4xl
|
|
296
|
+
header row: uppercase, small, muted, elevated bg
|
|
297
|
+
data rows: revealed one at a time via data-step
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Table headers use the same style as section labels (small, uppercase, wide tracking, muted color). Data cells use body text size. Accent color highlights the "winning" values.
|
|
301
|
+
|
|
302
|
+
### Quote slide
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
Center-aligned layout:
|
|
306
|
+
large open-quote glyph (accent color, 30% opacity) decorative
|
|
307
|
+
quote text (28-36pt, light weight, relaxed leading) mt-6 to mt-8
|
|
308
|
+
avatar circle + name + role (left-aligned pair) mt-10 to mt-12
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Constrain the quote to `max-w-3xl` for comfortable line length. The open-quote glyph is decorative, not structural.
|
|
312
|
+
|
|
313
|
+
### Timeline / roadmap
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
Top-left title + centered visual layout:
|
|
317
|
+
section label + title top-left anchored
|
|
318
|
+
visual container flex-1 flex items-center justify-center
|
|
319
|
+
horizontal connector line thin, muted, full width within container
|
|
320
|
+
timeline nodes grid cols, each with:
|
|
321
|
+
dot (accent, with glow)
|
|
322
|
+
quarter label (bold, mt-4)
|
|
323
|
+
milestone name (medium, mt-1)
|
|
324
|
+
detail (small, muted, mt-1)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
The title stays top-left. The timeline itself centers vertically and horizontally in the remaining space below the title. Completed milestones use full accent color. Future milestones use dimmed dot (muted background, no glow).
|
|
328
|
+
|
|
329
|
+
## Background treatments
|
|
330
|
+
|
|
331
|
+
### Gradient mesh
|
|
332
|
+
|
|
333
|
+
Subtle radial gradients in the background create depth without competing with content. Use the accent color at 4-8% opacity in two overlapping ellipses at different positions.
|
|
334
|
+
|
|
335
|
+
```css
|
|
336
|
+
background:
|
|
337
|
+
radial-gradient(ellipse at 20% 50%, rgba(accent, 0.08) 0%, transparent 50%),
|
|
338
|
+
radial-gradient(ellipse at 80% 20%, rgba(accent, 0.04) 0%, transparent 40%),
|
|
339
|
+
var(--color-background);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Alternate between warm and cool mesh positions across slides for visual variety.
|
|
343
|
+
|
|
344
|
+
### Film grain
|
|
345
|
+
|
|
346
|
+
A subtle noise texture at 2-3% opacity adds tactile quality to dark backgrounds. Apply as a pseudo-element on `[data-slide]` so it covers every slide automatically.
|
|
347
|
+
|
|
348
|
+
### Section divider backgrounds
|
|
349
|
+
|
|
350
|
+
Use a linear gradient from primary to surface color. This is the visual cue that says "this is a structural break, not a content slide."
|
|
351
|
+
|
|
352
|
+
## Card surfaces
|
|
353
|
+
|
|
354
|
+
Charts, tables, and code blocks sit inside card surfaces rather than directly on the slide background. A card surface is:
|
|
355
|
+
|
|
356
|
+
- Background: `var(--color-surface)` (one step lighter than slide background)
|
|
357
|
+
- Border: 1px solid at 6% white opacity
|
|
358
|
+
- Border radius: 12px
|
|
359
|
+
- Padding: 1.5-2rem
|
|
360
|
+
|
|
361
|
+
Cards create depth and separation. They are the visual equivalent of a frame around a painting.
|
|
362
|
+
|
|
363
|
+
## What to avoid
|
|
364
|
+
|
|
365
|
+
- Centering everything. Most slides are top-left anchored. Only big stat, section divider, quote, and closing use centered layout. If you are unsure, use top-left.
|
|
366
|
+
- More than one chart per slide.
|
|
367
|
+
- Text below 16pt.
|
|
368
|
+
- More than 3 type sizes on one slide.
|
|
369
|
+
- Symmetric column splits when asymmetric would work.
|
|
370
|
+
- Content that fills the entire slide with no whitespace.
|
|
371
|
+
- Background images behind text without a contrast overlay.
|
|
372
|
+
- Decorative elements that do not support the content hierarchy.
|
|
373
|
+
- Inconsistent positioning of recurring elements across slides.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Script from 'next/script'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom analytics component.
|
|
5
|
+
*
|
|
6
|
+
* Wire your analytics provider here. This component is loaded in the root
|
|
7
|
+
* layout after the page is interactive.
|
|
8
|
+
*
|
|
9
|
+
* Common patterns:
|
|
10
|
+
* - Add a Script tag with your provider's snippet
|
|
11
|
+
* - Import and initialize your provider's SDK
|
|
12
|
+
* - Track page views and slide navigation events
|
|
13
|
+
*/
|
|
14
|
+
export const CustomAnalytics = () => (
|
|
15
|
+
<Script
|
|
16
|
+
id="custom-analytics"
|
|
17
|
+
strategy="afterInteractive"
|
|
18
|
+
src="/analytics/custom.js"
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Script from 'next/script'
|
|
2
|
+
|
|
3
|
+
export const GA4Analytics = () => (
|
|
4
|
+
<>
|
|
5
|
+
<Script
|
|
6
|
+
src={`https://www.googletagmanager.com/gtag/js?id={{ANALYTICS_ID}}`}
|
|
7
|
+
strategy="afterInteractive"
|
|
8
|
+
/>
|
|
9
|
+
<Script
|
|
10
|
+
id="ga4-init"
|
|
11
|
+
strategy="afterInteractive"
|
|
12
|
+
src={`/analytics/ga4-init.js`}
|
|
13
|
+
/>
|
|
14
|
+
</>
|
|
15
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Script from 'next/script'
|
|
2
|
+
|
|
3
|
+
export const PostHogAnalytics = () => (
|
|
4
|
+
<Script
|
|
5
|
+
id="posthog-script"
|
|
6
|
+
strategy="afterInteractive"
|
|
7
|
+
src="https://app.posthog.com/static/array.js"
|
|
8
|
+
onLoad={() => {
|
|
9
|
+
if (typeof window !== 'undefined' && (window as Record<string, unknown>).posthog) {
|
|
10
|
+
(window as Record<string, unknown> & { posthog: { init: (key: string, opts: Record<string, string>) => void } }).posthog.init('{{ANALYTICS_ID}}', { api_host: 'https://app.posthog.com' })
|
|
11
|
+
}
|
|
12
|
+
}}
|
|
13
|
+
/>
|
|
14
|
+
)
|