sheleg-design-skill 1.27.1 → 1.31.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 +310 -0
- package/README.md +7 -4
- package/bin/cli.js +9 -2
- package/cursor/rules/sheleg-design.mdc +14 -1
- package/kits/ora/.design-sync/config.json +14 -0
- package/kits/ora/.design-sync/conventions.md +61 -0
- package/kits/ora/README.md +43 -0
- package/kits/ora/package.json +29 -0
- package/kits/ora/src/Button.md +21 -0
- package/kits/ora/src/Button.tsx +33 -0
- package/kits/ora/src/Card.md +19 -0
- package/kits/ora/src/Card.tsx +24 -0
- package/kits/ora/src/Chip.md +16 -0
- package/kits/ora/src/Chip.tsx +25 -0
- package/kits/ora/src/Heading.md +15 -0
- package/kits/ora/src/Heading.tsx +19 -0
- package/kits/ora/src/LayerBar.md +26 -0
- package/kits/ora/src/LayerBar.tsx +57 -0
- package/kits/ora/src/Rule.md +15 -0
- package/kits/ora/src/Rule.tsx +18 -0
- package/kits/ora/src/SectionRule.md +18 -0
- package/kits/ora/src/SectionRule.tsx +37 -0
- package/kits/ora/src/Stat.md +15 -0
- package/kits/ora/src/Stat.tsx +17 -0
- package/kits/ora/src/StatusDot.md +16 -0
- package/kits/ora/src/StatusDot.tsx +21 -0
- package/kits/ora/src/StepLog.md +22 -0
- package/kits/ora/src/StepLog.tsx +39 -0
- package/kits/ora/src/Terminal.md +18 -0
- package/kits/ora/src/Terminal.tsx +27 -0
- package/kits/ora/src/Verdict.md +21 -0
- package/kits/ora/src/Verdict.tsx +47 -0
- package/kits/ora/src/index.ts +27 -0
- package/kits/ora/src/styles.css +669 -0
- package/kits/ora/tsconfig.json +15 -0
- package/kits/paperclip/.design-sync/config.json +14 -0
- package/kits/paperclip/.design-sync/conventions.md +62 -0
- package/kits/paperclip/README.md +46 -0
- package/kits/paperclip/package.json +29 -0
- package/kits/paperclip/src/Button.md +23 -0
- package/kits/paperclip/src/Button.tsx +33 -0
- package/kits/paperclip/src/CapsuleCurtain.md +32 -0
- package/kits/paperclip/src/CapsuleCurtain.tsx +109 -0
- package/kits/paperclip/src/Card.md +22 -0
- package/kits/paperclip/src/Card.tsx +24 -0
- package/kits/paperclip/src/Chip.md +21 -0
- package/kits/paperclip/src/Chip.tsx +25 -0
- package/kits/paperclip/src/HairlineGrid.md +34 -0
- package/kits/paperclip/src/HairlineGrid.tsx +23 -0
- package/kits/paperclip/src/Heading.md +21 -0
- package/kits/paperclip/src/Heading.tsx +19 -0
- package/kits/paperclip/src/LedgerRow.md +31 -0
- package/kits/paperclip/src/LedgerRow.tsx +54 -0
- package/kits/paperclip/src/OrgNode.md +27 -0
- package/kits/paperclip/src/OrgNode.tsx +42 -0
- package/kits/paperclip/src/Rule.md +20 -0
- package/kits/paperclip/src/Rule.tsx +18 -0
- package/kits/paperclip/src/ScheduleLane.md +31 -0
- package/kits/paperclip/src/ScheduleLane.tsx +58 -0
- package/kits/paperclip/src/SectionBadge.md +23 -0
- package/kits/paperclip/src/SectionBadge.tsx +21 -0
- package/kits/paperclip/src/Stat.md +18 -0
- package/kits/paperclip/src/Stat.tsx +17 -0
- package/kits/paperclip/src/Terminal.md +34 -0
- package/kits/paperclip/src/Terminal.tsx +67 -0
- package/kits/paperclip/src/index.ts +29 -0
- package/kits/paperclip/src/styles.css +962 -0
- package/kits/paperclip/tsconfig.json +15 -0
- package/kits/tenor/.design-sync/config.json +14 -0
- package/kits/tenor/.design-sync/conventions.md +70 -0
- package/kits/tenor/README.md +43 -0
- package/kits/tenor/package.json +29 -0
- package/kits/tenor/src/Button.md +21 -0
- package/kits/tenor/src/Button.tsx +33 -0
- package/kits/tenor/src/Card.md +18 -0
- package/kits/tenor/src/Card.tsx +24 -0
- package/kits/tenor/src/Chip.md +15 -0
- package/kits/tenor/src/Chip.tsx +25 -0
- package/kits/tenor/src/Eyebrow.md +13 -0
- package/kits/tenor/src/Eyebrow.tsx +22 -0
- package/kits/tenor/src/FilmFrame.md +18 -0
- package/kits/tenor/src/FilmFrame.tsx +40 -0
- package/kits/tenor/src/Guardrail.md +20 -0
- package/kits/tenor/src/Guardrail.tsx +27 -0
- package/kits/tenor/src/Heading.md +17 -0
- package/kits/tenor/src/Heading.tsx +19 -0
- package/kits/tenor/src/Lattice.md +19 -0
- package/kits/tenor/src/Lattice.tsx +23 -0
- package/kits/tenor/src/LatticeCell.md +20 -0
- package/kits/tenor/src/LatticeCell.tsx +37 -0
- package/kits/tenor/src/Rule.md +13 -0
- package/kits/tenor/src/Rule.tsx +18 -0
- package/kits/tenor/src/SplitHeadline.md +22 -0
- package/kits/tenor/src/SplitHeadline.tsx +30 -0
- package/kits/tenor/src/Staircase.md +25 -0
- package/kits/tenor/src/Staircase.tsx +33 -0
- package/kits/tenor/src/Stat.md +14 -0
- package/kits/tenor/src/Stat.tsx +17 -0
- package/kits/tenor/src/index.ts +29 -0
- package/kits/tenor/src/styles.css +646 -0
- package/kits/tenor/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 +2 -2
- 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 +12 -6
- package/plugins/sheleg-design/skills/sheleg-design/SURFACE_COMPOSITION.md +4 -4
- package/plugins/sheleg-design/skills/sheleg-design/styles/blueprint.md +4 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/datasheet.md +5 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/instrument-console.md +10 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/manpage.md +5 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/ora.md +536 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/orchard.md +9 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/paperclip.md +775 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/roster.md +5 -1
- package/plugins/sheleg-design/skills/sheleg-design/styles/tenor.md +470 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/ora.css +219 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/paperclip.css +294 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/tokens/tenor.css +207 -0
- package/plugins/sheleg-design/skills/sheleg-design/styles/workbench.md +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,316 @@ 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.31.0] - 2026-08-14
|
|
8
|
+
|
|
9
|
+
**T29 ran, and the pack it was written for did not survive it intact.** Both branches
|
|
10
|
+
green — the routing worked — and the pair returned forty-one findings, twenty-six of them
|
|
11
|
+
against `paperclip`, a pack that had passed all three gates three times. Every one was
|
|
12
|
+
reproduced before an edit; every one is fixed here.
|
|
13
|
+
|
|
14
|
+
### Fixed — in `paperclip`, found by T29a
|
|
15
|
+
|
|
16
|
+
- **`--cream` was prescribed and never declared.** The dark primary button's hover was
|
|
17
|
+
specified to keep its label and border at `--cream`, a token this pack does not ship. It
|
|
18
|
+
means `--accent`, and now says so.
|
|
19
|
+
- **The dark card hover was a no-op.** A card rests at `--surface` and the hover was
|
|
20
|
+
written as `--surface`. A card and a grid cell are now separated: the cell rests at
|
|
21
|
+
`--bg` and hovers one step toward the card's fill; the card does not hover at all.
|
|
22
|
+
- **`--terminal-dim` at 2.92:1 was the label of a tab a reader has to click.** Repaired to
|
|
23
|
+
`--terminal-mid` (5.64:1). `--terminal-dim` survives for the prompt glyph, which is
|
|
24
|
+
`aria-hidden` punctuation, and now carries an `@role non-text:` note saying so.
|
|
25
|
+
- **`--shadow-alert` was a second resting shadow in a pack that claimed one** — and it
|
|
26
|
+
hardcoded the reference's **light**-theme amber into a value only ever painted on the
|
|
27
|
+
dark field. Derived from `--warn` with `color-mix()`, and the Texture section now names
|
|
28
|
+
both shadows.
|
|
29
|
+
- **All three stagger formulas hardcoded `.14s`.** Zeroing `--stagger` under reduced
|
|
30
|
+
motion would have left every one of them running. They spend `var(--stagger)` now, and
|
|
31
|
+
the pack says why in the sentence that used to say "change it in one place".
|
|
32
|
+
- **The reduced-motion blanket had no mechanism for half of what it promised.** The
|
|
33
|
+
marquee and the two 1.5s trace loops are literals inside `animation` shorthands, which no
|
|
34
|
+
token can zero. The pack now ships the rule block beside the token list.
|
|
35
|
+
- **The signature element's generation rule did not reproduce its own artwork.** The
|
|
36
|
+
bottom stop was stated at −10.3°/step and does not land on the last capsule; the value
|
|
37
|
+
implied by the anchors is **−10.45°**. "Near-constant saturation and lightness" was true
|
|
38
|
+
of the top ramp (S 96→84, L 56→48) and false of the bottom (S 96→69, L 56→33) — the
|
|
39
|
+
bottom stop darkens as it turns, which is what keeps the curtain's lower edge off the
|
|
40
|
+
field. Both ramps are now stated separately, and "forty-five gradients" no longer sits
|
|
41
|
+
two sentences from "every capsule is filled with its own": a column carries twelve and
|
|
42
|
+
the eight columns reuse the ramps, four of them in reverse.
|
|
43
|
+
- **The concentric-radius rule was arithmetically wrong about a nest that does not exist.**
|
|
44
|
+
`8 − 2 ≈ 4.8` is 6, and the reference's tab group sits inside a header with no radius.
|
|
45
|
+
The rule is now declared as the pack's own decision, with a worked example that computes,
|
|
46
|
+
and the reference's actual behaviour — pick by element size, no arithmetic — recorded.
|
|
47
|
+
- **`--radius-lg` was called "never spent" and is spent five times**, on the three large
|
|
48
|
+
mock panels. `--radius-md` is the rung that is never spent.
|
|
49
|
+
- Smaller, and all reproduced: the artwork called 1200px *tall* where 1200 is its frame's
|
|
50
|
+
width (it is a 560 × 630 curtain in a 1200 × 675 frame); "nothing in this pack overlaps"
|
|
51
|
+
in a pack whose hero is an overlap; a 1.5 line-height floor claimed against a display
|
|
52
|
+
ramp that runs 0.98; `--font-serif` and `--font-sans` named as if the layer declared
|
|
53
|
+
them; an icon range of 14–16px that excluded the pack's own 11px nav glyph; a mono ramp
|
|
54
|
+
called width-invariant beside an axis mark that steps at 768px; a Gotchas count of seven
|
|
55
|
+
where eight are defects; the grain's 512-unit filter in a 256px tile, which is the
|
|
56
|
+
reference's own arrangement and doubles the effective frequency to ~5.9 — now stated with
|
|
57
|
+
its consequence rather than repaired; weight 450 prescribed in a pack that documents 450
|
|
58
|
+
as unrenderable; and an invented "roughly 22 characters per line", replaced by the two
|
|
59
|
+
lines the reference actually sets.
|
|
60
|
+
|
|
61
|
+
### Fixed — in neighbours, found by the same run
|
|
62
|
+
|
|
63
|
+
- **`ora`'s merge-time fork clause called this pack "three grotesques and a monospace".**
|
|
64
|
+
It is two grotesques and a monospace; the pack's own Bans cap it at three families.
|
|
65
|
+
- **`SKILL.md` marked three packs `(standalone)` and its ceiling paragraph named four.**
|
|
66
|
+
`ora`, `tenor` and `paperclip` all declare standalone in their own Registers and all
|
|
67
|
+
three pin a ceiling — 4, 4 and 5 — that the paragraph never mentioned. An agent choosing
|
|
68
|
+
any of them off the table alone would have taken `MOTION_INTENSITY` 7 from the marketing
|
|
69
|
+
row. All three are marked and all three ceilings enumerated.
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- **`--terminal-dot`, `--mark-rest`, `--scrim`** — three colours the pack spent as literals
|
|
74
|
+
in its Components section. `--scrim` is `#0a0a0a8c` in **both** themes, because the
|
|
75
|
+
reference veils a light modal in coal too, and it stays a literal because the palette gate
|
|
76
|
+
cannot compute a `color-mix()` into `transparent` — and an unparseable token is a failure
|
|
77
|
+
there, not a skip.
|
|
78
|
+
- **`--t-hero-art` and `--t-hero-copy` in the Motion tokens table**, which shipped in the
|
|
79
|
+
token layer and appeared only as prose. The table is now the whole set.
|
|
80
|
+
- **B-038 … B-043** — fifteen findings against `instrument-console` from T29b, filed rather
|
|
81
|
+
than fixed because they belong to a shipped pack this run does not own. Four reproduced
|
|
82
|
+
first: zero `--danger`/`--info` tokens against Bans that legislate for four statuses; a
|
|
83
|
+
pressed primary label at **3.06:1**; one of only two token layers with no
|
|
84
|
+
`prefers-reduced-motion` branch, in the pack that mandates a particle field; and a Bans
|
|
85
|
+
line that forbids coloured shadows "besides `--accent-glow`", which is a colour.
|
|
86
|
+
|
|
87
|
+
## [1.30.0] - 2026-08-14
|
|
88
|
+
|
|
89
|
+
A twentieth pack, **`paperclip`**, extracted from a live reference rather than composed:
|
|
90
|
+
<https://paperclip.ing>, read from the two shipped stylesheets
|
|
91
|
+
(`/_next/static/chunks/0sw-z-v7xc9dd.css`, 622 rules; `/_next/static/chunks/19xj4kovk13jy.css`,
|
|
92
|
+
712 rules), the hero's inline SVG and the `@font-face` block. It is the first pack whose
|
|
93
|
+
thesis is that **colour is ornament**: there is no functional colour anywhere in the
|
|
94
|
+
interface, and the whole chromatic budget is spent on two things a reader cannot click.
|
|
95
|
+
|
|
96
|
+
Authored on `feat/paperclip-pack` in a dedicated worktree while another run held the
|
|
97
|
+
`PACK-TENOR` lease on the shared checkout, per `docs/DOCMAP.md`. That run landed `ora` and
|
|
98
|
+
`tenor` as 1.29.0 while this branch was open — including the version this branch had
|
|
99
|
+
already taken — so the merge moved it to 1.30.0 and recounted every site from eighteen to
|
|
100
|
+
twenty. Nothing was lost in either direction; the counted-claims gate named all eleven
|
|
101
|
+
sites that needed moving.
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
|
|
105
|
+
- **`styles/paperclip.md` + `styles/tokens/paperclip.css` — widened contract, all thirteen
|
|
106
|
+
headings.** A neutral coal field (`#0a0a0a`) with `#fafafa` ink at 18.97:1, and a light
|
|
107
|
+
twin on pure white at 19.80:1 that has **no elevation step at all**: the reference sets
|
|
108
|
+
`--background` and `--card` to the same white and separates a card from the page with a
|
|
109
|
+
1px rule and nothing else.
|
|
110
|
+
- **The accent is the inverted field, and colour is ornament.** Every control is
|
|
111
|
+
monochrome — `.navbar-cta`, `.hero-btn-primary`, `.sim-submit` and `.cta-btn` are one
|
|
112
|
+
component wearing four names — and the pack's central rule is one sentence: a gradient
|
|
113
|
+
that can be clicked, hovered or focused has left the pack. The corollary is what makes
|
|
114
|
+
the four status hues land: because colour is spent entirely on things that do nothing,
|
|
115
|
+
anything coloured reads as scenery.
|
|
116
|
+
- **The capsule curtain as the signature element.** 96 capsules in 8 columns on a 70px
|
|
117
|
+
pitch, each 70 × 170 at `rx: 35`, stepped 34.5px so every capsule covers all but a
|
|
118
|
+
34.5px band of the one above it. The 45 gradients filling them are **generated, not
|
|
119
|
+
chosen**: the top stop rotates forward around the hue wheel by ~12.4° per capsule and
|
|
120
|
+
the bottom stop backward by ~10.3°, at near-constant saturation and lightness — so the
|
|
121
|
+
stops stay near-complementary and each column inverts its own gradient between its first
|
|
122
|
+
capsule and its last. Measured across all 45 gradients and 89 distinct stops.
|
|
123
|
+
- **One noise recipe, on every saturated surface and nowhere else.** `fractalNoise`,
|
|
124
|
+
`baseFrequency 2.95`, 5 octaves, seed 9, tiled at 256px under `isolation: isolate` with
|
|
125
|
+
`mix-blend-mode: overlay` — 12% on a section badge, 86% over the artwork through an
|
|
126
|
+
alpha mask of the capsules themselves. The same seed on both, which is why a
|
|
127
|
+
twelve-gradient page does not band.
|
|
128
|
+
- **Twelve section-badge gradients, each with its own hand-picked label ink** — white on
|
|
129
|
+
six, and `#2a1530` / `#3d3010` / `#1a2a40` / `#2a2340` / `#1a3a38` on the five light
|
|
130
|
+
ramps, because a 90° gradient has two ends and one label has to clear both.
|
|
131
|
+
- **`kits/paperclip/` — the React reference kit**, the six-name spine plus seven signature
|
|
132
|
+
components: `CapsuleCurtain`, `SectionBadge`, `HairlineGrid`, `OrgNode`, `LedgerRow`,
|
|
133
|
+
`ScheduleLane`, `Terminal`. `src/styles.css` opens with the token layer byte for byte,
|
|
134
|
+
and four of the seven carry `container-type: inline-size`, so no component in the kit is
|
|
135
|
+
sized by the screen.
|
|
136
|
+
- **`T29` in `test/scenarios.md`** — the operator register and its fork against the
|
|
137
|
+
console, with the negative branch, and a second rejected pack because `ora` now sits
|
|
138
|
+
inside the same silhouette. **Written and not yet run**, and the scenario says so in its
|
|
139
|
+
own Result line rather than in a footnote.
|
|
140
|
+
|
|
141
|
+
### Fixed — in the pack, against its own reference
|
|
142
|
+
|
|
143
|
+
- **`--info` is derived and marked derived.** The reference's dark block overrides five
|
|
144
|
+
status *icon* colours and leaves the four base status colours at their light values, so
|
|
145
|
+
`--status-task-in_progress` renders at **3.83:1** on the coal field and is set as text
|
|
146
|
+
(`● 1 live`). The pack ships `#60a5fa`, the 400 step of the same ramp, at 7.79:1.
|
|
147
|
+
- **The focus ring is kept.** The reference's one text input sets `outline: none` on focus
|
|
148
|
+
and replaces the ring with a 1px border colour change.
|
|
149
|
+
- **Two 1.5s infinite loops are stopped under `prefers-reduced-motion`.** `dotPulse` and
|
|
150
|
+
`statusBlink` survive the reference's own reduced-motion blocks, which do calm the hero,
|
|
151
|
+
the parallax, the marquee tracks and the modal.
|
|
152
|
+
- **The budget bar animates `transform: scaleX()`**, not `width` for 1.2s per bar with six
|
|
153
|
+
bars in view.
|
|
154
|
+
|
|
155
|
+
### Changed
|
|
156
|
+
|
|
157
|
+
- **Four reciprocal fork clauses.** `instrument-console`, `workbench` and `orchard` each
|
|
158
|
+
gain one against `paperclip`; `ora` and `paperclip` gain the pair in both directions,
|
|
159
|
+
which is the one edge no gate could have asked for — neither pack existed in the other's
|
|
160
|
+
tree, so `validate_fork_reciprocity()` had nothing to check. The two are the closest in
|
|
161
|
+
the library: both dark by default, both refusing a brand hue, both spending the accent as
|
|
162
|
+
the inverted field. Three tests separate them, and both packs now carry all three.
|
|
163
|
+
- Counts moved from nineteen to twenty in the README, `bin/cli.js`, the three manifests,
|
|
164
|
+
`SURFACE_COMPOSITION.md`, `MOBILE_SURFACES.md` and `DESIGN_SYNC_BRIDGE.md`; the
|
|
165
|
+
`@role non-text:` tally is recomputed (fourteen of twenty, from thirteen of nineteen) and
|
|
166
|
+
the accent tally with it (eighteen, from seventeen).
|
|
167
|
+
- `/sheleg-design`'s by-name fast path said "the fourteen are" over a list of nineteen —
|
|
168
|
+
a count no gate reads, because it has no counted noun after it. It now says twenty and
|
|
169
|
+
lists them.
|
|
170
|
+
- `SKILL.md`'s core-contract paragraph: six of the twenty, the other fourteen.
|
|
171
|
+
|
|
172
|
+
## [1.29.0] - 2026-08-14
|
|
173
|
+
|
|
174
|
+
A nineteenth pack, **`tenor`**, and the first one in the library extracted from a
|
|
175
|
+
**hand-authored stylesheet** rather than a compiled bundle: <https://heytenor.com> ships
|
|
176
|
+
33,822 bytes of CSS somebody wrote, so the token names, the ratios between them and the
|
|
177
|
+
reasons they exist were all legible in the source instead of having to be reconstructed.
|
|
178
|
+
|
|
179
|
+
### Added
|
|
180
|
+
|
|
181
|
+
- **`styles/tenor.md` + `styles/tokens/tenor.css` — widened contract, all thirteen
|
|
182
|
+
headings.** Warm paper `#f7f6f2` under near-black ink at 17.61:1, **zero `border-radius`
|
|
183
|
+
and zero `box-shadow` in the entire reference**, and one border weight for the whole
|
|
184
|
+
system. The colour argument is the pack: at rest the page carries a single 25px orange
|
|
185
|
+
square, and every other appearance of the accent is a hover fill or the focus ring — a
|
|
186
|
+
page in this pack screenshots with no colour in it at all.
|
|
187
|
+
- **Severity as value rather than hue.** The reference's guardrail chips settle it in one
|
|
188
|
+
row: ALWAYS ASK is the orange, LIMIT is a grey, NEVER is the ink, and the *word* carries
|
|
189
|
+
the meaning in all three. The pack ships `--sev-ask` / `--sev-limit` / `--sev-never` as
|
|
190
|
+
the primary system; `--warn` is the accent and `--danger` is the ink, so `--good`
|
|
191
|
+
`#296b46` is the only value in the pack the reference does not contain, and it is marked
|
|
192
|
+
DERIVED at its declaration.
|
|
193
|
+
- **Type: two families, two weights, and tracking that runs both ways.** The sans is held
|
|
194
|
+
at weight 400 and tracks negative, tightening to `-0.065em` on the hero; the mono is 500
|
|
195
|
+
and tracks positive, opening to `0.12em` on the smallest label. Display line-height goes
|
|
196
|
+
**below one** — 0.91 at a `12ch` measure — which is what turns every heading into a
|
|
197
|
+
three- or four-line stack.
|
|
198
|
+
- **`kits/tenor/` — the React reference kit**, the six-name spine plus seven signature
|
|
199
|
+
components: `Staircase` (the signature element, typed as a **four-tuple** so the value
|
|
200
|
+
ramp cannot grow a fifth rung), `SplitHeadline`, `Lattice` + `LatticeCell`, `FilmFrame`,
|
|
201
|
+
`Guardrail` and `Eyebrow`. Every breakpoint in `src/styles.css` is a `@container` query;
|
|
202
|
+
`FilmFrame` deliberately does not call `play()`, because the page owns the motion policy
|
|
203
|
+
and a kit is the static half of a pack.
|
|
204
|
+
|
|
205
|
+
### Changed
|
|
206
|
+
|
|
207
|
+
- **The library is nineteen packs**, and every counted claim moved with it: `SKILL.md`
|
|
208
|
+
(the routing table, the core-contract split — six of the nineteen, the other thirteen —
|
|
209
|
+
and the token-vocabulary note), `README.md`, `bin/cli.js`, `install.sh`, the three
|
|
210
|
+
manifests, the Cursor rule, the slash command, `MOBILE_SURFACES.md`,
|
|
211
|
+
`SURFACE_COMPOSITION.md` (`--accent` in seventeen packs, `@role non-text:` in thirteen of
|
|
212
|
+
the nineteen) and `DESIGN_SYNC_BRIDGE.md` (nineteen kits).
|
|
213
|
+
- **`blueprint` and `roster` fork against it, reciprocally.** `blueprint` also refuses
|
|
214
|
+
radius outright and also builds from hairlines — the tell is the marks, since it draws
|
|
215
|
+
registration marks over a visible grid and `tenor` has neither. `roster` also spends one
|
|
216
|
+
orange on a light field and also forbids it from carrying a word — it argues *who
|
|
217
|
+
already uses you*, where `tenor` argues *how the work is organised*.
|
|
218
|
+
- **`bin/cli.js` now names `ora` as well.** The enumeration gate had passed it since
|
|
219
|
+
1.28.0 because `ora` is a substring of `cyclorama` — the under-reporting the machine's
|
|
220
|
+
own notes warn about, found by the same check failing honestly on `tenor`.
|
|
221
|
+
- **Ratchet floors raised** to 2294 / 1156 / 478, purely additive; all three self-tests
|
|
222
|
+
still catch every planted defect.
|
|
223
|
+
|
|
224
|
+
### Six defects in the reference, recorded in the pack rather than copied
|
|
225
|
+
|
|
226
|
+
- **`--ink-soft` is 4.16:1** on the paper and carries every lead paragraph at 16px, which
|
|
227
|
+
is not large text — short of AA by a margin no one notices and every audit finds.
|
|
228
|
+
- **`--ink-faint` is 2.36:1** and carries the grey half of the hero headline at 40.8px to
|
|
229
|
+
74.4px, below even the 3:1 that large text is allowed.
|
|
230
|
+
- **The accent clears its non-text floor by 0.02**, and contrast is symmetric — so a paper
|
|
231
|
+
label on an orange fill is the same 3.02:1. Both of the reference's orange-filled
|
|
232
|
+
elements put a label below the large-text threshold on it, including **every CTA at the
|
|
233
|
+
moment it is hovered**, where the label falls from 17.61:1 to 3.02:1.
|
|
234
|
+
- **A variable font is loaded across two axes and used at one point**: Instrument Sans is
|
|
235
|
+
requested as `wdth,wght@75..100,400..600` against zero `font-stretch` declarations, zero
|
|
236
|
+
`font-variation-settings` and exactly one weight in 33,822 bytes.
|
|
237
|
+
- **The mobile panel ships the pre-`dvh` viewport unit as its base** with a `@supports`
|
|
238
|
+
upgrade, so it jumps on every browser that lacks the upgrade.
|
|
239
|
+
- **Seven display selectors carry hand-written `<br>` tags** whose visibility is then
|
|
240
|
+
managed at 620px, and one of them appears in both the hide rule and the re-show rule.
|
|
241
|
+
|
|
242
|
+
## [1.28.0] - 2026-08-14
|
|
243
|
+
|
|
244
|
+
> Authored and gated on its own, **released inside `v1.29.0`**: the `tenor` pack followed
|
|
245
|
+
> it in the same session before a tag was cut, and splitting the two after the fact would
|
|
246
|
+
> have produced an intermediate commit whose ratchet floors no longer matched its own
|
|
247
|
+
> tree. There is no `v1.28.0` tag; this section is the record of what it added.
|
|
248
|
+
|
|
249
|
+
An eighteenth pack, **`ora`**, extracted from a live reference rather than composed:
|
|
250
|
+
<https://ora.ai> and <https://journey.ora.ai>, read from the shipped stylesheet
|
|
251
|
+
`/_next/static/chunks/feb8eaf5618096ba.css` and the route bundles beside it. It is the
|
|
252
|
+
first pack in the library whose **default theme is dark** — because that is the
|
|
253
|
+
reference's own arrangement, which paints its dark values on
|
|
254
|
+
`:root:not([data-theme=light])`, so an unattributed root is dark.
|
|
255
|
+
|
|
256
|
+
### Added
|
|
257
|
+
|
|
258
|
+
- **`styles/ora.md` + `styles/tokens/ora.css` — widened contract, all thirteen
|
|
259
|
+
headings.** A warm coal field, cream ink, and **no third hue**: the accent is the
|
|
260
|
+
inverted field, which the reference names out loud as
|
|
261
|
+
`--accent-signature` / `--accent-signature-foreground` and spends as
|
|
262
|
+
`bg-foreground text-background` on its one primary action. Both themes ship: coal
|
|
263
|
+
`#141210` with cream `#f7f2e5` at 16.72:1, paper `#f9f7f2` with `#1a1a1a` at 16.26:1.
|
|
264
|
+
- **Two families and one of them is a serif doing the sans job.** `--font-sans`,
|
|
265
|
+
`--font-serif` and `--default-font-family` all resolve to Lora, so there is no sans
|
|
266
|
+
anywhere in the system; Space Mono carries every machine fact. The rule the pair
|
|
267
|
+
encodes — a serif means a person said it, mono means a machine reported it — is what
|
|
268
|
+
the whole page is read through, and the pack bans adding a sans for that reason.
|
|
269
|
+
- **`kits/ora/` — the React reference kit**, the six-name spine plus six signature
|
|
270
|
+
components: `Verdict` (the signature element), `LayerBar`, `Terminal`, `StepLog`,
|
|
271
|
+
`SectionRule`, `StatusDot`. `src/styles.css` opens with the token layer byte for byte;
|
|
272
|
+
every breakpoint in it is a `@container` query, so no component is sized by the screen.
|
|
273
|
+
- **The verdict numeral as the signature element.** One number in the display serif in
|
|
274
|
+
its grade colour, a hairline `/ 100` at half its size, and the letter plus the word
|
|
275
|
+
beneath. `grade` and `label` are **required props** on the component, which is the
|
|
276
|
+
palette rule made into an API: under deuteranopia `--good` and `--danger` separate by
|
|
277
|
+
6.5 in dark and 7.4 in light, below the 8.0 CVD floor, so the letter and the word are
|
|
278
|
+
what make the verdict legible.
|
|
279
|
+
|
|
280
|
+
### Changed
|
|
281
|
+
|
|
282
|
+
- **The library is eighteen packs**, and every counted claim moved with it: `SKILL.md`
|
|
283
|
+
(the routing table, the core-contract split — six of the eighteen, the other twelve —
|
|
284
|
+
and the token-vocabulary note), `README.md`, `bin/cli.js`, `install.sh`, the three
|
|
285
|
+
manifests, the Cursor rule, the slash command, `MOBILE_SURFACES.md`,
|
|
286
|
+
`SURFACE_COMPOSITION.md` (`--accent` in sixteen packs, `@role non-text:` in twelve of
|
|
287
|
+
the eighteen) and `DESIGN_SYNC_BRIDGE.md` (eighteen kits).
|
|
288
|
+
- **`datasheet` and `manpage` fork against it, reciprocally.** Both are verdict-shaped
|
|
289
|
+
and both refuse a second family, so an agent reaching either first now learns the
|
|
290
|
+
distinction: `datasheet` when the artefact is a row of cells, `manpage` when the page
|
|
291
|
+
is documentation, `ora` when the artefact is a number with a grade and the reader must
|
|
292
|
+
be shown the raw response a machine received.
|
|
293
|
+
- **Ratchet floors raised** to 2179 / 1095 / 464, purely additive; all three self-tests
|
|
294
|
+
still catch every planted defect.
|
|
295
|
+
|
|
296
|
+
### Six defects in the reference, recorded in the pack rather than copied
|
|
297
|
+
|
|
298
|
+
Named in `## Gotchas` because a pack extracted from a live site inherits its accidents
|
|
299
|
+
unless someone reads them:
|
|
300
|
+
|
|
301
|
+
- `--border-strong` is declared once in the light `:root` and never re-declared for
|
|
302
|
+
dark, so the reference paints a paper-coloured hairline at **12.02:1** on the coal
|
|
303
|
+
field. This pack ships a dark value of its own and marks it derived at the declaration.
|
|
304
|
+
- `--shadow-pop` is a complete shadow in the app scope and a bare **colour** in the
|
|
305
|
+
journey scope. Copying the wrong one produces an invalid declaration, so the shadow
|
|
306
|
+
disappears silently rather than erroring.
|
|
307
|
+
- The shadcn `--accent` is a raised **surface**, not an accent — an agent reading token
|
|
308
|
+
names alone concludes the pack has none.
|
|
309
|
+
- Two dark greys in one product: warm coal `#141210` against neutral `#151515`, each
|
|
310
|
+
with its own ladder and its own accent.
|
|
311
|
+
- Two radius systems: the proportional ladder off `--radius: .5rem`, and
|
|
312
|
+
`rounded-[7px]` / `rounded-[9px]` literals that sit on no ladder.
|
|
313
|
+
- Four webfont families are loaded on `<html>` and two are referenced in the stylesheet;
|
|
314
|
+
the progress fill is animated with `transition-all`, which animates `width` and lays
|
|
315
|
+
out every frame.
|
|
316
|
+
|
|
7
317
|
## [1.27.1] - 2026-08-13
|
|
8
318
|
|
|
9
319
|
This project's own pipeline paperwork moved from `docs/superpowers/` to
|
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 **
|
|
14
|
+
decides whether to animate before it decides how, and **twenty 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
|
|
|
@@ -62,6 +62,9 @@ into the cinematic layer, and says so in its own *Motion flavor* section.
|
|
|
62
62
|
| `manpage` | cream paper under the reader's own system monospace — zero webfont bytes for the display face — a 48px display that never grows louder, a 576px argument column, coral label chips that are real `<h2>`s, `└` tree glyphs in their own grid column, and one dark code frame as the focal point | developer products whose buyer reads code — APIs, SDKs, CLIs, MCP servers, developer infrastructure, where the honest hero is the call itself |
|
|
63
63
|
| `pigeonhole` | a white field ruled by hairlines, a display face that never passes weight 400 with exactly one italic word, and **nine categories in which a hue is the category**, drawn from an eleven-ramp pastel system — each rendered as a two-layer chip, 8px outside and 7px inside, whose label word is mandatory because the hue cannot carry the meaning alone | products whose job is to sort the reader's incoming mess into named categories — email triage, ticket routing, notification digests, file organisers, CRM inboxes |
|
|
64
64
|
| `roster` | a white field in a faint grid of squares, hairlines instead of shadows, a display set in the **body** face while the section heads take another, and one orange that may never carry a word | products whose argument is **who already carries them** — AI-search and GEO visibility, SEO and content platforms, agencies, marketplaces, integration-led tooling |
|
|
65
|
+
| `ora` | a warm coal field with cream ink and **no third hue** — the accent is the inverted field, so the one solid object on a page is the one meant to be pressed — a serif doing the sans job over a monospace that carries every machine fact, a terminal surface cut *below* the page plane, a six-step verdict ramp, and dark as the default theme rather than the option | products whose output is **a machine's verdict about the reader** — agent-readiness and crawlability scores, SEO and answer-engine audits, agent-run traces, MCP and protocol surfaces, bot observability |
|
|
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
|
+
| `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 |
|
|
65
68
|
|
|
66
69
|
Each pack locks palette, type, texture, motion tokens, signature motifs and
|
|
67
70
|
bans — and ships a `tokens/<pack>.css` to copy verbatim, so the agent never
|
|
@@ -136,7 +139,7 @@ skills.
|
|
|
136
139
|
| `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 |
|
|
137
140
|
| `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 |
|
|
138
141
|
| `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 |
|
|
139
|
-
| `styles/*.md` | The
|
|
142
|
+
| `styles/*.md` | The twenty style packs — palette, type, texture, motion tokens, motifs, bans, and the traps each one carries |
|
|
140
143
|
| `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) |
|
|
141
144
|
| `styles/STYLE_PACK_TEMPLATE.md` | The pack contract as a skeleton, so a new style is authored against the same headings rather than improvised |
|
|
142
145
|
|
|
@@ -207,7 +210,7 @@ cd ./ds-workbench && npm install && npm run build
|
|
|
207
210
|
then `/design-sync` in that directory, from Claude Code. Three layers cross: the
|
|
208
211
|
pack's **bans** as the design system's own README, `styles.css` built from
|
|
209
212
|
`tokens/<pack>.css` verbatim, and the components — a six-name spine that is
|
|
210
|
-
identical in all
|
|
213
|
+
identical in all twenty kits, so switching packs swaps identity rather than API,
|
|
211
214
|
plus each pack's signature parts. **Motion does not cross**, exactly as it does
|
|
212
215
|
not cross into Figma: a kit is the static half of a pack, and saying so is what
|
|
213
216
|
stops an agent inventing motion to fill the silence.
|
|
@@ -253,7 +256,7 @@ a pack's four widened sections used to make two gates *quieter* and still green.
|
|
|
253
256
|
One honest limit: the npx installer is checked by asserting its runtime bundle
|
|
254
257
|
walker exists, not by reading a file list — it has none by design. What proves
|
|
255
258
|
it ships the right files is CI, which installs the bundle through **both**
|
|
256
|
-
installers and `diff -r`s the result against the source, then builds all
|
|
259
|
+
installers and `diff -r`s the result against the source, then builds all twenty
|
|
257
260
|
kits.
|
|
258
261
|
|
|
259
262
|
`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/
|
|
237
|
+
styles/ twenty 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
|
|
@@ -251,7 +251,14 @@ ${c("bold", "What it installs")}
|
|
|
251
251
|
pigeonhole (a white sorting wall whose nine pastel
|
|
252
252
|
categories are a filing scheme, one hue each),
|
|
253
253
|
roster (a white wall of other people's marks: the proof
|
|
254
|
-
is a name rather than a number)
|
|
254
|
+
is a name rather than a number), ora (a warm coal field
|
|
255
|
+
whose accent is the inverted field, a serif over mono,
|
|
256
|
+
and a terminal cut below the page), tenor (warm paper at
|
|
257
|
+
zero radius and zero shadow, one orange that exists only
|
|
258
|
+
on hover, and proof delivered as silent looping video),
|
|
259
|
+
paperclip (neutral coal with no functional colour at all
|
|
260
|
+
and one curtain of gradient capsules that cannot be
|
|
261
|
+
clicked, for products that run themselves) —
|
|
255
262
|
plus a ready-made token CSS per pack and
|
|
256
263
|
STYLE_PACK_TEMPLATE.md for authoring more
|
|
257
264
|
`);
|
|
@@ -43,7 +43,20 @@ that file the reader's incoming mess into named categories; roster — a white
|
|
|
43
43
|
field in a faint grid of squares whose whole argument is other people's
|
|
44
44
|
marks, with client logotypes in pill-labelled industry columns and an
|
|
45
45
|
engine's wordmark inside the headline, for products sold on who already
|
|
46
|
-
carries them
|
|
46
|
+
carries them; ora — a warm coal field with cream ink and no third hue, where
|
|
47
|
+
the accent is the inverted field, a serif carries every human sentence and a
|
|
48
|
+
monospace every machine fact, and a terminal surface is cut below the page,
|
|
49
|
+
for products whose output is a machine's verdict about the reader; tenor — warm
|
|
50
|
+
paper with zero radius and zero shadow, one hairline weight, an orange that
|
|
51
|
+
exists only on hover and on focus, a sans at weight 400 tracked negative
|
|
52
|
+
against a mono tracked positive, display at a line-height below one in an
|
|
53
|
+
eight-to-twelve-character measure, and proof delivered as silent looping
|
|
54
|
+
video, for products arguing that a new kind of thing must be managed like an
|
|
55
|
+
existing organisation; paperclip — neutral coal with no functional colour
|
|
56
|
+
anywhere, every control monochrome and elevation made of hairlines, the whole
|
|
57
|
+
chromatic budget spent on a curtain of gradient capsules and a row of gradient
|
|
58
|
+
section badges that cannot be clicked, for products that ask a person to run
|
|
59
|
+
something that runs itself);
|
|
47
60
|
otherwise follow the contract below (self-contained on purpose).
|
|
48
61
|
|
|
49
62
|
## Whether to animate at all — before how
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pkg": "@sheleg-design/ora",
|
|
3
|
+
"globalName": "ShelegOra",
|
|
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,61 @@
|
|
|
1
|
+
# Ora — the design contract
|
|
2
|
+
|
|
3
|
+
The reference is <https://ora.ai> and <https://journey.ora.ai> (era labs), read
|
|
4
|
+
2026-08-14 from the shipped stylesheet `/_next/static/chunks/feb8eaf5618096ba.css` and
|
|
5
|
+
the route bundles beside it. The full pack is `styles/ora.md`; this file is what a
|
|
6
|
+
design agent must not get wrong.
|
|
7
|
+
|
|
8
|
+
## The one thing this pack is
|
|
9
|
+
|
|
10
|
+
**A page that tells a person what a machine concluded about them.** A warm coal field,
|
|
11
|
+
cream ink, and no third hue — the accent is the inverted field. A serif carries every
|
|
12
|
+
human sentence and a monospace every machine fact. The only surface that leaves the
|
|
13
|
+
page plane goes *down*, into a terminal block cut below the field.
|
|
14
|
+
|
|
15
|
+
## Non-negotiable
|
|
16
|
+
|
|
17
|
+
- **There is no brand colour.** `--accent` is the ink: cream on coal, near-black on
|
|
18
|
+
paper, 16.72:1 and 16.90:1 on their own fields. One filled element per view. A second
|
|
19
|
+
filled button is a design error, not a variant.
|
|
20
|
+
- **No sans-serif.** `--font-sans`, `--font-serif` and the default family all resolve to
|
|
21
|
+
Lora in the reference. Adding a real sans dismantles the rule the whole page is read
|
|
22
|
+
through: a serif means a person said it, mono means a machine reported it.
|
|
23
|
+
- **Status is never by colour alone.** Every dot, bar and number in a status colour
|
|
24
|
+
carries its word; the six-step grade ramp carries its letter. Under deuteranopia
|
|
25
|
+
`--good` and `--danger` separate by 6.5 in dark and 7.4 in light, and under protanopia
|
|
26
|
+
`--good` and `--warn` by 6.4 in light. In the light theme `--good` (2.13:1) and
|
|
27
|
+
`--warn` (2.01:1) are below the non-text floor on paper and may not set text at all.
|
|
28
|
+
- **Elevation is a hairline.** `--border` at 1.15:1 is a seam. Shadows exist for things
|
|
29
|
+
that float over the page — overlays, popovers, tooltips — and a card does not float.
|
|
30
|
+
- **The terminal is darker than the page**, in both themes, and never carries a shadow.
|
|
31
|
+
- **One radius root.** `--radius: 0.5rem`, and every other radius is a ratio of it:
|
|
32
|
+
chip ×0.5, control ×1, card ×1.5, plus the pill. Do not add a step.
|
|
33
|
+
- **A layer that does not apply is hatched and reads `N/A`.** Never an empty bar — an
|
|
34
|
+
empty bar reads as zero, which is a different verdict about the same product.
|
|
35
|
+
- **Motion is entrance, hover and two ambient loops.** No scroll-jacking, no parallax,
|
|
36
|
+
no `animation-timeline`, no scroll library — zero occurrences of any of them in the
|
|
37
|
+
reference's shipped bundles. Scroll drives two things only: the sticky nav's 1px
|
|
38
|
+
hairline shadow and one pinned two-panel comparison. Hover changes colour, border and
|
|
39
|
+
opacity and never geometry. Under reduced motion every duration token collapses to
|
|
40
|
+
zero and the page keeps every value it was showing.
|
|
41
|
+
- **Numbers are `tabular-nums`, always.** A count that changes while the reader watches
|
|
42
|
+
must not reflow.
|
|
43
|
+
|
|
44
|
+
## What this kit is not
|
|
45
|
+
|
|
46
|
+
It is the **static half** of the pack. The hero's breathing glows, the drifting agent
|
|
47
|
+
marks and the scroll-pinned comparison section are page-level motion and do not cross
|
|
48
|
+
into a component library. Nothing here invents motion to fill that silence.
|
|
49
|
+
|
|
50
|
+
## The traps the reference itself carries
|
|
51
|
+
|
|
52
|
+
Four of them, so a design agent does not reproduce them from a screenshot:
|
|
53
|
+
|
|
54
|
+
1. `--border-strong` is never re-declared for dark, so the reference paints a
|
|
55
|
+
paper-coloured hairline at 12.02:1 on coal. This kit ships a dark value of its own.
|
|
56
|
+
2. `--shadow-pop` is a complete shadow in one scope and a bare colour in the other.
|
|
57
|
+
Here it is always complete.
|
|
58
|
+
3. The reference's shadcn `--accent` is a raised *surface*, not an accent. The real one
|
|
59
|
+
is `--accent-signature`, which points at the foreground.
|
|
60
|
+
4. The progress fill is animated with `transition-all`, which animates `width` and lays
|
|
61
|
+
out every frame. Here it is `transform: scaleX()` from a left origin.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @sheleg-design/ora
|
|
2
|
+
|
|
3
|
+
The React reference kit for the SHELEG **Ora** style pack — a warm coal field with cream
|
|
4
|
+
ink and no third hue, where the accent is the inverted field, a serif carries every human
|
|
5
|
+
sentence and a monospace every machine fact, and the only surface that leaves the page
|
|
6
|
+
plane goes down, into a terminal block cut below the field.
|
|
7
|
+
|
|
8
|
+
It is generated from the pack, not authored beside it: `src/styles.css` opens with
|
|
9
|
+
`styles/tokens/ora.css` byte for byte, and the rules the design agent must obey are in
|
|
10
|
+
[`.design-sync/conventions.md`](./.design-sync/conventions.md).
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install && npm run build
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then run `/design-sync` in Claude Code from this directory to push it to
|
|
17
|
+
claude.ai/design.
|
|
18
|
+
|
|
19
|
+
## The spine, and this pack's six
|
|
20
|
+
|
|
21
|
+
`Button`, `Card`, `Chip`, `Stat`, `Heading` and `Rule` are identical in name, props and
|
|
22
|
+
types across every SHELEG kit — switching packs swaps identity, not API.
|
|
23
|
+
|
|
24
|
+
| Component | What it is |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `Verdict` | one number in the display serif, in its grade colour, with the letter and the word beneath — the **signature element** |
|
|
27
|
+
| `LayerBar` | the weighted score bar, where a layer that does not apply is hatched and reads `N/A` rather than empty |
|
|
28
|
+
| `Terminal` | the surface below the page plane: raw machine output, `white-space: pre`, and never a shadow |
|
|
29
|
+
| `StepLog` | the loading idiom — one mono line per step, appended as it happens, the caret on the running line |
|
|
30
|
+
| `SectionRule` | the band between sections: a squiggle through a hairline strip with a numbered label knocked out over it |
|
|
31
|
+
| `StatusDot` | a 6px dot and its word, where the word is a required prop |
|
|
32
|
+
|
|
33
|
+
## Theme
|
|
34
|
+
|
|
35
|
+
Dark is the default, because it is the default in the reference. Set
|
|
36
|
+
`data-theme="light"` on `:root` for the twin; both are declared in the token block at the
|
|
37
|
+
top of `src/styles.css`.
|
|
38
|
+
|
|
39
|
+
## What is not here
|
|
40
|
+
|
|
41
|
+
The hero's breathing glows, the drifting agent marks and the scroll-pinned comparison
|
|
42
|
+
section are page-level motion. A kit is the static half of a pack, and inventing motion
|
|
43
|
+
to fill that silence is the failure this note exists to prevent.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sheleg-design/ora",
|
|
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
|
+
`primary` is the **inverted field**: `--accent` is the ink, so the button is a solid
|
|
6
|
+
cream slab on coal and a solid near-black slab on paper, and the label takes
|
|
7
|
+
`--accent-ink`. At 16.72:1 in dark and 16.90:1 in light it is the highest-contrast
|
|
8
|
+
object on the page, which is why the pack allows **one per view**.
|
|
9
|
+
|
|
10
|
+
Hover is the reference's own: the fill drops to 90% opacity. Nothing translates,
|
|
11
|
+
scales or lifts — this pack does not press.
|
|
12
|
+
|
|
13
|
+
`secondary` is a hairline over `--surface-raised`; its hover moves the **border** to
|
|
14
|
+
`--border-strong` and leaves the fill where it is. `ghost` is mono, `--muted`, and
|
|
15
|
+
gains `--ink` on hover.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Button>Run</Button>
|
|
19
|
+
<Button variant="secondary">Rescan</Button>
|
|
20
|
+
<Button variant="ghost">View logs</Button>
|
|
21
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonProps {
|
|
4
|
+
/** `primary` is the accent fill — at most 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={['ora-btn', `ora-btn--${variant}`, `ora-btn--${size}`, className]
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join(' ')}
|
|
27
|
+
disabled={disabled}
|
|
28
|
+
onClick={onClick}
|
|
29
|
+
>
|
|
30
|
+
{children}
|
|
31
|
+
</button>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
category: Surfaces
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`--surface` inside a 1px `--border`, at `--radius-card`. The border is 1.15:1 against
|
|
6
|
+
the field: a seam, not a line. There is no shadow, because a card does not float —
|
|
7
|
+
`--shadow-pop` exists for overlays and nothing else.
|
|
8
|
+
|
|
9
|
+
A row of facts inside a card is separated by a top border and padding, never by a
|
|
10
|
+
nested card. Three equal blocks share **one** card with internal dividers.
|
|
11
|
+
|
|
12
|
+
The head sizes against its **container** (`container-type: inline-size`), so a card in a
|
|
13
|
+
narrow column wraps its title and meta instead of overflowing.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Card title="Can an agent discover and trust you?" meta="5/100">
|
|
17
|
+
…
|
|
18
|
+
</Card>
|
|
19
|
+
```
|