wand-kit 0.3.3 → 0.5.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/PROMPT.md +182 -16
- package/SKILL.md +91 -18
- package/START-HERE.md +12 -1
- package/brands/interim/assets/avatar.svg +1 -0
- package/brands/interim/assets/closing-art.png +0 -0
- package/brands/interim/assets/cover-art.png +0 -0
- package/brands/interim/assets/cover-portrait-art.png +0 -0
- package/brands/interim/assets/divider-art.png +0 -0
- package/brands/interim/assets/glyphs/README.md +29 -0
- package/brands/interim/assets/glyphs/activity.svg +15 -0
- package/brands/interim/assets/glyphs/atom.svg +17 -0
- package/brands/interim/assets/glyphs/badge-check.svg +16 -0
- package/brands/interim/assets/glyphs/bell.svg +16 -0
- package/brands/interim/assets/glyphs/blocks.svg +16 -0
- package/brands/interim/assets/glyphs/book-open.svg +16 -0
- package/brands/interim/assets/glyphs/bot.svg +20 -0
- package/brands/interim/assets/glyphs/boxes.svg +26 -0
- package/brands/interim/assets/glyphs/brain.svg +23 -0
- package/brands/interim/assets/glyphs/briefcase.svg +16 -0
- package/brands/interim/assets/glyphs/building-2.svg +21 -0
- package/brands/interim/assets/glyphs/calendar.svg +18 -0
- package/brands/interim/assets/glyphs/chart-column.svg +18 -0
- package/brands/interim/assets/glyphs/chart-line.svg +16 -0
- package/brands/interim/assets/glyphs/chart-pie.svg +16 -0
- package/brands/interim/assets/glyphs/circle-check.svg +16 -0
- package/brands/interim/assets/glyphs/clipboard-check.svg +17 -0
- package/brands/interim/assets/glyphs/clock.svg +16 -0
- package/brands/interim/assets/glyphs/cloud.svg +15 -0
- package/brands/interim/assets/glyphs/code.svg +15 -0
- package/brands/interim/assets/glyphs/coins.svg +18 -0
- package/brands/interim/assets/glyphs/compass.svg +16 -0
- package/brands/interim/assets/glyphs/cpu.svg +24 -0
- package/brands/interim/assets/glyphs/database.svg +17 -0
- package/brands/interim/assets/glyphs/eye.svg +16 -0
- package/brands/interim/assets/glyphs/file-check.svg +17 -0
- package/brands/interim/assets/glyphs/filter.svg +15 -0
- package/brands/interim/assets/glyphs/fingerprint.svg +23 -0
- package/brands/interim/assets/glyphs/flag.svg +16 -0
- package/brands/interim/assets/glyphs/gauge.svg +16 -0
- package/brands/interim/assets/glyphs/gavel.svg +19 -0
- package/brands/interim/assets/glyphs/git-branch.svg +18 -0
- package/brands/interim/assets/glyphs/globe.svg +17 -0
- package/brands/interim/assets/glyphs/graduation-cap.svg +17 -0
- package/brands/interim/assets/glyphs/handshake.svg +19 -0
- package/brands/interim/assets/glyphs/hexagon.svg +15 -0
- package/brands/interim/assets/glyphs/index.json +177 -0
- package/brands/interim/assets/glyphs/infinity.svg +15 -0
- package/brands/interim/assets/glyphs/key.svg +17 -0
- package/brands/interim/assets/glyphs/landmark.svg +20 -0
- package/brands/interim/assets/glyphs/layers.svg +17 -0
- package/brands/interim/assets/glyphs/lightbulb.svg +17 -0
- package/brands/interim/assets/glyphs/link.svg +16 -0
- package/brands/interim/assets/glyphs/list-checks.svg +19 -0
- package/brands/interim/assets/glyphs/lock.svg +16 -0
- package/brands/interim/assets/glyphs/map.svg +17 -0
- package/brands/interim/assets/glyphs/megaphone.svg +16 -0
- package/brands/interim/assets/glyphs/message-square.svg +15 -0
- package/brands/interim/assets/glyphs/milestone.svg +17 -0
- package/brands/interim/assets/glyphs/network.svg +19 -0
- package/brands/interim/assets/glyphs/orbit.svg +19 -0
- package/brands/interim/assets/glyphs/package.svg +18 -0
- package/brands/interim/assets/glyphs/plug.svg +18 -0
- package/brands/interim/assets/glyphs/puzzle.svg +15 -0
- package/brands/interim/assets/glyphs/radar.svg +22 -0
- package/brands/interim/assets/glyphs/receipt.svg +17 -0
- package/brands/interim/assets/glyphs/refresh-cw.svg +18 -0
- package/brands/interim/assets/glyphs/rocket.svg +18 -0
- package/brands/interim/assets/glyphs/route.svg +17 -0
- package/brands/interim/assets/glyphs/scale.svg +19 -0
- package/brands/interim/assets/glyphs/search.svg +16 -0
- package/brands/interim/assets/glyphs/server.svg +18 -0
- package/brands/interim/assets/glyphs/settings.svg +16 -0
- package/brands/interim/assets/glyphs/share-2.svg +19 -0
- package/brands/interim/assets/glyphs/shield-check.svg +16 -0
- package/brands/interim/assets/glyphs/shuffle.svg +19 -0
- package/brands/interim/assets/glyphs/sparkles.svg +19 -0
- package/brands/interim/assets/glyphs/square-stack.svg +17 -0
- package/brands/interim/assets/glyphs/target.svg +17 -0
- package/brands/interim/assets/glyphs/trending-up.svg +16 -0
- package/brands/interim/assets/glyphs/triangle-alert.svg +17 -0
- package/brands/interim/assets/glyphs/trophy.svg +20 -0
- package/brands/interim/assets/glyphs/users.svg +18 -0
- package/brands/interim/assets/glyphs/wallet.svg +16 -0
- package/brands/interim/assets/glyphs/wand-sparkles.svg +22 -0
- package/brands/interim/assets/glyphs/workflow.svg +17 -0
- package/brands/interim/assets/glyphs/zap.svg +15 -0
- package/brands/interim/assets/mark.svg +1 -0
- package/brands/interim/assets/social/composition.json +6833 -0
- package/brands/interim/assets/spark-lavender.png +0 -0
- package/brands/interim/assets/spark-violet.png +0 -0
- package/brands/interim/assets/statement-art.png +0 -0
- package/brands/interim/assets/story/agent-alpha.png +0 -0
- package/brands/interim/assets/story/agent.png +0 -0
- package/brands/interim/assets/story/economy-alpha.png +0 -0
- package/brands/interim/assets/story/economy.png +0 -0
- package/brands/interim/assets/story/index.json +214 -0
- package/brands/interim/assets/story/learning-alpha.png +0 -0
- package/brands/interim/assets/story/learning.png +0 -0
- package/brands/interim/assets/story/organization-alpha.png +0 -0
- package/brands/interim/assets/story/organization.png +0 -0
- package/brands/interim/assets/story/worker-alpha.png +0 -0
- package/brands/interim/assets/story/worker-light.png +0 -0
- package/brands/interim/assets/story/worker.png +0 -0
- package/brands/interim/assets/wordmark-on-dark.png +0 -0
- package/brands/interim/assets/wordmark-on-dark.svg +1 -0
- package/brands/interim/assets/wordmark-on-light.png +0 -0
- package/brands/interim/assets/wordmark-on-light.svg +1 -0
- package/brands/interim/fonts/Geist-Book.ttf +0 -0
- package/brands/interim/fonts/Geist-Medium.ttf +0 -0
- package/brands/interim/fonts/Geist-Regular.ttf +0 -0
- package/brands/interim/fonts/Geist-SemiBold.ttf +0 -0
- package/brands/interim/fonts/Newsreader-Italic.ttf +0 -0
- package/brands/interim/fonts/Newsreader-Medium.ttf +0 -0
- package/brands/interim/fonts/Newsreader-MediumItalic.ttf +0 -0
- package/brands/interim/fonts/Newsreader-Regular.ttf +0 -0
- package/brands/interim/fonts/OFL-Geist.txt +93 -0
- package/brands/interim/fonts/OFL-Newsreader.txt +93 -0
- package/brands/interim/fonts/faces.json +12 -0
- package/brands/interim/lib/composition.js +169 -0
- package/brands/interim/lib/composition.mjs +101 -0
- package/brands/interim/lib/glyphs.js +89 -0
- package/brands/interim/lib/measure.js +121 -0
- package/brands/interim/lib/pdf.js +597 -0
- package/brands/interim/lib/ttf.py +169 -0
- package/brands/interim/lib/wandxml.py +37 -0
- package/brands/interim/tokens.json +299 -0
- package/examples/social/social.json +23 -0
- package/lib/audit.js +142 -0
- package/lib/brand.js +12 -7
- package/lib/components.js +13 -8
- package/lib/engine.js +55 -9
- package/lib/library.js +180 -0
- package/lib/pptx.js +1 -1
- package/lib/social.js +366 -0
- package/library/index.json +629 -0
- package/library/interim/avatar-800x800.png +0 -0
- package/library/interim/icons/apple-touch-icon.png +0 -0
- package/library/interim/icons/favicon-16.png +0 -0
- package/library/interim/icons/favicon-32.png +0 -0
- package/library/interim/icons/favicon-48.png +0 -0
- package/library/interim/icons/favicon.ico +0 -0
- package/library/interim/icons/favicon.svg +1 -0
- package/library/interim/icons/icon-192.png +0 -0
- package/library/interim/icons/icon-512.png +0 -0
- package/library/interim/icons/icon-tags.html +5 -0
- package/library/interim/icons/site.webmanifest +19 -0
- package/library/interim/linkedin-banner-1584x396.png +0 -0
- package/library/interim/linkedin-company-1128x191.png +0 -0
- package/library/interim/open-agent-discovery-share-1200x630.png +0 -0
- package/library/interim/open-agent-discovery-share-head-tags.html +17 -0
- package/library/interim/wand-ai-share-1200x630.png +0 -0
- package/library/interim/wand-ai-share-head-tags.html +17 -0
- package/library/interim/x-header-1500x500.png +0 -0
- package/package.json +2 -2
- package/templates/card.mjs +6 -2
- package/templates/page.mjs +1 -1
- package/templates/slide.mjs +1 -1
- package/templates/storyboard.mjs +1 -1
- package/wand.js +64 -5
package/PROMPT.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Wand Power Prompt — Studio (v0.1)
|
|
2
2
|
|
|
3
3
|
One design surface for every material a sales or marketing team needs, on
|
|
4
|
-
|
|
4
|
+
any of the three Wand brands. The page is HTML; it is composed from a component library on
|
|
5
5
|
brand tokens; Chromium renders it; every gate measures that render; and every
|
|
6
6
|
export (PDF, PNG, PowerPoint, a one-file HTML) is read from it, so nothing can
|
|
7
7
|
drift from what was reviewed on screen.
|
|
8
8
|
|
|
9
9
|
This document is the design system and the pipeline, and the source of truth
|
|
10
|
-
on every design question. `brand/BRAND.md
|
|
10
|
+
on every design question. `brand/BRAND.md`, `brand-next/BRAND.md` and
|
|
11
|
+
`brand-interim/BRAND.md` win on
|
|
11
12
|
values (a hex, a face, an asset); `STATUS.md` is state; `SKILL.md` is procedure.
|
|
12
13
|
|
|
13
14
|
**Why this exists.** The outputs that reviewed best in October 2026 (the
|
|
@@ -22,24 +23,27 @@ components, gates, exports.
|
|
|
22
23
|
|
|
23
24
|
## 0. Ground truth
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
Three brands, one component set.
|
|
26
27
|
|
|
27
28
|
| Brand | Directory | Faces | Guideline |
|
|
28
29
|
|---|---|---|---|
|
|
29
30
|
| `current` | `brand/` | Geist | the Kearney leadership deck; `brand/BRAND.md` |
|
|
30
|
-
| `next` | `brand-next/` | FK Roman Standard Light, Overused Grotesk | the website, read 2026-10-05; `brand-next/BRAND.md` |
|
|
31
|
+
| `next` | `brand-next/` | FK Roman Standard Light, Overused Grotesk | the staging website, read 2026-10-05; `brand-next/BRAND.md` |
|
|
32
|
+
| `interim` | `brand-interim/` | Geist, Newsreader | the live wand.ai, read 2026-10-21, and the social design approved on it 2026-10-22, which wins where they differ; `brand-interim/BRAND.md` |
|
|
31
33
|
|
|
32
34
|
Each directory's `tokens.json` carries the brand as values a kit can draw with:
|
|
33
35
|
`swatch` (the measured hexes), `roles` (what each value is for, once per
|
|
34
36
|
ground), `faces` (the files and their PowerPoint names), `shape` (radius,
|
|
35
|
-
strokes
|
|
37
|
+
strokes, and `artShade`, the shade the kit lays over a dark page's art, 0.3
|
|
38
|
+
unless a brand says otherwise) and `art` (which file plays which role). A component asks for a role
|
|
36
39
|
(`--ink`, `--accent`, `--emph`) and never for a hex. Where a hex in
|
|
37
40
|
`tokens.json` and `BRAND.md` differ, `BRAND.md` is right and `tokens.json` has
|
|
38
41
|
drifted.
|
|
39
42
|
|
|
40
|
-
`current` is the default while the
|
|
41
|
-
user asks for the new brand
|
|
42
|
-
|
|
43
|
+
`current` is the default while the brands overlap; a job is on `next` when the
|
|
44
|
+
user asks for the new brand and on `interim` when they ask for the interim
|
|
45
|
+
brand or the live site's look. The default is one constant, `DEFAULT_BRAND`
|
|
46
|
+
in `kit/lib/brand.js`, and `doctor` prints the rule from it. The FK Roman
|
|
43
47
|
Standard licence for documents is still to be confirmed
|
|
44
48
|
(`brand-next/fonts/LICENSE-FONTS.md`).
|
|
45
49
|
|
|
@@ -88,6 +92,15 @@ violets as grounds, beige as paper); see `brand-next/tokens.json`. Its
|
|
|
88
92
|
`second` is a quiet tone, not gold (7B7B79 on light, 9D99A8 on dark, large
|
|
89
93
|
type only; `secondSm`, the text grey, below that size).
|
|
90
94
|
|
|
95
|
+
The interim brand fills them from the live site and the social design
|
|
96
|
+
approved on it (2026-10-22), which wins where they differ: the approved
|
|
97
|
+
ground (`14101C`) is the dark ground, with ink `F7F5F9` and lavender
|
|
98
|
+
(`D4BCE8`) the accent for what is drawn; stone (`F5F3EF`) the light ground
|
|
99
|
+
with strong violet (`6D41B3`) the accent; a title's phrase is `violet`
|
|
100
|
+
(`C2A1EF`) on dark, on every page including the art pages (`accentText`), and
|
|
101
|
+
`765098` on light, the site's own `h1 em` colours; the spark takes the
|
|
102
|
+
phrase's colour. See `brand-interim/BRAND.md`.
|
|
103
|
+
|
|
91
104
|
**Rules.**
|
|
92
105
|
- One accent. The accent phrase in a title is the single most recognisable
|
|
93
106
|
device in the system: one per title, never two, the sentence period in ink.
|
|
@@ -98,6 +111,20 @@ type only; `secondSm`, the text grey, below that size).
|
|
|
98
111
|
wand.ai rebuild (October 2026) read as a template while every heading's
|
|
99
112
|
second line was gold: when gold is everywhere it means nothing. On the
|
|
100
113
|
current brand `second` is the accent, so nothing changes there.
|
|
114
|
+
- **On the interim brand a title's phrase changes face, not weight.** `<em>`
|
|
115
|
+
sets in Newsreader at the display's weight, the site's own `h1 em`; on the
|
|
116
|
+
pages that carry the art (the cover, a statement, the close) it is the
|
|
117
|
+
italic, as the hero's and the approved lockup's are. Its colour is one
|
|
118
|
+
violet on dark, the art pages too, as the approved banners set it; the
|
|
119
|
+
lavender accent stays for what is drawn, the figures and nothing else.
|
|
120
|
+
- **On the interim brand the cover is the approved composition.** The planet's
|
|
121
|
+
rim, four trails sweeping under the title to their dots and up through the
|
|
122
|
+
hero's oval, drawn unshaded (`shape.artShade` 0) with the title untracked
|
|
123
|
+
(`faces.display.coverTracking` 0). The composition itself
|
|
124
|
+
(`brand-interim/assets/social/composition.json`, drawn by
|
|
125
|
+
`brand-interim/lib/composition.mjs`) is what a link preview or a social
|
|
126
|
+
banner on this brand is cut from: a window of it at one scale, never its
|
|
127
|
+
parts re-proportioned.
|
|
101
128
|
- One emphasis card per row, at most one or two per page.
|
|
102
129
|
- Light pages carry no art. Dark pages carry art on the cover, the closing and
|
|
103
130
|
a statement; a dark content page is flat.
|
|
@@ -112,11 +139,16 @@ Three face roles per brand: `display` (titles, figures, the lockup), `body`
|
|
|
112
139
|
Tracking and leading travel with the face in `tokens.json`; the CSS sets them
|
|
113
140
|
from the same values.
|
|
114
141
|
|
|
115
|
-
| Role | current | next |
|
|
116
|
-
|
|
117
|
-
| display | Geist SemiBold, −0.02em | FK Roman Standard Light, −0.07em, 1.06 |
|
|
118
|
-
| body | Geist Regular | Overused Grotesk, −0.02em |
|
|
119
|
-
| label | Geist SemiBold, +0.18em, caps | FK Roman Standard Light, caps |
|
|
142
|
+
| Role | current | next | interim |
|
|
143
|
+
|---|---|---|---|
|
|
144
|
+
| display | Geist SemiBold, −0.02em | FK Roman Standard Light, −0.07em, 1.06 | Geist Medium (500), untracked, 1.025 |
|
|
145
|
+
| body | Geist Regular | Overused Grotesk, −0.02em | Geist Regular |
|
|
146
|
+
| label | Geist SemiBold, +0.18em, caps | FK Roman Standard Light, caps | Geist Medium, +0.11em, caps |
|
|
147
|
+
| phrase | the display face | the display face | Newsreader Medium (500, optical size 72), untracked; italic on the art pages |
|
|
148
|
+
|
|
149
|
+
A brand that sets a title's phrase in another face declares `faces.phrase`;
|
|
150
|
+
the CSS reads it as `--face-phrase` and friends, and a brand without it leaves
|
|
151
|
+
the phrase in the title's face, unchanged.
|
|
120
152
|
|
|
121
153
|
**Weight carries no hierarchy on the next brand** (the serif ships one weight);
|
|
122
154
|
the face does. Components therefore never rely on bold to separate levels, and
|
|
@@ -131,7 +163,8 @@ Figures are tabular (`font-variant-numeric: tabular-nums` on the page).
|
|
|
131
163
|
## 4. Chrome
|
|
132
164
|
|
|
133
165
|
Drawn by `c.page()` on every page: eyebrow (`job.tag | eyebrow`), mark, footer
|
|
134
|
-
(`job.footer`, page number
|
|
166
|
+
(`job.footer`, page number; a page's own `footer` replaces the line, for a
|
|
167
|
+
source note such as "Illustrative operating sequence"). The cover and closing pages are `c.cover()` and
|
|
135
168
|
`c.closing()`, which place the brand art and the lockup; a job gives them
|
|
136
169
|
words, never styling. Every piece of chrome is `.deco` or chrome-classed, so
|
|
137
170
|
the gates know what is content and what is frame.
|
|
@@ -175,6 +208,14 @@ decide, and that make or break a page:
|
|
|
175
208
|
ground.
|
|
176
209
|
- **Short lines in cards.** One sentence and an outcome. The card's body is
|
|
177
210
|
never the place for the argument.
|
|
211
|
+
- **Two lines a paragraph on a slide, at most** (Carlos, 2026-10-27: past two
|
|
212
|
+
"it breaks a lot", in PowerPoint and Google Slides above all). Keep the
|
|
213
|
+
words and give them room: two by two instead of four across, a ruled row
|
|
214
|
+
(the title left, the line right) instead of a narrow column, a band for a
|
|
215
|
+
unit, a lead under its title. The `lines` gate counts each block's lines
|
|
216
|
+
from the browser's own line boxes; it warns on every deck and fails a job
|
|
217
|
+
that sets `maxLines`. Titles balance and paragraphs wrap pretty
|
|
218
|
+
(`text-wrap`), so no word sits alone on a line.
|
|
178
219
|
- **Equal heights in a row** (`stretch`), titles at one height, and the empty
|
|
179
220
|
space at the foot of a page shared by its sections, never left under one.
|
|
180
221
|
- **One arc.** Night, then day, then first light: the dark cover with its
|
|
@@ -246,13 +287,17 @@ new ─▶ argue ─▶ content ─▶ compose ─▶ build ─▶ review ─▶
|
|
|
246
287
|
| pdf text | the PDF's text misses a line, or carries an em dash | |
|
|
247
288
|
| contrast (warn) | text under WCAG AA against its background, chrome excepted | |
|
|
248
289
|
| measure (warn) | a paragraph over the surface's characters-per-line | |
|
|
249
|
-
|
|
|
290
|
+
| lines (warn; hard with `maxLines`) | a block of text on a slide that sets in more than two lines (or the job's `maxLines`), counted from its line boxes; autosizing never steps a slide up past it | a two-line paragraph that reads badly |
|
|
291
|
+
| crop (warn, og) | a share image's words leave the centre square, which Slack and WhatsApp cut as their thumbnail | the chrome, and how the image reads at 128pt |
|
|
292
|
+
| images | an image did not load, or is drawn at another shape than its own (stretched or squeezed past 2%; only `object-fit` cover, contain or none may change a box's shape) | an image that loaded and is the wrong one |
|
|
250
293
|
| media | a demo, a clip or its poster is missing | a demo that loads and misbehaves |
|
|
251
294
|
| console | a page error | |
|
|
252
295
|
| runtime (ship, decks) | a slide or step the keyboard cannot reach, the overview or notes not opening, the presenter view out of step, a demo that never loads | how the motion feels |
|
|
253
296
|
| timing (warn, boards) | the board is more than 10% off its `target` | the real voiceover's pace |
|
|
254
297
|
| frames (warn, boards) | a frame is still to draw | a frame that is drawn and wrong |
|
|
255
298
|
| player (ship, boards) | the player does not run, scrub, or caption | |
|
|
299
|
+
| social (each image) | the lockup leaves its place or the centre square, the ring is cut, type under the floor, a share image over 300 KB | how it reads at 128pt: the review questions |
|
|
300
|
+
| library (`--check`) | a library file is not the one approved, or the kit no longer draws it within its tolerance | a file that was approved and is wrong |
|
|
256
301
|
|
|
257
302
|
The gates read the DOM Chromium laid out for the PDF; nothing is inferred from
|
|
258
303
|
the spec. What no gate sees: the argument, the pacing, and whether the right
|
|
@@ -306,7 +351,9 @@ component was chosen. That is the review.
|
|
|
306
351
|
4. **A scratch voice.** The Wand OS film timed its board against a voice from
|
|
307
352
|
macOS `say`; the chat sandbox has none, so timing here is words at `wpm`.
|
|
308
353
|
A recorded voiceover passed as `audio` leads the player.
|
|
309
|
-
|
|
354
|
+
5. **Email surfaces**: declared in §1's spirit, not yet in the table. Banners
|
|
355
|
+
exist on the interim brand, drawn from its composition (§14); on the other
|
|
356
|
+
brands they are still to come.
|
|
310
357
|
|
|
311
358
|
## 12. Talks: motion and the presenter
|
|
312
359
|
|
|
@@ -378,3 +425,122 @@ direction (the line, camera, motion, on screen, sound, into next).
|
|
|
378
425
|
- **Both brands:** the board is one job; `--brand next` builds it on the
|
|
379
426
|
website's brand beside the first. Frames drawn as sketches or on brand roles
|
|
380
427
|
follow; an image frame is per brand when it shows the brand.
|
|
428
|
+
|
|
429
|
+
## 14. Social images
|
|
430
|
+
|
|
431
|
+
A brand that carries an approved composition draws its social images from it
|
|
432
|
+
(`node wand.js social <social.json>`, `kit/lib/social.js`), not from a page.
|
|
433
|
+
The interim brand does: its X header, LinkedIn banner, LinkedIn company
|
|
434
|
+
banner and avatar (approved 2026-10-22) measured into one artwork in master
|
|
435
|
+
units (`brand-interim/assets/social/composition.json`: the planet and its
|
|
436
|
+
glow, four trails with their tint and fade, eight dots, the hero's oval, the
|
|
437
|
+
lockup, the marks), drawn by `brand-interim/lib/composition.js`. Every format
|
|
438
|
+
is a window onto it at one scale (`formats`), so a part never changes its
|
|
439
|
+
proportion to the others. Redrawn from it, the three approved banners match
|
|
440
|
+
their exports within 2.5 to 3.8 levels in 255.
|
|
441
|
+
|
|
442
|
+
| Kind | Size (export) | How it sits on the composition |
|
|
443
|
+
|---|---|---|
|
|
444
|
+
| `linkedin-banner` | 1584 × 396 (2x) | the approved banner's window |
|
|
445
|
+
| `x-header` | 1500 × 500 (2x) | the approved header's: lockup 28 higher, ring 38 left |
|
|
446
|
+
| `linkedin-company` | 1128 × 191 (2x) | the approved company banner's |
|
|
447
|
+
| `share` | 1200 × 630 | the art from the planet's rim to past the ring; the lockup set on its own in the centre square |
|
|
448
|
+
| `square` | 1080 × 1080 | the art's right half on its diagonal; the lockup in the corner it leaves |
|
|
449
|
+
| `avatar` | 800 × 800 | `avatar.svg` full bleed; every platform cuts its own circle |
|
|
450
|
+
| `profile-photo` | 800 × 800 | the banner's art behind the profile photo's circle, continued below the banner's edge, a cut-out of the person over it in the brand's photo grade |
|
|
451
|
+
| `icons` | 16, 32, 48, 180, 192, 512 | `avatar.svg` set at each size: the favicons as the disc on transparent, the apple-touch and manifest icons full bleed (iOS and Android cut their own shape); `favicon.ico` (16, 32, 48), `favicon.svg`, `site.webmanifest` |
|
|
452
|
+
|
|
453
|
+
**Start from what is live.** Before redrawing a page's preview, read it as
|
|
454
|
+
the feeds do: `node wand.js social --audit <url> [more urls]` reads each
|
|
455
|
+
page's og: and twitter: tags and its image, and shows that image in
|
|
456
|
+
LinkedIn's compact card, Slack's square, X's 2:1 and WhatsApp's thumbnail,
|
|
457
|
+
with the centre square outlined (`audit/audit.png`). Its rows name what the
|
|
458
|
+
2026-10-23 fix found by hand: no image, missing tags, an em dash, an
|
|
459
|
+
og:title that repeats the image, one image for every page, a file over 300
|
|
460
|
+
KB or off 1.91:1. A chat without web access is told so and passes a saved
|
|
461
|
+
page and its image instead (`--image`). A share card's `before` (the image
|
|
462
|
+
live now) puts the old image above the new one in the preview.
|
|
463
|
+
|
|
464
|
+
**A share image (og:image) is seen small and cut** (Hope Frank's feedback,
|
|
465
|
+
2026-10-23, on Rotem Alaluf's post and a Slack unfurl; `runs/2026-10-23-wand-og-fix`):
|
|
466
|
+
|
|
467
|
+
- Slack and WhatsApp show a square cut from the image's centre, so the
|
|
468
|
+
wordmark and the words sit inside the centre square (x 285 to 915 of 1200),
|
|
469
|
+
24px clear of it; the composition's gate and, on a page, the crop row hold
|
|
470
|
+
it. The banners' wide, stepped lockup does not survive that cut: the share
|
|
471
|
+
image sets it left-aligned without the step.
|
|
472
|
+
- LinkedIn shows a link in a post with text as a compact card, the whole
|
|
473
|
+
image about 128pt wide: the words as large as the square allows (64px for
|
|
474
|
+
the site's line), the wordmark at 1.5x the lockup's ratio, and no small
|
|
475
|
+
print at all.
|
|
476
|
+
- One image per page. An article carries its own headline, verbatim (X now
|
|
477
|
+
shows a link card's image with only the domain over it). The site's own
|
|
478
|
+
image carries its line.
|
|
479
|
+
- The `og:title` does not repeat the image's words (the site's became
|
|
480
|
+
`Wand AI`), and nothing in the tags carries an em dash. `head-tags.html`
|
|
481
|
+
holds each page's block: the image's absolute https URL, type, size and alt,
|
|
482
|
+
and one `twitter:card` with the X tags.
|
|
483
|
+
- Every upload goes to a new file name or folder, since every platform caches
|
|
484
|
+
an image by its URL; then LinkedIn Post Inspector, and Slack after its
|
|
485
|
+
cache (about 30 minutes). A post made before keeps its old preview.
|
|
486
|
+
|
|
487
|
+
**The hand-over carries its own instructions.** Every `social` job writes
|
|
488
|
+
`INSTALL.md` beside the images: where each file goes (the banner's pencil,
|
|
489
|
+
the company page's header, the upload folder), the Post Inspector and Sharing
|
|
490
|
+
Debugger links for each page, the cache to wait out, and that nothing is
|
|
491
|
+
verified until it is live. With the PNGs, `head-tags.html` and `preview.png`,
|
|
492
|
+
it goes into one zip (`<name>-<date>.zip`), which is what a web developer or
|
|
493
|
+
a social lead receives. The build prints review questions under the preview,
|
|
494
|
+
the ones that settled the 2026-10-23 cards: does the lockup read at 128pt,
|
|
495
|
+
does Slack's square keep it whole, does the phrase end where the dots meet
|
|
496
|
+
it, is the ring whole and clear, is the banner's lockup clear of the photo.
|
|
497
|
+
|
|
498
|
+
**A profile photo that continues the banner** needs a cut-out of the person
|
|
499
|
+
(a PNG with a transparent ground): Photos or Preview on a Mac lift a subject
|
|
500
|
+
in one step. The kit does not cut a person out itself; from a plain photo it
|
|
501
|
+
asks for the cut-out rather than guess an edge. Its circle is placed where
|
|
502
|
+
LinkedIn's desktop profile puts it; on mobile the photo sits elsewhere and the
|
|
503
|
+
art lines up only roughly, which the dark ground hides.
|
|
504
|
+
|
|
505
|
+
On a brand without a composition, social cards are pages on the `square` and
|
|
506
|
+
`og` surfaces; the crop row warns when a share image's words leave the
|
|
507
|
+
centre square.
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
## 15. The library: approved files, handed out as they are
|
|
511
|
+
|
|
512
|
+
Most asks for a Wand file are not design jobs: "send me the LinkedIn
|
|
513
|
+
banner", "the logo on dark", "the favicon set for the site". The answer is
|
|
514
|
+
the file a person approved, not a new drawing of it. The kit carries those
|
|
515
|
+
files in `library/` (`kit/library/index.json`): on the interim brand the
|
|
516
|
+
LinkedIn banner, the X header, the company banner, the avatar, the share
|
|
517
|
+
images for wand.ai and the NandaIndex article with their tags, and the
|
|
518
|
+
site's icons; on both live brands the wordmark, the mark and the slide art,
|
|
519
|
+
which it names inside the brand folders rather than copying.
|
|
520
|
+
|
|
521
|
+
- **List, then hand over.** `node wand.js library [words]` lists what there
|
|
522
|
+
is; `node wand.js library get <id> --to <folder>` copies it and prints where
|
|
523
|
+
each file goes and who approved it. It needs no browser. A bare name
|
|
524
|
+
(`wordmark`) resolves on the brand the rule gives; a vague one lists the
|
|
525
|
+
candidates.
|
|
526
|
+
- **Never redraw an approved file** to hand it over, never re-export or
|
|
527
|
+
recompress it, never retouch it. If the file asked for is not in the
|
|
528
|
+
library, say so and offer to make it (`social`, or a page): what the kit
|
|
529
|
+
makes is a candidate until a person approves it.
|
|
530
|
+
- **One file, one record.** Each carries its size, use, approval and
|
|
531
|
+
sha256; `get` refuses a copy that does not match.
|
|
532
|
+
- **The library and the kit cannot drift.** `node wand.js library --check`
|
|
533
|
+
proves every file is the one approved (its sha256), then draws again every
|
|
534
|
+
file the kit can draw, from the recipes in the index, and compares: within
|
|
535
|
+
its tolerance it passes; a visible difference warns (a 2px move of the
|
|
536
|
+
share image's lockup does); past 4 levels in 255 or 2% of pixels visibly
|
|
537
|
+
off it fails (a 6px move does). The share images are the files delivered
|
|
538
|
+
on 2026-10-23, drawn at 2x and reduced, which the kit's 1x redraw matches
|
|
539
|
+
within 0.75 levels; every other file is the kit's own, matched exactly.
|
|
540
|
+
- **A file enters only once approved**, through `tools/library.mjs` in the
|
|
541
|
+
repo (`add` for a file, `build` to draw the recipes and rewrite each
|
|
542
|
+
record). A changed sha256 is a changed approved file: the CHANGELOG says so.
|
|
543
|
+
|
|
544
|
+
What is deliberately not in it: the square card and the light-ground
|
|
545
|
+
versions (never approved), profile photos (one person's), and the next
|
|
546
|
+
brand (no approved social design, and its face's licence is open).
|
package/SKILL.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wand-design
|
|
3
|
-
description: Rebrand or create Wand
|
|
3
|
+
description: Rebrand or create Wand decks, documents, storyboards and social images on any Wand brand, or hand out approved Wand files (logos, banners, link previews, icons). Use for branded work or a Wand asset.
|
|
4
4
|
compatibility: Requires Node.js 18+, code execution enabled in claude.ai (Settings > Features), and a Chromium the kit can find (Playwright's cache or the system). No network needed once installed. Python 3 embeds fonts in the .pptx; without it the deck ships with the faces named, not embedded.
|
|
5
5
|
license: Proprietary - Wand AI
|
|
6
6
|
metadata:
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.5.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
|
|
@@ -25,7 +25,9 @@ node wand.js doctor
|
|
|
25
25
|
|
|
26
26
|
Every row must be clear, and `chromium` must name a binary. If it does not,
|
|
27
27
|
**stop and say so**: nothing renders without a browser, and never report checks
|
|
28
|
-
you did not run.
|
|
28
|
+
you did not run. The one exception is handing over an approved file
|
|
29
|
+
(`library`, below), which needs no browser. Every path below is relative to
|
|
30
|
+
the kit folder.
|
|
29
31
|
|
|
30
32
|
## Whichever Wand skill brought you here
|
|
31
33
|
|
|
@@ -57,31 +59,56 @@ page. `node wand.js components` lists the vocabulary.
|
|
|
57
59
|
|
|
58
60
|
## Which brand
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
the
|
|
62
|
+
Three brands, one kit: `current` (Geist), `next` (the staging website's) and
|
|
63
|
+
`interim` (the live wand.ai's as its approved social design sets it: Geist
|
|
64
|
+
and Newsreader on a near-black ground, the metallic oval and its trails). `doctor` ends
|
|
65
|
+
with the brand rule: which one is the default, and the words that ask for
|
|
66
|
+
each of the others. Follow it as printed. When the user names no brand, build
|
|
67
|
+
on the default without asking; when their words ask for another, pass
|
|
64
68
|
`--brand` to `new`. One brand per piece, never a mix, and the review note
|
|
65
69
|
says which. The rule lives in the kit, not here, so it can change without
|
|
66
70
|
anyone reinstalling the skill.
|
|
67
71
|
|
|
68
|
-
**The same piece on
|
|
69
|
-
(or `current`) builds the job again on that brand, into
|
|
70
|
-
beside the first. Nothing in the job changes.
|
|
72
|
+
**The same piece on another brand:** `node wand.js ship <job> --brand next`
|
|
73
|
+
(or `interim`, or `current`) builds the job again on that brand, into
|
|
74
|
+
`out-<brand>/` beside the first. Nothing in the job changes.
|
|
71
75
|
|
|
72
76
|
## Read only what the job needs
|
|
73
77
|
|
|
74
78
|
| Job | Read |
|
|
75
79
|
|---|---|
|
|
80
|
+
| An existing Wand file: a logo, a banner, a link preview, the icons, slide art | nothing: `node wand.js library` (PROMPT.md §15 if in doubt) |
|
|
76
81
|
| A document, a two-pager, a case study | `PROMPT.md` §5 and `templates/page.mjs`; `examples/overview/job.mjs` for a finished one |
|
|
77
82
|
| A deck | §5 and `templates/slide.mjs` |
|
|
78
83
|
| An animated deck, a talk, a live demo | §12 and `templates/slide.mjs`; `examples/talk/job.mjs` for a finished one |
|
|
79
84
|
| A storyboard from a script | §13 and `templates/storyboard.mjs`; `examples/storyboard/job.mjs` |
|
|
80
|
-
| Social
|
|
85
|
+
| Social images on the interim brand: banners, link previews, icons, a profile photo | PROMPT.md §14 and `examples/social/social.json` |
|
|
86
|
+
| Social cards on another brand | `templates/card.mjs` |
|
|
81
87
|
| Edit a job this kit built | the job's `job.mjs` only, then `build` |
|
|
82
88
|
|
|
83
89
|
## The jobs
|
|
84
90
|
|
|
91
|
+
### Ask for an existing file (the cheapest job: start here when it fits)
|
|
92
|
+
|
|
93
|
+
"The LinkedIn banner", "our logo on dark", "the favicon for the site", "the
|
|
94
|
+
image wand.ai shares as": these are approved files, and the library hands
|
|
95
|
+
them over as they are (PROMPT.md §15).
|
|
96
|
+
|
|
97
|
+
1. `node wand.js library <words>` (for example `library banner`, `library
|
|
98
|
+
logo`) lists what matches; `node wand.js library` lists everything.
|
|
99
|
+
2. `node wand.js library get <id> --to <folder>`: the folder the chat
|
|
100
|
+
delivers files from (in claude.ai, `/mnt/user-data/outputs`). A bare
|
|
101
|
+
`wordmark`, `mark` or `slide-art` takes the brand the rule gives; if it
|
|
102
|
+
names several, pick by the brand rule or ask which.
|
|
103
|
+
3. Deliver the files with the `use` line it prints (where each goes) and its
|
|
104
|
+
size. For a share image, its tags file goes with it and the install steps
|
|
105
|
+
of PROMPT.md §14 apply.
|
|
106
|
+
|
|
107
|
+
Never redraw, re-export, resize or recompress a library file to hand it over.
|
|
108
|
+
If what they ask for is not there, say so and offer to make it (the social
|
|
109
|
+
job below, or a page); what you make is a draft until someone approves it,
|
|
110
|
+
and the note says so.
|
|
111
|
+
|
|
85
112
|
### Rebuild from a source they attached (a .pptx, .docx, .pdf, .html)
|
|
86
113
|
|
|
87
114
|
1. Dump the source's strings verbatim, one per line, into `content.txt`:
|
|
@@ -97,6 +124,11 @@ beside the first. Nothing in the job changes.
|
|
|
97
124
|
at `out/sheet.png`. Open a page only where something looks off. Then answer
|
|
98
125
|
the review questions the build prints under the gates, as a creative
|
|
99
126
|
director would; if the variety row names a run of pages, recompose it.
|
|
127
|
+
On a deck, no paragraph sets in more than two lines: the lines row names
|
|
128
|
+
any that do. Re-lay, never reword: two by two instead of four across, a
|
|
129
|
+
ruled row (title left, line right) instead of a narrow column. Set
|
|
130
|
+
`maxLines: 2` in the job to make it a hard gate. A source note under one
|
|
131
|
+
slide goes in that page's `footer`.
|
|
100
132
|
5. `node wand.js ship work/<name>/job.mjs --pptx` for a deck; without `--pptx`
|
|
101
133
|
for a document. Deliver the PDF (and the .pptx, and the .html) with the
|
|
102
134
|
review note.
|
|
@@ -109,7 +141,9 @@ review reads the argument instead. Three sections a page, not four.
|
|
|
109
141
|
|
|
110
142
|
On the next brand, a title's phrase is its quiet second tone and gold is kept
|
|
111
143
|
for the cover, a statement, the close and the figures; photographs go through
|
|
112
|
-
`c.photo("walk")` (the brand's set, graded), large or not at all.
|
|
144
|
+
`c.photo("walk")` (the brand's set, graded), large or not at all. On the
|
|
145
|
+
interim brand the phrase changes face instead: `<em>` sets in Newsreader, the
|
|
146
|
+
italic only on the pages that carry the art.
|
|
113
147
|
|
|
114
148
|
### Make it generic (an industry version of a client piece)
|
|
115
149
|
|
|
@@ -151,10 +185,45 @@ talk adds:
|
|
|
151
185
|
HTML with its player. Say in the note that timing is scratch timing at the
|
|
152
186
|
`wpm` given until a real read exists, and which frames are still to draw.
|
|
153
187
|
|
|
154
|
-
### Social
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
the
|
|
188
|
+
### Social images
|
|
189
|
+
|
|
190
|
+
**First, is it already approved?** `node wand.js library <words>`: if the
|
|
191
|
+
file exists, hand it over (the job above) instead of drawing it again.
|
|
192
|
+
|
|
193
|
+
**On the interim brand** the banners, link previews, square, avatar and site
|
|
194
|
+
icons are the approved design itself, drawn from the brand's composition
|
|
195
|
+
(PROMPT.md §14):
|
|
196
|
+
|
|
197
|
+
1. For a link preview that is live and wrong (someone sent a screenshot of a
|
|
198
|
+
bad unfurl), read it first: `node wand.js social --audit <url> [more]`.
|
|
199
|
+
Its rows and `audit/audit.png` show what the feeds do to it; say what is
|
|
200
|
+
wrong in the note. Without web access it says so: ask for the saved page
|
|
201
|
+
and its image and pass them (`--audit page.html --image og.png`).
|
|
202
|
+
2. Copy `examples/social/social.json` beside the work and set `line` (the
|
|
203
|
+
words), the `cards` wanted, and for each share image its page's `url`,
|
|
204
|
+
`title`, `description` and `alt`, plus `upload` (where the images will
|
|
205
|
+
live: a new folder each time) and `before` (the image live now, if any).
|
|
206
|
+
An article's share image takes its headline verbatim as `lead` and
|
|
207
|
+
`phrase`. `{ "kind": "icons", "upload": "/assets/<date>/" }` adds the
|
|
208
|
+
favicons, app icons and manifest.
|
|
209
|
+
3. `node wand.js social work/<name>/social.json`. Every image has a row; a
|
|
210
|
+
share image fails if its words leave the centre square or its type falls
|
|
211
|
+
under the floor. Look at `out/preview.png`: each image as the profile, the
|
|
212
|
+
LinkedIn compact card, Slack, X and WhatsApp show it, the live image above
|
|
213
|
+
the new one. Then answer the review questions printed under it.
|
|
214
|
+
4. Deliver the zip (`out/<name>-<date>.zip`: the images, `head-tags.html`,
|
|
215
|
+
`INSTALL.md`, the preview). `INSTALL.md` already says where each file goes
|
|
216
|
+
and how to check it; the note adds that nothing is verified until it is
|
|
217
|
+
live, and that what you drew is a draft until approved.
|
|
218
|
+
|
|
219
|
+
A profile photo that continues the LinkedIn banner is a `profile-photo` card
|
|
220
|
+
with `photo`, a cut-out of the person (transparent ground). If they gave a
|
|
221
|
+
plain photo, ask for the cut-out (Photos or Preview: lift the subject) rather
|
|
222
|
+
than cutting it yourself.
|
|
223
|
+
|
|
224
|
+
**On another brand**: `--surface square` or `og`; one `c.page()` per card;
|
|
225
|
+
`out/pages/pNN.png` are the deliverables. The crop row warns when a share
|
|
226
|
+
image's words leave the centre square: keep them there.
|
|
158
227
|
|
|
159
228
|
### Older Wand work
|
|
160
229
|
|
|
@@ -172,11 +241,15 @@ two kits, or `edit --set`; none of it applies to anything else.
|
|
|
172
241
|
Which brand it is on; what was changed from the source and why (every edit,
|
|
173
242
|
every cut); the gate table as printed; what a human still has to decide (a figure to confirm, a
|
|
174
243
|
quote to clear, a claim legal should see). A file delivered without the gate
|
|
175
|
-
table has been checked by nobody.
|
|
244
|
+
table has been checked by nobody. A library file is the exception: it was
|
|
245
|
+
checked when it was approved, so its note is the `use` and `approved` lines
|
|
246
|
+
`get` prints.
|
|
176
247
|
|
|
177
248
|
## Available scripts
|
|
178
249
|
|
|
179
|
-
- **`wand.js`** — doctor, new, build, check, ship, watch, poster, gallery, components, brands
|
|
250
|
+
- **`wand.js`** — doctor, new, build, check, ship, watch, poster, social, library, gallery, components, brands
|
|
251
|
+
- **`lib/library.js`**, **`library/`** — the approved files, their records and the check
|
|
252
|
+
- **`lib/social.js`** — the social set from a brand's approved composition; **`lib/audit.js`** — a live page's link preview, read
|
|
180
253
|
- **`lib/engine.js`** — the render and the gates
|
|
181
254
|
- **`lib/components.js`** — the vocabulary and its CSS
|
|
182
255
|
- **`lib/pptx.js`**, **`tools/embed_fonts.py`** — the PowerPoint export
|
package/START-HERE.md
CHANGED
|
@@ -6,9 +6,20 @@ node wand.js new work/acme --surface letter # the default brand; doct
|
|
|
6
6
|
# write work/acme/job.mjs (pages(c)) and, for a rebuild, work/acme/content.txt
|
|
7
7
|
node wand.js build work/acme/job.mjs # gates, PDF, a PNG per page, out/sheet.png
|
|
8
8
|
node wand.js ship work/acme/job.mjs --pptx # + one-file HTML, PowerPoint
|
|
9
|
-
node wand.js ship work/acme/job.mjs --brand next # the same job on
|
|
9
|
+
node wand.js ship work/acme/job.mjs --brand next # the same job on another brand (next, interim), in out-<brand>/
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
Asked for a file that already exists (the logo, a banner, a link preview, the
|
|
13
|
+
icons), hand over the approved one: `node wand.js library banner`, then
|
|
14
|
+
`node wand.js library get linkedin-banner --to <folder>`. PROMPT.md §15.
|
|
15
|
+
|
|
16
|
+
On the interim brand, `node wand.js social examples/social/social.json` draws
|
|
17
|
+
the approved social set (banners, link previews with their tags, square,
|
|
18
|
+
avatar, a profile photo that continues the banner, the site's icons) from the
|
|
19
|
+
brand's own composition, with `INSTALL.md` and a zip of the hand-over;
|
|
20
|
+
`node wand.js social --audit <url>` reads a live page's preview first.
|
|
21
|
+
PROMPT.md §14 has the rules.
|
|
22
|
+
|
|
12
23
|
A deck's HTML is a talk: entrances, steps, a presenter view (P). A demo needs
|
|
13
24
|
a poster: `node wand.js poster demo.html --play 3`. A storyboard starts from
|
|
14
25
|
`node wand.js new work/film --surface storyboard`; its HTML plays the board.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800" role="img" aria-label="Wand"><circle cx="400" cy="400" r="400" fill="#261d3d"/><g transform="translate(180.48 300.24) scale(0.187233) translate(0 -512)"><path d="M0 530A18 18 0 0 1 18 512L352.5 512A18 18 0 0 1 370.5 530L370.5 1347A278 278 0 0 0 926.5 1347L926.5 530A18 18 0 0 1 944.5 512L1279 512A18 18 0 0 1 1297 530L1297 1347A278 278 0 0 0 1853 1347L1853 734A18 18 0 0 1 1871 716L1873 716Q1882 716 1888.13 722.59L1940.35 778.75A134.03 134.03 0 0 0 2136.65 778.75L2188.87 722.59Q2195 716 2204 716L2205.5 716A18 18 0 0 1 2223.5 734L2223.5 1347A648.5 648.5 0 0 1 1125.96 1814.89Q1111.75 1800.82 1097.54 1814.89A648.5 648.5 0 0 1 0 1347Z" fill="#ffffff"/><path d="M2021.58 -300.31A16.61 16.61 0 0 1 2055.42 -300.31A426.81 426.81 0 0 0 2465.31 109.58A16.61 16.61 0 0 1 2465.31 143.42A426.81 426.81 0 0 0 2055.42 553.31A16.61 16.61 0 0 1 2021.58 553.31A426.81 426.81 0 0 0 1611.69 143.42A16.61 16.61 0 0 1 1611.69 109.58A426.81 426.81 0 0 0 2021.58 -300.31Z" fill="#c2a1ef"/></g></svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Glyphs — Lucide
|
|
2
|
+
|
|
3
|
+
75 icons from [Lucide](https://lucide.dev) v0.469.0, **ISC licensed** (permissive:
|
|
4
|
+
use, modify and redistribute, keep the notice). They replace the numbered PNGs
|
|
5
|
+
that were reverse-extracted from a reference deck.
|
|
6
|
+
|
|
7
|
+
Two problems they fix, both of which were standing known gaps:
|
|
8
|
+
|
|
9
|
+
**Polarity.** The old glyphs were baked white or baked accent, so a white one on
|
|
10
|
+
a light-theme `surface` tile was invisible. These are single-colour stroke SVGs
|
|
11
|
+
with `stroke="currentColor"`, and the kit substitutes the theme's ink colour at
|
|
12
|
+
build time. There is no variant to pick and nothing to get wrong.
|
|
13
|
+
|
|
14
|
+
**Meaning.** They have names. A spec says `icon: "shield-check"`, not
|
|
15
|
+
`icon: "icon-17.png"`. `index.json` groups them by what a deck actually needs —
|
|
16
|
+
governance, workforce, platform, process, outcome, signal.
|
|
17
|
+
|
|
18
|
+
## How they reach the deck
|
|
19
|
+
|
|
20
|
+
As vector. pptxgenjs writes the OOXML `asvg:svgBlip` extension with a raster
|
|
21
|
+
fallback, so PowerPoint 2016+ renders the SVG and anything older gets the PNG.
|
|
22
|
+
Nothing is rasterised at build time, so the kit still needs no native
|
|
23
|
+
dependency.
|
|
24
|
+
|
|
25
|
+
## The old set
|
|
26
|
+
|
|
27
|
+
`../icons/*.png` is still there and still works — every existing spec references
|
|
28
|
+
those filenames. New specs should use glyph names. The two sets can coexist
|
|
29
|
+
indefinitely; `iconTile` resolves a name first and falls back to a filename.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-activity"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-atom"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<circle cx="12" cy="12" r="1" />
|
|
15
|
+
<path d="M20.2 20.2c2.04-2.03.02-7.36-4.5-11.9-4.54-4.52-9.87-6.54-11.9-4.5-2.04 2.03-.02 7.36 4.5 11.9 4.54 4.52 9.87 6.54 11.9 4.5Z" />
|
|
16
|
+
<path d="M15.7 15.7c4.52-4.54 6.54-9.87 4.5-11.9-2.03-2.04-7.36-.02-11.9 4.5-4.52 4.54-6.54 9.87-4.5 11.9 2.03 2.04 7.36.02 11.9-4.5Z" />
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-badge-check"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" />
|
|
15
|
+
<path d="m9 12 2 2 4-4" />
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-bell"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="M10.268 21a2 2 0 0 0 3.464 0" />
|
|
15
|
+
<path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" />
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-blocks"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<rect width="7" height="7" x="14" y="3" rx="1" />
|
|
15
|
+
<path d="M10 21V8a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H3" />
|
|
16
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!-- @license lucide-static v0.469.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-book-open"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="M12 7v14" />
|
|
15
|
+
<path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z" />
|
|
16
|
+
</svg>
|