figmatk 0.0.7 → 0.0.9
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/lib/api.mjs
CHANGED
|
@@ -1667,12 +1667,15 @@ function parseColor(fd, color) {
|
|
|
1667
1667
|
if (typeof color === 'string') {
|
|
1668
1668
|
// Hex string
|
|
1669
1669
|
if (/^#?[0-9a-fA-F]{6}$/.test(color)) return _hexToRgb(color);
|
|
1670
|
-
//
|
|
1670
|
+
// Figma theme variable first (exact match, preserves colorVar binding for slides)
|
|
1671
|
+
try {
|
|
1672
|
+
const variable = resolveColorVariable(fd, color);
|
|
1673
|
+
return { r: variable.r, g: variable.g, b: variable.b, _guid: variable.guid };
|
|
1674
|
+
} catch (_) {}
|
|
1675
|
+
// Designer alias fallback (case-insensitive)
|
|
1671
1676
|
const alias = DESIGNER_COLORS[color.toLowerCase()];
|
|
1672
1677
|
if (alias) return _hexToRgb(alias);
|
|
1673
|
-
|
|
1674
|
-
const variable = resolveColorVariable(fd, color);
|
|
1675
|
-
return { r: variable.r, g: variable.g, b: variable.b, _guid: variable.guid };
|
|
1678
|
+
throw new Error(`Unknown color: "${color}". Use a Light Slides name ('Black', 'Teal'), a designer alias ('navy', 'coral'), or a hex string ('#E63946').`);
|
|
1676
1679
|
}
|
|
1677
1680
|
throw new Error(`Invalid color: ${JSON.stringify(color)}`);
|
|
1678
1681
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: figma-slides-creator
|
|
3
|
+
description: >
|
|
4
|
+
Create, edit, and inspect Figma Slides .deck files. Use when the user asks to
|
|
5
|
+
create a presentation, build a slide deck, edit slides, update text or images,
|
|
6
|
+
clone or remove slides, or produce a .deck file for Figma Slides.
|
|
7
|
+
Powered by FigmaTK under the hood.
|
|
8
|
+
metadata:
|
|
9
|
+
version: "0.0.8"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# FigmaTK Skill
|
|
13
|
+
|
|
14
|
+
## ⚠️ Never open .deck files directly
|
|
15
|
+
|
|
16
|
+
`.deck` files are binary ZIP archives. **Never open, read, or display a `.deck` file** — it will show garbage bytes in the panel. To inspect or modify a `.deck` file, always use the CLI commands or Node.js API shown below.
|
|
17
|
+
|
|
18
|
+
To let the user view the result: tell them to **open the file in Figma Desktop** (`File → Open` or double-click the `.deck` file).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Reference
|
|
23
|
+
|
|
24
|
+
| Task | Approach |
|
|
25
|
+
|------|----------|
|
|
26
|
+
| Create a new deck from scratch | Use the high-level JS API (`lib/api.mjs`) |
|
|
27
|
+
| Edit text or images in an existing deck | Use MCP tools (`figmatk_update_text`, `figmatk_insert_image`) |
|
|
28
|
+
| Clone, remove, or restructure slides | Use MCP tools (`figmatk_clone_slide`, `figmatk_remove_slide`) |
|
|
29
|
+
| Inspect structure or read content | Use MCP tools (`figmatk_inspect`, `figmatk_list_text`) |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Path A — Create from Scratch (High-Level API)
|
|
34
|
+
|
|
35
|
+
Use this when the user wants a new presentation. Write a Node.js script and execute it.
|
|
36
|
+
|
|
37
|
+
> **Import path:** `figmatk` is an npm package. Import from the installed package:
|
|
38
|
+
> ```javascript
|
|
39
|
+
> import { Deck } from 'figmatk';
|
|
40
|
+
> ```
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
import { Deck } from 'figmatk';
|
|
44
|
+
|
|
45
|
+
const deck = await Deck.create('My Presentation');
|
|
46
|
+
|
|
47
|
+
const slide = deck.addBlankSlide(); // template blank slide auto-removed
|
|
48
|
+
slide.setBackground('Black'); // named color — see list below
|
|
49
|
+
slide.addText('Slide Title', {
|
|
50
|
+
style: 'Title', color: 'White',
|
|
51
|
+
x: 64, y: 80, width: 1792, align: 'LEFT'
|
|
52
|
+
});
|
|
53
|
+
slide.addText('Subtitle', {
|
|
54
|
+
style: 'Body 1', color: 'Grey',
|
|
55
|
+
x: 64, y: 240, width: 1200, align: 'LEFT'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await deck.save('/path/to/output.deck');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### ⚠️ Critical gotchas
|
|
62
|
+
|
|
63
|
+
| Issue | Wrong | Right |
|
|
64
|
+
|-------|-------|-------|
|
|
65
|
+
| `setBackground` with hex | `s.setBackground('#1A1A1A')` | `s.setBackground('Black')` |
|
|
66
|
+
| `setBackground` with raw RGB | `s.setBackground({ r:0.1, g:0.1, b:0.1 })` | `s.setBackground('Black')` — raw RGB silently renders white |
|
|
67
|
+
| Shape method signature | `s.addRectangle({ x:0, y:0, width:100 })` | `s.addRectangle(0, 0, 100, 100, opts)` |
|
|
68
|
+
| Shape fill color | `{ fill: '#F4900C' }` | `{ fill: hex('#F4900C') }` — use the hex() helper |
|
|
69
|
+
| `addLine` options | `{ strokeColor: ..., strokeWeight: 2 }` | `{ color: 'Black', weight: 2 }` |
|
|
70
|
+
| `align` value | `align: 'left'` | `align: 'LEFT'` (uppercase) |
|
|
71
|
+
|
|
72
|
+
### Hex color helper (for shape fills)
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
function hex(h) {
|
|
76
|
+
return { r: parseInt(h.slice(1,3),16)/255, g: parseInt(h.slice(3,5),16)/255, b: parseInt(h.slice(5,7),16)/255 };
|
|
77
|
+
}
|
|
78
|
+
// Usage: s.addRectangle(0, 0, 200, 50, { fill: hex('#F4900C') })
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Text styles
|
|
82
|
+
|
|
83
|
+
| Style | Size | Weight | Use for |
|
|
84
|
+
|-------|------|--------|---------|
|
|
85
|
+
| `Title` | 96pt | Bold | Slide title |
|
|
86
|
+
| `Header 1` | 60pt | Bold | Section headers |
|
|
87
|
+
| `Header 2` | 48pt | Bold | Sub-headers |
|
|
88
|
+
| `Header 3` | 36pt | Bold | In-slide headings |
|
|
89
|
+
| `Body 1` | 36pt | Regular | Primary body text |
|
|
90
|
+
| `Body 2` | 30pt | Regular | Secondary body text |
|
|
91
|
+
| `Body 3` | 24pt | Regular | Captions, labels |
|
|
92
|
+
| `Note` | 20pt | Regular | Footnotes, sources |
|
|
93
|
+
|
|
94
|
+
### Named colors for `setBackground()`
|
|
95
|
+
|
|
96
|
+
> **Case-sensitive.** `'Black'` works, `'black'` does not.
|
|
97
|
+
|
|
98
|
+
`'Black'`, `'White'`, `'Grey'`, `'Blue'`, `'Red'`, `'Yellow'`, `'Green'`, `'Orange'`, `'Pink'`, `'Purple'`, `'Teal'`, `'Violet'`, `'Persimmon'`, `'Pale Pink'`, `'Pale Blue'`, `'Pale Green'`, `'Pale Teal'`, `'Pale Purple'`, `'Pale Persimmon'`, `'Pale Violet'`, `'Pale Red'`, `'Pale Yellow'`
|
|
99
|
+
|
|
100
|
+
Use `'Black'` for dark backgrounds, `'White'` for light. For custom slide backgrounds, use the closest named color — **not hex**.
|
|
101
|
+
|
|
102
|
+
### Slide dimensions
|
|
103
|
+
|
|
104
|
+
1920 × 1080px. All positions and sizes in pixels.
|
|
105
|
+
|
|
106
|
+
### Slide methods (correct signatures)
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
slide.setBackground(namedColor) // named color only — hex/raw RGB render white
|
|
110
|
+
slide.addText(text, opts) // opts: style, color (named or hex('#...')), x, y, width, align, bold, italic, fontSize
|
|
111
|
+
slide.addFrame(opts) // auto-layout: stackMode, spacing, x, y, width, height
|
|
112
|
+
slide.addRectangle(x, y, width, height, opts) // opts: fill (named or {r,g,b}), opacity, cornerRadius
|
|
113
|
+
slide.addEllipse(x, y, width, height, opts) // opts: fill, opacity
|
|
114
|
+
slide.addDiamond(x, y, width, height, opts)
|
|
115
|
+
slide.addTriangle(x, y, width, height, opts)
|
|
116
|
+
slide.addStar(x, y, width, height, opts)
|
|
117
|
+
slide.addLine(x1, y1, x2, y2, opts) // opts: color, weight
|
|
118
|
+
slide.addImage(path, opts) // opts: x, y, width, height
|
|
119
|
+
slide.addTable(data, opts) // 2D string array; opts: x, y, width, colWidths, rowHeight
|
|
120
|
+
slide.addSVG(x, y, width, svgPathOrBuf, opts)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Path B — Edit an Existing Deck (MCP Tools)
|
|
126
|
+
|
|
127
|
+
Use this when the user provides a `.deck` file to modify.
|
|
128
|
+
|
|
129
|
+
### Workflow
|
|
130
|
+
|
|
131
|
+
1. `figmatk_inspect` — understand the deck structure (node IDs, slide count, symbols)
|
|
132
|
+
2. `figmatk_list_text` — read current text and images per slide
|
|
133
|
+
3. `figmatk_list_overrides` — find the override keys for each symbol (what's editable)
|
|
134
|
+
4. `figmatk_update_text` — apply text changes
|
|
135
|
+
5. `figmatk_insert_image` — apply image changes
|
|
136
|
+
6. `figmatk_clone_slide` — duplicate a slide and populate it
|
|
137
|
+
7. `figmatk_remove_slide` — mark unwanted slides as REMOVED
|
|
138
|
+
8. Always write to a **new output path** — never overwrite the source
|
|
139
|
+
|
|
140
|
+
### MCP tool reference
|
|
141
|
+
|
|
142
|
+
| Tool | Purpose |
|
|
143
|
+
|------|---------|
|
|
144
|
+
| `figmatk_inspect` | Node hierarchy tree — structure, node IDs, slide count |
|
|
145
|
+
| `figmatk_list_text` | All text strings and image hashes per slide |
|
|
146
|
+
| `figmatk_list_overrides` | Editable override keys per symbol (component) |
|
|
147
|
+
| `figmatk_update_text` | Set text overrides on a slide instance |
|
|
148
|
+
| `figmatk_insert_image` | Set image fill override (handles SHA-1 hashing + thumbnail) |
|
|
149
|
+
| `figmatk_clone_slide` | Deep-clone a slide with new text and images |
|
|
150
|
+
| `figmatk_remove_slide` | Mark slides as REMOVED (never deleted) |
|
|
151
|
+
| `figmatk_roundtrip` | Decode + re-encode for pipeline validation |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Design Philosophy
|
|
156
|
+
|
|
157
|
+
Every deck must look **intentionally designed**, not AI-generated.
|
|
158
|
+
|
|
159
|
+
### Colour
|
|
160
|
+
|
|
161
|
+
- Pick a bold palette for the **specific topic** — not a generic one.
|
|
162
|
+
- One dominant colour (60–70%) + 1–2 supporting tones + one sharp accent.
|
|
163
|
+
- Dark backgrounds on title/conclusion slides, light on content ("sandwich") — or fully dark for premium feel.
|
|
164
|
+
|
|
165
|
+
**Starter palettes** (use nearest named color for `setBackground`, hex helper for shapes):
|
|
166
|
+
|
|
167
|
+
| Theme | Background | Shape accent | Text |
|
|
168
|
+
|-------|-----------|-------------|------|
|
|
169
|
+
| Midnight | `'Black'` | `hex('#CADCFC')` | `'White'` |
|
|
170
|
+
| Forest | `'Green'` | `hex('#97BC62')` | `'White'` |
|
|
171
|
+
| Coral | `'Persimmon'` | `hex('#2F3C7E')` | `'White'` |
|
|
172
|
+
| Terracotta | `'Persimmon'` | `hex('#E7E8D1')` | `'White'` |
|
|
173
|
+
| Ocean | `'Blue'` | `hex('#21295C')` | `'White'` |
|
|
174
|
+
| Minimal | `'White'` | `hex('#36454F')` | `'Black'` |
|
|
175
|
+
|
|
176
|
+
### Layout
|
|
177
|
+
|
|
178
|
+
- Every slide needs at least **one visual element** — shape, image, SVG, or table.
|
|
179
|
+
- **Vary layouts** — never repeat the same structure slide after slide.
|
|
180
|
+
- Carry one visual motif through every slide (coloured accent bar, icon circles, etc.).
|
|
181
|
+
|
|
182
|
+
**Layout options:** two-column, icon+text rows, 2×2/2×3 grid, large stat callout, half-background image, timeline/steps.
|
|
183
|
+
|
|
184
|
+
### Typography
|
|
185
|
+
|
|
186
|
+
- Left-align body text. Centre only titles.
|
|
187
|
+
- Minimum 64px margin from slide edges. 24–48px between content blocks.
|
|
188
|
+
|
|
189
|
+
### Never do
|
|
190
|
+
|
|
191
|
+
- Repeat the same layout slide after slide
|
|
192
|
+
- Centre body text
|
|
193
|
+
- Use accent lines under slide titles (hallmark of AI-generated slides)
|
|
194
|
+
- Text-only slides
|
|
195
|
+
- Low-contrast text against background
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## QA
|
|
200
|
+
|
|
201
|
+
1. Self-check: no placeholder text (`lorem ipsum`, `[title here]`) remains
|
|
202
|
+
2. Tell the user to open the `.deck` in Figma Desktop to catch rendering issues
|
|
203
|
+
3. Offer to fix anything they report
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Critical Format Rules
|
|
208
|
+
|
|
209
|
+
- Blank text must be `" "` (space), never `""` — empty string crashes Figma
|
|
210
|
+
- Image overrides need both a full-image hash and thumbnail hash (40-char hex SHA-1)
|
|
211
|
+
- Removed nodes: set `phase: 'REMOVED'`, never delete from `nodeChanges`
|
|
212
|
+
- Chunk 1 of `canvas.fig` must be zstd-compressed
|
|
213
|
+
- `thumbHash` must be `new Uint8Array(0)`, never `{}`
|
package/skills/figmatk/SKILL.md
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: figmatk
|
|
3
|
-
description: >
|
|
4
|
-
Create, edit, and inspect Figma Slides .deck files. Use when the user asks to
|
|
5
|
-
create a presentation, build a slide deck, edit slides, update text or images,
|
|
6
|
-
clone or remove slides, or produce a .deck file for Figma Slides.
|
|
7
|
-
metadata:
|
|
8
|
-
version: "0.0.6"
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# FigmaTK Skill
|
|
12
|
-
|
|
13
|
-
## Quick Reference
|
|
14
|
-
|
|
15
|
-
| Task | Approach |
|
|
16
|
-
|------|----------|
|
|
17
|
-
| Create a new deck from scratch | Use the high-level JS API (`lib/api.mjs`) |
|
|
18
|
-
| Edit text or images in an existing deck | Use MCP tools (`figmatk_update_text`, `figmatk_insert_image`) |
|
|
19
|
-
| Clone, remove, or restructure slides | Use MCP tools (`figmatk_clone_slide`, `figmatk_remove_slide`) |
|
|
20
|
-
| Inspect structure or read content | Use MCP tools (`figmatk_inspect`, `figmatk_list_text`) |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Path A — Create from Scratch (High-Level API)
|
|
25
|
-
|
|
26
|
-
Use this when the user wants a new presentation. Write a Node.js script and execute it.
|
|
27
|
-
|
|
28
|
-
```javascript
|
|
29
|
-
import { Deck } from 'figmatk';
|
|
30
|
-
|
|
31
|
-
const deck = await Deck.create('My Presentation');
|
|
32
|
-
const slide = deck.addBlankSlide();
|
|
33
|
-
|
|
34
|
-
slide.setBackground('slate');
|
|
35
|
-
slide.addText('Slide Title', { style: 'Title', color: 'white', x: 64, y: 80, width: 1792 });
|
|
36
|
-
slide.addText('Subtitle or tagline here', { style: 'Body 1', color: 'light-gray', x: 64, y: 240, width: 1200 });
|
|
37
|
-
|
|
38
|
-
await deck.save('/path/to/output.deck');
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Text styles
|
|
42
|
-
|
|
43
|
-
| Style | Size | Weight | Use for |
|
|
44
|
-
|-------|------|--------|---------|
|
|
45
|
-
| `Title` | 96pt | Bold | Slide title |
|
|
46
|
-
| `Header 1` | 60pt | Bold | Section headers |
|
|
47
|
-
| `Header 2` | 48pt | Bold | Sub-headers |
|
|
48
|
-
| `Header 3` | 36pt | Bold | In-slide headings |
|
|
49
|
-
| `Body 1` | 36pt | Regular | Primary body text |
|
|
50
|
-
| `Body 2` | 30pt | Regular | Secondary body text |
|
|
51
|
-
| `Body 3` | 24pt | Regular | Captions, labels |
|
|
52
|
-
| `Note` | 20pt | Regular | Footnotes, sources |
|
|
53
|
-
|
|
54
|
-
### Colors
|
|
55
|
-
|
|
56
|
-
Use **names** — never RGB values. The API accepts:
|
|
57
|
-
|
|
58
|
-
| Type | Example |
|
|
59
|
-
|------|---------|
|
|
60
|
-
| Designer name | `'teal'`, `'coral'`, `'navy'`, `'midnight'`, `'forest'`, `'charcoal'`, `'cream'`, `'gold'`, `'terracotta'`, `'sage'`, `'cobalt'`, `'rose'`, `'indigo'`, `'burgundy'`, `'sand'`... |
|
|
61
|
-
| Hex string | `'#E63946'` |
|
|
62
|
-
| Light Slides theme | `'Blue'`, `'Red'`, `'Green'`, `'Yellow'`, `'Orange'`, `'Pink'`, `'Purple'`, `'Slate'`, `'White'`, `'Black'` |
|
|
63
|
-
|
|
64
|
-
Pick colors by feeling: "warm terracotta on cream", "midnight blue with coral accent". Let the design drive the choice, then pick the closest name.
|
|
65
|
-
|
|
66
|
-
### Slide dimensions
|
|
67
|
-
|
|
68
|
-
1920 × 1080px. Position and size all elements in pixels.
|
|
69
|
-
|
|
70
|
-
### Available slide methods
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
slide.setBackground(color) // named color or hex
|
|
74
|
-
slide.addText(text, opts) // opts: style, color, x, y, width, align, bold, italic, fontSize
|
|
75
|
-
slide.addFrame(opts) // auto-layout frame: stackMode, spacing, x, y, width, height
|
|
76
|
-
slide.addRectangle(opts) // opts: x, y, width, height, fill, opacity, cornerRadius
|
|
77
|
-
slide.addEllipse(opts) // circle/ellipse: x, y, width, height, fill
|
|
78
|
-
slide.addDiamond(opts) // diamond shape
|
|
79
|
-
slide.addTriangle(opts) // triangle
|
|
80
|
-
slide.addStar(opts) // 5-pointed star
|
|
81
|
-
slide.addLine(x1, y1, x2, y2, opts) // line: strokeColor, strokeWeight
|
|
82
|
-
slide.addImage(path, opts) // freestanding image: x, y, width, height
|
|
83
|
-
slide.addTable(data, opts) // 2D array of strings: x, y, width, colWidths, rowHeight
|
|
84
|
-
slide.addSVG(x, y, width, svgPathOrBuf, opts) // import SVG vector graphic
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Path B — Edit an Existing Deck (MCP Tools)
|
|
90
|
-
|
|
91
|
-
Use this when the user provides a `.deck` file to modify.
|
|
92
|
-
|
|
93
|
-
### Workflow
|
|
94
|
-
|
|
95
|
-
1. `figmatk_inspect` — understand the deck structure (node IDs, slide count, symbols)
|
|
96
|
-
2. `figmatk_list_text` — read current text and images per slide
|
|
97
|
-
3. `figmatk_list_overrides` — find the override keys for each symbol (what's editable)
|
|
98
|
-
4. `figmatk_update_text` — apply text changes
|
|
99
|
-
5. `figmatk_insert_image` — apply image changes
|
|
100
|
-
6. `figmatk_clone_slide` — duplicate a slide and populate it
|
|
101
|
-
7. `figmatk_remove_slide` — mark unwanted slides as REMOVED
|
|
102
|
-
8. Always write to a **new output path** — never overwrite the source
|
|
103
|
-
|
|
104
|
-
### MCP tool reference
|
|
105
|
-
|
|
106
|
-
| Tool | Purpose |
|
|
107
|
-
|------|---------|
|
|
108
|
-
| `figmatk_inspect` | Node hierarchy tree — structure, node IDs, slide count |
|
|
109
|
-
| `figmatk_list_text` | All text strings and image hashes per slide |
|
|
110
|
-
| `figmatk_list_overrides` | Editable override keys per symbol (component) |
|
|
111
|
-
| `figmatk_update_text` | Set text overrides on a slide instance |
|
|
112
|
-
| `figmatk_insert_image` | Set image fill override (handles SHA-1 hashing + thumbnail) |
|
|
113
|
-
| `figmatk_clone_slide` | Deep-clone a slide with new text and images |
|
|
114
|
-
| `figmatk_remove_slide` | Mark slides as REMOVED (never deleted) |
|
|
115
|
-
| `figmatk_roundtrip` | Decode + re-encode for pipeline validation |
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Design Philosophy
|
|
120
|
-
|
|
121
|
-
Every deck must look **intentionally designed**, not AI-generated. Follow these rules on every presentation task.
|
|
122
|
-
|
|
123
|
-
### Colour
|
|
124
|
-
|
|
125
|
-
- Pick a bold palette that reflects the **specific topic**. If the same palette would suit a completely different presentation, it's not specific enough.
|
|
126
|
-
- Use **one dominant colour** (60–70% visual weight) + 1–2 supporting tones + one sharp accent.
|
|
127
|
-
- Use dark backgrounds on title and conclusion slides, light on content slides ("sandwich" structure) — or commit fully to dark for a premium feel.
|
|
128
|
-
|
|
129
|
-
**Starter palettes:**
|
|
130
|
-
|
|
131
|
-
| Theme | Background | Accent | Text |
|
|
132
|
-
|-------|-----------|--------|------|
|
|
133
|
-
| Midnight | `navy` | `sky` | `white` |
|
|
134
|
-
| Forest | `forest` | `sage` | `white` |
|
|
135
|
-
| Coral | `coral` | `indigo` | `white` |
|
|
136
|
-
| Terracotta | `terracotta` | `sand` | `white` |
|
|
137
|
-
| Ocean | `cobalt` | `midnight` | `white` |
|
|
138
|
-
| Minimal | `smoke` | `charcoal` | `black` |
|
|
139
|
-
|
|
140
|
-
### Layout
|
|
141
|
-
|
|
142
|
-
- Every slide needs at least **one visual element** — shape, image, SVG icon, or table. Text-only slides are forgettable.
|
|
143
|
-
- **Vary layouts** — never use the same structure slide after slide.
|
|
144
|
-
- Pick one visual motif (e.g. rounded image frames, coloured icon circles, thick side accent bars) and carry it through every slide.
|
|
145
|
-
|
|
146
|
-
**Layout options per slide:**
|
|
147
|
-
|
|
148
|
-
- Two-column (text left, visual right)
|
|
149
|
-
- Icon + text rows (icon in coloured circle, bold header, description)
|
|
150
|
-
- 2×2 or 2×3 grid of cards
|
|
151
|
-
- Large stat callout (big number + small label)
|
|
152
|
-
- Half-background image with text overlay
|
|
153
|
-
- Timeline / numbered steps
|
|
154
|
-
|
|
155
|
-
### Typography
|
|
156
|
-
|
|
157
|
-
- Left-align body text. Centre only titles.
|
|
158
|
-
- **Font sizes:** titles use `Title` style (96pt); section headers `Header 1` (60pt); body `Body 1` or `Body 2`; captions `Body 3` or `Note`.
|
|
159
|
-
- Minimum 64px margin from slide edges. 24–48px gap between content blocks.
|
|
160
|
-
|
|
161
|
-
### Things to never do
|
|
162
|
-
|
|
163
|
-
- Repeat the same layout slide after slide
|
|
164
|
-
- Centre body text
|
|
165
|
-
- Use accent lines under slide titles (hallmark of AI-generated slides — use colour or whitespace instead)
|
|
166
|
-
- Create text-only slides
|
|
167
|
-
- Use low-contrast text — always check text against its background
|
|
168
|
-
- Default to generic blue — pick colours that reflect the topic
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## QA
|
|
173
|
-
|
|
174
|
-
After generating or editing a deck:
|
|
175
|
-
|
|
176
|
-
1. **Self-check:** confirm all placeholder text has been replaced, no `lorem ipsum` or `[title here]` remains
|
|
177
|
-
2. **Tell the user** to upload the `.deck` to Figma Slides and review visually — this is the only way to catch rendering issues
|
|
178
|
-
3. **Offer to fix** any issues the user reports after upload
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## Critical Format Rules
|
|
183
|
-
|
|
184
|
-
- Blank text fields must use `" "` (space), **never** empty string — empty string crashes Figma
|
|
185
|
-
- Image overrides require both a full-image hash and a ~320px thumbnail hash (40-char hex SHA-1)
|
|
186
|
-
- Removed nodes use `phase: 'REMOVED'` — never delete from `nodeChanges`
|
|
187
|
-
- Chunk 1 of `canvas.fig` must be zstd-compressed — Figma silently rejects deflateRaw
|
|
188
|
-
- `thumbHash` must be `new Uint8Array(0)`, never `{}`
|