sheleg-design-skill 1.38.0 → 1.40.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 +168 -0
- package/README.md +9 -4
- package/bin/cli.js +13 -2
- package/cursor/rules/sheleg-design.mdc +22 -0
- package/kits/almanac/.design-sync/config.json +14 -0
- package/kits/almanac/.design-sync/conventions.md +32 -0
- package/kits/almanac/README.md +22 -0
- package/kits/almanac/package.json +29 -0
- package/kits/almanac/src/Button.md +21 -0
- package/kits/almanac/src/Button.tsx +33 -0
- package/kits/almanac/src/Card.md +18 -0
- package/kits/almanac/src/Card.tsx +24 -0
- package/kits/almanac/src/Chip.md +16 -0
- package/kits/almanac/src/Chip.tsx +25 -0
- package/kits/almanac/src/Heading.md +17 -0
- package/kits/almanac/src/Heading.tsx +19 -0
- package/kits/almanac/src/Rule.md +17 -0
- package/kits/almanac/src/Rule.tsx +18 -0
- package/kits/almanac/src/Skeleton.md +16 -0
- package/kits/almanac/src/Skeleton.tsx +17 -0
- package/kits/almanac/src/Stat.md +15 -0
- package/kits/almanac/src/Stat.tsx +17 -0
- package/kits/almanac/src/StatusDot.md +20 -0
- package/kits/almanac/src/StatusDot.tsx +19 -0
- package/kits/almanac/src/TaggedBox.md +17 -0
- package/kits/almanac/src/TaggedBox.tsx +16 -0
- package/kits/almanac/src/index.ts +21 -0
- package/kits/almanac/src/styles.css +472 -0
- package/kits/almanac/tsconfig.json +15 -0
- package/kits/daylight/.design-sync/config.json +14 -0
- package/kits/daylight/.design-sync/conventions.md +32 -0
- package/kits/daylight/README.md +22 -0
- package/kits/daylight/package.json +29 -0
- package/kits/daylight/src/Button.md +21 -0
- package/kits/daylight/src/Button.tsx +33 -0
- package/kits/daylight/src/Card.md +18 -0
- package/kits/daylight/src/Card.tsx +24 -0
- package/kits/daylight/src/Chip.md +16 -0
- package/kits/daylight/src/Chip.tsx +25 -0
- package/kits/daylight/src/Heading.md +17 -0
- package/kits/daylight/src/Heading.tsx +19 -0
- package/kits/daylight/src/LiftPanel.md +15 -0
- package/kits/daylight/src/LiftPanel.tsx +10 -0
- package/kits/daylight/src/Rule.md +17 -0
- package/kits/daylight/src/Rule.tsx +18 -0
- package/kits/daylight/src/Skeleton.md +16 -0
- package/kits/daylight/src/Skeleton.tsx +17 -0
- package/kits/daylight/src/Stat.md +15 -0
- package/kits/daylight/src/Stat.tsx +17 -0
- package/kits/daylight/src/StatusDot.md +20 -0
- package/kits/daylight/src/StatusDot.tsx +19 -0
- package/kits/daylight/src/index.ts +21 -0
- package/kits/daylight/src/styles.css +450 -0
- package/kits/daylight/tsconfig.json +15 -0
- package/kits/notation/.design-sync/config.json +14 -0
- package/kits/notation/.design-sync/conventions.md +33 -0
- package/kits/notation/README.md +22 -0
- package/kits/notation/package.json +29 -0
- package/kits/notation/src/Button.md +21 -0
- package/kits/notation/src/Button.tsx +33 -0
- package/kits/notation/src/Card.md +18 -0
- package/kits/notation/src/Card.tsx +24 -0
- package/kits/notation/src/Chip.md +16 -0
- package/kits/notation/src/Chip.tsx +25 -0
- package/kits/notation/src/Eyebrow.md +13 -0
- package/kits/notation/src/Eyebrow.tsx +10 -0
- package/kits/notation/src/Heading.md +17 -0
- package/kits/notation/src/Heading.tsx +19 -0
- package/kits/notation/src/Rule.md +17 -0
- package/kits/notation/src/Rule.tsx +18 -0
- package/kits/notation/src/Skeleton.md +16 -0
- package/kits/notation/src/Skeleton.tsx +17 -0
- package/kits/notation/src/Stat.md +15 -0
- package/kits/notation/src/Stat.tsx +17 -0
- package/kits/notation/src/StatusDot.md +20 -0
- package/kits/notation/src/StatusDot.tsx +19 -0
- package/kits/notation/src/index.ts +21 -0
- package/kits/notation/src/styles.css +444 -0
- package/kits/notation/tsconfig.json +15 -0
- package/kits/router/.design-sync/config.json +14 -0
- package/kits/router/.design-sync/conventions.md +49 -0
- package/kits/router/README.md +33 -0
- package/kits/router/package.json +29 -0
- package/kits/router/src/Button.md +21 -0
- package/kits/router/src/Button.tsx +33 -0
- package/kits/router/src/Card.md +18 -0
- package/kits/router/src/Card.tsx +24 -0
- package/kits/router/src/Chip.md +16 -0
- package/kits/router/src/Chip.tsx +25 -0
- package/kits/router/src/Heading.md +17 -0
- package/kits/router/src/Heading.tsx +19 -0
- package/kits/router/src/Rule.md +17 -0
- package/kits/router/src/Rule.tsx +18 -0
- package/kits/router/src/Skeleton.md +16 -0
- package/kits/router/src/Skeleton.tsx +17 -0
- package/kits/router/src/Stat.md +15 -0
- package/kits/router/src/Stat.tsx +17 -0
- package/kits/router/src/StatusDot.md +20 -0
- package/kits/router/src/StatusDot.tsx +19 -0
- package/kits/router/src/index.ts +19 -0
- package/kits/router/src/styles.css +475 -0
- package/kits/router/tsconfig.json +15 -0
- package/kits/vitrine/.design-sync/config.json +14 -0
- package/kits/vitrine/.design-sync/conventions.md +36 -0
- package/kits/vitrine/README.md +22 -0
- package/kits/vitrine/package.json +29 -0
- package/kits/vitrine/src/Button.md +21 -0
- package/kits/vitrine/src/Button.tsx +33 -0
- package/kits/vitrine/src/Card.md +18 -0
- package/kits/vitrine/src/Card.tsx +24 -0
- package/kits/vitrine/src/Chip.md +16 -0
- package/kits/vitrine/src/Chip.tsx +25 -0
- package/kits/vitrine/src/Frame.md +18 -0
- package/kits/vitrine/src/Frame.tsx +19 -0
- package/kits/vitrine/src/Heading.md +17 -0
- package/kits/vitrine/src/Heading.tsx +19 -0
- package/kits/vitrine/src/Rule.md +17 -0
- package/kits/vitrine/src/Rule.tsx +18 -0
- package/kits/vitrine/src/Skeleton.md +16 -0
- package/kits/vitrine/src/Skeleton.tsx +17 -0
- package/kits/vitrine/src/Stat.md +15 -0
- package/kits/vitrine/src/Stat.tsx +17 -0
- package/kits/vitrine/src/StatusDot.md +20 -0
- package/kits/vitrine/src/StatusDot.tsx +19 -0
- package/kits/vitrine/src/index.ts +21 -0
- package/kits/vitrine/src/styles.css +458 -0
- package/kits/vitrine/tsconfig.json +15 -0
- package/package.json +2 -2
- package/plugins/sheleg-design/.claude-plugin/plugin.json +2 -2
- package/plugins/sheleg-design/commands/sheleg-design.md +1 -1
- package/plugins/sheleg-design/skills/sheleg-design/DESIGN_SYNC_BRIDGE.md +1 -1
- package/plugins/sheleg-design/skills/sheleg-design/MOBILE_SURFACES.md +1 -1
- package/plugins/sheleg-design/skills/sheleg-design/SKILL.md +10 -5
- package/plugins/sheleg-design/skills/sheleg-design/SURFACE_COMPOSITION.md +1 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/almanac.md +249 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/daylight.md +238 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/notation.md +231 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/router.md +336 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/almanac.css +145 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/daylight.css +139 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/notation.css +130 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/router.css +170 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/vitrine.css +126 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/vitrine.md +227 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,124 @@ 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.40.0] - 2026-08-17
|
|
8
|
+
|
|
9
|
+
**A reference sweep has been in this pack since the Lazyweb bridge and could never be asked
|
|
10
|
+
for.** `SKILL.md` carries an *Optional — real-world references (Lazyweb, Mobbin, Refero)*
|
|
11
|
+
section, step 1 of *How to Apply* says to sweep before any layout exists to defend, and
|
|
12
|
+
`DESIGN_SYNC_BRIDGE.md` §4 tells the three servers apart by what each returns — Lazyweb web
|
|
13
|
+
products and growth mechanics, Mobbin evenly-spaced preview images per step, Refero visually
|
|
14
|
+
similar screens and flows as structure. None of it was in the `description`, so
|
|
15
|
+
`нужны визуальные референсы` reached no route.
|
|
16
|
+
|
|
17
|
+
Two triggers now do, and one of them cost nothing at all:
|
|
18
|
+
|
|
19
|
+
| Trigger | What it cost |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `style pack` | **zero** — the description has said *"Product UI through its style packs"* since the style packs existed. The word was advertised and unroutable for as long as this router has had a table |
|
|
22
|
+
| `visual reference` / `визуальные референсы` | 42 characters, paid for by compressing two clauses |
|
|
23
|
+
|
|
24
|
+
**The unqualified word went to `super-ux` instead, on this pack's own rule.**
|
|
25
|
+
`DESIGN_SYNC_BRIDGE.md` §4 opens with *"A reference sweep answers what a good version of
|
|
26
|
+
this screen contains — sections, hierarchy, content order. It never answers what it looks
|
|
27
|
+
like."* Structure is `super-ux`'s ground, so `референсы` routes there (`super-ux` 0.43.0) and
|
|
28
|
+
only the visual half lands here. A prompt naming both raises both.
|
|
29
|
+
|
|
30
|
+
### What was refused, and it is the word the operator actually types
|
|
31
|
+
|
|
32
|
+
`подбери стиль` reaches nothing and stays that way. Measured against control sentences from
|
|
33
|
+
this machine's own vocabulary: the bare `стиль` fires on «стиль кода» and «стиль коммитов»,
|
|
34
|
+
the phrase `подбери стиль` fires on both as well because the matcher tolerates a qualifier
|
|
35
|
+
between the words, and the English `pick a style` fires on *pick a style guide for python*.
|
|
36
|
+
Every form an operator would naturally type carries a second trade, so the route takes the
|
|
37
|
+
qualified phrases and lets the ambiguous ones reach nothing rather than the wrong craft.
|
|
38
|
+
`вдохновение` was refused the same way — it fires on «вдохновение закончилось».
|
|
39
|
+
|
|
40
|
+
**Budget, and it was tight before this change.** 948 → 955 characters against a 970 working
|
|
41
|
+
limit: 15 free. Two clauses were compressed to pay for it, and one of them briefly took
|
|
42
|
+
`heroes` out of the description — which the umbrella's `triggers_test.js` caught immediately,
|
|
43
|
+
because `hero` is a routed trigger. The word is back.
|
|
44
|
+
|
|
45
|
+
## [1.39.0] - 2026-08-17
|
|
46
|
+
|
|
47
|
+
**Five packs at once, and the library goes from twenty-two to twenty-seven.** All five
|
|
48
|
+
were extracted from live references while building one product's landing site and are
|
|
49
|
+
ported back here whole: `router`, `daylight`, `notation`, `almanac` and `vitrine`. Every
|
|
50
|
+
one is on the **widened** contract, carries an addressable origin, a token layer whose
|
|
51
|
+
every stated ratio the palette gate recomputes, and a reference kit whose spine props are
|
|
52
|
+
byte-identical to `workbench`'s.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- **`router`**, from [openrouter.ai](https://openrouter.ai) — and **the first pack in this
|
|
57
|
+
library measured from a running product rather than from a served stylesheet.** A
|
|
58
|
+
near-white field with a trace of blue and white cards standing on that tint, hairline
|
|
59
|
+
seams instead of shadows anywhere, body at 14px and weight 450, one royal blue at 97%
|
|
60
|
+
saturation doing every accent job and none of the chart work. The second reading
|
|
61
|
+
corrected three values the first had wrong, all named in the pack's Gotchas: their
|
|
62
|
+
`--text-xs` is 14px and not 12, the sidebar is 224 and not 244, and the border asymmetry
|
|
63
|
+
that reads as a register decision belongs to `--sidebar-border` alone.
|
|
64
|
+
- **`daylight`**, from [taskip.net](https://taskip.net) — a cool portal field with generous
|
|
65
|
+
radii whose whole depth is **one very large soft shadow spent on a single object per
|
|
66
|
+
screen**, Inter Tight 700 tracked negative over Manrope 400.
|
|
67
|
+
- **`notation`**, from [twenty.com](https://twenty.com) — a near-white page drawn **entirely
|
|
68
|
+
in hairlines instead of cards**, radii of 2 and 4px, a slab serif held at 300 against a
|
|
69
|
+
monospace, **no bold anywhere**, an ink primary, and one chamfered corner per page.
|
|
70
|
+
- **`almanac`**, from [auxia.io](https://www.auxia.io) — **oatmeal paper rather than white**,
|
|
71
|
+
seams at 2px with **no 1px anywhere**, a 104px display at weight 500 set **below a
|
|
72
|
+
line-height of one**, and uppercase mono tags notched through the edges of drawn boxes.
|
|
73
|
+
- **`vitrine`**, from [attio.com](https://attio.com) — a white hairline field with a serif
|
|
74
|
+
display, an **ink primary** so the accent stays free to mark what can be read, and one
|
|
75
|
+
framed record with a 1px inset highlight carrying the page's evidence.
|
|
76
|
+
- **Five reference kits**, each with the six-component spine plus `StatusDot`, `Skeleton`
|
|
77
|
+
and the pack's own signature component — `LiftPanel`, `Eyebrow`, `TaggedBox`, `Frame`.
|
|
78
|
+
|
|
79
|
+
### The idiom worth naming: the status triplet
|
|
80
|
+
|
|
81
|
+
Every status in `router` holds **three** tokens rather than one — `--ok-mark` is painted,
|
|
82
|
+
`--ok` is written, `--ok-weak` is laid under. The reference's own delta is drawn in
|
|
83
|
+
`#00bf6f` and set in `#007544`: *the colour you paint with is not the colour you write
|
|
84
|
+
with.* The `-mark` values are identical in both registers because only the words have to
|
|
85
|
+
be read, and the split is what lets a 97%-saturated hue be an accent without becoming an
|
|
86
|
+
unreadable label. `StatusDot` ships it as one object with a **required** label.
|
|
87
|
+
|
|
88
|
+
### What the gates decided, rather than taste
|
|
89
|
+
|
|
90
|
+
- **`router`'s `--info` was authored as a teal and refused**: 9.0 apart from `--ok` at full
|
|
91
|
+
colour against a hard floor of 10.0 — two semantic states in one colour, which secondary
|
|
92
|
+
encoding does not excuse. The reference had already answered it; its `--color-info` and
|
|
93
|
+
its `--or-royal` are the same hex.
|
|
94
|
+
- **`almanac`'s derived `--danger` is a crimson, not a red**, for the same reason: an
|
|
95
|
+
orange-red beside its burnt-orange `--warn` measured 6.4 apart. Moved along the hue until
|
|
96
|
+
it separated at the floor.
|
|
97
|
+
- **`router`'s dark `--danger` is not the reference's.** Theirs is 5.02 on the field and
|
|
98
|
+
clears, but **4.38 on its own chip tint** — and a danger chip is where the word most
|
|
99
|
+
needs to be read.
|
|
100
|
+
- **`vitrine`'s `--shadow-1` had to be reordered.** Written colour-first the palette gate
|
|
101
|
+
reads it as a colour it cannot compute; written length-first it is the same shadow and
|
|
102
|
+
is checkable.
|
|
103
|
+
- **Three packs ship a derived `--danger`** — `daylight`, `notation` and `almanac`, whose
|
|
104
|
+
references are marketing sites that paint no error state. Each is marked derived **at
|
|
105
|
+
the declaration**, so a later reader cannot mistake it for a measurement.
|
|
106
|
+
|
|
107
|
+
### Two findings from the palette work, recorded in the packs' Gotchas
|
|
108
|
+
|
|
109
|
+
- **Six chart series will not fit and the arithmetic says so.** Six distinguishable steps
|
|
110
|
+
need about 60 L* of range; the dark end is bounded by usefulness and the light end runs
|
|
111
|
+
into the page, so the palest measured **1.38** against the field. Four is what clears, at
|
|
112
|
+
3.31 light and 4.61 dark. **The number of series is a decision of the palette, not of the
|
|
113
|
+
data.**
|
|
114
|
+
- **A monochrome chart palette is the weakest, not the safest** — it holds two series on
|
|
115
|
+
white (3.22) and three on ink (4.25); a third ink step on white lands at 2.72, under the
|
|
116
|
+
non-text floor.
|
|
117
|
+
|
|
118
|
+
### Changed
|
|
119
|
+
|
|
120
|
+
- Every counted claim moved from twenty-two to twenty-seven, in all nine sources the
|
|
121
|
+
counted-claims check reads. **The remainder beside the total moved with it** — the stale
|
|
122
|
+
remainder is precisely the failure that check was written for, and it fired once during
|
|
123
|
+
this change, exactly as its own comment predicts.
|
|
124
|
+
|
|
7
125
|
## [1.38.0] - 2026-08-16
|
|
8
126
|
|
|
9
127
|
### The routing table stopped being a second copy of the packs
|
|
@@ -589,6 +707,11 @@ reproduced before an edit; every one is fixed here.
|
|
|
589
707
|
|
|
590
708
|
## [1.30.0] - 2026-08-14
|
|
591
709
|
|
|
710
|
+
> **Never released on its own.** There is no `v1.30.0` tag and no `1.30.0` on npm,
|
|
711
|
+
> so `npm install sheleg-design-skill@1.30.0` and `git checkout v1.30.0` both fail. This section
|
|
712
|
+
> describes work that shipped inside a later version. The note is here because
|
|
713
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
714
|
+
|
|
592
715
|
A twentieth pack, **`paperclip`**, extracted from a live reference rather than composed:
|
|
593
716
|
<https://paperclip.ing>, read from the two shipped stylesheets
|
|
594
717
|
(`/_next/static/chunks/0sw-z-v7xc9dd.css`, 622 rules; `/_next/static/chunks/19xj4kovk13jy.css`,
|
|
@@ -744,6 +867,11 @@ reasons they exist were all legible in the source instead of having to be recons
|
|
|
744
867
|
|
|
745
868
|
## [1.28.0] - 2026-08-14
|
|
746
869
|
|
|
870
|
+
> **Never released on its own.** There is no `v1.28.0` tag and no `1.28.0` on npm,
|
|
871
|
+
> so `npm install sheleg-design-skill@1.28.0` and `git checkout v1.28.0` both fail. This section
|
|
872
|
+
> describes work that shipped inside a later version. The note is here because
|
|
873
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
874
|
+
|
|
747
875
|
> Authored and gated on its own, **released inside `v1.29.0`**: the `tenor` pack followed
|
|
748
876
|
> it in the same session before a tag was cut, and splitting the two after the fact would
|
|
749
877
|
> have produced an intermediate commit whose ratchet floors no longer matched its own
|
|
@@ -2183,6 +2311,11 @@ and so far only pack on the thirteen-heading contract.
|
|
|
2183
2311
|
|
|
2184
2312
|
## [1.5.0] - 2026-08-04
|
|
2185
2313
|
|
|
2314
|
+
> **Never released on its own.** There is no `v1.5.0` tag and no `1.5.0` on npm,
|
|
2315
|
+
> so `npm install sheleg-design-skill@1.5.0` and `git checkout v1.5.0` both fail. This section
|
|
2316
|
+
> describes work that shipped inside a later version. The note is here because
|
|
2317
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
2318
|
+
|
|
2186
2319
|
The register the skill was missing for its own audience: a developer tool that
|
|
2187
2320
|
does not live on a dark console. Six packs could dress a landing page, a
|
|
2188
2321
|
dashboard, a deck and two kinds of consumer health, and none of them had an
|
|
@@ -2269,6 +2402,11 @@ the software the people using this skill actually build.
|
|
|
2269
2402
|
|
|
2270
2403
|
## [1.4.0] - 2026-08-03
|
|
2271
2404
|
|
|
2405
|
+
> **Never released on its own.** There is no `v1.4.0` tag and no `1.4.0` on npm,
|
|
2406
|
+
> so `npm install sheleg-design-skill@1.4.0` and `git checkout v1.4.0` both fail. This section
|
|
2407
|
+
> describes work that shipped inside a later version. The note is here because
|
|
2408
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
2409
|
+
|
|
2272
2410
|
Two packs for the warm consumer register, extracted from two production sites
|
|
2273
2411
|
that solve the same brief in opposite ways — one premium and editorial, one
|
|
2274
2412
|
friendly and modular. Between them they replace the reflex a generated wellness
|
|
@@ -2566,6 +2704,11 @@ change what an existing token means. Removing or renaming either is a major.
|
|
|
2566
2704
|
|
|
2567
2705
|
## [0.9.1] - 2026-07-28
|
|
2568
2706
|
|
|
2707
|
+
> **Never released on its own.** There is no `v0.9.1` tag and no `0.9.1` on npm,
|
|
2708
|
+
> so `npm install sheleg-design-skill@0.9.1` and `git checkout v0.9.1` both fail. This section
|
|
2709
|
+
> describes work that shipped inside a later version. The note is here because
|
|
2710
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
2711
|
+
|
|
2569
2712
|
### Added
|
|
2570
2713
|
|
|
2571
2714
|
- Optional **Lazyweb MCP** step: when `mcp__lazyweb__*` tools are present, the
|
|
@@ -2663,6 +2806,11 @@ Review pass.
|
|
|
2663
2806
|
|
|
2664
2807
|
## [0.6.0] - 2026-07-20
|
|
2665
2808
|
|
|
2809
|
+
> **Published, never tagged.** `0.6.0` is installable from npm but there is no
|
|
2810
|
+
> `v0.6.0` tag, so the artifact exists and the commit it was cut from cannot be
|
|
2811
|
+
> checked out. A bug report against this version has no source tree to read
|
|
2812
|
+
> (2026-08-17, umbrella `B-71`).
|
|
2813
|
+
|
|
2666
2814
|
### Added
|
|
2667
2815
|
|
|
2668
2816
|
- Ready-made token layers `styles/tokens/<pack>.css` for all three packs
|
|
@@ -2689,6 +2837,11 @@ Review pass.
|
|
|
2689
2837
|
|
|
2690
2838
|
## [0.5.0] - 2026-07-20
|
|
2691
2839
|
|
|
2840
|
+
> **Never released on its own.** There is no `v0.5.0` tag and no `0.5.0` on npm,
|
|
2841
|
+
> so `npm install sheleg-design-skill@0.5.0` and `git checkout v0.5.0` both fail. This section
|
|
2842
|
+
> describes work that shipped inside a later version. The note is here because
|
|
2843
|
+
> the section reads as a release (2026-08-17, umbrella `B-71`).
|
|
2844
|
+
|
|
2692
2845
|
### Added
|
|
2693
2846
|
|
|
2694
2847
|
- **`workbench` style pack** — quiet light+dark utilitarian product UI for
|
|
@@ -2702,6 +2855,11 @@ Review pass.
|
|
|
2702
2855
|
|
|
2703
2856
|
## [0.4.0] - 2026-07-19
|
|
2704
2857
|
|
|
2858
|
+
> **Published, never tagged.** `0.4.0` is installable from npm but there is no
|
|
2859
|
+
> `v0.4.0` tag, so the artifact exists and the commit it was cut from cannot be
|
|
2860
|
+
> checked out. A bug report against this version has no source tree to read
|
|
2861
|
+
> (2026-08-17, umbrella `B-71`).
|
|
2862
|
+
|
|
2705
2863
|
### Added
|
|
2706
2864
|
|
|
2707
2865
|
- **Style packs** (`styles/`): the motion methodology is now style-agnostic
|
|
@@ -2717,6 +2875,11 @@ Review pass.
|
|
|
2717
2875
|
|
|
2718
2876
|
## [0.3.0] - 2026-07-19
|
|
2719
2877
|
|
|
2878
|
+
> **Published, never tagged.** `0.3.0` is installable from npm but there is no
|
|
2879
|
+
> `v0.3.0` tag, so the artifact exists and the commit it was cut from cannot be
|
|
2880
|
+
> checked out. A bug report against this version has no source tree to read
|
|
2881
|
+
> (2026-08-17, umbrella `B-71`).
|
|
2882
|
+
|
|
2720
2883
|
### Added
|
|
2721
2884
|
|
|
2722
2885
|
- Claude Code marketplace layout: `.claude-plugin/marketplace.json` +
|
|
@@ -2738,6 +2901,11 @@ Review pass.
|
|
|
2738
2901
|
|
|
2739
2902
|
## [0.2.0] - 2026-07-19
|
|
2740
2903
|
|
|
2904
|
+
> **Published, never tagged.** `0.2.0` is installable from npm but there is no
|
|
2905
|
+
> `v0.2.0` tag, so the artifact exists and the commit it was cut from cannot be
|
|
2906
|
+
> checked out. A bug report against this version has no source tree to read
|
|
2907
|
+
> (2026-08-17, umbrella `B-71`).
|
|
2908
|
+
|
|
2741
2909
|
### Changed
|
|
2742
2910
|
|
|
2743
2911
|
- SKILL.md reworked to skill-authoring canon: trigger-only description
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ problem — invented colors, six accent hues, dark mode retrofitted later.
|
|
|
11
11
|
|
|
12
12
|
This skill is the taste layer. It gives a coding agent **one motion
|
|
13
13
|
methodology** for cinematic, scroll-driven pages, **a motion doctrine** that
|
|
14
|
-
decides whether to animate before it decides how, and **twenty-
|
|
14
|
+
decides whether to animate before it decides how, and **twenty-seven locked style
|
|
15
15
|
packs** with ready-made design tokens, so what it builds reads as one system
|
|
16
16
|
instead of a pile of effects.
|
|
17
17
|
|
|
@@ -66,6 +66,11 @@ into the cinematic layer, and says so in its own *Motion flavor* section.
|
|
|
66
66
|
| `tenor` | warm paper with **zero radius and zero shadow anywhere**, a single hairline weight assembling every lattice, and one orange that exists only on hover and on focus — so the page screenshots with no colour in it at all — a sans held at weight 400 and tracked negative against a mono tracked positive, display at a line-height below one in an eight-to-twelve-character measure, and proof delivered as silent looping video in a 1px rectangle | products arguing a **management thesis** — that a new kind of thing has to be run like an existing organisation: AI-workforce and agent-operations platforms, autonomous back-office, revenue and sales operations, sold to the director who will have to manage it |
|
|
67
67
|
| `paperclip` | neutral coal with **no functional colour at all** — every control monochrome, elevation made of hairlines, and the whole chromatic budget spent on a curtain of 96 gradient capsules and twelve gradient section badges that cannot be clicked — a tight grotesque over a plain one over a monospace, and the capsule as the shape of everything from a button to a 10 × 20 schedule tick | products that ask a person to **run something that runs itself** — agent teams and orchestrators, autonomous back-office, schedulers, job runners, budget-governed compute |
|
|
68
68
|
| `awning` | white forecourt where **the accent is black** and no hue reaches the chrome at all; a pill whose radius is a declared component token, one variable grotesque at **420 / 550 with no 700**, two rule weights and a single three-layer shadow | commerce and platform front doors — the surface that sells a system other businesses will run their storefront, payroll, billing or logistics on |
|
|
69
|
+
| `router` | a near-white field with a trace of blue and white cards standing on that tint, **hairline seams instead of shadows anywhere** — one lift exists and it is a menu — body at 14px and weight 450, one royal blue at 97% saturation doing every accent job and none of the chart work, and a status triplet in which the colour you paint with is not the colour you write with | **product consoles and the pages that have to look like them** — dashboards, admin and developer platforms, billing and usage surfaces, and a landing page whose argument is an inventory rather than a promise (standalone) |
|
|
70
|
+
| `daylight` | a cool near-white portal field with generous radii and **one very large soft shadow spent on a single object per screen**, Inter Tight 700 tracked negative over Manrope 400, and a four-step blue tile ramp for stacked bands | **client-facing portals and the pages that sell them** — onboarding, workspaces a customer logs into, service dashboards, scheduling and billing (standalone) |
|
|
71
|
+
| `notation` | a near-white page drawn **entirely in hairlines instead of cards**, radii of 2 and 4px, a slab serif held at weight 300 against a monospace, **no bold anywhere**, an ink primary that leaves the accent free to mark what can be read, and one chamfered corner per page | **developer and technical products sold on restraint** — open source front pages, workspaces for people who dislike being sold to, documentation homes (standalone) |
|
|
72
|
+
| `almanac` | **oatmeal paper rather than white**, seams at 2px and 4px with **no 1px anywhere**, a 104px display at weight 500 with a line-height below one that locks its lines into a block, uppercase mono tags notched through the edges of drawn boxes, and one object per page floating on four stacked shadow stops | **pages that assert a category** — a manifesto, a company saying what this kind of thing is, a product whose argument is editorial rather than functional (standalone) |
|
|
73
|
+
| `vitrine` | a white field drawn **entirely in hairlines**, a serif display over a sans body, an ink primary so the accent stays free to mark what can be read, a grey panel that groups without lifting, and **one framed record** with a 1px inset highlight carrying the page's evidence | **the front door of a product sold on trust** — B2B software under evaluation, security and compliance surfaces, specification and comparison pages (standalone) |
|
|
69
74
|
| `ledger` | warm cream paper where elevation is a **1px hairline at 12% ink** and no card casts a shadow, radii of 7.5/10/15/20 nested concentrically, an **ink** primary button, and a terracotta accent forbidden from filling any control — it labels, as a 10px monospace uppercase kicker — over 32px data rows, with a seal on every card stating how its number is known | the console of a product that answers questions **about data** — AI analysts, BI surfaces, query workspaces, agents that read a warehouse and write back a figure |
|
|
70
75
|
|
|
71
76
|
Each pack locks palette, type, texture, motion tokens, signature motifs and
|
|
@@ -141,7 +146,7 @@ skills.
|
|
|
141
146
|
| `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 |
|
|
142
147
|
| `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 |
|
|
143
148
|
| `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 |
|
|
144
|
-
| `styles/*.md` | The twenty-
|
|
149
|
+
| `styles/*.md` | The twenty-seven style packs — palette, type, texture, motion tokens, motifs, bans, and the traps each one carries |
|
|
145
150
|
| `styles/tokens/*.css` | The ready-made token layer per pack, copied verbatim instead of transcribed (`workbench` and `field-notes` each ship a light `:root` plus a `data-theme="dark"` twin) |
|
|
146
151
|
| `styles/STYLE_PACK_TEMPLATE.md` | The pack contract as a skeleton, so a new style is authored against the same headings rather than improvised |
|
|
147
152
|
|
|
@@ -212,7 +217,7 @@ cd ./ds-workbench && npm install && npm run build
|
|
|
212
217
|
then `/design-sync` in that directory, from Claude Code. Three layers cross: the
|
|
213
218
|
pack's **bans** as the design system's own README, `styles.css` built from
|
|
214
219
|
`tokens/<pack>.css` verbatim, and the components — a six-name spine that is
|
|
215
|
-
identical in all twenty-
|
|
220
|
+
identical in all twenty-seven kits, so switching packs swaps identity rather than API,
|
|
216
221
|
plus each pack's signature parts. **Motion does not cross**, exactly as it does
|
|
217
222
|
not cross into Figma: a kit is the static half of a pack, and saying so is what
|
|
218
223
|
stops an agent inventing motion to fill the silence.
|
|
@@ -258,7 +263,7 @@ a pack's four widened sections used to make two gates *quieter* and still green.
|
|
|
258
263
|
One honest limit: the npx installer is checked by asserting its runtime bundle
|
|
259
264
|
walker exists, not by reading a file list — it has none by design. What proves
|
|
260
265
|
it ships the right files is CI, which installs the bundle through **both**
|
|
261
|
-
installers and `diff -r`s the result against the source, then builds all twenty-
|
|
266
|
+
installers and `diff -r`s the result against the source, then builds all twenty-seven
|
|
262
267
|
kits.
|
|
263
268
|
|
|
264
269
|
`test/scenarios.md` (T1–T19) is the behavioral harness: fresh subagents given a
|
package/bin/cli.js
CHANGED
|
@@ -234,7 +234,7 @@ ${c("bold", "What it installs")}
|
|
|
234
234
|
DESIGN_SYNC_BRIDGE.md the Claude Design contract (what a pack sends, and
|
|
235
235
|
what does not cross)
|
|
236
236
|
AI_PRODUCT_PATTERNS.md chat / agent / streaming surfaces (honest state)
|
|
237
|
-
styles/ twenty-
|
|
237
|
+
styles/ twenty-seven style packs — instrument-console (dark console),
|
|
238
238
|
editorial-luxury (warm editorial), workbench (light/dark
|
|
239
239
|
product UI), briefing-room (dark 16:9 presentation deck),
|
|
240
240
|
atrium (warm cream consumer health), orchard (friendly
|
|
@@ -265,7 +265,18 @@ ${c("bold", "What it installs")}
|
|
|
265
265
|
awning (a white forecourt where the accent is black and
|
|
266
266
|
no hue reaches the chrome, a pill whose radius is a
|
|
267
267
|
declared component token, and one variable grotesque at
|
|
268
|
-
420/550 with no 700)
|
|
268
|
+
420/550 with no 700),
|
|
269
|
+
router (a near-white field with a trace of blue, hairline
|
|
270
|
+
seams instead of shadows, body at 14px and weight 450, and
|
|
271
|
+
a status triplet where the painted colour is not the
|
|
272
|
+
written one), daylight (a cool portal field whose whole
|
|
273
|
+
depth is one very large soft shadow spent on one object),
|
|
274
|
+
notation (hairlines instead of cards, a light serif over
|
|
275
|
+
a monospace, an ink primary and one chamfered corner),
|
|
276
|
+
almanac (oatmeal paper at 2px with no 1px anywhere and a
|
|
277
|
+
display set below a line-height of one), vitrine (a white
|
|
278
|
+
hairline field with a serif display, an ink primary, and
|
|
279
|
+
one framed record carrying the evidence) —
|
|
269
280
|
plus a ready-made token CSS per pack and
|
|
270
281
|
STYLE_PACK_TEMPLATE.md for authoring more
|
|
271
282
|
`);
|
|
@@ -65,6 +65,28 @@ awning — a white forecourt where the accent is black and no hue reaches the
|
|
|
65
65
|
chrome at all, a pill whose radius is a declared component token, one variable
|
|
66
66
|
grotesque at 420/550 with no 700, two rule weights and a single three-layer
|
|
67
67
|
shadow, for commerce and platform front doors);
|
|
68
|
+
router — a near-white field with a trace of blue and white cards standing on
|
|
69
|
+
that tint, hairline seams instead of shadows anywhere, body at 14px and weight
|
|
70
|
+
450, one royal blue at 97% saturation doing every accent job and none of the
|
|
71
|
+
chart work, and a status triplet in which the colour you paint with is not the
|
|
72
|
+
colour you write with, for product consoles, developer platforms and the landing
|
|
73
|
+
pages that have to look like them;
|
|
74
|
+
daylight — a cool near-white portal field with generous radii whose whole depth
|
|
75
|
+
is one very large soft shadow spent on a single object per screen, Inter Tight
|
|
76
|
+
700 tracked negative over Manrope 400, for client-facing portals and the pages
|
|
77
|
+
that sell them;
|
|
78
|
+
notation — a near-white page drawn entirely in hairlines instead of cards, radii
|
|
79
|
+
of 2 and 4px, a slab serif held at weight 300 against a monospace with no bold
|
|
80
|
+
anywhere, an ink primary that leaves the accent free to mark what can be read,
|
|
81
|
+
and one chamfered corner per page, for developer products sold on restraint;
|
|
82
|
+
almanac — oatmeal paper rather than white, seams at 2px with no 1px anywhere, a
|
|
83
|
+
104px display at weight 500 set below a line-height of one, uppercase mono tags
|
|
84
|
+
notched through the edges of drawn boxes, and one object per page floating on
|
|
85
|
+
four stacked shadow stops, for pages that assert a category;
|
|
86
|
+
vitrine — a white field drawn entirely in hairlines, a serif display over a sans
|
|
87
|
+
body, an ink primary, a grey panel that groups without lifting, and one framed
|
|
88
|
+
record with a 1px inset highlight carrying the page's evidence, for the front
|
|
89
|
+
door of a product sold on trust);
|
|
68
90
|
otherwise follow the contract below (self-contained on purpose).
|
|
69
91
|
|
|
70
92
|
## Whether to animate at all — before how
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pkg": "@sheleg-design/almanac",
|
|
3
|
+
"globalName": "ShelegAlmanac",
|
|
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,32 @@
|
|
|
1
|
+
# Almanac — the contract this design system ships under
|
|
2
|
+
|
|
3
|
+
**Register.** Choose Almanac for **pages that assert a category**: a manifesto page, a
|
|
4
|
+
company saying what this kind of thing is, a product whose argument is editorial. The
|
|
5
|
+
field is **oatmeal `#f0efe3`, not white**, and it is the whole first impression. Light
|
|
6
|
+
is the default register and dark is a first-class twin; both come from the same
|
|
7
|
+
tokens, so build every screen against `var(--…)` and never a literal.
|
|
8
|
+
|
|
9
|
+
**Seams are 2px and there is no 1px anywhere.** Structure is read by mass rather than
|
|
10
|
+
by contrast, which is why the seam values sit far under a hairline pack's and are not
|
|
11
|
+
a defect. Neither seam carries meaning alone: every panel edge in this pack has an
|
|
12
|
+
uppercase mono tag notched through it.
|
|
13
|
+
|
|
14
|
+
**One object floats per page**, on four stacked shadow stops whose deepest is 162px
|
|
15
|
+
of blur. A second floating object is the fastest way to lose the effect.
|
|
16
|
+
|
|
17
|
+
**`--warn` is two different colours and swapping them is silent.** `#993f0e` on the
|
|
18
|
+
light register and `#fa6838` on the dark are the same orange at two steps, because
|
|
19
|
+
the bright one measures 2.32 on oatmeal. Using the bright value on the light field
|
|
20
|
+
ships a warning nobody can read and nothing on screen looks broken.
|
|
21
|
+
|
|
22
|
+
**Status is never by colour alone.** Every state is a mono tag or a dot **plus a
|
|
23
|
+
word**. `--danger` is **derived** and is a crimson on purpose: an orange-red beside
|
|
24
|
+
this pack's burnt-orange warn fails the palette gate's hard floor.
|
|
25
|
+
|
|
26
|
+
**Bans** (verbatim from the pack):
|
|
27
|
+
|
|
28
|
+
- No 1px anywhere; no second floating object; no drawn box without its tag.
|
|
29
|
+
- No sentence in the mono — it is the label voice.
|
|
30
|
+
- No weight 700 as the default emphasis; 500 is the pack's weight.
|
|
31
|
+
- No white field. The oatmeal is the identity.
|
|
32
|
+
- No status by colour alone.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @sheleg-design/almanac
|
|
2
|
+
|
|
3
|
+
The React reference kit for the SHELEG **Almanac** style pack — an oatmeal-paper grammar (light default, dark twin) with 2px seams and no 1px anywhere, a display set below a line-height of one, and uppercase mono tags notched through the edges of drawn boxes.
|
|
4
|
+
|
|
5
|
+
It is generated from the pack, not authored beside it: `src/styles.css` opens with
|
|
6
|
+
`styles/tokens/almanac.css` byte for byte, and the rules the design agent must obey
|
|
7
|
+
are in [`.design-sync/conventions.md`](./.design-sync/conventions.md).
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install && npm run build
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## The spine
|
|
14
|
+
|
|
15
|
+
`Button`, `Card`, `Chip`, `Stat`, `Heading`, `Rule` — identical names, props and
|
|
16
|
+
types in every SHELEG kit. Switching packs swaps identity, not API.
|
|
17
|
+
|
|
18
|
+
## This pack's own
|
|
19
|
+
|
|
20
|
+
`StatusDot` carries the status triplet with a **required** label, because this pack
|
|
21
|
+
states that status is never by colour alone. `Skeleton` is static. `TaggedBox` is the
|
|
22
|
+
pack's signature element — see [`styles/almanac.md`](../../plugins/sheleg-design/skills/sheleg-design/styles/almanac.md).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sheleg-design/almanac",
|
|
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,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Actions
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Height 36, radius 6, weight 500, label at 14 — the reference's own control, and
|
|
6
|
+
every variant wears the same radius. `primary` fills with the accent and states
|
|
7
|
+
its label colour on the rule rather than inheriting it, because an anchor reset
|
|
8
|
+
that says `color: inherit` will otherwise win the label and paint ink on accent.
|
|
9
|
+
`secondary` is the 1px `--edge` bordered one; `ghost` carries no border at all
|
|
10
|
+
and belongs in toolbars and table rows, where a border adds a line the eye has
|
|
11
|
+
to parse.
|
|
12
|
+
|
|
13
|
+
Hover moves background, border and colour. **Nothing translates and nothing
|
|
14
|
+
scales** — the reference presses nothing, and a button that pops on click has
|
|
15
|
+
left this pack.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Button onClick={connect}>Connect account</Button>
|
|
19
|
+
<Button variant="secondary" onClick={exportAll}>Export</Button>
|
|
20
|
+
<Button variant="ghost" size="sm" onClick={dismiss}>Dismiss</Button>
|
|
21
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonProps {
|
|
4
|
+
/** `primary` is the accent fill — the pack allows one 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={['al-btn', `al-btn--${variant}`, `al-btn--${size}`, className]
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join(' ')}
|
|
27
|
+
disabled={disabled}
|
|
28
|
+
onClick={onClick}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</button>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Surfaces
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`--panel` on `--bg`, a 1px seam, radius 8, **no shadow**. That is the whole
|
|
6
|
+
elevation model of this pack: the reference sets `box-shadow: none` almost
|
|
7
|
+
everywhere and the single lift it owns is a menu.
|
|
8
|
+
|
|
9
|
+
**Use a card when the content is a record.** A list of paragraphs takes a seam
|
|
10
|
+
between them and no box — the reference's own settings pages are seams, not
|
|
11
|
+
cards, and boxing prose is the fastest way to make this pack look like a
|
|
12
|
+
template.
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
<Card title="Managed accounts" meta="4 held">
|
|
16
|
+
<DataRows />
|
|
17
|
+
</Card>
|
|
18
|
+
```
|
|
@@ -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, a window, a state. */
|
|
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={['al-card', className].filter(Boolean).join(' ')}>
|
|
15
|
+
{head && (
|
|
16
|
+
<div className="al-card__head">
|
|
17
|
+
{title !== undefined && <h3 className="al-card__title">{title}</h3>}
|
|
18
|
+
{meta !== undefined && <span className="al-card__meta">{meta}</span>}
|
|
19
|
+
</div>
|
|
20
|
+
)}
|
|
21
|
+
<div className="al-card__body">{children}</div>
|
|
22
|
+
</section>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Foundations
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
A pill at `--r-pill`, 12px, weight 500. `neutral` sits on `--panel-2`;
|
|
6
|
+
`accent` takes the accent at 7.8% with the accent as its word — the reference's
|
|
7
|
+
own tint alpha, and the same pair its selected sidebar item wears.
|
|
8
|
+
|
|
9
|
+
`selected` adds a 2px rail on the leading edge. **Selected is not hover:** a
|
|
10
|
+
selected chip keeps its tint and rail after the pointer leaves, and a hovered
|
|
11
|
+
one does not.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Chip>30d</Chip>
|
|
15
|
+
<Chip tone="accent" selected>Overview</Chip>
|
|
16
|
+
```
|
|
@@ -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
|
+
'al-chip',
|
|
15
|
+
`al-chip--${tone}`,
|
|
16
|
+
selected ? 'al-chip--selected' : undefined,
|
|
17
|
+
className,
|
|
18
|
+
]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' ')}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Foundations
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Three levels and no more: `--t-page` 30, `--t-section` 24, `--t-card` 16. All
|
|
6
|
+
three carry `--track-tight`; level 3 is the same size as body and separates by
|
|
7
|
+
weight alone, which is what keeps a dense screen from turning into a ladder of
|
|
8
|
+
sizes.
|
|
9
|
+
|
|
10
|
+
The hero's 36px display is **not** in this component. It belongs to the landing
|
|
11
|
+
register, is fluid, and is capped at 17ch — a headline that reaches five lines
|
|
12
|
+
is a broken hero, not a long one.
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
<Heading level={1}>Managed accounts</Heading>
|
|
16
|
+
<Heading>Volume by account</Heading>
|
|
17
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface HeadingProps {
|
|
4
|
+
/** 1 = page title (30px), 2 = section (24px), 3 = card title (16px). */
|
|
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={['al-heading', `al-heading--${level}`, className].filter(Boolean).join(' ')}
|
|
15
|
+
>
|
|
16
|
+
{children}
|
|
17
|
+
</Tag>
|
|
18
|
+
);
|
|
19
|
+
}
|