@codenhub/styles 0.7.0 → 0.9.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.
Files changed (130) hide show
  1. package/README.es.md +9 -8
  2. package/README.md +8 -7
  3. package/README.pt-BR.md +9 -8
  4. package/dist/aesthetics/chunky-tile.css +1 -1
  5. package/dist/aesthetics/cyber.css +1 -1
  6. package/dist/aesthetics/glass.css +1 -1
  7. package/dist/aesthetics/index.css +2 -2
  8. package/dist/aesthetics/neobrutalism.css +1 -1
  9. package/dist/aesthetics/pixel.css +1 -1
  10. package/dist/aesthetics/sketch.css +1 -1
  11. package/dist/cli.js +358 -0
  12. package/dist/components.css +50 -2
  13. package/dist/index.css +50 -2
  14. package/dist/index.d.ts +1 -0
  15. package/dist/native.css +50 -2
  16. package/dist/palette.css +1 -1
  17. package/dist/purge/classes.json +1 -0
  18. package/dist/purge/index.css +50 -0
  19. package/dist/theme.css +2 -2
  20. package/docs/accessibility.md +46 -27
  21. package/docs/changelog/0.8.0.md +70 -0
  22. package/docs/changelog/0.9.0.md +40 -0
  23. package/docs/changelog/index.md +2 -0
  24. package/docs/es/accessibility.md +47 -28
  25. package/docs/es/index.md +4 -3
  26. package/docs/es/integrating/index.md +38 -10
  27. package/docs/es/integrating/tailwind.md +79 -8
  28. package/docs/es/integrating/without-a-bundler.md +157 -5
  29. package/docs/es/setup.md +43 -34
  30. package/docs/es/usage/aesthetics.md +20 -14
  31. package/docs/es/usage/buttons.md +6 -2
  32. package/docs/es/usage/composing.md +6 -2
  33. package/docs/es/usage/content-and-layout.md +10 -4
  34. package/docs/es/usage/customizing.md +46 -26
  35. package/docs/es/usage/feedback.md +5 -1
  36. package/docs/es/usage/forms.md +30 -5
  37. package/docs/es/usage/index.md +7 -3
  38. package/docs/es/usage/presets.md +92 -0
  39. package/docs/es/usage/solo.md +4 -2
  40. package/docs/es/usage/theming.md +29 -16
  41. package/docs/es/usage/tooltips.md +2 -2
  42. package/docs/index.md +3 -2
  43. package/docs/integrating/index.md +38 -10
  44. package/docs/integrating/tailwind.md +78 -7
  45. package/docs/integrating/without-a-bundler.md +156 -4
  46. package/docs/pt-BR/accessibility.md +47 -28
  47. package/docs/pt-BR/index.md +4 -3
  48. package/docs/pt-BR/integrating/index.md +38 -10
  49. package/docs/pt-BR/integrating/tailwind.md +79 -8
  50. package/docs/pt-BR/integrating/without-a-bundler.md +157 -5
  51. package/docs/pt-BR/setup.md +43 -34
  52. package/docs/pt-BR/usage/aesthetics.md +20 -14
  53. package/docs/pt-BR/usage/buttons.md +6 -2
  54. package/docs/pt-BR/usage/composing.md +6 -2
  55. package/docs/pt-BR/usage/content-and-layout.md +10 -4
  56. package/docs/pt-BR/usage/customizing.md +46 -26
  57. package/docs/pt-BR/usage/feedback.md +5 -1
  58. package/docs/pt-BR/usage/forms.md +30 -5
  59. package/docs/pt-BR/usage/index.md +7 -3
  60. package/docs/pt-BR/usage/presets.md +92 -0
  61. package/docs/pt-BR/usage/solo.md +4 -2
  62. package/docs/pt-BR/usage/theming.md +22 -9
  63. package/docs/pt-BR/usage/tooltips.md +2 -2
  64. package/docs/setup.md +31 -22
  65. package/docs/usage/aesthetics.md +19 -13
  66. package/docs/usage/buttons.md +5 -1
  67. package/docs/usage/composing.md +5 -1
  68. package/docs/usage/content-and-layout.md +9 -3
  69. package/docs/usage/customizing.md +45 -25
  70. package/docs/usage/feedback.md +4 -0
  71. package/docs/usage/forms.md +29 -4
  72. package/docs/usage/index.md +6 -2
  73. package/docs/usage/presets.md +91 -0
  74. package/docs/usage/solo.md +3 -1
  75. package/docs/usage/theming.md +21 -8
  76. package/docs/usage/tooltips.md +1 -1
  77. package/llms-full.txt +695 -134
  78. package/llms.txt +3 -2
  79. package/package.json +117 -65
  80. package/{dist/tw → tw}/aesthetics/chunky-tile.css +43 -20
  81. package/{dist/tw → tw}/aesthetics/cyber.css +19 -25
  82. package/{dist/tw → tw}/aesthetics/glass.css +110 -36
  83. package/{dist/tw → tw}/aesthetics/neobrutalism.css +41 -21
  84. package/{dist/tw → tw}/aesthetics/pixel.css +3 -0
  85. package/tw/aesthetics/sketch.css +435 -0
  86. package/{dist/tw → tw}/box.css +109 -26
  87. package/tw/components/button.css +11 -0
  88. package/tw/components/button.rules.css +187 -0
  89. package/tw/components/feedback.css +11 -0
  90. package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +156 -33
  91. package/tw/components/form.css +11 -0
  92. package/{dist/tw/components/form.css → tw/components/form.rules.css} +584 -141
  93. package/tw/components/index.css +16 -0
  94. package/tw/components/rules.css +41 -0
  95. package/tw/components/surface.css +11 -0
  96. package/tw/components/surface.rules.css +225 -0
  97. package/tw/components/tooltip.css +11 -0
  98. package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +82 -61
  99. package/{dist/tw → tw}/corner.css +18 -12
  100. package/{dist/tw → tw}/elevation.css +27 -21
  101. package/{dist/tw → tw}/index.css +11 -9
  102. package/tw/index.d.ts +1 -0
  103. package/tw/intent.css +312 -0
  104. package/tw/modifiers.css +127 -0
  105. package/tw/native.css +323 -0
  106. package/tw/presentation.css +139 -0
  107. package/tw/reset.css +10 -0
  108. package/{dist/tw/reset.css → tw/reset.rules.css} +7 -8
  109. package/tw/size.css +34 -0
  110. package/tw/surface.css +9 -0
  111. package/tw/surface.rules.css +212 -0
  112. package/{dist/tw → tw}/theme.css +93 -29
  113. package/tw/typography.css +8 -0
  114. package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
  115. package/{dist/tw → tw}/utilities/content.css +248 -108
  116. package/tw/utilities/index.css +11 -0
  117. package/tw/utilities/layout.css +210 -0
  118. package/tw/utilities/rules.css +8 -0
  119. package/dist/tw/aesthetics/sketch.css +0 -398
  120. package/dist/tw/components/button.css +0 -139
  121. package/dist/tw/components/index.css +0 -35
  122. package/dist/tw/components/surface.css +0 -184
  123. package/dist/tw/intent.css +0 -229
  124. package/dist/tw/native.css +0 -203
  125. package/dist/tw/palette.css +0 -460
  126. package/dist/tw/presentation.css +0 -68
  127. package/dist/tw/surface.css +0 -61
  128. package/dist/tw/utilities/index.css +0 -6
  129. package/dist/tw/utilities/layout.css +0 -144
  130. /package/{dist/tw → tw}/aesthetics/index.css +0 -0
package/llms.txt CHANGED
@@ -17,7 +17,7 @@ is what the public docs describe and the demo at https://demo.codenhub.dev/style
17
17
  - [Vue](./docs/integrating/vue.md): Importing the stylesheet in a Vue or Vite app.
18
18
  - [Svelte](./docs/integrating/svelte.md): Importing the stylesheet in a Svelte or SvelteKit app.
19
19
  - [Astro](./docs/integrating/astro.md): Importing the stylesheet in an Astro app.
20
- - [Without a bundler](./docs/integrating/without-a-bundler.md): Linking the compiled files from plain HTML, Rails, Django, or a CDN.
20
+ - [Without a bundler](./docs/integrating/without-a-bundler.md): Linking the compiled files from plain HTML, Rails, Django, or a CDN, and the `chs build` command that writes a stylesheet with only the classes your templates use.
21
21
  - [Building a screen](./docs/concepts.md): Layout, type, cards, and buttons, and the model behind them: intent, fill, edge, aesthetic, and what passes down to children.
22
22
  - [Usage overview](./docs/usage/index.md): The task guides in order, then the lookup pages.
23
23
  - [Buttons](./docs/usage/buttons.md): Destructive and secondary actions, icon buttons, sizes, link buttons, disabled states, and loading icons.
@@ -28,7 +28,8 @@ is what the public docs describe and the demo at https://demo.codenhub.dev/style
28
28
  - [Aesthetics](./docs/usage/aesthetics.md): The six optional looks, what each changes, its knobs, and its limits.
29
29
  - [Solo classes](./docs/usage/solo.md): Painting an aesthetic onto one element from another library, and what a solo class reads and ignores.
30
30
  - [Composing](./docs/usage/composing.md): Lookup for combining classes, every component's default look, presentation rules, the component axis matrix, and elevation.
31
- - [Customizing](./docs/usage/customizing.md): Lookup for presentation and material tokens, aesthetic knobs, the six public component variables, the generated palette, and composition helpers.
31
+ - [Customizing](./docs/usage/customizing.md): Lookup for presentation and material tokens, aesthetic knobs, the public component variables, the generated palette, and composition helpers.
32
32
  - [Content and layout](./docs/usage/content-and-layout.md): Lookup for layout helpers, the type scale, cards and panels, tables, quotes, code, and keys.
33
+ - [Presets](./docs/usage/presets.md): Three ways to set a look once instead of on every element, and when to reach for each.
33
34
  - [Accessibility](./docs/accessibility.md): What the CSS provides for focus, states, motion, contrast, forced colors, and right-to-left text, and what the application must add.
34
35
  - [Changelog](./docs/changelog/index.md): Release history, including breaking changes.
package/package.json CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "@codenhub/styles",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "private": false,
5
5
  "description": "Build a consistent, themeable interface by writing class names on plain HTML, with one stylesheet of tokens, a reset, layout and type helpers, and component classes, and no JavaScript.",
6
- "homepage": "https://github.com/codenhub/codenhub/tree/main/packages/styles",
6
+ "homepage": "https://codenhub.dev/packages/styles/",
7
7
  "license": "Apache-2.0",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/codenhub/codenhub.git",
11
11
  "directory": "packages/styles"
12
12
  },
13
+ "bin": {
14
+ "chs": "./dist/cli.js"
15
+ },
13
16
  "files": [
14
17
  "dist",
18
+ "tw",
15
19
  "NOTICE",
16
20
  "README.md",
17
21
  "docs",
@@ -22,158 +26,190 @@
22
26
  "sideEffects": [
23
27
  "**/*.css"
24
28
  ],
29
+ "types": "./dist/index.d.ts",
25
30
  "exports": {
26
31
  ".": {
32
+ "types": "./dist/index.d.ts",
27
33
  "style": "./dist/index.css",
28
34
  "import": "./dist/index.css",
29
35
  "default": "./dist/index.css"
30
36
  },
31
37
  "./theme": {
38
+ "types": "./dist/index.d.ts",
32
39
  "style": "./dist/theme.css",
33
40
  "import": "./dist/theme.css",
34
41
  "default": "./dist/theme.css"
35
42
  },
36
43
  "./palette": {
44
+ "types": "./dist/index.d.ts",
37
45
  "style": "./dist/palette.css",
38
46
  "import": "./dist/palette.css",
39
47
  "default": "./dist/palette.css"
40
48
  },
41
49
  "./components": {
50
+ "types": "./dist/index.d.ts",
42
51
  "style": "./dist/components.css",
43
52
  "import": "./dist/components.css",
44
53
  "default": "./dist/components.css"
45
54
  },
46
55
  "./aesthetics": {
56
+ "types": "./dist/index.d.ts",
47
57
  "style": "./dist/aesthetics/index.css",
48
58
  "import": "./dist/aesthetics/index.css",
49
59
  "default": "./dist/aesthetics/index.css"
50
60
  },
51
61
  "./aesthetics/neobrutalism": {
62
+ "types": "./dist/index.d.ts",
52
63
  "style": "./dist/aesthetics/neobrutalism.css",
53
64
  "import": "./dist/aesthetics/neobrutalism.css",
54
65
  "default": "./dist/aesthetics/neobrutalism.css"
55
66
  },
56
67
  "./aesthetics/glass": {
68
+ "types": "./dist/index.d.ts",
57
69
  "style": "./dist/aesthetics/glass.css",
58
70
  "import": "./dist/aesthetics/glass.css",
59
71
  "default": "./dist/aesthetics/glass.css"
60
72
  },
61
73
  "./aesthetics/pixel": {
74
+ "types": "./dist/index.d.ts",
62
75
  "style": "./dist/aesthetics/pixel.css",
63
76
  "import": "./dist/aesthetics/pixel.css",
64
77
  "default": "./dist/aesthetics/pixel.css"
65
78
  },
66
79
  "./aesthetics/chunky-tile": {
80
+ "types": "./dist/index.d.ts",
67
81
  "style": "./dist/aesthetics/chunky-tile.css",
68
82
  "import": "./dist/aesthetics/chunky-tile.css",
69
83
  "default": "./dist/aesthetics/chunky-tile.css"
70
84
  },
71
85
  "./aesthetics/cyber": {
86
+ "types": "./dist/index.d.ts",
72
87
  "style": "./dist/aesthetics/cyber.css",
73
88
  "import": "./dist/aesthetics/cyber.css",
74
89
  "default": "./dist/aesthetics/cyber.css"
75
90
  },
76
91
  "./aesthetics/sketch": {
92
+ "types": "./dist/index.d.ts",
77
93
  "style": "./dist/aesthetics/sketch.css",
78
94
  "import": "./dist/aesthetics/sketch.css",
79
95
  "default": "./dist/aesthetics/sketch.css"
80
96
  },
81
97
  "./tw": {
82
- "style": "./dist/tw/index.css",
83
- "import": "./dist/tw/index.css",
84
- "default": "./dist/tw/index.css"
98
+ "types": "./tw/index.d.ts",
99
+ "style": "./tw/index.css",
100
+ "import": "./tw/index.css",
101
+ "default": "./tw/index.css"
85
102
  },
86
103
  "./tw/theme": {
87
- "style": "./dist/tw/theme.css",
88
- "import": "./dist/tw/theme.css",
89
- "default": "./dist/tw/theme.css"
104
+ "types": "./tw/index.d.ts",
105
+ "style": "./tw/theme.css",
106
+ "import": "./tw/theme.css",
107
+ "default": "./tw/theme.css"
90
108
  },
91
109
  "./tw/components": {
92
- "style": "./dist/tw/components/index.css",
93
- "import": "./dist/tw/components/index.css",
94
- "default": "./dist/tw/components/index.css"
110
+ "types": "./tw/index.d.ts",
111
+ "style": "./tw/components/index.css",
112
+ "import": "./tw/components/index.css",
113
+ "default": "./tw/components/index.css"
95
114
  },
96
115
  "./tw/surface": {
97
- "style": "./dist/tw/components/surface.css",
98
- "import": "./dist/tw/components/surface.css",
99
- "default": "./dist/tw/components/surface.css"
116
+ "types": "./tw/index.d.ts",
117
+ "style": "./tw/components/surface.css",
118
+ "import": "./tw/components/surface.css",
119
+ "default": "./tw/components/surface.css"
100
120
  },
101
121
  "./tw/button": {
102
- "style": "./dist/tw/components/button.css",
103
- "import": "./dist/tw/components/button.css",
104
- "default": "./dist/tw/components/button.css"
122
+ "types": "./tw/index.d.ts",
123
+ "style": "./tw/components/button.css",
124
+ "import": "./tw/components/button.css",
125
+ "default": "./tw/components/button.css"
105
126
  },
106
127
  "./tw/form": {
107
- "style": "./dist/tw/components/form.css",
108
- "import": "./dist/tw/components/form.css",
109
- "default": "./dist/tw/components/form.css"
128
+ "types": "./tw/index.d.ts",
129
+ "style": "./tw/components/form.css",
130
+ "import": "./tw/components/form.css",
131
+ "default": "./tw/components/form.css"
110
132
  },
111
133
  "./tw/feedback": {
112
- "style": "./dist/tw/components/feedback.css",
113
- "import": "./dist/tw/components/feedback.css",
114
- "default": "./dist/tw/components/feedback.css"
134
+ "types": "./tw/index.d.ts",
135
+ "style": "./tw/components/feedback.css",
136
+ "import": "./tw/components/feedback.css",
137
+ "default": "./tw/components/feedback.css"
115
138
  },
116
139
  "./tw/tooltip": {
117
- "style": "./dist/tw/components/tooltip.css",
118
- "import": "./dist/tw/components/tooltip.css",
119
- "default": "./dist/tw/components/tooltip.css"
140
+ "types": "./tw/index.d.ts",
141
+ "style": "./tw/components/tooltip.css",
142
+ "import": "./tw/components/tooltip.css",
143
+ "default": "./tw/components/tooltip.css"
120
144
  },
121
145
  "./tw/reset": {
122
- "style": "./dist/tw/reset.css",
123
- "import": "./dist/tw/reset.css",
124
- "default": "./dist/tw/reset.css"
146
+ "types": "./tw/index.d.ts",
147
+ "style": "./tw/reset.css",
148
+ "import": "./tw/reset.css",
149
+ "default": "./tw/reset.css"
125
150
  },
126
151
  "./tw/native": {
127
- "style": "./dist/tw/native.css",
128
- "import": "./dist/tw/native.css",
129
- "default": "./dist/tw/native.css"
152
+ "types": "./tw/index.d.ts",
153
+ "style": "./tw/native.css",
154
+ "import": "./tw/native.css",
155
+ "default": "./tw/native.css"
130
156
  },
131
157
  "./tw/typography": {
132
- "style": "./dist/tw/typography.css",
133
- "import": "./dist/tw/typography.css",
134
- "default": "./dist/tw/typography.css"
158
+ "types": "./tw/index.d.ts",
159
+ "style": "./tw/typography.css",
160
+ "import": "./tw/typography.css",
161
+ "default": "./tw/typography.css"
135
162
  },
136
163
  "./tw/utilities": {
137
- "style": "./dist/tw/utilities/index.css",
138
- "import": "./dist/tw/utilities/index.css",
139
- "default": "./dist/tw/utilities/index.css"
164
+ "types": "./tw/index.d.ts",
165
+ "style": "./tw/utilities/index.css",
166
+ "import": "./tw/utilities/index.css",
167
+ "default": "./tw/utilities/index.css"
140
168
  },
141
169
  "./tw/aesthetics": {
142
- "style": "./dist/tw/aesthetics/index.css",
143
- "import": "./dist/tw/aesthetics/index.css",
144
- "default": "./dist/tw/aesthetics/index.css"
170
+ "types": "./tw/index.d.ts",
171
+ "style": "./tw/aesthetics/index.css",
172
+ "import": "./tw/aesthetics/index.css",
173
+ "default": "./tw/aesthetics/index.css"
145
174
  },
146
175
  "./tw/aesthetics/neobrutalism": {
147
- "style": "./dist/tw/aesthetics/neobrutalism.css",
148
- "import": "./dist/tw/aesthetics/neobrutalism.css",
149
- "default": "./dist/tw/aesthetics/neobrutalism.css"
176
+ "types": "./tw/index.d.ts",
177
+ "style": "./tw/aesthetics/neobrutalism.css",
178
+ "import": "./tw/aesthetics/neobrutalism.css",
179
+ "default": "./tw/aesthetics/neobrutalism.css"
150
180
  },
151
181
  "./tw/aesthetics/glass": {
152
- "style": "./dist/tw/aesthetics/glass.css",
153
- "import": "./dist/tw/aesthetics/glass.css",
154
- "default": "./dist/tw/aesthetics/glass.css"
182
+ "types": "./tw/index.d.ts",
183
+ "style": "./tw/aesthetics/glass.css",
184
+ "import": "./tw/aesthetics/glass.css",
185
+ "default": "./tw/aesthetics/glass.css"
155
186
  },
156
187
  "./tw/aesthetics/pixel": {
157
- "style": "./dist/tw/aesthetics/pixel.css",
158
- "import": "./dist/tw/aesthetics/pixel.css",
159
- "default": "./dist/tw/aesthetics/pixel.css"
188
+ "types": "./tw/index.d.ts",
189
+ "style": "./tw/aesthetics/pixel.css",
190
+ "import": "./tw/aesthetics/pixel.css",
191
+ "default": "./tw/aesthetics/pixel.css"
160
192
  },
161
193
  "./tw/aesthetics/chunky-tile": {
162
- "style": "./dist/tw/aesthetics/chunky-tile.css",
163
- "import": "./dist/tw/aesthetics/chunky-tile.css",
164
- "default": "./dist/tw/aesthetics/chunky-tile.css"
194
+ "types": "./tw/index.d.ts",
195
+ "style": "./tw/aesthetics/chunky-tile.css",
196
+ "import": "./tw/aesthetics/chunky-tile.css",
197
+ "default": "./tw/aesthetics/chunky-tile.css"
165
198
  },
166
199
  "./tw/aesthetics/cyber": {
167
- "style": "./dist/tw/aesthetics/cyber.css",
168
- "import": "./dist/tw/aesthetics/cyber.css",
169
- "default": "./dist/tw/aesthetics/cyber.css"
200
+ "types": "./tw/index.d.ts",
201
+ "style": "./tw/aesthetics/cyber.css",
202
+ "import": "./tw/aesthetics/cyber.css",
203
+ "default": "./tw/aesthetics/cyber.css"
170
204
  },
171
205
  "./tw/aesthetics/sketch": {
172
- "style": "./dist/tw/aesthetics/sketch.css",
173
- "import": "./dist/tw/aesthetics/sketch.css",
174
- "default": "./dist/tw/aesthetics/sketch.css"
206
+ "types": "./tw/index.d.ts",
207
+ "style": "./tw/aesthetics/sketch.css",
208
+ "import": "./tw/aesthetics/sketch.css",
209
+ "default": "./tw/aesthetics/sketch.css"
175
210
  },
176
211
  "./native": {
212
+ "types": "./dist/index.d.ts",
177
213
  "style": "./dist/native.css",
178
214
  "import": "./dist/native.css",
179
215
  "default": "./dist/native.css"
@@ -186,9 +222,13 @@
186
222
  "devDependencies": {
187
223
  "@codenhub/tools": "0.1.0",
188
224
  "@playwright/test": "~1.63.0",
189
- "@tailwindcss/cli": "^4.3.2",
225
+ "@tailwindcss/cli": "^4.3.4",
226
+ "@tailwindcss/node": "^4.3.4",
227
+ "@tailwindcss/oxide": "^4.3.4",
190
228
  "@types/node": "^26.6.6",
191
- "tailwindcss": "^4.3.2",
229
+ "@vitest/coverage-v8": "^4.1.10",
230
+ "tailwindcss": "^4.3.4",
231
+ "tsdown": "^0.23.5",
192
232
  "typescript": "^6.0.3",
193
233
  "vitest": "^4.1.10"
194
234
  },
@@ -200,27 +240,39 @@
200
240
  "optional": true
201
241
  }
202
242
  },
243
+ "engines": {
244
+ "node": ">=24"
245
+ },
203
246
  "codenhub": {
204
247
  "label": "StyleKit",
205
248
  "status": "active",
206
- "docs": {}
249
+ "docs": {
250
+ "versions": [
251
+ "^0.8.0"
252
+ ]
253
+ },
254
+ "tools": {
255
+ "timeout": 1800
256
+ }
207
257
  },
208
258
  "scripts": {
209
- "clean": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
259
+ "clean": "node -e \"for (const d of ['dist', 'tw']) fs.rmSync(d, { recursive: true, force: true })\"",
210
260
  "dev": "pnpm --filter=@codenhub/styles-dev dev",
211
261
  "debug": "pnpm build && pnpm --filter=@codenhub/styles-debug dev",
212
262
  "demo": "pnpm build && pnpm --filter=@codenhub/styles-demo dev",
213
263
  "generate": "node scripts/generate-palette.mjs",
214
- "build": "pnpm clean && node scripts/build-styles.mjs && pnpm build:tw",
264
+ "build": "pnpm clean && node scripts/build-styles.mjs && pnpm build:tw && pnpm build:purge && pnpm build:cli",
215
265
  "build:styles": "node scripts/build-styles.mjs --styles",
216
266
  "build:aesthetics": "node scripts/build-styles.mjs --aesthetics",
217
267
  "build:tw": "node scripts/build-tw.mjs",
268
+ "build:purge": "node scripts/build-purge.mjs",
269
+ "build:cli": "tsdown src/cli/cli.ts --format esm --no-clean --no-fixed-extension --no-dts",
218
270
  "status:npm": "npm view @codenhub/styles version dist-tags time --json && npm dist-tag ls @codenhub/styles && npm access get status @codenhub/styles",
219
271
  "status:pack": "npm pack --dry-run --ignore-scripts",
220
272
  "test": "vitest run",
221
273
  "test:browser": "playwright test",
222
274
  "test:browser:watch": "playwright test --ui",
223
- "test:coverage": "pnpm test",
275
+ "test:coverage": "vitest run --coverage",
224
276
  "test:watch": "vitest --watch",
225
277
  "typecheck": "tsc -b"
226
278
  }
@@ -144,6 +144,17 @@
144
144
  --ui-label-case: initial;
145
145
  --ui-label-shadow: initial;
146
146
  }
147
+
148
+ /* More contrast asked for: the tile takes the controls' grey, since its own
149
+ is about 2.5:1 against the page in both themes. The bar under a tile is
150
+ this ink too, and darkens with it. A rule of its own rather than nested
151
+ above: `registry.test.ts` reads that block's declarations flat. See
152
+ docs/accessibility.md. */
153
+ @media (prefers-contrast: more) {
154
+ .chunky-tile {
155
+ --ui-ink: light-dark(var(--color-neutral-600), var(--color-neutral-400));
156
+ }
157
+ }
147
158
  }
148
159
 
149
160
  /* Solo: the same look painted onto the one element carrying the class, for an
@@ -183,15 +194,26 @@
183
194
  --_tile-bar: color-mix(in oklab, var(--_solo-ink) 72%, rgb(0 0 0));
184
195
  --_solo-depth: calc(var(--_tile-lift) * var(--ui-elevation, 1));
185
196
 
197
+ /* Printed as drawn; see `.glass-solo`. */
198
+ print-color-adjust: exact;
199
+
186
200
  border: 2px solid var(--_solo-edge);
187
201
  border-radius: var(--tile-radius, 0.75rem);
188
202
  box-shadow:
189
203
  0 var(--_solo-depth) 0 0 var(--_tile-bar),
190
204
  inset 0 0 0 100vmax var(--_solo-fill);
191
205
  font-family: var(--font-rounded, var(--font-default, ui-sans-serif, system-ui, sans-serif));
192
- transition:
193
- box-shadow var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1)),
194
- transform var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1));
206
+ }
207
+
208
+ /* More contrast asked for: the controls' grey, as on `.chunky-tile`, for the
209
+ same 2.5:1. An element's intent still colours the line. */
210
+ @media (prefers-contrast: more) {
211
+ .chunky-tile-solo {
212
+ --_solo-ink: var(
213
+ --_solo-intent-border,
214
+ light-dark(var(--color-neutral-600, oklch(43.9% 0 0)), var(--color-neutral-400, oklch(70.8% 0 0)))
215
+ );
216
+ }
195
217
  }
196
218
 
197
219
  /* An intent class on the element colours it, as on a component. Named rather
@@ -223,7 +245,12 @@
223
245
  color: var(--_solo-fg);
224
246
  }
225
247
 
226
- /* The heavier, tracked label is an action's, as under the aesthetic class. */
248
+ /* The heavier, tracked label is an action's, as under the aesthetic class.
249
+
250
+ So is the press's transition: `transition` is one list, so writing it on
251
+ every solo element replaced a container's own -- a toast's fade and height
252
+ stopped animating. The travel is the independent `translate`, so the
253
+ element's own `transform` stays its own. */
227
254
  .chunky-tile-solo:is(
228
255
  button,
229
256
  a[href],
@@ -235,6 +262,16 @@
235
262
  ) {
236
263
  font-weight: 800;
237
264
  letter-spacing: 0.04em;
265
+ transition:
266
+ box-shadow var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1)),
267
+ translate var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1));
268
+
269
+ /* Reduced motion keeps the press and drops its motion: the tile lands on
270
+ its bar at once. The near-zero duration `box` uses, so a `transitionend`
271
+ still fires. */
272
+ @media (prefers-reduced-motion: reduce) {
273
+ transition-duration: 0.01ms;
274
+ }
238
275
  }
239
276
 
240
277
  /* The press, only on something pressed: an action, not disabled. A solo
@@ -248,23 +285,9 @@
248
285
  input[type="button"],
249
286
  input[type="submit"],
250
287
  input[type="reset"]
251
- ):active:not(:disabled, [aria-disabled="true"]) {
288
+ ):active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
252
289
  box-shadow:
253
290
  0 0 0 0 var(--_tile-bar),
254
291
  inset 0 0 0 100vmax var(--_solo-fill);
255
- transform: translateY(var(--_solo-depth));
256
- }
257
-
258
- @media (prefers-reduced-motion: reduce) {
259
- .chunky-tile-solo:is(
260
- button,
261
- a[href],
262
- [role="button"],
263
- summary,
264
- input[type="button"],
265
- input[type="submit"],
266
- input[type="reset"]
267
- ):active:not(:disabled, [aria-disabled="true"]) {
268
- transform: none;
269
- }
292
+ translate: 0 var(--_solo-depth);
270
293
  }
@@ -88,7 +88,7 @@
88
88
 
89
89
  /* The glow holds still under the pointer and under a press; the press is the
90
90
  base scale, restated because a region nested inside another aesthetic must
91
- not inherit that one's travel. Reduced motion drops it below. */
91
+ not inherit that one's travel. */
92
92
  --ui-hover-transform: none;
93
93
  --ui-active-shadow-x: 0px;
94
94
  --ui-active-shadow-y: 0px;
@@ -145,12 +145,6 @@
145
145
  --ui-radius-surface: 0;
146
146
  }
147
147
  }
148
-
149
- @media (prefers-reduced-motion: reduce) {
150
- .cyber {
151
- --ui-active-transform: none;
152
- }
153
- }
154
148
  }
155
149
 
156
150
  /* Solo: the same look painted onto the one element carrying the class, for an
@@ -185,6 +179,9 @@
185
179
  );
186
180
  --_solo-edge: color-mix(in oklab, var(--_solo-ink) var(--ui-border, 100%), var(--_solo-fill));
187
181
 
182
+ /* Printed as drawn; see `.glass-solo`. */
183
+ print-color-adjust: exact;
184
+
188
185
  border: 1px solid var(--_solo-edge);
189
186
  /* The surface shape: the element this exists for is usually a pane. An action
190
187
  takes the control shape below. */
@@ -199,7 +196,6 @@
199
196
  0 0 var(--cyber-glow, 8px) 1px color-mix(in oklab, var(--_solo-ink) 60%, transparent),
200
197
  inset 0 0 0 100vmax var(--_solo-fill);
201
198
  font-family: var(--font-cyber, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
202
- transition: transform var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1));
203
199
  }
204
200
 
205
201
  /* An intent class on the element colours it, as on a component. Named rather
@@ -231,7 +227,12 @@
231
227
  color: var(--_solo-fg);
232
228
  }
233
229
 
234
- /* An action takes the control shape, on the opposite diagonal to a pane's. */
230
+ /* An action takes the control shape, on the opposite diagonal to a pane's.
231
+
232
+ And the press's transition, on an action only: `transition` is one list, so
233
+ writing it on every solo element replaced a container's own -- a toast's
234
+ fade and height stopped animating. The press is the independent `scale`, so
235
+ the element's own `transform` stays its own. */
235
236
  .cyber-solo:is(
236
237
  button,
237
238
  a[href],
@@ -242,6 +243,13 @@
242
243
  input[type="reset"]
243
244
  ) {
244
245
  border-radius: var(--cyber-shape, min(var(--cyber-cut, 0.625rem), 25%) 0 / min(var(--cyber-cut, 0.625rem), 25%) 0);
246
+ transition: scale var(--motion-duration-normal, 200ms) var(--motion-ease, cubic-bezier(0.2, 0, 0, 1));
247
+
248
+ /* Reduced motion keeps the press and drops its motion: the element gives at
249
+ once. The near-zero duration `box` uses, so a `transitionend` still fires. */
250
+ @media (prefers-reduced-motion: reduce) {
251
+ transition-duration: 0.01ms;
252
+ }
245
253
  }
246
254
 
247
255
  @supports not (corner-shape: bevel) {
@@ -270,20 +278,6 @@
270
278
  input[type="button"],
271
279
  input[type="submit"],
272
280
  input[type="reset"]
273
- ):active:not(:disabled, [aria-disabled="true"]) {
274
- transform: scale(0.97);
275
- }
276
-
277
- @media (prefers-reduced-motion: reduce) {
278
- .cyber-solo:is(
279
- button,
280
- a[href],
281
- [role="button"],
282
- summary,
283
- input[type="button"],
284
- input[type="submit"],
285
- input[type="reset"]
286
- ):active:not(:disabled, [aria-disabled="true"]) {
287
- transform: none;
288
- }
281
+ ):active:not(:disabled, .disabled, [aria-disabled="true"], [data-disabled]) {
282
+ scale: 0.97;
289
283
  }