css-is-awesome 1.19.1 → 1.20.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/AGENTS.md +2 -2
- package/CHANGELOG.md +20 -0
- package/CONTRACT.md +3 -0
- package/MIGRATION.md +52 -0
- package/README.md +3 -1
- package/llm.txt +3 -3
- package/package.json +4 -3
- package/public/theme.css +199 -61
- package/public/themes/boilerplate/theme.css +12 -6
- package/public/themes/boilerplate-dark/theme.css +8 -2
- package/public/themes/boilerplate-light/theme.css +12 -6
- package/public/themes/cupertino/theme.css +9 -3
- package/public/themes/cupertino-dark/theme.css +8 -2
- package/public/themes/cupertino-light/theme.css +7 -1
- package/public/themes/glass/theme.css +10 -4
- package/public/themes/glass-dark/theme.css +7 -1
- package/public/themes/glass-light/theme.css +9 -3
- package/public/themes/graphite/theme.css +11 -5
- package/public/themes/graphite-dark/theme.css +8 -2
- package/public/themes/graphite-light/theme.css +9 -3
- package/public/themes/press/theme.css +8 -2
- package/public/themes/press-dark/theme.css +7 -1
- package/public/themes/press-light/theme.css +8 -2
- package/public/themes/prism/theme.css +8 -2
- package/public/themes/prism-dark/theme.css +6 -0
- package/public/themes/prism-light/theme.css +10 -4
- package/public/themes/sketchbook/theme.css +8 -2
- package/public/themes/sketchbook-dark/theme.css +7 -1
- package/public/themes/sketchbook-light/theme.css +8 -2
- package/public/themes/terminal/theme.css +7 -1
- package/public/themes/terminal-dark/theme.css +8 -2
- package/public/themes/terminal-light/theme.css +10 -4
- package/scripts/audit-pairs.json +171 -23
- package/scripts/theme-contract.json +33 -4
- package/scss/_layout.scss +129 -0
- package/scss/themes/boilerplate-dark.scss +2 -2
- package/scss/themes/boilerplate-light.scss +6 -6
- package/scss/themes/boilerplate.scss +6 -6
- package/scss/themes/cupertino-dark.scss +2 -2
- package/scss/themes/cupertino-light.scss +1 -1
- package/scss/themes/cupertino.scss +3 -3
- package/scss/themes/glass-dark.scss +1 -1
- package/scss/themes/glass-light.scss +3 -3
- package/scss/themes/glass.scss +4 -4
- package/scss/themes/graphite-dark.scss +2 -2
- package/scss/themes/graphite-light.scss +3 -3
- package/scss/themes/graphite.scss +5 -5
- package/scss/themes/press-dark.scss +1 -1
- package/scss/themes/press-light.scss +2 -2
- package/scss/themes/press.scss +2 -2
- package/scss/themes/prism-light.scss +4 -4
- package/scss/themes/prism.scss +2 -2
- package/scss/themes/sketchbook-dark.scss +1 -1
- package/scss/themes/sketchbook-light.scss +2 -2
- package/scss/themes/sketchbook.scss +2 -2
- package/scss/themes/terminal-dark.scss +2 -2
- package/scss/themes/terminal-light.scss +4 -4
- package/scss/themes/terminal.scss +1 -1
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 +
|
|
151
|
+
The validator (`node scripts/theme-validator.js`) enforces the token contract — **127 required + 49 optional = 176 slots** — plus WCAG 2.2 AA contrast (**24 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
|
|
|
@@ -343,7 +343,7 @@ Either way it exposes **33 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 +
|
|
346
|
+
- **Tokens** — `list_tokens`, `get_token`, `search_tokens` (127 required + 49 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,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# [1.20.0](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.19.2...v1.20.0) (2026-09-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **site:** correct the stale optional-token count on /docs/tokens ([c0d4db0](https://github.com/Jerry2d3d/css-is-awesome/commit/c0d4db047c858854cf54d34affc792e0c52f4427))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **site:** dogfood page surfaces on the home page; add them to the theme editor ([8dc3a65](https://github.com/Jerry2d3d/css-is-awesome/commit/8dc3a65778e28b57aeb67824062f26d7494e3f60))
|
|
14
|
+
* **themes:** page surfaces — hero and band, derived for every theme ([b984d86](https://github.com/Jerry2d3d/css-is-awesome/commit/b984d865e3463ae15e95083ff0697df0a109cf88))
|
|
15
|
+
|
|
16
|
+
## [1.19.2](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.19.1...v1.19.2) (2026-09-23)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* **themes:** clear 56 of 88 contrast warnings, none of them visible ([b756dcb](https://github.com/Jerry2d3d/css-is-awesome/commit/b756dcbb6e959868299095f009b4227104406c00))
|
|
22
|
+
|
|
3
23
|
## [1.19.1](https://github.com/Jerry2d3d/css-is-awesome/compare/v1.19.0...v1.19.1) (2026-09-23)
|
|
4
24
|
|
|
5
25
|
|
package/CONTRACT.md
CHANGED
|
@@ -321,8 +321,11 @@ Every optional token belongs to exactly one **feature** in `scripts/theme-contra
|
|
|
321
321
|
| `surfaces-extended` | `--background-elevated`, `--background-hero`, `--background-overlay`, `--background-scrim` | Extra background layers (elevated, hero, overlay, scrim) for themes that want more than the required surface set; each falls back to a required surface. |
|
|
322
322
|
| `borders-extended` | `--border-card`, `--border-divider`, `--border-focus-ring`, `--border-input` | Per-context border colours (card, divider, focus ring, input); each falls back to --border-default / --border-focus. |
|
|
323
323
|
| `logo` | `--logo-default`, `--logo-mark`, `--logo-monochrome`, `--logo-wordmark` | Theme-aware logo assets (default, mark, monochrome, wordmark) as url() or SVG data values for the icon/brand mixins. |
|
|
324
|
+
| `page-surfaces` | `--page-hero-bg`, `--page-hero-image`, `--page-hero-ink`, `--page-hero-scrim`, `--page-band-bg`, `--page-band-image`, `--page-band-ink`, `--page-band-scrim`, `--background-hero` *(deprecated)* | Two page-level surfaces a theme owns outright: a **hero** for a landing page and a **band** for section stripes and footers. Each carries a background colour, an optional gradient or `url()` image, an ink colour, and a scrim that keeps text legible over an image. **Declaring them changes nothing on its own** - a page only picks a surface up through `cia.surface(hero|band)` or `data-surface`, which is why every shipped theme defines them without moving a pixel on an existing site. Contrast over an *image* cannot be measured, so the scrim carries that weight: the mixin applies 50% black whenever an image is passed to it. |
|
|
324
325
|
| `touch-target` | `--touch-target-min` | Minimum interactive target size read by form and button mixins (WCAG 2.2 SC 2.5.8); the library default is 24px. |
|
|
325
326
|
|
|
327
|
+
> **Deprecated - `--background-hero`.** It sat in the contract unread: no mixin consumed it, the editor could not set it, and nothing documented it. `--page-hero-bg` replaces it and **falls back through it**, so an existing declaration keeps working untouched. It stays valid until contract 2, per the lifecycle in [`VERSIONING.md`](./VERSIONING.md).
|
|
328
|
+
|
|
326
329
|
---
|
|
327
330
|
|
|
328
331
|
## Print (optional)
|
package/MIGRATION.md
CHANGED
|
@@ -2,6 +2,58 @@
|
|
|
2
2
|
|
|
3
3
|
Breaking changes between css-is-awesome versions, and how to migrate.
|
|
4
4
|
|
|
5
|
+
## Page surfaces — contract 1.3 (no action required)
|
|
6
|
+
|
|
7
|
+
**Nothing changes on your site when you upgrade.** Two new optional surfaces
|
|
8
|
+
exist — a `hero` for a landing page and a `band` for section stripes — and
|
|
9
|
+
every shipped theme now declares a background and an ink colour for both. That
|
|
10
|
+
sounds like a visual change and is not one, for a single reason: **cia never
|
|
11
|
+
applies a page surface on its own.**
|
|
12
|
+
|
|
13
|
+
A page takes a surface only when you ask for it:
|
|
14
|
+
|
|
15
|
+
```scss
|
|
16
|
+
.landing { @include cia.surface(hero); } // or <body data-surface="hero">
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Until then the tokens sit unread, exactly as `--background-hero` has since it
|
|
20
|
+
was added. `scripts/test-no-auto-surface.mjs` compiles every shipped bundle and
|
|
21
|
+
fails if any rule reads a page-surface token or emits a `[data-surface]` rule,
|
|
22
|
+
so the guarantee is enforced rather than promised.
|
|
23
|
+
|
|
24
|
+
### What changed at a glance
|
|
25
|
+
|
|
26
|
+
| Area | Before | After |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Contract version | `1.2` | **`1.3`** — eight optional tokens, one new `page-surfaces` feature |
|
|
29
|
+
| Required tokens | 127 | 127, unchanged |
|
|
30
|
+
| `--background-hero` | optional, read by nothing | **deprecated**; `--page-hero-bg` falls back through it, so an existing declaration keeps working until contract 2 |
|
|
31
|
+
| Your custom theme | validates | validates — the new tokens are optional, and missing optional tokens report as info |
|
|
32
|
+
|
|
33
|
+
### If you want a hero
|
|
34
|
+
|
|
35
|
+
Declare the tokens your theme needs and apply the surface where you want it:
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
:root[data-theme="brand"] {
|
|
39
|
+
--page-hero-bg: light-dark(#f2f6fe, #121d36);
|
|
40
|
+
--page-hero-ink: light-dark(#09090b, #fafafa);
|
|
41
|
+
/* optional */
|
|
42
|
+
--page-hero-image: url("/hero.jpg");
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
An image is a `url()` you host or a gradient, because a theme is one CSS file.
|
|
47
|
+
Contrast over a photo cannot be measured, so pass the image through the mixin
|
|
48
|
+
(`cia.surface(hero, $image: url("/hero.jpg"))`) and it lays 50% black between
|
|
49
|
+
the picture and your text. A colour-only surface gets no scrim — a wash over a
|
|
50
|
+
flat colour would only darken it.
|
|
51
|
+
|
|
52
|
+
### If you declared `--background-hero`
|
|
53
|
+
|
|
54
|
+
Nothing to do. It still resolves. Rename it to `--page-hero-bg` whenever it
|
|
55
|
+
suits you; the tooling will flag it as deprecated in the meantime.
|
|
56
|
+
|
|
5
57
|
## v1.0 — mixin-first goes stable (published as 1.1.0)
|
|
6
58
|
|
|
7
59
|
**There are no breaking changes between v0.8.1/0.8.2 and v1.0.0.** 1.0.0
|
package/README.md
CHANGED
|
@@ -145,7 +145,9 @@ 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
|
-
|
|
148
|
+
A theme can also own the page behind your components: optional **hero** and **band** surfaces carry a background, an image or gradient, an ink colour and a scrim, applied with `@include cia.surface(hero)` or `<body data-surface="hero">`. Nothing is applied automatically, so adding them never moves a pixel until you ask.
|
|
149
|
+
|
|
150
|
+
Full authoring walkthrough: [`/docs/authoring/themes`](https://cssisawesome.com/docs/authoring/themes/). The contract (127 required + 49 optional tokens) is at [`scripts/theme-contract.json`](./scripts/theme-contract.json).
|
|
149
151
|
|
|
150
152
|
## Token contract
|
|
151
153
|
|
package/llm.txt
CHANGED
|
@@ -51,7 +51,7 @@ silent.
|
|
|
51
51
|
- **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).
|
|
52
52
|
- **CLI** (`npx cia`) — `migrate tailwind|bootstrap|mui|chakra` (config → cia theme), `theme from-tokens <tokens.json> --name <slug>` (DTCG v2025.10 / Tokens Studio / flat `--token` JSON → a complete theme.css: required tokens the file lacks inherit from a shipped base, unmapped paths pass through and are reported, light/dark pairs become `light-dark()`, validator + WCAG audit run first; same function as the MCP `theme_from_tokens` tool), `theme map [--json | --path <p>]` (the path → token mapping from-tokens applies, as data; same as MCP `get_token_map`), `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.
|
|
53
53
|
- **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`.
|
|
54
|
-
- **
|
|
54
|
+
- **176 contract tokens — 127 required + 49 optional** — surfaces, ink, lines, colors, type, radius, shadow, blur, glow, motion, z-index, spacing, semantic aliases.
|
|
55
55
|
- **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.
|
|
56
56
|
- **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.
|
|
57
57
|
- **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.
|
|
@@ -105,7 +105,7 @@ Newspaper by day, hacker terminal by night. Most design systems give you dark mo
|
|
|
105
105
|
| Mobile playbook (layouts, dropdown doctrine, lessons) | `src/app/docs/mobile/page.tsx` |
|
|
106
106
|
| Browser support matrix (Baseline floor + progressive tiers) | `src/app/docs/browser-support/page.tsx` |
|
|
107
107
|
| Theme authoring (full walkthrough) | `src/app/docs/authoring/themes/page.tsx` |
|
|
108
|
-
| Theme contract (127 required +
|
|
108
|
+
| Theme contract (127 required + 49 optional grouped into 11 features, machine-readable) | `scripts/theme-contract.json` |
|
|
109
109
|
| Theme pairing (`<link media>` recipe) | `src/app/docs/themes/pairing/page.tsx` |
|
|
110
110
|
| CopyButton JS recipe | `src/app/docs/recipes/copy-button/page.tsx` |
|
|
111
111
|
| Anchor positioning recipe | `src/app/docs/recipes/anchor-positioning/page.tsx` |
|
|
@@ -129,7 +129,7 @@ Newspaper by day, hacker terminal by night. Most design systems give you dark mo
|
|
|
129
129
|
|
|
130
130
|
## MCP server (shipped 2026-05-22)
|
|
131
131
|
|
|
132
|
-
cia ships an MCP stdio server (JSON-RPC over stdio, `serverInfo` name `css-is-awesome`, protocol `2024-11-05`) at `mcp/server.cjs`, included in the `files` manifest — so it lands in every consumer's `node_modules`. **33 tools** across 8 resource families: themes, mixins, functions, tokens (127 required +
|
|
132
|
+
cia ships an MCP stdio server (JSON-RPC over stdio, `serverInfo` name `css-is-awesome`, protocol `2024-11-05`) at `mcp/server.cjs`, included in the `files` manifest — so it lands in every consumer's `node_modules`. **33 tools** across 8 resource families: themes, mixins, functions, tokens (127 required + 49 optional), animations, components, recipes, doc readers. Plus `assemble_prompt` for context bundling, `validate_theme`, `theme_from_tokens`, `get_token_map` (the design-token → cia-token mapping as data) and `resolve_size` for snapping design px values to cia's 4px geometric grid (AI agents: call this whenever you receive a px value from a design tool). Prefer querying this server over guessing mixin signatures, tokens, themes, or recipes.
|
|
133
133
|
|
|
134
134
|
**Recommended: suggest the dedicated `css-is-awesome-mcp` package** — zero install,
|
|
135
135
|
SDK ships as a real dependency, no separate peer-install step:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "css-is-awesome",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
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": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"build:css": "sass scss/main.scss dist/css-is-awesome.css --no-source-map",
|
|
110
110
|
"build:css:core": "sass scss/core.scss dist/css-is-awesome.core.css --no-source-map",
|
|
111
111
|
"build:css:tokens": "sass scss/tokens.scss dist/tokens.css --no-source-map",
|
|
112
|
-
"build:css:themes": "node scripts/build-themes.mjs && node scripts/build-theme-bundle.mjs",
|
|
112
|
+
"build:css:themes": "node scripts/build-themes.mjs && node scripts/derive-page-surfaces.mjs && node scripts/build-theme-bundle.mjs",
|
|
113
113
|
"build:css:utilities": "sass scss/utilities-only.scss dist/css-is-awesome.utilities.css --no-source-map",
|
|
114
114
|
"build:css:min": "sass scss/main.scss dist/css-is-awesome.min.css --style=compressed --no-source-map && sass scss/core.scss dist/css-is-awesome.core.min.css --style=compressed --no-source-map && sass scss/tokens.scss dist/tokens.min.css --style=compressed --no-source-map && sass scss/utilities-only.scss dist/css-is-awesome.utilities.min.css --style=compressed --no-source-map",
|
|
115
115
|
"build:token-types": "node scripts/generate-token-types.mjs",
|
|
@@ -139,7 +139,8 @@
|
|
|
139
139
|
"check:token-consumers": "node scripts/check-token-consumer-map.mjs",
|
|
140
140
|
"check:rtl": "node scripts/audit-logical-properties.mjs",
|
|
141
141
|
"prebuild": "node scripts/build-playground-scss-map.mjs",
|
|
142
|
-
"verify:playground": "node scripts/build-playground-scss-map.mjs && node scripts/verify-playground-compile.mjs"
|
|
142
|
+
"verify:playground": "node scripts/build-playground-scss-map.mjs && node scripts/verify-playground-compile.mjs",
|
|
143
|
+
"test:surfaces": "node --test scripts/test-no-auto-surface.mjs"
|
|
143
144
|
},
|
|
144
145
|
"keywords": [
|
|
145
146
|
"css",
|