sheleg-design-skill 1.7.0 → 1.9.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/CHANGELOG.md +116 -0
- package/README.md +6 -1
- package/bin/cli.js +7 -3
- package/cursor/rules/sheleg-design.mdc +10 -1
- package/kits/blueprint/.design-sync/config.json +14 -0
- package/kits/blueprint/.design-sync/conventions.md +52 -0
- package/kits/blueprint/README.md +14 -0
- package/kits/blueprint/package.json +29 -0
- package/kits/blueprint/src/Button.md +5 -0
- package/kits/blueprint/src/Button.tsx +33 -0
- package/kits/blueprint/src/Card.md +5 -0
- package/kits/blueprint/src/Card.tsx +24 -0
- package/kits/blueprint/src/Chip.md +5 -0
- package/kits/blueprint/src/Chip.tsx +25 -0
- package/kits/blueprint/src/CodeLine.md +14 -0
- package/kits/blueprint/src/CodeLine.tsx +28 -0
- package/kits/blueprint/src/GridField.md +14 -0
- package/kits/blueprint/src/GridField.tsx +23 -0
- package/kits/blueprint/src/Heading.md +5 -0
- package/kits/blueprint/src/Heading.tsx +19 -0
- package/kits/blueprint/src/RegistrationMarks.md +17 -0
- package/kits/blueprint/src/RegistrationMarks.tsx +34 -0
- package/kits/blueprint/src/Rule.md +5 -0
- package/kits/blueprint/src/Rule.tsx +18 -0
- package/kits/blueprint/src/RuledColumn.md +17 -0
- package/kits/blueprint/src/RuledColumn.tsx +25 -0
- package/kits/blueprint/src/Stat.md +5 -0
- package/kits/blueprint/src/Stat.tsx +17 -0
- package/kits/blueprint/src/index.ts +23 -0
- package/kits/blueprint/src/styles.css +233 -0
- package/kits/blueprint/tsconfig.json +15 -0
- package/kits/cyclorama/.design-sync/config.json +12 -0
- package/kits/cyclorama/.design-sync/conventions.md +69 -0
- package/kits/cyclorama/README.md +23 -0
- package/kits/cyclorama/package.json +14 -0
- package/kits/cyclorama/src/AppWindow.md +27 -0
- package/kits/cyclorama/src/AppWindow.tsx +46 -0
- package/kits/cyclorama/src/Button.md +26 -0
- package/kits/cyclorama/src/Button.tsx +43 -0
- package/kits/cyclorama/src/Card.md +19 -0
- package/kits/cyclorama/src/Card.tsx +33 -0
- package/kits/cyclorama/src/Chip.md +19 -0
- package/kits/cyclorama/src/Chip.tsx +34 -0
- package/kits/cyclorama/src/ComparePanel.md +27 -0
- package/kits/cyclorama/src/ComparePanel.tsx +61 -0
- package/kits/cyclorama/src/FieldStop.md +29 -0
- package/kits/cyclorama/src/FieldStop.tsx +33 -0
- package/kits/cyclorama/src/Heading.md +20 -0
- package/kits/cyclorama/src/Heading.tsx +27 -0
- package/kits/cyclorama/src/Rule.md +18 -0
- package/kits/cyclorama/src/Rule.tsx +27 -0
- package/kits/cyclorama/src/Stat.md +19 -0
- package/kits/cyclorama/src/Stat.tsx +25 -0
- package/kits/cyclorama/src/StatusPill.md +31 -0
- package/kits/cyclorama/src/StatusPill.tsx +37 -0
- package/kits/cyclorama/src/index.ts +25 -0
- package/kits/cyclorama/src/styles.css +569 -0
- package/kits/cyclorama/tsconfig.json +15 -0
- package/kits/field-notes/src/styles.css +5 -2
- package/kits/maquette/.design-sync/config.json +14 -0
- package/kits/maquette/.design-sync/conventions.md +54 -0
- package/kits/maquette/README.md +14 -0
- package/kits/maquette/package.json +29 -0
- package/kits/maquette/src/AquaPill.md +15 -0
- package/kits/maquette/src/AquaPill.tsx +30 -0
- package/kits/maquette/src/Button.md +5 -0
- package/kits/maquette/src/Button.tsx +33 -0
- package/kits/maquette/src/Card.md +5 -0
- package/kits/maquette/src/Card.tsx +24 -0
- package/kits/maquette/src/Chip.md +5 -0
- package/kits/maquette/src/Chip.tsx +25 -0
- package/kits/maquette/src/CliLine.md +14 -0
- package/kits/maquette/src/CliLine.tsx +27 -0
- package/kits/maquette/src/Heading.md +5 -0
- package/kits/maquette/src/Heading.tsx +19 -0
- package/kits/maquette/src/LeaderLabel.md +17 -0
- package/kits/maquette/src/LeaderLabel.tsx +24 -0
- package/kits/maquette/src/ModelBlock.md +21 -0
- package/kits/maquette/src/ModelBlock.tsx +39 -0
- package/kits/maquette/src/Rule.md +5 -0
- package/kits/maquette/src/Rule.tsx +18 -0
- package/kits/maquette/src/Stat.md +5 -0
- package/kits/maquette/src/Stat.tsx +17 -0
- package/kits/maquette/src/index.ts +24 -0
- package/kits/maquette/src/styles.css +253 -0
- package/kits/maquette/tsconfig.json +15 -0
- package/kits/prism/.design-sync/config.json +14 -0
- package/kits/prism/.design-sync/conventions.md +50 -0
- package/kits/prism/README.md +14 -0
- package/kits/prism/package.json +29 -0
- package/kits/prism/src/BenchmarkRow.md +13 -0
- package/kits/prism/src/BenchmarkRow.tsx +25 -0
- package/kits/prism/src/Button.md +5 -0
- package/kits/prism/src/Button.tsx +33 -0
- package/kits/prism/src/Card.md +5 -0
- package/kits/prism/src/Card.tsx +24 -0
- package/kits/prism/src/Chip.md +5 -0
- package/kits/prism/src/Chip.tsx +25 -0
- package/kits/prism/src/Heading.md +5 -0
- package/kits/prism/src/Heading.tsx +19 -0
- package/kits/prism/src/InstallLine.md +16 -0
- package/kits/prism/src/InstallLine.tsx +29 -0
- package/kits/prism/src/RepoBadge.md +13 -0
- package/kits/prism/src/RepoBadge.tsx +25 -0
- package/kits/prism/src/Rule.md +5 -0
- package/kits/prism/src/Rule.tsx +18 -0
- package/kits/prism/src/Stat.md +5 -0
- package/kits/prism/src/Stat.tsx +17 -0
- package/kits/prism/src/Wash.md +17 -0
- package/kits/prism/src/Wash.tsx +23 -0
- package/kits/prism/src/index.ts +24 -0
- package/kits/prism/src/styles.css +223 -0
- package/kits/prism/tsconfig.json +15 -0
- package/kits/showroom/.design-sync/config.json +14 -0
- package/kits/showroom/.design-sync/conventions.md +50 -0
- package/kits/showroom/README.md +14 -0
- package/kits/showroom/package.json +29 -0
- package/kits/showroom/src/Button.md +5 -0
- package/kits/showroom/src/Button.tsx +33 -0
- package/kits/showroom/src/Card.md +5 -0
- package/kits/showroom/src/Card.tsx +24 -0
- package/kits/showroom/src/Chip.md +5 -0
- package/kits/showroom/src/Chip.tsx +25 -0
- package/kits/showroom/src/ColumnHeader.md +15 -0
- package/kits/showroom/src/ColumnHeader.tsx +33 -0
- package/kits/showroom/src/DataRow.md +14 -0
- package/kits/showroom/src/DataRow.tsx +31 -0
- package/kits/showroom/src/Heading.md +5 -0
- package/kits/showroom/src/Heading.tsx +19 -0
- package/kits/showroom/src/Rule.md +5 -0
- package/kits/showroom/src/Rule.tsx +18 -0
- package/kits/showroom/src/Specimen.md +26 -0
- package/kits/showroom/src/Specimen.tsx +44 -0
- package/kits/showroom/src/Stat.md +5 -0
- package/kits/showroom/src/Stat.tsx +17 -0
- package/kits/showroom/src/StatusChip.md +19 -0
- package/kits/showroom/src/StatusChip.tsx +26 -0
- package/kits/showroom/src/index.ts +23 -0
- package/kits/showroom/src/styles.css +249 -0
- package/kits/showroom/tsconfig.json +15 -0
- package/package.json +2 -2
- package/plugins/sheleg-design/.claude-plugin/plugin.json +2 -2
- package/plugins/sheleg-design/skills/sheleg-design/SKILL.md +5 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/blueprint.md +336 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/cyclorama.md +417 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/field-notes.md +22 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/instrument-console.md +12 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/maquette.md +323 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/prism.md +297 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/showroom.md +303 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/blueprint.css +143 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/cyclorama.css +201 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/field-notes.css +5 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/maquette.css +154 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/prism.css +138 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/showroom.css +160 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/workbench.md +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,122 @@ All notable changes to this project are documented in this file. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions
|
|
5
5
|
follow [SemVer](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.9.0] - 2026-08-09
|
|
8
|
+
|
|
9
|
+
Four style packs, taking the library from eight to twelve — and a fix to the
|
|
10
|
+
thing that would have made twelve worse than eight.
|
|
11
|
+
|
|
12
|
+
Extracted from four live references on 2026-08-09. Three of them sell vector
|
|
13
|
+
databases and none of them collapse into each other; two are the same company's
|
|
14
|
+
project page and product page, and they share a type stack and nothing else.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`showroom`** — from [attio.com](https://attio.com/). A white gallery where
|
|
19
|
+
one real product surface is the exhibit, under a **seven-layer shadow**. The
|
|
20
|
+
reference declares its palette in **CIE Lab**, which this repo's palette gate
|
|
21
|
+
cannot parse; every value was converted by painting it into a canvas and
|
|
22
|
+
reading the sRGB bytes back — the browser's conversion, not ours.
|
|
23
|
+
- **`blueprint`** — from [pinecone.io](https://www.pinecone.io/). A drawing
|
|
24
|
+
sheet: a 32px grid, ruled column boundaries, corner registration marks, one
|
|
25
|
+
electric blue that works as ink *and* as fill at 7.53:1 both ways, and **no
|
|
26
|
+
radius anywhere**.
|
|
27
|
+
- **`prism`** — from [milvus.io](https://milvus.io/). One static iridescent wash
|
|
28
|
+
with a hard bottom edge, a heavy grotesque display over **mono body copy** —
|
|
29
|
+
the inversion that makes a page read as a project rather than a company.
|
|
30
|
+
- **`maquette`** — from [zilliz.com](https://zilliz.com/). A near-black table
|
|
31
|
+
with a cream axonometric model on it, mono block labels, and the only accent in
|
|
32
|
+
this library's four new packs that works as text (15.49:1).
|
|
33
|
+
- Four reference kits, each with the six-component spine plus four signature
|
|
34
|
+
parts, and four routing scenario pairs (**T16–T19**), every one with its
|
|
35
|
+
negative branch.
|
|
36
|
+
|
|
37
|
+
### Fixed — the routing table, which was a list
|
|
38
|
+
|
|
39
|
+
**Five of the eight shipped packs named no other pack at all.** Forks existed
|
|
40
|
+
only in `field-notes`, `cyclorama` and `atrium`, and every one pointed backwards
|
|
41
|
+
at packs that never pointed back — so an agent entering at `instrument-console`,
|
|
42
|
+
which is where any infrastructure brief lands first, never learned that a
|
|
43
|
+
distinction existed. Four more one-way forks would have made twelve packs with
|
|
44
|
+
eight dead ends.
|
|
45
|
+
|
|
46
|
+
- `instrument-console`, `workbench`, `field-notes` and `cyclorama` each gain the
|
|
47
|
+
mirror clause for the new pack that forks against them.
|
|
48
|
+
- **A new `validate.py` check enforces it:** a markdown link from one pack to
|
|
49
|
+
another must be reciprocated. Watched failing against a planted defect before
|
|
50
|
+
it landed.
|
|
51
|
+
|
|
52
|
+
### Fixed — in the packs, not in the references
|
|
53
|
+
|
|
54
|
+
- **`blueprint`'s reference sets pure black as body ink**, on 316 elements, which
|
|
55
|
+
the doctrine bans. The pack ships the reference's *own* second ink `#111827`
|
|
56
|
+
(136 elements) and does not pretend it is the same colour: the two sit **21.2
|
|
57
|
+
apart** in OKLab.
|
|
58
|
+
- **`showroom`'s reference names `#A4ADBA` "caption-foreground"** and it measures
|
|
59
|
+
**2.27:1** on its own white field. Kept, renamed `--disabled`, and captions
|
|
60
|
+
routed to an ink that passes.
|
|
61
|
+
- **`prism`'s reference sets 72px display type in `#00B3FF`** — **2.36:1**, which
|
|
62
|
+
fails even the relaxed large-text floor. The cyan is a fill in this pack.
|
|
63
|
+
- **Neither `blueprint` nor `prism` ships a `prefers-reduced-motion` branch** —
|
|
64
|
+
zero blocks each, against live marquee, ping, pulse and scroll. Both packs
|
|
65
|
+
require the branch their references omit.
|
|
66
|
+
- **`maquette`'s status palette is derived, not extracted**, and the token layer
|
|
67
|
+
says so at the declaration. The reference exposes none; the first set this run
|
|
68
|
+
reached for was a framework default, and the palette gate caught it colliding.
|
|
69
|
+
|
|
70
|
+
## [1.8.0] - 2026-08-08
|
|
71
|
+
|
|
72
|
+
An eighth style pack, and the first one whose reference already implements this
|
|
73
|
+
skill's own core pattern.
|
|
74
|
+
|
|
75
|
+
`cyclorama` is extracted from [codos.ai](https://www.codos.ai/): a pale field
|
|
76
|
+
that breathes through **six pastel stops on a 32-second loop** under near-black
|
|
77
|
+
ink that never moves with it, a **monospaced typewriter serif** over a
|
|
78
|
+
monospaced sans, one orange used only as a fill, and no shadows anywhere. Its
|
|
79
|
+
reference ships GSAP ScrollTrigger with real pinning and two WebGL canvases
|
|
80
|
+
whose formation holds and then redeploys — principle 3 in production rather than
|
|
81
|
+
in a doc.
|
|
82
|
+
|
|
83
|
+
### Added
|
|
84
|
+
|
|
85
|
+
- **`styles/cyclorama.md`** on the thirteen-heading widened contract plus
|
|
86
|
+
`## Motion flavor`, with an addressable origin and every ratio computed by
|
|
87
|
+
importing `test/validate_palette.py` rather than by a second implementation.
|
|
88
|
+
- **`styles/tokens/cyclorama.css`** — the six cycle stops as named tokens, one
|
|
89
|
+
ease, three durations plus the 32s loop, a five-step radius ramp whose nesting
|
|
90
|
+
is arithmetic, and an inline accent-dot cursor.
|
|
91
|
+
- **`kits/cyclorama/`** — the six-component spine plus four signature parts:
|
|
92
|
+
`FieldStop` (the six stops as six static surfaces — the cycle itself does not
|
|
93
|
+
cross the border), `AppWindow` (a hairline frame with **no fill**, so the
|
|
94
|
+
field shows through it), `StatusPill` and `ComparePanel`.
|
|
95
|
+
- **`docs/adr/0001-style-pack-naming.md`** — restored to `main`. It was written
|
|
96
|
+
on a branch that held at its stage-0 gate and never merged, so the decision
|
|
97
|
+
register began at `0002` for four days while the rule it records was already
|
|
98
|
+
binding. It is why this pack is `cyclorama` and not `codos`.
|
|
99
|
+
- **T15** in `test/scenarios.md` — a routing pair with its negative branch, so
|
|
100
|
+
"is `cyclorama` distinguishable from `field-notes`?" can fail in the
|
|
101
|
+
interesting direction.
|
|
102
|
+
|
|
103
|
+
### Fixed — in the pack, not in the reference
|
|
104
|
+
|
|
105
|
+
- The reference paints its section eyebrows in the accent on the field, which
|
|
106
|
+
measures **1.71–1.97:1** across the six stops. This pack does not propagate
|
|
107
|
+
it: the accent is a fill, eyebrows take `--ink-soft` at 8.36:1. The three
|
|
108
|
+
darkened-orange candidates are recorded in `## Gotchas` **with their numbers**,
|
|
109
|
+
because each one trades a WCAG failure for a colour-blindness collision with
|
|
110
|
+
`--danger` or `--warning` — there is no text-safe orange in this palette, and
|
|
111
|
+
the next reader should not have to rediscover that.
|
|
112
|
+
- The pack states that `--accent` and `--signal` sit 6.8 apart under protanopia
|
|
113
|
+
and that **the palette gate cannot see it**, because `--signal` is not one of
|
|
114
|
+
the names it treats as semantic. Written down rather than renamed around: a
|
|
115
|
+
token renamed to satisfy a checker is worse than an unchecked token that says
|
|
116
|
+
so out loud.
|
|
117
|
+
- The reference's own display fallback is `Fraunces`, which is **proportional**,
|
|
118
|
+
while the face it replaces is monospaced — so a reader without the licensed
|
|
119
|
+
font gets a hero that reflows rather than merely restyles. The pack ships
|
|
120
|
+
measured substitutes instead (Courier Prime 0.600, Cutive Mono 0.605 against
|
|
121
|
+
the original's 0.590).
|
|
122
|
+
|
|
7
123
|
## [1.7.0] - 2026-08-05
|
|
8
124
|
|
|
9
125
|
The Claude Design border, and the first code this skill has ever shipped.
|
package/README.md
CHANGED
|
@@ -49,6 +49,11 @@ voice is the timeline and slides therefore never animate).
|
|
|
49
49
|
| `atrium` | warm cream daylight field with no dark bands, one terracotta accent, light serif with italic asides, fluted-glass hero over photography | consumer health, longevity & diagnostics, wellness, premium care, high-trust DTC |
|
|
50
50
|
| `orchard` | warm oat field of rounded slabs, sage brand + one candy-orange action, rounded geometric display, soft-3D pills built from inset light | friendly consumer biotech, DTC wellness, testing kits & supplements |
|
|
51
51
|
| `field-notes` | warm green-cast paper ruled by hairlines, one rust accent, a hero that dissolves into the page instead of ending, numbered mono eyebrows, crop marks, colour that encodes how a claim is known | open-source & developer tools sold on auditability — code intelligence, provenance, evals, agent memory |
|
|
52
|
+
| `showroom` | white gallery, near-black ink, one blue that works as link and as fill, Inter Display + Inter + JetBrains Mono, a seven-layer shadow framing one real product surface | product-led companies whose best argument is the application on screen |
|
|
53
|
+
| `blueprint` | white drawing stock, 32px grid, ruled column edges, corner registration marks, one electric blue, zero radius anywhere | infrastructure sold on precision — vector databases, search, storage and query engines |
|
|
54
|
+
| `prism` | one static iridescent wash with a hard bottom edge, heavy grotesque display over mono body copy, cyan as a fill only | an open-source project's front door, where the first action is a command |
|
|
55
|
+
| `maquette` | near-black table, cream ink and cream axonometric models, mono block labels, pale aqua that works as text, one offset shadow | enterprise data infrastructure sold to an architecture buyer |
|
|
56
|
+
| `cyclorama` | a pale field cycling through six pastel stops on a 32s loop under near-black ink that never moves with it, a monospaced typewriter serif over mono, one orange used only as a fill, a particle organ that holds then redeploys, no shadows anywhere | enterprise AI transformation, applied-AI services, technical consultancies — where what is sold is a change of state and there is no screenshot worth showing |
|
|
52
57
|
|
|
53
58
|
Each pack locks palette, type, texture, motion tokens, signature motifs and
|
|
54
59
|
bans — and ships a `tokens/<pack>.css` to copy verbatim, so the agent never
|
|
@@ -121,7 +126,7 @@ skills.
|
|
|
121
126
|
| `DESIGN_SYNC_BRIDGE.md` | The Claude Design contract: what a pack sends to claude.ai/design and in what shape, the rule for each of the four reference types, and the border motion does not cross |
|
|
122
127
|
| `FIGMA_BRIDGE.md` | The design↔code contract: how a pack's tokens map onto Figma variable collections and modes, how to implement a design without importing raw values, and what cannot cross the border |
|
|
123
128
|
| `AI_PRODUCT_PATTERNS.md` | The surfaces a model drives: the five states of a call, streaming instead of spinners, latency, provenance and uncertainty, agent confirmations, and the bans that keep it honest |
|
|
124
|
-
| `styles/*.md` | The
|
|
129
|
+
| `styles/*.md` | The twelve style packs — palette, type, texture, motion tokens, motifs, bans, and the traps each one carries |
|
|
125
130
|
| `styles/tokens/*.css` | The ready-made token layer per pack, copied verbatim instead of transcribed (workbench ships a light `:root` plus a `data-theme="dark"` twin) |
|
|
126
131
|
| `styles/STYLE_PACK_TEMPLATE.md` | The pack contract as a skeleton, so a new style is authored against the same headings rather than improvised |
|
|
127
132
|
|
package/bin/cli.js
CHANGED
|
@@ -230,11 +230,15 @@ ${c("bold", "What it installs")}
|
|
|
230
230
|
SHELEG_DESIGN.md the full reference (architecture, recipes, why it works)
|
|
231
231
|
FIGMA_BRIDGE.md the design↔code contract (tokens ⇄ Figma variables)
|
|
232
232
|
AI_PRODUCT_PATTERNS.md chat / agent / streaming surfaces (honest state)
|
|
233
|
-
styles/
|
|
233
|
+
styles/ twelve style packs — instrument-console (dark console),
|
|
234
234
|
editorial-luxury (warm editorial), workbench (light/dark
|
|
235
235
|
product UI), briefing-room (dark 16:9 presentation deck),
|
|
236
236
|
atrium (warm cream consumer health), orchard (friendly
|
|
237
|
-
consumer biotech), field-notes (warm paper dev tools)
|
|
237
|
+
consumer biotech), field-notes (warm paper dev tools),
|
|
238
|
+
cyclorama (a pastel field on a 32s cycle), showroom
|
|
239
|
+
(the product as the exhibit), blueprint (a drawing sheet,
|
|
240
|
+
zero radius), prism (one iridescent wash over mono body),
|
|
241
|
+
maquette (cream axonometric models on a dark table) —
|
|
238
242
|
plus a ready-made token CSS per pack and
|
|
239
243
|
STYLE_PACK_TEMPLATE.md for authoring more
|
|
240
244
|
`);
|
|
@@ -315,7 +319,7 @@ function main() {
|
|
|
315
319
|
`\n${c("green", "✓")} ${c("bold", "SHELEG Design")} installed to ${c("blue", rel + "/")}\n` +
|
|
316
320
|
` ${c("dim", "SKILL.md")} the agent skill\n` +
|
|
317
321
|
` ${c("dim", "SHELEG_DESIGN.md")} the full reference\n` +
|
|
318
|
-
` ${c("dim", "styles/")} style packs + token CSS (instrument-console / editorial-luxury / workbench / briefing-room / atrium / orchard / field-notes)\n\n` +
|
|
322
|
+
` ${c("dim", "styles/")} style packs + token CSS (instrument-console / editorial-luxury / workbench / briefing-room / atrium / orchard / field-notes / cyclorama / showroom / blueprint / prism / maquette)\n\n` +
|
|
319
323
|
`Your Cursor / Claude agent can now discover the skill and build\n` +
|
|
320
324
|
`cinematic, scroll-driven pages — or style product UI (dashboards,\n` +
|
|
321
325
|
`admin, internal tools) from the workbench pack — on its principles.\n\n` +
|
|
@@ -17,7 +17,16 @@ never animate; atrium — warm cream consumer-health field, one terracotta
|
|
|
17
17
|
accent, fluted-glass hero; orchard — friendly consumer biotech, oat slabs,
|
|
18
18
|
sage brand and one candy-orange action; field-notes — open-source developer
|
|
19
19
|
tools on warm green-cast paper ruled by hairlines, one rust accent, a hero
|
|
20
|
-
that dissolves into the page, and colour that encodes how a claim is known
|
|
20
|
+
that dissolves into the page, and colour that encodes how a claim is known;
|
|
21
|
+
cyclorama — enterprise AI transformation on a pale field that cycles through
|
|
22
|
+
six pastel stops on a 32s loop under fixed near-black ink, a monospaced
|
|
23
|
+
typewriter serif, one orange used only as a fill, and no shadows at all;
|
|
24
|
+
showroom — a white gallery where one real product surface is the exhibit,
|
|
25
|
+
under a seven-layer shadow; blueprint — a drawing sheet for infrastructure
|
|
26
|
+
sold on precision: grid, ruled columns, registration marks, one electric
|
|
27
|
+
blue and zero radius; prism — an open-source project's front door, one
|
|
28
|
+
static iridescent wash over mono body copy; maquette — enterprise data
|
|
29
|
+
infrastructure as a cream axonometric model on a near-black table);
|
|
21
30
|
otherwise follow the contract below (self-contained on purpose).
|
|
22
31
|
|
|
23
32
|
## Five principles, in order
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pkg": "@sheleg-design/blueprint",
|
|
3
|
+
"globalName": "ShelegBlueprint",
|
|
4
|
+
"shape": "package",
|
|
5
|
+
"buildCmd": "npm run build",
|
|
6
|
+
"srcDir": "src",
|
|
7
|
+
"tsconfig": "tsconfig.json",
|
|
8
|
+
"cssEntry": "src/styles.css",
|
|
9
|
+
"docsDir": "src",
|
|
10
|
+
"readmeHeader": ".design-sync/conventions.md",
|
|
11
|
+
"guidelinesGlob": [
|
|
12
|
+
"guidelines/*.md"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Blueprint — the contract this design system ships under
|
|
2
|
+
|
|
3
|
+
**Register.** Choose Blueprint for **infrastructure sold on precision**: vector
|
|
4
|
+
databases, search and retrieval, storage and query engines. Its vocabulary is
|
|
5
|
+
technical drafting — a white sheet, a 32px grid, ruled column edges, registration
|
|
6
|
+
marks, one saturated blue used the way a draftsman uses ink. The fork people get
|
|
7
|
+
wrong is against `field-notes`: that pack is **warm paper** arguing from
|
|
8
|
+
provenance (*how do you know*), this one is **cold stock** arguing from precision
|
|
9
|
+
(*how is it built*). Against `instrument-console`: that pack's subject is a
|
|
10
|
+
running system with a changing value; this one's is a mechanism drawn to scale.
|
|
11
|
+
Build every screen against `var(--…)` and never a literal.
|
|
12
|
+
|
|
13
|
+
**There is no radius.** `--radius: 0`, everywhere, and the token exists so the
|
|
14
|
+
ban is greppable. The single exception is `--radius-round: 50%` for a dot or an
|
|
15
|
+
avatar. Most component libraries ship a default radius — zero it globally rather
|
|
16
|
+
than per component, or the page ends up with three rounded inputs nobody notices
|
|
17
|
+
until it looks cheap and nobody can say why.
|
|
18
|
+
|
|
19
|
+
**One blue does everything.** `--accent` `#002BFF` measures 7.53:1 as text on the
|
|
20
|
+
stock *and* 7.53:1 under white. It sets a heading word, draws a 1.5px rule, fills
|
|
21
|
+
a button and rings a focused input, with no second token. It is unusually
|
|
22
|
+
saturated and vibrates against `--ink` at small sizes — never set body copy in
|
|
23
|
+
it.
|
|
24
|
+
|
|
25
|
+
**The ink is not the reference's ink, and the pack says so.** The reference sets
|
|
26
|
+
pure black on 316 elements; the doctrine bans pure black as ink. This system
|
|
27
|
+
ships `#111827` — the reference's own second ink, on 136 of its elements. The two
|
|
28
|
+
sit 21.2 apart in OKLab: it is a visible substitution, not a rounding.
|
|
29
|
+
|
|
30
|
+
**Category marks are squares, not circles.** A circle is a status; a square is a
|
|
31
|
+
kind. Every pair clears both separation floors under all three dichromacies —
|
|
32
|
+
label them anyway, because a legend of four coloured squares is a legend nobody
|
|
33
|
+
reads.
|
|
34
|
+
|
|
35
|
+
**Bans** (verbatim from the pack):
|
|
36
|
+
|
|
37
|
+
- A radius. Any radius, on anything, except `50%` for a dot or an avatar.
|
|
38
|
+
- A shadow used for elevation.
|
|
39
|
+
- `--ink-faint` as text; `--accent` as a large field fill.
|
|
40
|
+
- A circle used as a category mark; a category colour used to mean health.
|
|
41
|
+
- The annotation size without its tracking; caps annotations set at 0.
|
|
42
|
+
- A geometric or humanist substitute for the display face.
|
|
43
|
+
- Fluid `clamp()` type; `transition: all`; `100vh`; a scroll listener.
|
|
44
|
+
- Animating the grid, or parallaxing it.
|
|
45
|
+
- A screenshot as the hero's figure. Draw it, or use `showroom`.
|
|
46
|
+
|
|
47
|
+
**The reference ships no `prefers-reduced-motion` branch at all**, against live
|
|
48
|
+
marquee, ping, pulse and scroll animations. This system requires the branch its
|
|
49
|
+
reference omits.
|
|
50
|
+
|
|
51
|
+
Motion is not part of this design system and must not be invented: a kit is the
|
|
52
|
+
static half of a pack, and anything that moves stays behind in the pack.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @sheleg-design/blueprint
|
|
2
|
+
|
|
3
|
+
The React reference kit for the SHELEG **Blueprint** style pack — a drawing sheet: grid, ruled columns, registration marks, one electric blue, and zero radius anywhere.
|
|
4
|
+
|
|
5
|
+
It is generated from the pack, not authored beside it: `src/styles.css` opens
|
|
6
|
+
with `styles/tokens/blueprint.css` byte for byte, and the rules the design agent
|
|
7
|
+
must obey are in [`.design-sync/conventions.md`](./.design-sync/conventions.md).
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install && npm run build
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then run `/design-sync` in Claude Code from this directory to push it to
|
|
14
|
+
claude.ai/design.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sheleg-design/blueprint",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": ">=18"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"typescript": "^5.6.0",
|
|
27
|
+
"@types/react": "^18.3.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonProps {
|
|
4
|
+
/** `primary` is the pack's default fill — at most one accent action per view. */
|
|
5
|
+
variant?: 'primary' | 'secondary' | 'ghost';
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
onClick?: () => void;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Button({
|
|
14
|
+
variant = 'primary',
|
|
15
|
+
size = 'md',
|
|
16
|
+
disabled = false,
|
|
17
|
+
onClick,
|
|
18
|
+
children,
|
|
19
|
+
className,
|
|
20
|
+
}: ButtonProps) {
|
|
21
|
+
return (
|
|
22
|
+
<button
|
|
23
|
+
type="button"
|
|
24
|
+
className={['bp-btn', `bp-btn--${variant}`, `bp-btn--${size}`, className]
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join(' ')}
|
|
27
|
+
disabled={disabled}
|
|
28
|
+
onClick={onClick}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</button>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface CardProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Right-aligned metadata on the title row: a count, an id, a timestamp. */
|
|
6
|
+
meta?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function Card({ title, meta, children, className }: CardProps) {
|
|
12
|
+
const head = title !== undefined || meta !== undefined;
|
|
13
|
+
return (
|
|
14
|
+
<section className={['bp-card', className].filter(Boolean).join(' ')}>
|
|
15
|
+
{head && (
|
|
16
|
+
<div className="bp-card__head">
|
|
17
|
+
{title !== undefined && <h3 className="bp-card__title">{title}</h3>}
|
|
18
|
+
{meta !== undefined && <span className="bp-card__meta">{meta}</span>}
|
|
19
|
+
</div>
|
|
20
|
+
)}
|
|
21
|
+
<div className="bp-card__body">{children}</div>
|
|
22
|
+
</section>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ChipProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
selected?: boolean;
|
|
6
|
+
tone?: 'neutral' | 'accent';
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function Chip({ children, selected = false, tone = 'neutral', className }: ChipProps) {
|
|
11
|
+
return (
|
|
12
|
+
<span
|
|
13
|
+
className={[
|
|
14
|
+
'bp-chip',
|
|
15
|
+
`bp-chip--${tone}`,
|
|
16
|
+
selected ? 'bp-chip--selected' : undefined,
|
|
17
|
+
className,
|
|
18
|
+
]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' ')}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Data
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
JetBrains Mono on `--surface-2`, **zero radius**, a `$` prompt in `--ink-faint`,
|
|
6
|
+
a copy control at the right.
|
|
7
|
+
|
|
8
|
+
The control changes its **label**, not only its colour. A colour-only
|
|
9
|
+
confirmation is invisible to a meaningful share of the readers this page is for,
|
|
10
|
+
and it is the same rule the pack applies to its category marks.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<CodeLine command="pip install pinecone" copied={done} onCopy={copy} />
|
|
14
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface CodeLineProps {
|
|
2
|
+
command: string;
|
|
3
|
+
/** Shown before the command, in --ink-faint. Defaults to a shell prompt. */
|
|
4
|
+
prompt?: string;
|
|
5
|
+
onCopy?: () => void;
|
|
6
|
+
/** Flipped by the caller after a copy. Changes the LABEL, not just a colour. */
|
|
7
|
+
copied?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A command in JetBrains Mono on `--surface-2`, zero radius, with a copy
|
|
13
|
+
* control at the right.
|
|
14
|
+
*
|
|
15
|
+
* The copy control changes its **label** to `copied`, not only its colour — the
|
|
16
|
+
* same rule the pack applies to category marks, and for the same readers.
|
|
17
|
+
*/
|
|
18
|
+
export function CodeLine({ command, prompt = '$', onCopy, copied = false, className }: CodeLineProps) {
|
|
19
|
+
return (
|
|
20
|
+
<div className={['bp-code', className].filter(Boolean).join(' ')}>
|
|
21
|
+
<span className="bp-code__prompt" aria-hidden="true">{prompt}</span>
|
|
22
|
+
<code className="bp-code__cmd">{command}</code>
|
|
23
|
+
<button type="button" className="bp-code__copy" onClick={onCopy}>
|
|
24
|
+
{copied ? 'copied' : 'copy'}
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Foundations
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
1px dots in `--line-grid` at `--grid-step` 32px, halving to 16px below 768px so
|
|
6
|
+
the density stays visually constant as the viewport narrows.
|
|
7
|
+
|
|
8
|
+
Depth layer 1: `pointer-events: none`, `aria-hidden`, never on a scroller, and
|
|
9
|
+
**never animated**. The grid is the sheet. A sheet that drifts, parallaxes or
|
|
10
|
+
fades in turns a drawing into a screensaver.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<GridField />
|
|
14
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface GridFieldProps {
|
|
2
|
+
/** Dot spacing in px. Halves below 768px so density stays visually constant. */
|
|
3
|
+
step?: number;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The drawing grid: 1px dots in `--line-grid` at `--grid-step`.
|
|
9
|
+
*
|
|
10
|
+
* It sits at depth layer 1 — `pointer-events: none`, `aria-hidden`, behind
|
|
11
|
+
* everything, never on a scroller. **It never animates**: not on load, not on
|
|
12
|
+
* scroll, not on hover. It is the sheet the page is drawn on, and a sheet that
|
|
13
|
+
* moves is a different kind of page.
|
|
14
|
+
*/
|
|
15
|
+
export function GridField({ step, className }: GridFieldProps) {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className={['bp-grid', className].filter(Boolean).join(' ')}
|
|
19
|
+
style={step !== undefined ? ({ ['--grid-step' as string]: `${step}px` } as object) : undefined}
|
|
20
|
+
aria-hidden="true"
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface HeadingProps {
|
|
4
|
+
/** 1 = page title, 2 = section, 3 = sub-head. */
|
|
5
|
+
level?: 1 | 2 | 3;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function Heading({ level = 2, children, className }: HeadingProps) {
|
|
11
|
+
const Tag = `h${level}` as 'h1' | 'h2' | 'h3';
|
|
12
|
+
return (
|
|
13
|
+
<Tag
|
|
14
|
+
className={['bp-heading', `bp-heading--${level}`, className].filter(Boolean).join(' ')}
|
|
15
|
+
>
|
|
16
|
+
{children}
|
|
17
|
+
</Tag>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Signature
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Four L-shaped brackets — `--tick-len` 8px arms at `--tick-w` 1px, offset
|
|
6
|
+
`--tick-gap` 6px — around the thing the page is registering.
|
|
7
|
+
|
|
8
|
+
**Spend them on one thing per viewport.** The primary action, or the figure the
|
|
9
|
+
section argues from. Marks on every card is a texture; marks on the one thing
|
|
10
|
+
that matters is an argument, and it is the argument this pack is making.
|
|
11
|
+
|
|
12
|
+
Desktop only: below 768px they come off buttons, where 8px brackets become
|
|
13
|
+
touch-target confetti, and stay on framed figures.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<RegistrationMarks tone="accent"><Button>Start Building</Button></RegistrationMarks>
|
|
17
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface RegistrationMarksProps {
|
|
4
|
+
/** `accent` puts the marks in the pack's blue; `grid` keeps them faint. */
|
|
5
|
+
tone?: 'grid' | 'accent';
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Four L-shaped brackets at the corners of whatever it wraps: 8px arms at 1px,
|
|
12
|
+
* offset 6px from the object they register.
|
|
13
|
+
*
|
|
14
|
+
* They are the pack's signature and they must stay rare. A registration mark
|
|
15
|
+
* exists so two plates line up in a press — it is a mark about *accuracy*, made
|
|
16
|
+
* by someone who assumed you would recognise it. Put them on **one** thing per
|
|
17
|
+
* viewport: the action the page wants, or the figure it is arguing from. Marks
|
|
18
|
+
* on every card is a texture; marks on the one thing that matters is an
|
|
19
|
+
* argument.
|
|
20
|
+
*
|
|
21
|
+
* Desktop only. At 8px they become touch-target confetti on a phone, so they
|
|
22
|
+
* come off buttons below 768px and stay only on framed figures.
|
|
23
|
+
*/
|
|
24
|
+
export function RegistrationMarks({ tone = 'grid', children, className }: RegistrationMarksProps) {
|
|
25
|
+
return (
|
|
26
|
+
<span className={['bp-reg', `bp-reg--${tone}`, className].filter(Boolean).join(' ')}>
|
|
27
|
+
{children}
|
|
28
|
+
<i className="bp-reg__tick bp-reg__tick--tl" aria-hidden="true" />
|
|
29
|
+
<i className="bp-reg__tick bp-reg__tick--tr" aria-hidden="true" />
|
|
30
|
+
<i className="bp-reg__tick bp-reg__tick--bl" aria-hidden="true" />
|
|
31
|
+
<i className="bp-reg__tick bp-reg__tick--br" aria-hidden="true" />
|
|
32
|
+
</span>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface RuleProps {
|
|
2
|
+
tone?: 'hairline' | 'strong';
|
|
3
|
+
className?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function Rule({ tone = 'hairline', className }: RuleProps) {
|
|
7
|
+
return (
|
|
8
|
+
<hr
|
|
9
|
+
className={[
|
|
10
|
+
'bp-rule',
|
|
11
|
+
tone === 'strong' ? 'bp-rule--strong' : undefined,
|
|
12
|
+
className,
|
|
13
|
+
]
|
|
14
|
+
.filter(Boolean)
|
|
15
|
+
.join(' ')}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Foundations
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Two 1px verticals in `--line-strong` at `--column-max` 1280px, running the full
|
|
6
|
+
height of the section.
|
|
7
|
+
|
|
8
|
+
This is the layout made visible. A max-width container with no rules is a
|
|
9
|
+
website; the same container with its boundaries drawn is a sheet, and that
|
|
10
|
+
difference is most of what separates this pack from a plain white page.
|
|
11
|
+
|
|
12
|
+
Below 1024px the rules move to the viewport edges; below 768px they are removed
|
|
13
|
+
entirely.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<RuledColumn><Heading level={1}>Give agents knowledge</Heading></RuledColumn>
|
|
17
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface RuledColumnProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The content column with its two 1px vertical rules, in `--line-strong`,
|
|
10
|
+
* running the section's full height at `--column-max`.
|
|
11
|
+
*
|
|
12
|
+
* They are the layout made visible, and they are why the page reads as a sheet
|
|
13
|
+
* rather than as a container with a max-width. Below 1024px they collapse to
|
|
14
|
+
* the viewport edges; below 768px they are removed entirely, because two rules
|
|
15
|
+
* 16px in from the screen edge read as a rendering error.
|
|
16
|
+
*/
|
|
17
|
+
export function RuledColumn({ children, className }: RuledColumnProps) {
|
|
18
|
+
return (
|
|
19
|
+
<div className={['bp-column', className].filter(Boolean).join(' ')}>
|
|
20
|
+
<span className="bp-column__rule bp-column__rule--l" aria-hidden="true" />
|
|
21
|
+
<div className="bp-column__inner">{children}</div>
|
|
22
|
+
<span className="bp-column__rule bp-column__rule--r" aria-hidden="true" />
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|