sheleg-design-skill 1.8.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 +63 -0
- package/README.md +5 -1
- package/bin/cli.js +8 -5
- package/cursor/rules/sheleg-design.mdc +7 -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/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 +1 -1
- package/plugins/sheleg-design/skills/sheleg-design/SKILL.md +4 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/blueprint.md +336 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/cyclorama.md +9 -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/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,69 @@ 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
|
+
|
|
7
70
|
## [1.8.0] - 2026-08-08
|
|
8
71
|
|
|
9
72
|
An eighth style pack, and the first one whose reference already implements this
|
package/README.md
CHANGED
|
@@ -49,6 +49,10 @@ 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 |
|
|
52
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 |
|
|
53
57
|
|
|
54
58
|
Each pack locks palette, type, texture, motion tokens, signature motifs and
|
|
@@ -122,7 +126,7 @@ skills.
|
|
|
122
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 |
|
|
123
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 |
|
|
124
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 |
|
|
125
|
-
| `styles/*.md` | The
|
|
129
|
+
| `styles/*.md` | The twelve style packs — palette, type, texture, motion tokens, motifs, bans, and the traps each one carries |
|
|
126
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) |
|
|
127
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 |
|
|
128
132
|
|
package/bin/cli.js
CHANGED
|
@@ -230,14 +230,17 @@ ${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
237
|
consumer biotech), field-notes (warm paper dev tools),
|
|
238
|
-
cyclorama (a pastel field on a 32s cycle,
|
|
239
|
-
|
|
240
|
-
|
|
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) —
|
|
242
|
+
plus a ready-made token CSS per pack and
|
|
243
|
+
STYLE_PACK_TEMPLATE.md for authoring more
|
|
241
244
|
`);
|
|
242
245
|
}
|
|
243
246
|
|
|
@@ -316,7 +319,7 @@ function main() {
|
|
|
316
319
|
`\n${c("green", "✓")} ${c("bold", "SHELEG Design")} installed to ${c("blue", rel + "/")}\n` +
|
|
317
320
|
` ${c("dim", "SKILL.md")} the agent skill\n` +
|
|
318
321
|
` ${c("dim", "SHELEG_DESIGN.md")} the full reference\n` +
|
|
319
|
-
` ${c("dim", "styles/")} style packs + token CSS (instrument-console / editorial-luxury / workbench / briefing-room / atrium / orchard / field-notes / cyclorama)\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` +
|
|
320
323
|
`Your Cursor / Claude agent can now discover the skill and build\n` +
|
|
321
324
|
`cinematic, scroll-driven pages — or style product UI (dashboards,\n` +
|
|
322
325
|
`admin, internal tools) from the workbench pack — on its principles.\n\n` +
|
|
@@ -20,7 +20,13 @@ tools on warm green-cast paper ruled by hairlines, one rust accent, a hero
|
|
|
20
20
|
that dissolves into the page, and colour that encodes how a claim is known;
|
|
21
21
|
cyclorama — enterprise AI transformation on a pale field that cycles through
|
|
22
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
|
|
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);
|
|
24
30
|
otherwise follow the contract below (self-contained on purpose).
|
|
25
31
|
|
|
26
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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface StatProps {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
/** Where the figure came from — a query, a window, a dashboard. */
|
|
5
|
+
source?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function Stat({ value, label, source, className }: StatProps) {
|
|
10
|
+
return (
|
|
11
|
+
<div className={['bp-stat', className].filter(Boolean).join(' ')}>
|
|
12
|
+
<span className="bp-stat__label">{label}</span>
|
|
13
|
+
<span className="bp-stat__value">{value}</span>
|
|
14
|
+
{source !== undefined && <span className="bp-stat__source">{source}</span>}
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// The spine — identical names, props and types in every SHELEG kit.
|
|
2
|
+
export { Button } from './Button.js';
|
|
3
|
+
export type { ButtonProps } from './Button.js';
|
|
4
|
+
export { Card } from './Card.js';
|
|
5
|
+
export type { CardProps } from './Card.js';
|
|
6
|
+
export { Chip } from './Chip.js';
|
|
7
|
+
export type { ChipProps } from './Chip.js';
|
|
8
|
+
export { Stat } from './Stat.js';
|
|
9
|
+
export type { StatProps } from './Stat.js';
|
|
10
|
+
export { Heading } from './Heading.js';
|
|
11
|
+
export type { HeadingProps } from './Heading.js';
|
|
12
|
+
export { Rule } from './Rule.js';
|
|
13
|
+
export type { RuleProps } from './Rule.js';
|
|
14
|
+
|
|
15
|
+
// Signature — this pack's own motifs, static forms only.
|
|
16
|
+
export { RegistrationMarks } from './RegistrationMarks.js';
|
|
17
|
+
export type { RegistrationMarksProps } from './RegistrationMarks.js';
|
|
18
|
+
export { GridField } from './GridField.js';
|
|
19
|
+
export type { GridFieldProps } from './GridField.js';
|
|
20
|
+
export { RuledColumn } from './RuledColumn.js';
|
|
21
|
+
export type { RuledColumnProps } from './RuledColumn.js';
|
|
22
|
+
export { CodeLine } from './CodeLine.js';
|
|
23
|
+
export type { CodeLineProps } from './CodeLine.js';
|