@phcdevworks/spectre-ui 1.5.0 → 1.7.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 +500 -0
- package/README.md +328 -35
- package/dist/base.css +23 -26
- package/dist/components.css +683 -79
- package/dist/index.cjs +275 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +683 -79
- package/dist/index.d.cts +125 -2
- package/dist/index.d.ts +125 -2
- package/dist/index.js +268 -45
- package/dist/index.js.map +1 -1
- package/dist/utilities.css +23 -26
- package/package.json +34 -29
package/README.md
CHANGED
|
@@ -1,21 +1,56 @@
|
|
|
1
1
|
# @phcdevworks/spectre-ui
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@phcdevworks/spectre-ui)
|
|
4
|
+
[](https://github.com/phcdevworks/spectre-ui/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://nodejs.org)
|
|
6
7
|
|
|
7
|
-
`@phcdevworks/spectre-ui` is the
|
|
8
|
+
`@phcdevworks/spectre-ui` is **Layer 2 of the Spectre design suite**. It turns
|
|
8
9
|
[`@phcdevworks/spectre-tokens`](https://github.com/phcdevworks/spectre-tokens)
|
|
9
|
-
and
|
|
10
|
+
into reusable CSS bundles, Tailwind tooling, and type-safe class recipes for
|
|
11
|
+
downstream adapters and apps.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
token-driven, and follows a strict zero-hex policy so visual values do not drift
|
|
14
|
-
locally.
|
|
13
|
+
**For:** adapter authors and app developers who need a stable, token-driven
|
|
14
|
+
styling contract without re-implementing class logic themselves.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**Not for:** authoring design tokens (that belongs in
|
|
17
|
+
`@phcdevworks/spectre-tokens`) or building framework-specific components (that
|
|
18
|
+
belongs in adapter packages such as `@phcdevworks/spectre-ui-astro`).
|
|
19
|
+
|
|
20
|
+
[Contributing](CONTRIBUTING.md) | [Code of Conduct](CODE_OF_CONDUCT.md) |
|
|
21
|
+
[Changelog](CHANGELOG.md) | [Roadmap](ROADMAP.md) |
|
|
17
22
|
[Security Policy](SECURITY.md)
|
|
18
23
|
|
|
24
|
+
## Source of truth
|
|
25
|
+
|
|
26
|
+
`@phcdevworks/spectre-tokens` is the source of truth for visual values and
|
|
27
|
+
semantic meaning. `ui-contract.manifest.json` is the machine-readable contract
|
|
28
|
+
authority for this package's public styling surface.
|
|
29
|
+
|
|
30
|
+
| Layer | Path | Rule |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Token authority | Published `@phcdevworks/spectre-tokens` package | Design values and semantic meaning start there |
|
|
33
|
+
| UI contract authority | `ui-contract.manifest.json` | Governs public recipes, CSS entry points, and Tailwind exports |
|
|
34
|
+
| Source CSS | `src/styles/` | Token-backed CSS classes and bundle entry points |
|
|
35
|
+
| Source recipes | `src/recipes/` | Framework-agnostic class string APIs |
|
|
36
|
+
| Tailwind helpers | `src/tailwind/` | Tailwind theme and preset integration |
|
|
37
|
+
| Generated dist | `dist/` | **Never edit directly** — regenerated by `npm run build` |
|
|
38
|
+
|
|
39
|
+
After any contract-facing source change: run `npm run check` to validate the
|
|
40
|
+
full UI contract.
|
|
41
|
+
|
|
42
|
+
## Architecture
|
|
43
|
+
|
|
44
|
+
| Layer | Package or consumer | Responsibility | Relationship to this package |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| 1 | `@phcdevworks/spectre-tokens` | Defines design values and semantic token meaning | Upstream source of truth |
|
|
47
|
+
| 2 | `@phcdevworks/spectre-ui` | Translates tokens into CSS bundles, Tailwind helpers, and class recipes | This package |
|
|
48
|
+
| 3 | Adapters and apps, such as `@phcdevworks/spectre-ui-astro` | Deliver Spectre through framework-native ergonomics | Downstream consumers |
|
|
49
|
+
|
|
50
|
+
`@phcdevworks/spectre-components` is a separate component package that can wrap
|
|
51
|
+
this styling contract in Lit web components. This package owns Layer 2 only: it
|
|
52
|
+
does not deliver components and it does not define tokens.
|
|
53
|
+
|
|
19
54
|
## Key capabilities
|
|
20
55
|
|
|
21
56
|
- Ships precompiled CSS: `index.css`, `base.css`, `components.css`, and
|
|
@@ -28,6 +63,27 @@ locally.
|
|
|
28
63
|
- Enforces a zero-hex approach so visual values stay tied to
|
|
29
64
|
`@phcdevworks/spectre-tokens`
|
|
30
65
|
|
|
66
|
+
## What this package owns
|
|
67
|
+
|
|
68
|
+
- Token-backed CSS class contracts in `src/styles/`
|
|
69
|
+
- Precompiled CSS bundles for root, base, components, and utilities
|
|
70
|
+
- Framework-agnostic class recipe functions in `src/recipes/`
|
|
71
|
+
- Tailwind preset and theme helpers in `src/tailwind/`
|
|
72
|
+
- Contract validation that keeps CSS, recipes, exports, and docs aligned
|
|
73
|
+
|
|
74
|
+
This package is the correct place to define reusable styling structure on top
|
|
75
|
+
of Spectre tokens.
|
|
76
|
+
|
|
77
|
+
## What this package does not own
|
|
78
|
+
|
|
79
|
+
- Design token values or semantic visual meaning. Those belong in
|
|
80
|
+
[`@phcdevworks/spectre-tokens`](https://github.com/phcdevworks/spectre-tokens).
|
|
81
|
+
- Framework components, templates, hooks, or runtime behavior. Those belong in
|
|
82
|
+
adapter packages.
|
|
83
|
+
- App-level layout, routing, data fetching, or product-specific composition.
|
|
84
|
+
- Local redefinition of token meaning. Downstream consumers should consume the
|
|
85
|
+
token contract rather than recreate it.
|
|
86
|
+
|
|
31
87
|
## Installation
|
|
32
88
|
|
|
33
89
|
```bash
|
|
@@ -36,7 +92,34 @@ npm install @phcdevworks/spectre-ui
|
|
|
36
92
|
|
|
37
93
|
## Quick start
|
|
38
94
|
|
|
39
|
-
### CSS
|
|
95
|
+
### Vanilla HTML — CSS classes only
|
|
96
|
+
|
|
97
|
+
No framework needed. Import the CSS and use the `sp-*` classes directly:
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<!doctype html>
|
|
101
|
+
<html>
|
|
102
|
+
<head>
|
|
103
|
+
<link rel="stylesheet" href="node_modules/@phcdevworks/spectre-ui/dist/index.css" />
|
|
104
|
+
</head>
|
|
105
|
+
<body>
|
|
106
|
+
<button class="sp-btn sp-btn--primary sp-btn--md">Save</button>
|
|
107
|
+
<button class="sp-btn sp-btn--ghost sp-btn--md">Cancel</button>
|
|
108
|
+
<span class="sp-badge sp-badge--success sp-badge--sm">Published</span>
|
|
109
|
+
|
|
110
|
+
<div class="sp-card sp-card--elevated">
|
|
111
|
+
<p>Card content</p>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="sp-input-wrapper">
|
|
115
|
+
<label class="sp-label">Email</label>
|
|
116
|
+
<input class="sp-input sp-input--md" type="email" />
|
|
117
|
+
</div>
|
|
118
|
+
</body>
|
|
119
|
+
</html>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### CSS import (bundler or framework)
|
|
40
123
|
|
|
41
124
|
Import the full stylesheet:
|
|
42
125
|
|
|
@@ -87,31 +170,78 @@ const badge = getBadgeClasses({ variant: 'success', size: 'sm' })
|
|
|
87
170
|
const pricingCard = getPricingCardClasses({ featured: true })
|
|
88
171
|
```
|
|
89
172
|
|
|
90
|
-
##
|
|
173
|
+
## When to use this package
|
|
91
174
|
|
|
92
|
-
|
|
93
|
-
- Precompiled CSS bundles and utility classes
|
|
94
|
-
- Tailwind helpers and preset generation
|
|
95
|
-
- Type-safe class recipes for shared UI contracts
|
|
96
|
-
- Stable styling behavior consumed by downstream adapters and apps
|
|
175
|
+
Use `@phcdevworks/spectre-ui` when you need:
|
|
97
176
|
|
|
98
|
-
|
|
177
|
+
- precompiled, token-backed CSS ready to drop into any framework
|
|
178
|
+
- a Tailwind preset or theme helper built from Spectre tokens
|
|
179
|
+
- stable, type-safe class recipes for shared UI patterns (buttons, badges,
|
|
180
|
+
cards, inputs, etc.) that you want to remain consistent across frameworks
|
|
181
|
+
- a styling contract that is enforced through tests and CI rather than
|
|
182
|
+
conventions alone
|
|
99
183
|
|
|
100
|
-
##
|
|
184
|
+
## When not to use this package
|
|
185
|
+
|
|
186
|
+
Do not use `@phcdevworks/spectre-ui` when you need to:
|
|
187
|
+
|
|
188
|
+
- **Define new design values** — add them to
|
|
189
|
+
[`@phcdevworks/spectre-tokens`](https://github.com/phcdevworks/spectre-tokens)
|
|
190
|
+
instead.
|
|
191
|
+
- **Deliver framework components** — use an adapter package such as
|
|
192
|
+
`@phcdevworks/spectre-ui-astro` that wraps this package in framework-native
|
|
193
|
+
components.
|
|
194
|
+
- **Use raw Tailwind utilities without a shared recipe contract** — import
|
|
195
|
+
Tailwind directly and use the Spectre preset; you do not need this package's
|
|
196
|
+
recipe layer if you are building one-off UI with utility classes.
|
|
197
|
+
|
|
198
|
+
## What belongs here vs elsewhere
|
|
101
199
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
200
|
+
| What | Where it lives |
|
|
201
|
+
|---|---|
|
|
202
|
+
| Semantic color values, spacing scale, type scale | `@phcdevworks/spectre-tokens` |
|
|
203
|
+
| Token-to-CSS variable mapping | **here** — `src/styles/` |
|
|
204
|
+
| Precompiled CSS bundles | **here** — built to `dist/*.css` |
|
|
205
|
+
| Class recipe functions (input → class string) | **here** — `src/recipes/` |
|
|
206
|
+
| Tailwind preset and theme helpers | **here** — `src/tailwind/` |
|
|
207
|
+
| Astro, React, Vue, Lit, Svelte components | Adapter packages (e.g. `spectre-ui-astro`) |
|
|
208
|
+
| WordPress shortcodes or PHP templates | A WordPress adapter package |
|
|
209
|
+
| App-level layout, routing, or data fetching | Consuming apps |
|
|
210
|
+
| New design decisions (new colors, new spacing) | `@phcdevworks/spectre-tokens` |
|
|
211
|
+
|
|
212
|
+
Golden rule: this package consumes tokens and exposes class contracts. It does
|
|
213
|
+
not define tokens and it does not deliver framework components.
|
|
108
214
|
|
|
109
215
|
## Package exports / API surface
|
|
110
216
|
|
|
217
|
+
### Recipe quick reference
|
|
218
|
+
|
|
219
|
+
All recipe functions accept a plain options object and return a class string.
|
|
220
|
+
All options are optional and fall back to sensible defaults.
|
|
221
|
+
|
|
222
|
+
| Recipe | Function | Variants | Sizes | Common boolean flags |
|
|
223
|
+
|---|---|---|---|---|
|
|
224
|
+
| Button | `getButtonClasses` | `primary` `secondary` `ghost` `danger` `success` `cta` `accent` | `sm` `md` `lg` | `disabled` `loading` `fullWidth` `pill` `iconOnly` |
|
|
225
|
+
| Badge | `getBadgeClasses` | `primary` `secondary` `success` `warning` `danger` `neutral` `info` `ghost` `accent` `cta` | `sm` `md` `lg` | `interactive` `disabled` `loading` `fullWidth` |
|
|
226
|
+
| Card | `getCardClasses` | `elevated` `flat` `outline` `ghost` | — | `interactive` `padded` `fullHeight` `disabled` `loading` |
|
|
227
|
+
| Input | `getInputClasses` | — | `sm` `md` `lg` | `disabled` `loading` `fullWidth` `pill` |
|
|
228
|
+
| Input state | `getInputClasses` | `state`: `default` `error` `success` `disabled` `loading` | — | — |
|
|
229
|
+
| IconBox | `getIconBoxClasses` | `primary` `secondary` `success` `warning` `danger` `info` `neutral` `ghost` `accent` `cta` | `sm` `md` `lg` | `interactive` `disabled` `loading` `pill` `fullWidth` |
|
|
230
|
+
| PricingCard | `getPricingCardClasses` | — | — | `featured` `interactive` `disabled` `loading` `fullHeight` |
|
|
231
|
+
| Rating | `getRatingClasses` | — | `sm` `md` `lg` | `interactive` `disabled` `loading` `pill` `fullWidth` |
|
|
232
|
+
| Testimonial | `getTestimonialClasses` | `elevated` `flat` `outline` `ghost` | — | `interactive` `disabled` `loading` `fullHeight` |
|
|
233
|
+
| Alert | `getAlertClasses` | `info` `success` `warning` `danger` `neutral` | `sm` `md` `lg` | `dismissed` |
|
|
234
|
+
| Avatar | `getAvatarClasses` | — | `sm` `md` `lg` `xl` | shape: `circle` `square` |
|
|
235
|
+
| Tag | `getTagClasses` | `default` `primary` `secondary` `success` `warning` `danger` `info` `neutral` `accent` `cta` `outline` `ghost` | `sm` `md` `lg` | `dismissible` `selected` `disabled` `loading` `interactive` `fullWidth` |
|
|
236
|
+
| Spinner | `getSpinnerClasses` | — | `sm` `md` `lg` | — |
|
|
237
|
+
|
|
238
|
+
Each recipe family also exports sub-element helpers for its structural parts
|
|
239
|
+
(labels, wrappers, sub-containers, text elements). See the full list below.
|
|
240
|
+
|
|
111
241
|
### Root package
|
|
112
242
|
|
|
113
|
-
The root package exports CSS path constants plus the recipe functions
|
|
114
|
-
from `src/recipes/index.ts`.
|
|
243
|
+
The root package exports CSS path constants plus the recipe functions
|
|
244
|
+
re-exported from `src/recipes/index.ts`.
|
|
115
245
|
|
|
116
246
|
Root constants:
|
|
117
247
|
|
|
@@ -123,6 +253,8 @@ Root constants:
|
|
|
123
253
|
|
|
124
254
|
Root recipe functions:
|
|
125
255
|
|
|
256
|
+
- `getAlertClasses`
|
|
257
|
+
- `getAvatarClasses`
|
|
126
258
|
- `getBadgeClasses`
|
|
127
259
|
- `getButtonClasses`
|
|
128
260
|
- `getCardClasses`
|
|
@@ -130,10 +262,16 @@ Root recipe functions:
|
|
|
130
262
|
- `getInputClasses`
|
|
131
263
|
- `getPricingCardClasses`
|
|
132
264
|
- `getRatingClasses`
|
|
265
|
+
- `getSpinnerClasses`
|
|
266
|
+
- `getTagClasses`
|
|
133
267
|
- `getTestimonialClasses`
|
|
134
268
|
|
|
135
269
|
Root recipe helper functions:
|
|
136
270
|
|
|
271
|
+
- `getInputErrorMessageClasses`
|
|
272
|
+
- `getInputHelperTextClasses`
|
|
273
|
+
- `getInputLabelClasses`
|
|
274
|
+
- `getInputWrapperClasses`
|
|
137
275
|
- `getPricingCardBadgeClasses`
|
|
138
276
|
- `getPricingCardDescriptionClasses`
|
|
139
277
|
- `getPricingCardPriceClasses`
|
|
@@ -164,6 +302,75 @@ state TypeScript types defined by those recipes.
|
|
|
164
302
|
- `@phcdevworks/spectre-ui/components.css`
|
|
165
303
|
- `@phcdevworks/spectre-ui/utilities.css`
|
|
166
304
|
|
|
305
|
+
## Public contract guarantees
|
|
306
|
+
|
|
307
|
+
`ui-contract.manifest.json` defines the public styling contract for this
|
|
308
|
+
package.
|
|
309
|
+
|
|
310
|
+
It covers:
|
|
311
|
+
|
|
312
|
+
- CSS entry points
|
|
313
|
+
- root package constants and recipe function exports
|
|
314
|
+
- Tailwind subpath exports
|
|
315
|
+
- recipe families, variants, sizes, and public states
|
|
316
|
+
|
|
317
|
+
Every contract-facing surface must match that manifest. Validation fails when
|
|
318
|
+
README documentation omits manifest-declared exports, when export snapshots
|
|
319
|
+
drift, when Tailwind artifacts drift, or when CSS contract coverage no longer
|
|
320
|
+
matches the declared surface.
|
|
321
|
+
|
|
322
|
+
## Downstream boundaries
|
|
323
|
+
|
|
324
|
+
Downstream packages should never redefine locally:
|
|
325
|
+
|
|
326
|
+
- Spectre design token meaning
|
|
327
|
+
- CSS class semantics already provided by this package
|
|
328
|
+
- recipe option names, variants, sizes, or states
|
|
329
|
+
- package CSS entry point behavior
|
|
330
|
+
- Tailwind helper export names
|
|
331
|
+
|
|
332
|
+
Downstream packages may:
|
|
333
|
+
|
|
334
|
+
- compose application UI with the exported classes
|
|
335
|
+
- wrap recipe functions in framework-specific adapters
|
|
336
|
+
- import CSS entry points directly in applications or adapter packages
|
|
337
|
+
- extend app-specific layout around Spectre contracts
|
|
338
|
+
|
|
339
|
+
## Upgrade expectations for consumers
|
|
340
|
+
|
|
341
|
+
Consumers should treat this package as a SemVer-governed styling contract.
|
|
342
|
+
|
|
343
|
+
Practical guidance:
|
|
344
|
+
|
|
345
|
+
- additive recipes, variants, states, and helpers are intended to be safe for
|
|
346
|
+
existing consumers
|
|
347
|
+
- semantic shifts may keep the same class or option name but still affect
|
|
348
|
+
visual output
|
|
349
|
+
- renames, removals, and behavior changes to existing classes or options are
|
|
350
|
+
breaking
|
|
351
|
+
- generated JS, TypeScript declarations, CSS bundles, Tailwind exports, README
|
|
352
|
+
docs, and `ui-contract.manifest.json` are expected to stay aligned
|
|
353
|
+
|
|
354
|
+
If a downstream package depends on a class, recipe option, CSS entry point, or
|
|
355
|
+
Tailwind helper:
|
|
356
|
+
|
|
357
|
+
- read `CHANGELOG.md` for contract change classification
|
|
358
|
+
- prefer documented public exports over internal paths
|
|
359
|
+
- run consuming app validation after package upgrades
|
|
360
|
+
|
|
361
|
+
### Change classification
|
|
362
|
+
|
|
363
|
+
Contract-affecting changes should be classified in `CHANGELOG.md [Unreleased]`
|
|
364
|
+
before release.
|
|
365
|
+
|
|
366
|
+
| Classification | When to use | Examples |
|
|
367
|
+
|---|---|---|
|
|
368
|
+
| `additive` | New public styling surface that does not break existing consumers | Adding a recipe helper, variant, state, or CSS entry point |
|
|
369
|
+
| `semantic change` | Public name remains but behavior or visual meaning shifts | Adjusting an existing class or recipe option to map to different token intent |
|
|
370
|
+
| `breaking` | Existing consumers may need code changes | Renaming or removing a class, option, export, or CSS entry point |
|
|
371
|
+
|
|
372
|
+
Renames and removals are always breaking regardless of perceived scope.
|
|
373
|
+
|
|
167
374
|
## Relationship to the rest of Spectre
|
|
168
375
|
|
|
169
376
|
Spectre keeps responsibilities separate:
|
|
@@ -172,24 +379,79 @@ Spectre keeps responsibilities separate:
|
|
|
172
379
|
defines design values and semantic meaning
|
|
173
380
|
- `@phcdevworks/spectre-ui` turns those tokens into reusable CSS, Tailwind
|
|
174
381
|
tooling, and type-safe class recipes
|
|
382
|
+
- `@phcdevworks/spectre-components` turns those styling contracts into
|
|
383
|
+
framework-agnostic Lit web components
|
|
175
384
|
- Adapters and apps consume `@phcdevworks/spectre-ui` instead of re-implementing
|
|
176
|
-
its styling layer
|
|
385
|
+
its styling layer, or wrap Spectre component contracts for a specific runtime
|
|
177
386
|
|
|
178
387
|
That separation keeps recipe behavior consistent across frameworks and reduces
|
|
179
388
|
implementation drift.
|
|
180
389
|
|
|
390
|
+
## Consumer checklist
|
|
391
|
+
|
|
392
|
+
For downstream packages and compatible apps:
|
|
393
|
+
|
|
394
|
+
- import `@phcdevworks/spectre-ui/index.css` for the full styling contract
|
|
395
|
+
- import split CSS entry points only when the consumer needs bundle-level
|
|
396
|
+
control
|
|
397
|
+
- use recipe functions when framework adapters need stable class strings
|
|
398
|
+
- use `@phcdevworks/spectre-ui/tailwind` for Tailwind theme integration
|
|
399
|
+
- consume tokens from `@phcdevworks/spectre-tokens` instead of inventing visual
|
|
400
|
+
values locally
|
|
401
|
+
- treat `dist/` as generated package output, not an authoring surface
|
|
402
|
+
- do not add framework runtime logic to this package
|
|
403
|
+
|
|
181
404
|
## Development
|
|
182
405
|
|
|
183
|
-
|
|
406
|
+
### Local setup
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
git clone https://github.com/phcdevworks/spectre-ui.git
|
|
410
|
+
cd spectre-ui
|
|
411
|
+
nvm use # picks up .nvmrc (Node 22.22.2)
|
|
412
|
+
npm install
|
|
413
|
+
npm run ci:verify
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
This project requires Node.js `^22.13.0 || >=24.0.0` and npm `>=10.0.0`.
|
|
417
|
+
The checked-in package manager is `npm@11.15.0`.
|
|
184
418
|
|
|
185
|
-
|
|
419
|
+
### Common commands
|
|
186
420
|
|
|
187
|
-
|
|
421
|
+
| Command | What it does |
|
|
422
|
+
|---|---|
|
|
423
|
+
| `npm run check` | Full validation gate — run before every PR |
|
|
424
|
+
| `npm run ci:verify` | Underlying verification sequence used by `npm run check` |
|
|
425
|
+
| `npm test` | Build then run the contract and regression test suite |
|
|
426
|
+
| `npm run build` | Emit TypeScript and CSS artifacts to `dist/` |
|
|
427
|
+
| `npm run lint` | ESLint with TypeScript-aware config |
|
|
428
|
+
| `npm run validate:exports` | Verify root export surface against snapshot |
|
|
429
|
+
| `npm run validate:exports:update` | Update the export snapshot after adding a public export |
|
|
430
|
+
| `npm run validate:tailwind` | Verify Tailwind exports and emitted subpath artifacts |
|
|
431
|
+
| `npm run validate:tailwind:update` | Update the Tailwind export snapshot |
|
|
432
|
+
| `npm run validate:tokens` | Check for token drift against latest published release |
|
|
188
433
|
|
|
189
|
-
|
|
190
|
-
- [`TODO.md`](TODO.md)
|
|
434
|
+
### Troubleshooting
|
|
191
435
|
|
|
192
|
-
|
|
436
|
+
**`validate:runtime` fails** — you are on the wrong Node version. Run
|
|
437
|
+
`nvm use` to switch to the version in `.nvmrc`, or install Node 22 or 24.
|
|
438
|
+
|
|
439
|
+
**`validate:tokens` fails with a network error** — the check requires outbound
|
|
440
|
+
npm registry access. In a restricted environment, run the other validators
|
|
441
|
+
individually; this step is the only network-dependent one in `ci:verify`.
|
|
442
|
+
|
|
443
|
+
**Tests pass but the build shows stale output** — `npm test` rebuilds
|
|
444
|
+
automatically via the `pretest` hook. If you ran `vitest` directly, run
|
|
445
|
+
`npm run build` first.
|
|
446
|
+
|
|
447
|
+
**Lint fails locally but passes in CI** — confirm you are on the same Node
|
|
448
|
+
version as CI (Node 22.x or 24.x). ESLint plugin resolution can differ
|
|
449
|
+
across runtimes.
|
|
450
|
+
|
|
451
|
+
**Export snapshot out of date** — run `npm run validate:exports:update` after
|
|
452
|
+
adding a public export, then commit the updated `scripts/export-snapshot.json`.
|
|
453
|
+
|
|
454
|
+
### Key source areas
|
|
193
455
|
|
|
194
456
|
- `src/styles/` for source CSS
|
|
195
457
|
- `src/recipes/` for class recipes
|
|
@@ -197,6 +459,9 @@ Key source areas:
|
|
|
197
459
|
- `tests/` for contract and regression coverage
|
|
198
460
|
- `examples/` for visual demos and verification fixtures
|
|
199
461
|
|
|
462
|
+
Planning artifacts for contract hardening live in [ROADMAP.md](ROADMAP.md) and
|
|
463
|
+
[TODO.md](TODO.md).
|
|
464
|
+
|
|
200
465
|
## Examples
|
|
201
466
|
|
|
202
467
|
Use [`examples/examples.html`](examples/examples.html) as the visual index for
|
|
@@ -208,6 +473,34 @@ Available examples include:
|
|
|
208
473
|
- `showroom.html` for a richer marketing-style composition
|
|
209
474
|
- `verification.html` and focused verification fixtures for regression checks
|
|
210
475
|
|
|
476
|
+
## Validation
|
|
477
|
+
|
|
478
|
+
Run the full validation gate before any pull request:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
npm run check
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
This runs: runtime check → lint → export validation → README validation →
|
|
485
|
+
token drift check → build → Tailwind contract → CSS contract → tests. All
|
|
486
|
+
steps must pass.
|
|
487
|
+
|
|
488
|
+
## AI and automation boundaries
|
|
489
|
+
|
|
490
|
+
Claude Code (`claude-sonnet-4-6`) is the primary development agent for this
|
|
491
|
+
repository. Codex handles releases and production stabilization. Jules handles
|
|
492
|
+
small automated fixes and token sync passes. GitHub Copilot provides
|
|
493
|
+
development support.
|
|
494
|
+
|
|
495
|
+
Claude Code, Codex, and Copilot do not create git commits by default. Jules may
|
|
496
|
+
commit only bounded automated maintenance when the `JULES.md` scope and
|
|
497
|
+
validation gates pass. Release decisions, tags, and publishing remain with
|
|
498
|
+
Bradley Potts.
|
|
499
|
+
|
|
500
|
+
**Protected from automated change:** CSS contracts, recipe public API surface,
|
|
501
|
+
and the zero-hex policy (no hardcoded color/spacing values). See
|
|
502
|
+
[AGENTS.md](AGENTS.md) for full agent governance and boundary rules.
|
|
503
|
+
|
|
211
504
|
## Contributing
|
|
212
505
|
|
|
213
506
|
PHCDevworks maintains this package as part of the Spectre suite.
|
|
@@ -217,7 +510,7 @@ When contributing:
|
|
|
217
510
|
- keep styling token-driven
|
|
218
511
|
- keep recipe APIs and CSS classes in sync
|
|
219
512
|
- avoid local visual values unless clearly intentional
|
|
220
|
-
- run npm run
|
|
513
|
+
- run `npm run check` before opening a pull request
|
|
221
514
|
|
|
222
515
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow.
|
|
223
516
|
|
package/dist/base.css
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
--sp-surface-page: #f7f8fb;
|
|
3
3
|
--sp-surface-card: #ffffff;
|
|
4
4
|
--sp-surface-input: #ffffff;
|
|
5
|
-
--sp-surface-overlay: rgba(
|
|
5
|
+
--sp-surface-overlay: rgba(0, 0, 0, 0.6);
|
|
6
6
|
--sp-surface-alternate: #eef1f6;
|
|
7
7
|
--sp-surface-hero: linear-gradient(135deg, #5b6ee1 0%, #6f3fd7 100%);
|
|
8
8
|
--sp-text-on-page-default: #141b24;
|
|
@@ -144,10 +144,14 @@
|
|
|
144
144
|
--sp-layout-container-max-width: 72rem;
|
|
145
145
|
--sp-border-width-base: 1px;
|
|
146
146
|
--sp-border-width-thick: 2px;
|
|
147
|
+
--sp-border-style-none: none;
|
|
148
|
+
--sp-border-style-solid: solid;
|
|
147
149
|
--sp-radius-none: 0;
|
|
148
150
|
--sp-radius-sm: 2px;
|
|
149
151
|
--sp-radius-md: 4px;
|
|
150
152
|
--sp-radius-lg: 8px;
|
|
153
|
+
--sp-radius-xl: 12px;
|
|
154
|
+
--sp-radius-2xl: 16px;
|
|
151
155
|
--sp-radius-pill: 999px;
|
|
152
156
|
--sp-font-family-sans: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
|
|
153
157
|
--sp-font-family-serif: 'Times New Roman', Times, serif;
|
|
@@ -183,34 +187,21 @@
|
|
|
183
187
|
--sp-font-6xl-line-height: 5rem;
|
|
184
188
|
--sp-font-6xl-weight: 900;
|
|
185
189
|
--sp-font-xs-letter-spacing: 0.02em;
|
|
186
|
-
--sp-
|
|
187
|
-
--sp-
|
|
188
|
-
--sp-
|
|
189
|
-
--sp-
|
|
190
|
-
--sp-
|
|
191
|
-
--sp-
|
|
192
|
-
--sp-
|
|
193
|
-
--sp-
|
|
194
|
-
--sp-
|
|
195
|
-
--sp-badge-neutral-text: #374253;
|
|
196
|
-
--sp-badge-info-bg: #e0f2fe;
|
|
197
|
-
--sp-badge-info-text: #075985;
|
|
198
|
-
--sp-badge-success-bg: #dcfce7;
|
|
199
|
-
--sp-badge-success-text: #166534;
|
|
200
|
-
--sp-badge-warning-bg: #fff1c2;
|
|
201
|
-
--sp-badge-warning-text: #8f5200;
|
|
202
|
-
--sp-badge-danger-bg: #fee2e2;
|
|
203
|
-
--sp-badge-danger-text: #991b1b;
|
|
204
|
-
--sp-icon-box-bg: #ffffff;
|
|
205
|
-
--sp-icon-box-border: #d9dfeb;
|
|
206
|
-
--sp-icon-box-icon-default: #0369a1;
|
|
207
|
-
--sp-icon-box-icon-success: #16a34a;
|
|
208
|
-
--sp-icon-box-icon-warning: #d48806;
|
|
209
|
-
--sp-icon-box-icon-danger: #dc2626;
|
|
190
|
+
--sp-font-sm-letter-spacing: 0em;
|
|
191
|
+
--sp-font-md-letter-spacing: 0em;
|
|
192
|
+
--sp-font-lg-letter-spacing: 0em;
|
|
193
|
+
--sp-font-xl-letter-spacing: 0em;
|
|
194
|
+
--sp-font-2xl-letter-spacing: 0em;
|
|
195
|
+
--sp-font-3xl-letter-spacing: 0em;
|
|
196
|
+
--sp-font-4xl-letter-spacing: 0em;
|
|
197
|
+
--sp-font-5xl-letter-spacing: 0em;
|
|
198
|
+
--sp-font-6xl-letter-spacing: 0em;
|
|
210
199
|
--sp-shadow-none: none;
|
|
211
200
|
--sp-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
212
201
|
--sp-shadow-md: 0 2px 6px -1px rgba(0, 0, 0, 0.08);
|
|
213
202
|
--sp-shadow-lg: 0 6px 16px -4px rgba(0, 0, 0, 0.12);
|
|
203
|
+
--sp-shadow-xl: 0 12px 24px -6px rgba(0, 0, 0, 0.15);
|
|
204
|
+
--sp-shadow-2xl: 0 20px 48px -12px rgba(0, 0, 0, 0.20);
|
|
214
205
|
--sp-breakpoint-sm: 640px;
|
|
215
206
|
--sp-breakpoint-md: 768px;
|
|
216
207
|
--sp-breakpoint-lg: 1024px;
|
|
@@ -224,20 +215,26 @@
|
|
|
224
215
|
--sp-z-index-modal: 1400;
|
|
225
216
|
--sp-z-index-popover: 1500;
|
|
226
217
|
--sp-z-index-tooltip: 1600;
|
|
218
|
+
--sp-z-index-toast: 1700;
|
|
227
219
|
--sp-duration-instant: 75ms;
|
|
228
220
|
--sp-duration-fast: 150ms;
|
|
229
221
|
--sp-duration-base: 200ms;
|
|
222
|
+
--sp-duration-relaxed: 250ms;
|
|
230
223
|
--sp-duration-moderate: 300ms;
|
|
231
224
|
--sp-duration-slow: 500ms;
|
|
232
225
|
--sp-duration-slower: 700ms;
|
|
226
|
+
--sp-duration-long: 1000ms;
|
|
227
|
+
--sp-duration-slowest: 1200ms;
|
|
233
228
|
--sp-easing-linear: linear;
|
|
234
229
|
--sp-easing-in: cubic-bezier(0.4, 0, 1, 1);
|
|
235
230
|
--sp-easing-out: cubic-bezier(0, 0, 0.2, 1);
|
|
236
231
|
--sp-easing-inout: cubic-bezier(0.4, 0, 0.2, 1);
|
|
237
232
|
--sp-easing-spring: cubic-bezier(0.4, 0, 0.2, 1);
|
|
233
|
+
--sp-easing-overshoot: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
238
234
|
--sp-opacity-disabled: 0.38;
|
|
239
235
|
--sp-opacity-hover: 0.92;
|
|
240
236
|
--sp-opacity-active: 0.84;
|
|
237
|
+
--sp-opacity-loading: 0.6;
|
|
241
238
|
--sp-opacity-focus: 1;
|
|
242
239
|
--sp-opacity-overlay: 0.5;
|
|
243
240
|
--sp-opacity-tooltip: 0.95;
|
|
@@ -369,7 +366,7 @@
|
|
|
369
366
|
--sp-button-text-default: #eef1f6;
|
|
370
367
|
--sp-button-text-on-primary: #ffffff;
|
|
371
368
|
--sp-badge-neutral-bg: #374253;
|
|
372
|
-
--sp-badge-neutral-text: #
|
|
369
|
+
--sp-badge-neutral-text: #f7f8fb;
|
|
373
370
|
--sp-badge-info-bg: #0c4a6e;
|
|
374
371
|
--sp-badge-info-text: #e0f2fe;
|
|
375
372
|
--sp-badge-success-bg: #166534;
|