css-is-awesome 1.16.0 → 1.16.1

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/AGENTS.md CHANGED
@@ -148,7 +148,7 @@ Authoring template (in your own project — a theme file is a global stylesheet,
148
148
 
149
149
  `$standalone` defaults to `true` (emit `:root, :root[data-theme="<name>"]`). Pass `$standalone: false` only when your block is going into a multi-theme bundle where the bare `:root` would collide.
150
150
 
151
- The validator (`node scripts/theme-validator.js`) enforces the token contract — **127 required + 36 optional = 163 slots** — plus WCAG 2.2 AA contrast (**22 audited pairs per theme**, including five `--code-*` pairs). Themes that miss required tokens or fail contrast cannot ship without `--allow-a11y-fail`.
151
+ The validator (`node scripts/theme-validator.js`) enforces the token contract — **127 required + 41 optional = 168 slots** — plus WCAG 2.2 AA contrast (**22 audited pairs per theme**, including five `--code-*` pairs). Themes that miss required tokens or fail contrast cannot ship without `--allow-a11y-fail`.
152
152
 
153
153
  ### Theming spacing (new — read this before you set a size token)
154
154
 
@@ -168,7 +168,7 @@ Why it matters: components call `cia.space(4)`, which resolves to `var(--space-4
168
168
 
169
169
  Two `<link media>` themes still work under the new selector model: a stylesheet whose `media` doesn't match is loaded but never applied, so only the matching file's `:root` block lands.
170
170
 
171
- Validator: `node scripts/theme-validator.js path/to/theme.css` (or `--all` for every shipped theme). Every theme must declare every required contract token (127 required in v1; missing tokens always fail). The audit also runs a WCAG 2.2 AA contrast check over 22 pairs; **a11y FAILs are fatal by default** as of v0.7. Pass `--allow-a11y-fail` to downgrade contrast failures to a report-only warning (the older `--strict` flag is accepted as a no-op alias). `--border-default` is treated as decorative per WCAG 2.2 SC 1.4.11 and reports as info, not FAIL.
171
+ Validator: `node scripts/theme-validator.js path/to/theme.css` (or `--all` for every shipped theme). Every theme must declare every required contract token (127 required in contract 1.1; missing required tokens always fail, missing optional ones are reported as info). The audit also runs a WCAG 2.2 AA contrast check over 22 pairs; **a11y FAILs are fatal by default** as of v0.7. Pass `--allow-a11y-fail` to downgrade contrast failures to a report-only warning (the older `--strict` flag is accepted as a no-op alias). `--border-default` is treated as decorative per WCAG 2.2 SC 1.4.11 and reports as info, not FAIL.
172
172
 
173
173
  ### Theme init (Next.js / SSR consumers)
174
174
 
@@ -343,7 +343,7 @@ Either way it exposes **31 tools** across 8 families:
343
343
  - **Themes** — `list_themes`, `get_theme`, `search_themes`
344
344
  - **Mixins** — `list_mixins`, `get_mixin`, `search_mixins` (real signatures — don't guess)
345
345
  - **Functions** — `list_functions`, `get_function`, `search_functions`
346
- - **Tokens** — `list_tokens`, `get_token`, `search_tokens` (127 required + 36 optional contract tokens)
346
+ - **Tokens** — `list_tokens`, `get_token`, `search_tokens` (127 required + 41 optional contract tokens)
347
347
  - **Animations** — `list_animations`, `get_animation`
348
348
  - **Components** — `list_components`, `get_component`, `search_components`
349
349
  - **Recipes** — `list_recipes`, `get_recipe`
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ # Changelog
2
+
3
+ ## [1.16.1](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.16.0...v1.16.1) (2026-09-18)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **contract:** --space-unit is optional, not required — contract 1.1 + CI growth gate ([42292ff](https://github.com/Jerry2d3d/css-is-awesome/commit/42292ff995a3e6d7fa1623404614f3519e30a284))
9
+
10
+
11
+ ### Features
12
+
13
+ * **site:** "Try in playground" on every recipe page ([9d2c7cc](https://github.com/Jerry2d3d/css-is-awesome/commit/9d2c7cc18399ff0c55c5c986ed70bdd9b6e1ddb5))
14
+ * **site:** /playground — in-browser Sass compile, CodeMirror panes, live preview ([c1474e4](https://github.com/Jerry2d3d/css-is-awesome/commit/c1474e40bfecaa7bd7b742ca545bf7f8f6756021))
15
+ * **site:** link the playground from the nav, the docs intro and the README ([9acabcc](https://github.com/Jerry2d3d/css-is-awesome/commit/9acabcc66f84e30f83cc8a7ff01e4845635ee2c4))
16
+ * **site:** playground groundwork — scss source map, [@use](https://github.com/use) resolver, share codec ([f5fb619](https://github.com/Jerry2d3d/css-is-awesome/commit/f5fb619d5b3d11dff9c77beeb77cd192b4b6d090))
17
+
1
18
  # [1.16.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.15.0...v1.16.0) (2026-09-17)
2
19
 
3
20
 
@@ -400,132 +417,17 @@
400
417
  * **site:** print the story, not the chrome — dogfoods cia's print mixins ([ece519c](https://github.com/Jerry2d3d/css-is-awesome/commit/ece519c43f62230e1b3392538dae5148fc31ddf6))
401
418
  * **themes:** themes own the spacing rhythm, not just the palette ([4bc1e24](https://github.com/Jerry2d3d/css-is-awesome/commit/4bc1e24f1b64f33cacd35f3bab12327019634fea))
402
419
 
403
- # [1.1.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.0.0...v1.1.0) (2026-09-01)
404
-
405
-
406
- ### Bug Fixes
407
-
408
- * **a11y:** copy button used code-surface ink on a page-surface background ([bf84bf4](https://github.com/Jerry2d3d/css-is-awesome/commit/bf84bf4d6c23e3ebafdb5dc98a303d9961d68714))
409
- * **a11y:** validator ignored unquoted [data-theme]; grade the code palette ([2437f41](https://github.com/Jerry2d3d/css-is-awesome/commit/2437f4182ddccc01b372d9aacd898b6222fcabd3)), closes [#fafafa](https://github.com/Jerry2d3d/css-is-awesome/issues/fafafa) [#0a0a0a](https://github.com/Jerry2d3d/css-is-awesome/issues/0a0a0a)
410
- * **ci:** snapshot job installed chromium but ran all three engines ([f7b7fc9](https://github.com/Jerry2d3d/css-is-awesome/commit/f7b7fc9e29883863c6a525f44391e6eb4b4b9662))
411
- * **ci:** snapshot workflow silently discarded the baselines it created ([3358cac](https://github.com/Jerry2d3d/css-is-awesome/commit/3358cacb6fbf88d9dcf0109597bed301efeda483))
412
- * **compare:** correct every measurable claim on the comparison page ([3d1b602](https://github.com/Jerry2d3d/css-is-awesome/commit/3d1b602ff6074712a2e2d0aea5a1ad27128d2d70))
413
- * **pkg:** build dist/ on git installs via a prepare hook ([1a0deb1](https://github.com/Jerry2d3d/css-is-awesome/commit/1a0deb19e4fc6de15b7b3530847779920d01d784))
414
- * **print:** stop the freeze from flattening deliberate opacity and transform ([1af51d2](https://github.com/Jerry2d3d/css-is-awesome/commit/1af51d2e3a08cd61e51ac3b857eeaa261afd044e))
415
- * root barrel emitted no tokens; retract the false Turbopack claim ([d7f71e3](https://github.com/Jerry2d3d/css-is-awesome/commit/d7f71e366a1ef4b918cfcfd6dafcba8d352afcb5))
416
- * **sass:** stop using the deprecated if() function; sharpen the AI on-ramp ([61df05a](https://github.com/Jerry2d3d/css-is-awesome/commit/61df05a31228fce169664690c2562d128bf06958))
417
- * **site:** moat card uses grid; Tailwind sample updated to Headless UI v2 ([cb39e44](https://github.com/Jerry2d3d/css-is-awesome/commit/cb39e44b4eb8d7ab1a86377c1d828b1cde3ed58b))
418
- * **site:** moat code blocks now fill their card ([8e53d35](https://github.com/Jerry2d3d/css-is-awesome/commit/8e53d355b0f9279125b9dfd6f913851cf2ebcdc3))
419
- * six upstream bugs from the Boiler audit (BUG-1..7) ([84f4c4f](https://github.com/Jerry2d3d/css-is-awesome/commit/84f4c4fc6f6259bf74541a833fe0ad343821ab12))
420
- * **themes:** prism was missing from every theme picker ([4ce4f5f](https://github.com/Jerry2d3d/css-is-awesome/commit/4ce4f5f8a696728b513aa1adc148b33c5808e26e))
421
-
422
-
423
- ### Features
424
-
425
- * **animate:** accept a raw duration; add letter-spacing() coverage fixture ([25b7cd6](https://github.com/Jerry2d3d/css-is-awesome/commit/25b7cd6cbc09d76b51c9dd0b74077ec1af78c327))
426
- * **blog:** real posts from real commits, replacing seven dead stubs ([f37c5be](https://github.com/Jerry2d3d/css-is-awesome/commit/f37c5be94cd64f99548a6a119820325d559e6920))
427
- * **site:** print the story, not the chrome — dogfoods cia's print mixins ([ece519c](https://github.com/Jerry2d3d/css-is-awesome/commit/ece519c43f62230e1b3392538dae5148fc31ddf6))
428
- * **themes:** themes own the spacing rhythm, not just the palette ([4bc1e24](https://github.com/Jerry2d3d/css-is-awesome/commit/4bc1e24f1b64f33cacd35f3bab12327019634fea))
429
-
430
- # [1.1.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.0.0...v1.1.0) (2026-09-01)
431
-
432
-
433
- ### Bug Fixes
434
-
435
- * **a11y:** copy button used code-surface ink on a page-surface background ([bf84bf4](https://github.com/Jerry2d3d/css-is-awesome/commit/bf84bf4d6c23e3ebafdb5dc98a303d9961d68714))
436
- * **a11y:** validator ignored unquoted [data-theme]; grade the code palette ([2437f41](https://github.com/Jerry2d3d/css-is-awesome/commit/2437f4182ddccc01b372d9aacd898b6222fcabd3)), closes [#fafafa](https://github.com/Jerry2d3d/css-is-awesome/issues/fafafa) [#0a0a0a](https://github.com/Jerry2d3d/css-is-awesome/issues/0a0a0a)
437
- * **ci:** snapshot job installed chromium but ran all three engines ([f7b7fc9](https://github.com/Jerry2d3d/css-is-awesome/commit/f7b7fc9e29883863c6a525f44391e6eb4b4b9662))
438
- * **ci:** snapshot workflow silently discarded the baselines it created ([3358cac](https://github.com/Jerry2d3d/css-is-awesome/commit/3358cacb6fbf88d9dcf0109597bed301efeda483))
439
- * **compare:** correct every measurable claim on the comparison page ([3d1b602](https://github.com/Jerry2d3d/css-is-awesome/commit/3d1b602ff6074712a2e2d0aea5a1ad27128d2d70))
440
- * **pkg:** build dist/ on git installs via a prepare hook ([1a0deb1](https://github.com/Jerry2d3d/css-is-awesome/commit/1a0deb19e4fc6de15b7b3530847779920d01d784))
441
- * **print:** stop the freeze from flattening deliberate opacity and transform ([1af51d2](https://github.com/Jerry2d3d/css-is-awesome/commit/1af51d2e3a08cd61e51ac3b857eeaa261afd044e))
442
- * root barrel emitted no tokens; retract the false Turbopack claim ([d7f71e3](https://github.com/Jerry2d3d/css-is-awesome/commit/d7f71e366a1ef4b918cfcfd6dafcba8d352afcb5))
443
- * **sass:** stop using the deprecated if() function; sharpen the AI on-ramp ([61df05a](https://github.com/Jerry2d3d/css-is-awesome/commit/61df05a31228fce169664690c2562d128bf06958))
444
- * **site:** moat card uses grid; Tailwind sample updated to Headless UI v2 ([cb39e44](https://github.com/Jerry2d3d/css-is-awesome/commit/cb39e44b4eb8d7ab1a86377c1d828b1cde3ed58b))
445
- * **site:** moat code blocks now fill their card ([8e53d35](https://github.com/Jerry2d3d/css-is-awesome/commit/8e53d355b0f9279125b9dfd6f913851cf2ebcdc3))
446
- * six upstream bugs from the Boiler audit (BUG-1..7) ([84f4c4f](https://github.com/Jerry2d3d/css-is-awesome/commit/84f4c4fc6f6259bf74541a833fe0ad343821ab12))
447
- * **themes:** prism was missing from every theme picker ([4ce4f5f](https://github.com/Jerry2d3d/css-is-awesome/commit/4ce4f5f8a696728b513aa1adc148b33c5808e26e))
448
-
449
-
450
- ### Features
451
-
452
- * **animate:** accept a raw duration; add letter-spacing() coverage fixture ([25b7cd6](https://github.com/Jerry2d3d/css-is-awesome/commit/25b7cd6cbc09d76b51c9dd0b74077ec1af78c327))
453
- * **blog:** real posts from real commits, replacing seven dead stubs ([f37c5be](https://github.com/Jerry2d3d/css-is-awesome/commit/f37c5be94cd64f99548a6a119820325d559e6920))
454
- * **site:** print the story, not the chrome — dogfoods cia's print mixins ([ece519c](https://github.com/Jerry2d3d/css-is-awesome/commit/ece519c43f62230e1b3392538dae5148fc31ddf6))
455
- * **themes:** themes own the spacing rhythm, not just the palette ([4bc1e24](https://github.com/Jerry2d3d/css-is-awesome/commit/4bc1e24f1b64f33cacd35f3bab12327019634fea))
456
-
457
- # [1.1.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.0.0...v1.1.0) (2026-08-30)
458
-
459
-
460
- ### Bug Fixes
461
-
462
- * **a11y:** copy button used code-surface ink on a page-surface background ([bf84bf4](https://github.com/Jerry2d3d/css-is-awesome/commit/bf84bf4d6c23e3ebafdb5dc98a303d9961d68714))
463
- * **a11y:** validator ignored unquoted [data-theme]; grade the code palette ([2437f41](https://github.com/Jerry2d3d/css-is-awesome/commit/2437f4182ddccc01b372d9aacd898b6222fcabd3)), closes [#fafafa](https://github.com/Jerry2d3d/css-is-awesome/issues/fafafa) [#0a0a0a](https://github.com/Jerry2d3d/css-is-awesome/issues/0a0a0a)
464
- * **ci:** snapshot job installed chromium but ran all three engines ([f7b7fc9](https://github.com/Jerry2d3d/css-is-awesome/commit/f7b7fc9e29883863c6a525f44391e6eb4b4b9662))
465
- * **ci:** snapshot workflow silently discarded the baselines it created ([3358cac](https://github.com/Jerry2d3d/css-is-awesome/commit/3358cacb6fbf88d9dcf0109597bed301efeda483))
466
- * **compare:** correct every measurable claim on the comparison page ([3d1b602](https://github.com/Jerry2d3d/css-is-awesome/commit/3d1b602ff6074712a2e2d0aea5a1ad27128d2d70))
467
- * **pkg:** build dist/ on git installs via a prepare hook ([1a0deb1](https://github.com/Jerry2d3d/css-is-awesome/commit/1a0deb19e4fc6de15b7b3530847779920d01d784))
468
- * **print:** stop the freeze from flattening deliberate opacity and transform ([1af51d2](https://github.com/Jerry2d3d/css-is-awesome/commit/1af51d2e3a08cd61e51ac3b857eeaa261afd044e))
469
- * root barrel emitted no tokens; retract the false Turbopack claim ([d7f71e3](https://github.com/Jerry2d3d/css-is-awesome/commit/d7f71e366a1ef4b918cfcfd6dafcba8d352afcb5))
470
- * **sass:** stop using the deprecated if() function; sharpen the AI on-ramp ([61df05a](https://github.com/Jerry2d3d/css-is-awesome/commit/61df05a31228fce169664690c2562d128bf06958))
471
- * **site:** moat card uses grid; Tailwind sample updated to Headless UI v2 ([cb39e44](https://github.com/Jerry2d3d/css-is-awesome/commit/cb39e44b4eb8d7ab1a86377c1d828b1cde3ed58b))
472
- * **site:** moat code blocks now fill their card ([8e53d35](https://github.com/Jerry2d3d/css-is-awesome/commit/8e53d355b0f9279125b9dfd6f913851cf2ebcdc3))
473
- * six upstream bugs from the Boiler audit (BUG-1..7) ([84f4c4f](https://github.com/Jerry2d3d/css-is-awesome/commit/84f4c4fc6f6259bf74541a833fe0ad343821ab12))
474
- * **themes:** prism was missing from every theme picker ([4ce4f5f](https://github.com/Jerry2d3d/css-is-awesome/commit/4ce4f5f8a696728b513aa1adc148b33c5808e26e))
475
-
476
-
477
- ### Features
478
-
479
- * **animate:** accept a raw duration; add letter-spacing() coverage fixture ([25b7cd6](https://github.com/Jerry2d3d/css-is-awesome/commit/25b7cd6cbc09d76b51c9dd0b74077ec1af78c327))
480
- * **blog:** real posts from real commits, replacing seven dead stubs ([f37c5be](https://github.com/Jerry2d3d/css-is-awesome/commit/f37c5be94cd64f99548a6a119820325d559e6920))
481
- * **site:** print the story, not the chrome — dogfoods cia's print mixins ([ece519c](https://github.com/Jerry2d3d/css-is-awesome/commit/ece519c43f62230e1b3392538dae5148fc31ddf6))
482
- * **themes:** themes own the spacing rhythm, not just the palette ([4bc1e24](https://github.com/Jerry2d3d/css-is-awesome/commit/4bc1e24f1b64f33cacd35f3bab12327019634fea))
483
-
484
- ## [1.1.1](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.1.0...v1.1.1) (2026-08-30)
485
-
486
-
487
- ### Bug Fixes
488
-
489
- * **sass:** stop using the deprecated if() function; sharpen the AI on-ramp ([61df05a](https://github.com/Jerry2d3d/css-is-awesome/commit/61df05a31228fce169664690c2562d128bf06958))
490
-
491
- # [1.1.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.0.0...v1.1.0) (2026-08-30)
492
-
493
-
494
- ### Bug Fixes
495
-
496
- * **a11y:** copy button used code-surface ink on a page-surface background ([bf84bf4](https://github.com/Jerry2d3d/css-is-awesome/commit/bf84bf4d6c23e3ebafdb5dc98a303d9961d68714))
497
- * **a11y:** validator ignored unquoted [data-theme]; grade the code palette ([2437f41](https://github.com/Jerry2d3d/css-is-awesome/commit/2437f4182ddccc01b372d9aacd898b6222fcabd3)), closes [#fafafa](https://github.com/Jerry2d3d/css-is-awesome/issues/fafafa) [#0a0a0a](https://github.com/Jerry2d3d/css-is-awesome/issues/0a0a0a)
498
- * **ci:** snapshot job installed chromium but ran all three engines ([f7b7fc9](https://github.com/Jerry2d3d/css-is-awesome/commit/f7b7fc9e29883863c6a525f44391e6eb4b4b9662))
499
- * **ci:** snapshot workflow silently discarded the baselines it created ([3358cac](https://github.com/Jerry2d3d/css-is-awesome/commit/3358cacb6fbf88d9dcf0109597bed301efeda483))
500
- * **compare:** correct every measurable claim on the comparison page ([3d1b602](https://github.com/Jerry2d3d/css-is-awesome/commit/3d1b602ff6074712a2e2d0aea5a1ad27128d2d70))
501
- * **pkg:** build dist/ on git installs via a prepare hook ([1a0deb1](https://github.com/Jerry2d3d/css-is-awesome/commit/1a0deb19e4fc6de15b7b3530847779920d01d784))
502
- * **print:** stop the freeze from flattening deliberate opacity and transform ([1af51d2](https://github.com/Jerry2d3d/css-is-awesome/commit/1af51d2e3a08cd61e51ac3b857eeaa261afd044e))
503
- * root barrel emitted no tokens; retract the false Turbopack claim ([d7f71e3](https://github.com/Jerry2d3d/css-is-awesome/commit/d7f71e366a1ef4b918cfcfd6dafcba8d352afcb5))
504
- * **site:** moat card uses grid; Tailwind sample updated to Headless UI v2 ([cb39e44](https://github.com/Jerry2d3d/css-is-awesome/commit/cb39e44b4eb8d7ab1a86377c1d828b1cde3ed58b))
505
- * **site:** moat code blocks now fill their card ([8e53d35](https://github.com/Jerry2d3d/css-is-awesome/commit/8e53d355b0f9279125b9dfd6f913851cf2ebcdc3))
506
- * six upstream bugs from the Boiler audit (BUG-1..7) ([84f4c4f](https://github.com/Jerry2d3d/css-is-awesome/commit/84f4c4fc6f6259bf74541a833fe0ad343821ab12))
507
- * **themes:** prism was missing from every theme picker ([4ce4f5f](https://github.com/Jerry2d3d/css-is-awesome/commit/4ce4f5f8a696728b513aa1adc148b33c5808e26e))
508
-
509
-
510
- ### Features
511
-
512
- * **animate:** accept a raw duration; add letter-spacing() coverage fixture ([25b7cd6](https://github.com/Jerry2d3d/css-is-awesome/commit/25b7cd6cbc09d76b51c9dd0b74077ec1af78c327))
513
- * **blog:** real posts from real commits, replacing seven dead stubs ([f37c5be](https://github.com/Jerry2d3d/css-is-awesome/commit/f37c5be94cd64f99548a6a119820325d559e6920))
514
- * **site:** print the story, not the chrome — dogfoods cia's print mixins ([ece519c](https://github.com/Jerry2d3d/css-is-awesome/commit/ece519c43f62230e1b3392538dae5148fc31ddf6))
515
- * **themes:** themes own the spacing rhythm, not just the palette ([4bc1e24](https://github.com/Jerry2d3d/css-is-awesome/commit/4bc1e24f1b64f33cacd35f3bab12327019634fea))
516
-
517
- # Changelog
518
-
519
- All notable changes to this project will be documented in this file.
420
+ ---
520
421
 
521
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
522
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
422
+ ## Hand-written history (before automated releases)
523
423
 
524
- **See also:** [`VERSIONING.md`](./VERSIONING.md) — version policy, deprecation
525
- lifecycle, and the Conventional Commits → changelog section mapping that drives
526
- automated releases.
424
+ > Everything above this line is generated by `semantic-release`. Everything
425
+ > below was written by hand, up to and including the launch notes for 1.1.0
426
+ > (the first version published to npm, 2026-09-01). The generated 1.1.0 entry
427
+ > above is the terse commit list; the section right below is the same release
428
+ > explained.
527
429
 
528
- ## [Unreleased]
430
+ ## [1.1.0] — 2026-09-01 — launch notes (hand-written detail for the generated entry above)
529
431
 
530
432
  > Ships as **1.1.0** — the first release actually published to npm. `1.0.0` was
531
433
  > tagged but never published. The number is computed by `semantic-release` from
package/CONTRACT.md CHANGED
@@ -223,6 +223,7 @@ The **numbered scale is the source of truth and is contract-required**: a theme
223
223
  | Token | Type | Example (default rhythm) | Purpose |
224
224
  | --------------------------- | ------ | --------------------------------- | -------------------------------- |
225
225
  | `--space-0` … `--space-9` | length | `0`, `0.25rem`, `0.5rem`, … `6rem` | The numbered scale — **required** |
226
+ | `--space-unit` | length | `0.25rem` | The density knob — **optional** (contract 1.1). Shipped themes derive every `--space-N` from it via `calc()`; a hand-written theme that declares absolute `--space-N` values never references it, so nothing breaks without it. It was listed as *required* by mistake in library 1.12.0–1.16.0. |
226
227
 
227
228
  The t-shirt names are **optional aliases**. The library emits `xs`–`xl` as `var()` references into the numbered scale, so they follow it automatically; `--space-2xs` sits outside the numbered scale and emits as a literal:
228
229
 
package/MIGRATION.md CHANGED
@@ -2,6 +2,154 @@
2
2
 
3
3
  Breaking changes between css-is-awesome versions, and how to migrate.
4
4
 
5
+ ## v1.0 — mixin-first goes stable (published as 1.1.0)
6
+
7
+ **There are no breaking changes between v0.8.1/0.8.2 and v1.0.0.** 1.0.0
8
+ (tagged 2026-08-17) is the point at which the v0.8 mixin-first surface —
9
+ mixins, functions, token contract, theme architecture — became stable under
10
+ strict SemVer (see [`VERSIONING.md`](./VERSIONING.md)). Every mixin you called
11
+ in v0.8.1 compiles unchanged in v1.x; `npm run validate-api` guards the barrel
12
+ surface on every commit. The 67 commits between 0.8.2 and 1.0.0 carry no
13
+ rename, removal or signature change.
14
+
15
+ 1.0.0 itself was never published to npm. The first published release is
16
+ **1.1.0 (2026-09-01)**, so upgrading from v0.8 in practice means landing on
17
+ 1.1.x — and that release does carry **one action-required change for authors
18
+ of custom themes** (section 2 below). Consumers of the shipped themes have
19
+ nothing to do.
20
+
21
+ ### What changed at a glance
22
+
23
+ | Area | v0.8.x | v1.x |
24
+ |---|---|---|
25
+ | Component stylesheet import | `@use 'css-is-awesome/scss/mixins' as m` (deep path) or the emitting bundle | **`@use 'css-is-awesome/api' as cia`** — zero-emit barrel, safe in CSS Modules (additive; the deep paths still work) |
26
+ | Root-level `@use 'css-is-awesome'` | Worked only via the deep `scss/…` paths on a clean install | **Resolves on a clean install** — root shims `api.scss` + `_index.scss` shipped (Sass ignores `package.json` `exports`) |
27
+ | Custom-theme contract | `--space-{2xs,xs,sm,md,lg,xl}` required | **`--space-0` … `--space-9` required**, t-shirt names optional (1.1.0 — validator fails an unconverted theme) |
28
+ | Six `--radius-{button,card,input,modal,badge,avatar}` tokens | Required of every theme, read by nothing | **Dropped from the contract** — the live knobs are `--btn-radius`, `--card-radius`, … |
29
+ | Library defaults selector | `:root { … }` (tied a drop-in theme at 0,1,0 — library won) | **`:where(:root) { … }`** — a theme's bare `:root` always wins |
30
+ | `theme()` mixin output | Inconsistent (`:root`, `[data-theme]`, or `:root[data-theme]`) | **`:root, :root[data-theme="<name>"]`** — drop-in with no markup change; `$standalone: false` for bundles |
31
+ | `spinner` / `skeleton` keyframes | Emitted at module top level on import (leaked; CSS Modules renamed them) | **Emitted via `@at-root` inside the mixin** — only when called |
32
+ | Print / PDF | — | **New**: `print`, `print-base`, `print-hidden`, `print-only` mixins + `print-to-pdf` recipe |
33
+
34
+ ### 1. Adopt the two-import model (recommended, not required)
35
+
36
+ v0.8 consumers typically imported the whole library into every component
37
+ stylesheet, or reached for the deep `scss/mixins` path. Both still compile.
38
+ The v1 shape separates the two jobs:
39
+
40
+ ```scss
41
+ // app/globals.scss — loaded ONCE at the app root. Emits :root tokens + base.
42
+ @use 'css-is-awesome';
43
+
44
+ // Card.module.scss — per component. Emits NOTHING until a mixin is called,
45
+ // so it is safe under Next.js CSS Modules "pure" mode.
46
+ @use 'css-is-awesome/api' as cia;
47
+ .card { @include cia.card-base($shadow: 2); background: cia.color(surface-default); }
48
+ ```
49
+
50
+ If you were on the deep path, the swap is one line:
51
+
52
+ ```scss
53
+ // v0.8
54
+ @use 'css-is-awesome/scss/mixins' as m;
55
+ .btn { @include m.btn(primary); }
56
+
57
+ // v1.x — same mixins, one namespace for the whole API (layout + components too)
58
+ @use 'css-is-awesome/api' as cia;
59
+ .btn { @include cia.btn(primary); }
60
+ ```
61
+
62
+ `m.` was only ever the `_mixins.scss` leaf; `cia.` forwards every module, so
63
+ `cia.stack`, `cia.card-base` and `cia.print-base` are all reachable without a
64
+ second import. Deep paths remain supported for anyone who prefers them.
65
+
66
+ ### 2. Custom themes: declare `--space-0` … `--space-9` (1.1.0, action required)
67
+
68
+ In v0.8 a theme could satisfy the contract with the six t-shirt spacing
69
+ names, but components read the numbered scale (`space(4)` → `var(--space-4)`),
70
+ so a theme's spacing was never actually applied. 1.1.0 makes the numbered
71
+ scale the required source of truth and turns the t-shirt names into optional
72
+ aliases that reference it.
73
+
74
+ ```css
75
+ /* v0.8 custom theme — passes the old validator, but components ignored it */
76
+ :root[data-theme="brand"] {
77
+ --space-xs: 4px; --space-sm: 8px; --space-md: 16px;
78
+ --space-lg: 24px; --space-xl: 32px; --space-2xs: 2px;
79
+ }
80
+
81
+ /* v1.x custom theme — required. `npm run validate-themes` fails without it. */
82
+ :root[data-theme="brand"] {
83
+ --space-0: 0; --space-1: 4px; --space-2: 8px; --space-3: 12px;
84
+ --space-4: 16px; --space-5: 24px; --space-6: 32px; --space-7: 48px;
85
+ --space-8: 64px; --space-9: 96px;
86
+ /* optional aliases — keep them only if your own CSS reads them */
87
+ --space-md: var(--space-4);
88
+ }
89
+ ```
90
+
91
+ Shipped themes were all converted; if you copied one as a starting point,
92
+ re-copy its spacing block. `--space-unit` (the density knob, 1.12.0) is
93
+ **optional** — since contract 1.1 (library 1.16.1) the validator reports a
94
+ missing optional token as info, never a failure; between 1.12.0 and 1.16.0 it
95
+ was wrongly listed as required, which is why a custom theme could fail
96
+ validation after a minor upgrade. (Later 1.x releases derive the whole scale from a
97
+ single `--space-unit`; see the theme authoring docs for the current shape.)
98
+
99
+ While you are in the file: the six `--radius-button` / `-card` / `-input` /
100
+ `-modal` / `-badge` / `-avatar` tokens can be deleted. Nothing read them. The
101
+ per-component radius knobs that do work are `--btn-radius`, `--card-radius`,
102
+ `--input-radius`, `--modal-radius`, `--badge-radius` and `--tag-radius`.
103
+
104
+ ### 3. Drop-in themes need no markup (1.1.0, behaviour change, no action)
105
+
106
+ Two changes make a single theme file work when dropped into any page:
107
+
108
+ - Library defaults now emit under `:where(:root)` (specificity 0,0,0). In
109
+ v0.8 the library's own `:root` tied a theme's `:root` and, loading second,
110
+ won — so a drop-in theme rendered an untokenised page unless you also set
111
+ `<html data-theme>`. Specificity only *decreased*, so nothing that used to
112
+ win can start losing.
113
+ - `cia.theme('name')` now emits `:root, :root[data-theme="name"]`. If you build
114
+ a multi-theme bundle yourself, pass `$standalone: false` so twenty blocks
115
+ don't all claim `:root`.
116
+
117
+ If your app overrode a library default with a bare `:root` rule that only
118
+ worked because of source order, it now works by specificity instead.
119
+
120
+ ### 4. `spinner` / `skeleton` in CSS Modules (fix, no action)
121
+
122
+ v0.8 defined those mixins' `@keyframes` at module top level, so importing the
123
+ file leaked CSS and CSS Modules renamed the keyframes away from the
124
+ `animation-name` that referenced them. They now emit via `@at-root` inside the
125
+ mixin, co-located with the reference, so CSS Modules renames both together.
126
+ If you had worked around it by importing `animations-utilities` globally,
127
+ that workaround is harmless and can stay.
128
+
129
+ ### New mixins/features (additive, no migration needed)
130
+
131
+ - `css-is-awesome/api` — the zero-emit authoring barrel (section 1)
132
+ - `cia.print`, `cia.print-base($freeze-animations, $size, $margin)`,
133
+ `cia.print-hidden`, `cia.print-only` — pure-CSS print/PDF layer;
134
+ `print-base` is root-only (emits `@page`) and exposes `--is-print`,
135
+ `--print-hide`, `--print-show`. Recipe: `scss/recipes/print-to-pdf.md`
136
+ - The recipes book (`scss/recipes/*.md`) and the MCP server (`mcp/server.cjs`)
137
+ ship in the package; `npx cia add <recipe>` copies a recipe into your project
138
+ - `npm run validate-package` — packs, installs into a temp project and compiles
139
+ every documented `@use` specifier, which is how the root-shim break was found
140
+ - Theme build + drift gates (`check:theme-drift`), a corrected contrast
141
+ validator (it previously skipped unquoted `[data-theme=x]` blocks), and
142
+ 24 shipped themes all passing the contract and the a11y audit
143
+
144
+ ### Where to read more
145
+
146
+ - [`CHANGELOG.md`](./CHANGELOG.md) — `[1.0.0]` and `[1.1.0]` entries carry the
147
+ full detail and the reasoning behind each change
148
+ - [`VERSIONING.md`](./VERSIONING.md) — what counts as MAJOR from 1.0 on
149
+ - [`CONTRACT.md`](./CONTRACT.md) — the current required/optional token list
150
+
151
+ ---
152
+
5
153
  ## v0.8.1 — animations split + small renames
6
154
 
7
155
  Patch release with one real fix (animations CSS Modules bug) and two small
package/README.md CHANGED
@@ -145,7 +145,7 @@ node scripts/theme-validator.js public/themes/midnight/theme.css
145
145
  # <link rel="stylesheet" href="/themes/midnight/theme.css">
146
146
  ```
147
147
 
148
- Full authoring walkthrough: [`/docs/authoring/themes`](https://cssisawesome.com/docs/authoring/themes/). The contract (127 required + 36 optional tokens) is at [`scripts/theme-contract.json`](./scripts/theme-contract.json).
148
+ Full authoring walkthrough: [`/docs/authoring/themes`](https://cssisawesome.com/docs/authoring/themes/). The contract (127 required + 41 optional tokens) is at [`scripts/theme-contract.json`](./scripts/theme-contract.json).
149
149
 
150
150
  ## Token contract
151
151
 
@@ -334,7 +334,7 @@ npm install -D @modelcontextprotocol/sdk zod
334
334
 
335
335
  ## Docs site
336
336
 
337
- The docs site is live at **https://cssisawesome.com** (production — Vercel, deployed from the `prod-css-is-awesome` branch), with a GitHub Pages mirror at **https://jerry2d3d.github.io/css-is-awesome/** that auto-deploys from `main`. To run it locally:
337
+ The docs site is live at **https://cssisawesome.com** (production — Vercel, building `main` on every push), with a GitHub Pages mirror at **https://jerry2d3d.github.io/css-is-awesome/** that deploys after each release. To run it locally:
338
338
 
339
339
  ```bash
340
340
  git clone https://github.com/Jerry2d3d/css-is-awesome.git
@@ -345,6 +345,8 @@ npm run dev # http://localhost:5173
345
345
 
346
346
  The docs site is a Next.js 16 app at `src/` that dogfoods the library — every page uses CSS Modules composed from the same tokens and mixins the library ships.
347
347
 
348
+ It also hosts the **[playground](https://cssisawesome.com/playground/)**: write SCSS with cia mixins, see it render live against any of the 24 themes, and share the result as a link. Sass runs in your browser (dart-sass in a web worker against cia's own source), so nothing is uploaded and the site stays a static export. Every recipe page has a “Try in playground” button.
349
+
348
350
  ## Scripts
349
351
 
350
352
  | Script | Does |
@@ -359,7 +361,7 @@ The docs site is a Next.js 16 app at `src/` that dogfoods the library — every
359
361
  | `npm run dtcg-to-scss` | Convert DTCG-format design tokens into cia SCSS |
360
362
  | `npm run lint` | ESLint on the Next.js app |
361
363
  | `npm run lint:scss` | Stylelint on the SCSS library |
362
- | `npm run validate-themes` | Validate every theme against the 127-token contract + WCAG 2.2 AA contrast (FAIL-by-default since v0.7; checks both `light-dark()` branches and reports the worse) |
364
+ | `npm run validate-themes` | Validate every theme against the 127-required-token contract + WCAG 2.2 AA contrast (FAIL-by-default since v0.7; checks both `light-dark()` branches and reports the worse) |
363
365
  | `npm run validate-icons` | Validate the `core` icon pack against the 49-glyph contract |
364
366
  | `npm run validate-api` | Assert the `css-is-awesome/api` barrel stays zero-emit |
365
367
  | `npm run validate-package` | Pack + install into a temp project and compile every documented `@use` form — catches breakage that in-repo checks can't see |
@@ -410,7 +412,7 @@ Full detail: [`/docs/testing`](https://cssisawesome.com/docs/testing/).
410
412
 
411
413
  The 1.0 surface is the v0.8 mixin-first reframe — twelve mixin renames, theme system collapsed to 8 single-file theme families, six zero-JS components, intrinsic-layout vocabulary, opt-in utilities — plus the recipes book, the Tailwind/Bootstrap migration on-ramp, print/PDF support, and the 31-tool MCP server (now also available zero-install via the companion [`css-is-awesome-mcp`](https://www.npmjs.com/package/css-is-awesome-mcp) package). The npm package ships ZERO JavaScript by hard rule.
412
414
 
413
- See [CHANGELOG.md](./CHANGELOG.md) for the full history and [MIGRATION.md](./MIGRATION.md) for the v0.7 → v0.8 upgrade path.
415
+ See [CHANGELOG.md](./CHANGELOG.md) for the full history and [MIGRATION.md](./MIGRATION.md) for the v0.7 → v0.8 and v0.8 → v1.0 upgrade paths.
414
416
 
415
417
  For the deep authoring reference (tier decisions, mixin contracts, agent rules), read [`AGENTS.md`](./AGENTS.md).
416
418
 
package/VERSIONING.md CHANGED
@@ -30,6 +30,7 @@ Any change that can break a consumer upgrading blindly.
30
30
  | SCSS mixin renamed, removed, or breaking signature change | `m.btn($variant)` now requires `$size` |
31
31
  | SCSS mixin default changes rendered output | `m.card()` default radius flips from `md` → `lg` |
32
32
  | Contract: required token renamed or removed | `--surface-default` → `--surface-base` |
33
+ | Contract: **new required token added** (existing custom themes stop validating) | `--space-unit` added as required in 1.12.0 — a mistake, relaxed in contract 1.1 |
33
34
  | Contract: `version` field bumps to a new major (`"1"` → `"2"`) | Required-token removal in `scripts/theme-contract.json` |
34
35
  | Optional-peer floor rises | `@modelcontextprotocol/sdk` minimum raised |
35
36
 
@@ -42,6 +43,7 @@ Additive, non-breaking changes.
42
43
  | New public CSS class | `.cia-grid-auto-fit` added |
43
44
  | New public SCSS mixin | `m.cluster($gap)` added |
44
45
  | New optional token added to contract (`"1"` → `"1.1"`) | `--dropdown-offset-y` added to component section |
46
+ | Required token relaxed to optional (contract minor bump) | `--space-unit` required → optional, contract `"1"` → `"1.1"` (2026-09-18) |
45
47
  | New theme or recipe shipped | `prism` family added; `mobile-nav` recipe added |
46
48
  | New utility class (`.cia-*`) | `.cia-text-balance` added |
47
49
 
@@ -68,6 +70,8 @@ While the library was pre-1.0 (`0.x.x`), the rules above applied with one carve-
68
70
 
69
71
  **`1.0.0` locked the contract** (cut 2026-08-17). Breaking changes now require a MAJOR bump, no exceptions.
70
72
 
73
+ `npm run check:contract` (CI-gated since 2026-09-18) diffs `scripts/theme-contract.json` against the last release tag and fails the build when the required/optional lists change without the version bump these tables demand. It exists because 1.12.0 shipped a new *required* token in a MINOR and nothing caught it until a consumer's validator broke.
74
+
71
75
  ---
72
76
 
73
77
  ## 3. Deprecation policy
package/dist/tokens.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Generated from scripts/theme-contract.json on 2026-09-17.
1
+ // Generated from scripts/theme-contract.json on 2026-09-18.
2
2
  // Do not edit by hand. Run `npm run build:token-types` to regenerate.
3
3
 
4
4
  /** Every CSS custom property cia themes are required to declare. */
@@ -94,7 +94,6 @@ export type CiaToken =
94
94
  | "--shadow-xl"
95
95
  | "--shu"
96
96
  | "--shu-wash"
97
- | "--space-unit"
98
97
  | "--space-0"
99
98
  | "--space-1"
100
99
  | "--space-2"
@@ -225,7 +224,6 @@ export interface CiaTokenMap {
225
224
  "--shadow-xl": string;
226
225
  "--shu": string;
227
226
  "--shu-wash": string;
228
- "--space-unit": string;
229
227
  "--space-0": string;
230
228
  "--space-1": string;
231
229
  "--space-2": string;
@@ -265,4 +263,4 @@ export interface CiaTokenMap {
265
263
  }
266
264
 
267
265
  /** Count of required tokens in the current contract. */
268
- export declare const CIA_TOKEN_COUNT: 128;
266
+ export declare const CIA_TOKEN_COUNT: 127;
package/llm.txt CHANGED
@@ -50,7 +50,7 @@ silent.
50
50
  - **6 zero-JS interactive components** — accordion (`<details name>`), modal (`<dialog>`), tooltip (`popover="hint"`), dropdown (`[popover]` — the mixin re-asserts the UA's closed state and restores `display: flex` only under `:popover-open`, so menus never render permanently open on popover markup), tabs (radio + `:has()`), copy-button (Clipboard API via consumer-wired JS).
51
51
  - **CLI** (`npx cia`) — `migrate tailwind|bootstrap` (config → cia theme), `add <recipe>` (copy a recipe from the book into the project), `analyze [path]` (audit stylesheets against the installed API: dead `cia.*` symbols, the `space()` 1–9 trap, off-contract tokens (near-miss typos of real tokens only, never your own custom tokens), hard-coded hex, BEM; health score, CI exit codes). Low-noise on color: a hex in a `var(--token, #hex)` fallback is token-driven and a literal inside `@media print` is an intentional paper colour — neither is flagged.
52
52
  - **Mobile navigation family** — `cia.hamburger` / `cia.drawer` / `cia.sheet` / `cia.dock` ride `[popover]` + CSS Grid, zero JS; recipes `mobile-nav` (hamburger + drawer) and `bottom-nav` (dock + sheets). House rule: **on phones things take the space they're in** — a `cia.dropdown` menu opens 1px under its full-width trigger at the trigger's exact width via CSS anchor positioning (`position-try-fallbacks: flip-block` flips it above at the screen bottom; set `width: auto` at `&[popover]` specificity or the UA's `[popover] { width: fit-content }` and the mixin's inset reset win). Full spec: AGENTS.md quick decision #8 and `/docs/mobile`.
53
- - **163 contract tokens — 127 required + 36 optional** — surfaces, ink, lines, colors, type, radius, shadow, blur, glow, motion, z-index, spacing, semantic aliases.
53
+ - **168 contract tokens — 127 required + 41 optional** — surfaces, ink, lines, colors, type, radius, shadow, blur, glow, motion, z-index, spacing, semantic aliases.
54
54
  - **Spacing is themeable, and the numbered scale is the knob.** Themes declare `--space-0` … `--space-9` (contract-required). The t-shirt names (`--space-md`, `--space-lg` …) are contract-OPTIONAL and emitted by the library as `var()` aliases onto the numbered steps. `space(4)` compiles to `var(--space-4)`, so **theme the numbered step, never the alias** — setting `--space-md` alone leaves every component untouched. Library defaults emit under `:where(:root)` (specificity 0,0,0) so any theme declaration outranks them regardless of load order.
55
55
  - **Per-component shape knobs are `--btn-radius`, `--card-radius`, `--input-radius`, `--modal-radius`, `--badge-radius`, `--tag-radius`** — they cascade from the generic radii (`--btn-radius: var(--radius-md, 0.25rem)`). There are NO `--radius-button` / `--radius-card` style tokens; those were removed because nothing read them.
56
56
  - **Icons — two systems.** `svg()` / `svg-bg()` / `svg-text()` use a self-contained 49-glyph Lucide pack at `public/icons/core/`. Adding a glyph is drop-in: put `star.svg` in the folder and `cia.icon-svg(star)` works, no registration. Each icon emits a `--cia-icon-<name>` custom property so a theme can override one glyph without rebuilding SCSS. **`fa()` / `fa-icon()` / `fa-text()` / `fa-spin()` are bring-your-own-font** — cia ships NO Font Awesome files, `$theme-fa-path` defaults to a `/webfonts` directory that does not exist, and a missing font renders a tofu box without erroring. Default to `svg()` unless the user says they use Font Awesome.
@@ -104,7 +104,7 @@ Newspaper by day, hacker terminal by night. Most design systems give you dark mo
104
104
  | Mobile playbook (layouts, dropdown doctrine, lessons) | `src/app/docs/mobile/page.tsx` |
105
105
  | Browser support matrix (Baseline floor + progressive tiers) | `src/app/docs/browser-support/page.tsx` |
106
106
  | Theme authoring (full walkthrough) | `src/app/docs/authoring/themes/page.tsx` |
107
- | Theme contract (127 required + 36 optional, machine-readable) | `scripts/theme-contract.json` |
107
+ | Theme contract (127 required + 41 optional, machine-readable) | `scripts/theme-contract.json` |
108
108
  | Theme pairing (`<link media>` recipe) | `src/app/docs/themes/pairing/page.tsx` |
109
109
  | CopyButton JS recipe | `src/app/docs/recipes/copy-button/page.tsx` |
110
110
  | Anchor positioning recipe | `src/app/docs/recipes/anchor-positioning/page.tsx` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-is-awesome",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
4
4
  "description": "A token-driven SCSS design system with light/dark theming, semantic color tokens, and a 800+ LOC mixin API.",
5
5
  "homepage": "https://github.com/Jerry2d3d/css-is-awesome#readme",
6
6
  "bugs": {
@@ -90,7 +90,6 @@
90
90
  "THEMING.md",
91
91
  "MIGRATION.md",
92
92
  "CONTRACT.md",
93
- "ROADMAP.md",
94
93
  "VERSIONING.md",
95
94
  "scripts/prepare-dist.mjs"
96
95
  ],
@@ -130,8 +129,11 @@
130
129
  "prepare": "node scripts/prepare-dist.mjs",
131
130
  "prepublishOnly": "npm run build:css:all",
132
131
  "check:theme-drift": "node scripts/check-theme-drift.mjs",
132
+ "check:contract": "node scripts/check-contract-growth.mjs",
133
133
  "check:token-consumers": "node scripts/check-token-consumer-map.mjs",
134
- "check:rtl": "node scripts/audit-logical-properties.mjs"
134
+ "check:rtl": "node scripts/audit-logical-properties.mjs",
135
+ "prebuild": "node scripts/build-playground-scss-map.mjs",
136
+ "verify:playground": "node scripts/build-playground-scss-map.mjs && node scripts/verify-playground-compile.mjs"
135
137
  },
136
138
  "keywords": [
137
139
  "css",
@@ -172,6 +174,12 @@
172
174
  },
173
175
  "devDependencies": {
174
176
  "@axe-core/playwright": "^4.11.2",
177
+ "@codemirror/commands": "6.11.1",
178
+ "@codemirror/lang-html": "6.4.12",
179
+ "@codemirror/lang-sass": "6.0.2",
180
+ "@codemirror/language": "6.12.4",
181
+ "@codemirror/state": "6.7.5",
182
+ "@codemirror/view": "6.43.12",
175
183
  "@eslint/eslintrc": "^3.2.0",
176
184
  "@modelcontextprotocol/sdk": "^1.29.0",
177
185
  "@playwright/test": "^1.59.1",
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1",
3
- "description": "Authoritative token contract for css-is-awesome themes. Every theme.css MUST declare every token in `required`. Source of truth is CONTRACT.md (human-readable) and public/theme.css (Sketchbook reference).",
2
+ "version": "1.1",
3
+ "description": "Authoritative token contract for css-is-awesome themes. Every theme.css MUST declare every token in `required`. Tokens in `optional` are reported by the validator as info, never as failures \u2014 the library or the theme generator supplies a default. Source of truth is CONTRACT.md (human-readable) and public/theme.css (Sketchbook reference). Contract 1.1 (2026-09-18): --space-unit relaxed from required to optional; it had been added as required in library 1.12.0, which VERSIONING.md forbids in a MINOR.",
4
4
  "required": [
5
5
  "--action-primary-active",
6
6
  "--action-primary-default",
@@ -93,7 +93,6 @@
93
93
  "--shadow-xl",
94
94
  "--shu",
95
95
  "--shu-wash",
96
- "--space-unit",
97
96
  "--space-0",
98
97
  "--space-1",
99
98
  "--space-2",
@@ -168,6 +167,7 @@
168
167
  "--space-lg",
169
168
  "--space-md",
170
169
  "--space-sm",
170
+ "--space-unit",
171
171
  "--space-xl",
172
172
  "--space-xs",
173
173
  "--tag-radius",