css-is-awesome 1.1.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 +343 -0
- package/CHANGELOG.md +1036 -0
- package/CLAUDE.md +9 -0
- package/CONTRACT.md +580 -0
- package/GEMINI.md +9 -0
- package/LICENSE +21 -0
- package/LICENSE-third-party +88 -0
- package/MIGRATION.md +312 -0
- package/README.md +380 -0
- package/ROADMAP.md +714 -0
- package/THEMING.md +290 -0
- package/THREE-TIERS.md +158 -0
- package/VERSIONING.md +200 -0
- package/_index.scss +34 -0
- package/api.scss +16 -0
- package/bin/README.md +57 -0
- package/bin/cia.cjs +114 -0
- package/bin/migrate-bootstrap.cjs +427 -0
- package/bin/migrate-tailwind.cjs +832 -0
- package/css-is-awesome.instructions.md +533 -0
- package/dist/css-is-awesome.core.css +598 -0
- package/dist/css-is-awesome.core.min.css +1 -0
- package/dist/css-is-awesome.css +3733 -0
- package/dist/css-is-awesome.min.css +1 -0
- package/dist/css-is-awesome.utilities.css +2445 -0
- package/dist/css-is-awesome.utilities.min.css +1 -0
- package/dist/tokens.css +508 -0
- package/dist/tokens.d.ts +266 -0
- package/dist/tokens.min.css +1 -0
- package/figma-tokens/README.md +57 -0
- package/figma-tokens/primitives-brand.scss +121 -0
- package/figma-tokens/semantic-dark.scss +61 -0
- package/figma-tokens/semantic-light.scss +61 -0
- package/figma-tokens/tokens.json +144 -0
- package/llm.txt +183 -0
- package/mcp/server.cjs +1495 -0
- package/package.json +199 -0
- package/public/icons/README.md +278 -0
- package/public/icons/arrow-right.svg +4 -0
- package/public/icons/check.svg +4 -0
- package/public/icons/chevron-down.svg +4 -0
- package/public/icons/close.svg +4 -0
- package/public/icons/core/arrow-down.svg +13 -0
- package/public/icons/core/arrow-left.svg +13 -0
- package/public/icons/core/arrow-right.svg +13 -0
- package/public/icons/core/arrow-up.svg +13 -0
- package/public/icons/core/bell.svg +13 -0
- package/public/icons/core/calendar.svg +15 -0
- package/public/icons/core/check.svg +12 -0
- package/public/icons/core/chevron-down.svg +12 -0
- package/public/icons/core/chevron-left.svg +12 -0
- package/public/icons/core/chevron-right.svg +12 -0
- package/public/icons/core/chevron-up.svg +12 -0
- package/public/icons/core/clock.svg +13 -0
- package/public/icons/core/close.svg +13 -0
- package/public/icons/core/copy.svg +13 -0
- package/public/icons/core/download.svg +14 -0
- package/public/icons/core/edit.svg +13 -0
- package/public/icons/core/error.svg +14 -0
- package/public/icons/core/external-link.svg +14 -0
- package/public/icons/core/eye-off.svg +15 -0
- package/public/icons/core/eye.svg +13 -0
- package/public/icons/core/filter.svg +12 -0
- package/public/icons/core/heart.svg +12 -0
- package/public/icons/core/help.svg +14 -0
- package/public/icons/core/home.svg +13 -0
- package/public/icons/core/info.svg +14 -0
- package/public/icons/core/loading.svg +12 -0
- package/public/icons/core/lock.svg +13 -0
- package/public/icons/core/mail.svg +13 -0
- package/public/icons/core/menu.svg +14 -0
- package/public/icons/core/message.svg +12 -0
- package/public/icons/core/minus.svg +12 -0
- package/public/icons/core/more-horizontal.svg +14 -0
- package/public/icons/core/pause.svg +13 -0
- package/public/icons/core/play.svg +12 -0
- package/public/icons/core/plus.svg +13 -0
- package/public/icons/core/refresh.svg +15 -0
- package/public/icons/core/save.svg +14 -0
- package/public/icons/core/search.svg +13 -0
- package/public/icons/core/settings.svg +13 -0
- package/public/icons/core/share.svg +14 -0
- package/public/icons/core/sort.svg +15 -0
- package/public/icons/core/star.svg +12 -0
- package/public/icons/core/success.svg +13 -0
- package/public/icons/core/trash.svg +16 -0
- package/public/icons/core/unlock.svg +13 -0
- package/public/icons/core/upload.svg +14 -0
- package/public/icons/core/user.svg +13 -0
- package/public/icons/core/users.svg +15 -0
- package/public/icons/core/warning.svg +14 -0
- package/public/icons/download.svg +4 -0
- package/public/icons/edit.svg +4 -0
- package/public/icons/menu.svg +4 -0
- package/public/icons/search.svg +4 -0
- package/public/theme.css +4179 -0
- package/public/themes/README.md +102 -0
- package/public/themes/boilerplate/theme.css +154 -0
- package/public/themes/boilerplate-dark/theme.css +171 -0
- package/public/themes/boilerplate-light/theme.css +171 -0
- package/public/themes/cupertino/theme.css +165 -0
- package/public/themes/cupertino-dark/theme.css +200 -0
- package/public/themes/cupertino-light/theme.css +227 -0
- package/public/themes/glass/theme.css +190 -0
- package/public/themes/glass-dark/theme.css +201 -0
- package/public/themes/glass-light/theme.css +229 -0
- package/public/themes/graphite/theme.css +155 -0
- package/public/themes/graphite-dark/theme.css +223 -0
- package/public/themes/graphite-light/theme.css +191 -0
- package/public/themes/press/theme.css +189 -0
- package/public/themes/press-dark/theme.css +199 -0
- package/public/themes/press-light/theme.css +235 -0
- package/public/themes/prism/theme.css +159 -0
- package/public/themes/prism-dark/theme.css +185 -0
- package/public/themes/prism-light/theme.css +188 -0
- package/public/themes/sketchbook/theme.css +152 -0
- package/public/themes/sketchbook-dark/theme.css +194 -0
- package/public/themes/sketchbook-light/theme.css +188 -0
- package/public/themes/terminal/theme.css +159 -0
- package/public/themes/terminal-dark/theme.css +229 -0
- package/public/themes/terminal-light/theme.css +152 -0
- package/scripts/README.md +70 -0
- package/scripts/icon-contract.json +67 -0
- package/scripts/icon-validator.js +205 -0
- package/scripts/prepare-dist.mjs +65 -0
- package/scripts/theme-a11y.js +415 -0
- package/scripts/theme-contract.json +171 -0
- package/scripts/theme-validator.js +674 -0
- package/scss/README.md +55 -0
- package/scss/_animations-utilities.scss +107 -0
- package/scss/_animations.scss +248 -0
- package/scss/_app-styles.scss +15 -0
- package/scss/_generator.scss +174 -0
- package/scss/_icons.scss +475 -0
- package/scss/_index.scss +17 -0
- package/scss/_layout.scss +597 -0
- package/scss/_mixins.scss +1036 -0
- package/scss/_system.scss +291 -0
- package/scss/_utilities.scss +377 -0
- package/scss/api.scss +61 -0
- package/scss/components/_accordion.scss +72 -0
- package/scss/components/_buttons.scss +171 -0
- package/scss/components/_copy-button.scss +69 -0
- package/scss/components/_data.scss +190 -0
- package/scss/components/_feedback.scss +197 -0
- package/scss/components/_forms.scss +272 -0
- package/scss/components/_index.scss +17 -0
- package/scss/components/_navigation.scss +186 -0
- package/scss/components/_overlay.scss +259 -0
- package/scss/components/_stepper.scss +159 -0
- package/scss/components/_tabs.scss +72 -0
- package/scss/core.scss +54 -0
- package/scss/examples/_theming.scss +107 -0
- package/scss/examples/_usage.scss +317 -0
- package/scss/main.scss +64 -0
- package/scss/recipes/README.md +110 -0
- package/scss/recipes/_bare-tags.scss +232 -0
- package/scss/recipes/_recipe-template.md +119 -0
- package/scss/recipes/combobox.md +509 -0
- package/scss/recipes/dialog.md +265 -0
- package/scss/recipes/print-to-pdf.md +263 -0
- package/scss/theme/README.md +67 -0
- package/scss/theme/_brand.scss +18 -0
- package/scss/theme/_colors-dark.scss +68 -0
- package/scss/theme/_colors-light.scss +70 -0
- package/scss/theme/_components.scss +94 -0
- package/scss/theme/_icons.scss +104 -0
- package/scss/theme/_index.scss +62 -0
- package/scss/theme/_shadows.scss +65 -0
- package/scss/theme/_shape.scss +13 -0
- package/scss/theme/_typography.scss +9 -0
- package/scss/theme/registry.json +447 -0
- package/scss/themes/boilerplate-dark.scss +212 -0
- package/scss/themes/boilerplate-light.scss +209 -0
- package/scss/themes/boilerplate.scss +181 -0
- package/scss/themes/cupertino-dark.scss +238 -0
- package/scss/themes/cupertino-light.scss +266 -0
- package/scss/themes/cupertino.scss +194 -0
- package/scss/themes/glass-dark.scss +238 -0
- package/scss/themes/glass-light.scss +266 -0
- package/scss/themes/glass.scss +220 -0
- package/scss/themes/graphite-dark.scss +260 -0
- package/scss/themes/graphite-light.scss +228 -0
- package/scss/themes/graphite.scss +182 -0
- package/scss/themes/press-dark.scss +237 -0
- package/scss/themes/press-light.scss +273 -0
- package/scss/themes/press.scss +241 -0
- package/scss/themes/prism-dark.scss +217 -0
- package/scss/themes/prism-light.scss +220 -0
- package/scss/themes/prism.scss +190 -0
- package/scss/themes/sketchbook-dark.scss +231 -0
- package/scss/themes/sketchbook-light.scss +231 -0
- package/scss/themes/sketchbook.scss +178 -0
- package/scss/themes/terminal-dark.scss +267 -0
- package/scss/themes/terminal-light.scss +175 -0
- package/scss/themes/terminal.scss +185 -0
- package/scss/tokens.scss +23 -0
- package/scss/utilities-only.scss +4 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// BARE-TAG STYLING — Optional Pico-style drop-in
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Default behaviour of css-is-awesome is to leave bare HTML alone. Tokens,
|
|
5
|
+
// utilities, mixins, and React components ship — bare <button>, <table>, <h1>
|
|
6
|
+
// stay browser-default until the consumer styles them.
|
|
7
|
+
//
|
|
8
|
+
// This recipe styles the most common bare tags using existing mixins. It is
|
|
9
|
+
// OPT-IN. If you want it, add this line ONCE in your app's SCSS entry:
|
|
10
|
+
//
|
|
11
|
+
// @use 'css-is-awesome/scss/recipes/bare-tags';
|
|
12
|
+
//
|
|
13
|
+
// Or copy the contents into your own SCSS and edit to taste.
|
|
14
|
+
//
|
|
15
|
+
// Specificity is zero ( :where() = 0,0,0 ). To override, write ANY selector —
|
|
16
|
+
// even another bare tag — and it wins automatically:
|
|
17
|
+
//
|
|
18
|
+
// button { background: gold; } // wins, (0,0,1) > (0,0,0)
|
|
19
|
+
//
|
|
20
|
+
// Heads up: bare-tag styling is global. If you mount third-party React
|
|
21
|
+
// components that render their own <button> internally (Radix, react-select,
|
|
22
|
+
// react-datepicker, cmdk), they WILL inherit these rules. Either skip this
|
|
23
|
+
// recipe and write your own scoped wrappers, or scope this recipe by copying
|
|
24
|
+
// it into a `.cia-prose { … }` block in your own SCSS.
|
|
25
|
+
// ============================================================================
|
|
26
|
+
@use '../mixins' as m;
|
|
27
|
+
@use '../components/buttons' as b;
|
|
28
|
+
@use '../components/forms' as f;
|
|
29
|
+
@use '../components/data' as d;
|
|
30
|
+
@use '../components/overlay' as o;
|
|
31
|
+
|
|
32
|
+
// ----------------------------------------------------------------------------
|
|
33
|
+
// TYPOGRAPHY
|
|
34
|
+
// ----------------------------------------------------------------------------
|
|
35
|
+
:where(h1) { @include m.type(heading-1); margin-block: m.space(5) m.space(3); }
|
|
36
|
+
:where(h2) { @include m.type(heading-2); margin-block: m.space(5) m.space(3); }
|
|
37
|
+
:where(h3) { @include m.type(heading-3); margin-block: m.space(4) m.space(2); }
|
|
38
|
+
:where(h4) { @include m.type(heading-4); margin-block: m.space(4) m.space(2); }
|
|
39
|
+
:where(h5) { @include m.type(heading-4); margin-block: m.space(3) m.space(2); }
|
|
40
|
+
:where(h6) {
|
|
41
|
+
@include m.type(body);
|
|
42
|
+
font-weight: m.font-weight(semibold);
|
|
43
|
+
margin-block: m.space(3) m.space(2);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
:where(p) {
|
|
47
|
+
margin-block: 0 m.space(3);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:where(small) {
|
|
51
|
+
font-size: m.font-size(2);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
:where(blockquote) {
|
|
55
|
+
margin-block: m.space(4);
|
|
56
|
+
margin-inline: 0;
|
|
57
|
+
padding-block: m.space(2);
|
|
58
|
+
padding-inline: m.space(4);
|
|
59
|
+
border-inline-start: 4px solid m.color(border-default);
|
|
60
|
+
color: m.color(text-secondary);
|
|
61
|
+
font-style: italic;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ----------------------------------------------------------------------------
|
|
65
|
+
// CODE
|
|
66
|
+
// ----------------------------------------------------------------------------
|
|
67
|
+
:where(code, kbd, samp) {
|
|
68
|
+
font-family: m.font-family(mono);
|
|
69
|
+
font-size: 0.9em;
|
|
70
|
+
background: m.color(surface-subtle);
|
|
71
|
+
padding-inline: m.space(1);
|
|
72
|
+
border-radius: m.radius(sm);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
:where(pre) {
|
|
76
|
+
font-family: m.font-family(mono);
|
|
77
|
+
font-size: m.font-size(2);
|
|
78
|
+
background: m.color(surface-subtle);
|
|
79
|
+
padding: m.space(3);
|
|
80
|
+
border-radius: m.radius(md);
|
|
81
|
+
overflow-x: auto;
|
|
82
|
+
margin-block: m.space(3);
|
|
83
|
+
|
|
84
|
+
:where(code) {
|
|
85
|
+
background: transparent;
|
|
86
|
+
padding: 0;
|
|
87
|
+
border-radius: 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ----------------------------------------------------------------------------
|
|
92
|
+
// LISTS
|
|
93
|
+
// ----------------------------------------------------------------------------
|
|
94
|
+
:where(ul, ol) {
|
|
95
|
+
margin-block: 0 m.space(3);
|
|
96
|
+
padding-inline-start: m.space(5);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
:where(li) {
|
|
100
|
+
margin-block-end: m.space(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ----------------------------------------------------------------------------
|
|
104
|
+
// STRUCTURAL
|
|
105
|
+
// ----------------------------------------------------------------------------
|
|
106
|
+
:where(hr) {
|
|
107
|
+
border: none;
|
|
108
|
+
border-block-start: 1px solid m.color(border-default);
|
|
109
|
+
margin-block: m.space(5);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where(figure) {
|
|
113
|
+
margin-block: m.space(4);
|
|
114
|
+
margin-inline: 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
:where(figcaption) {
|
|
118
|
+
font-size: m.font-size(2);
|
|
119
|
+
color: m.color(text-secondary);
|
|
120
|
+
margin-block-start: m.space(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ----------------------------------------------------------------------------
|
|
124
|
+
// TABLES
|
|
125
|
+
// ----------------------------------------------------------------------------
|
|
126
|
+
:where(table) {
|
|
127
|
+
@include d.table-base;
|
|
128
|
+
margin-block: m.space(3);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ----------------------------------------------------------------------------
|
|
132
|
+
// FORMS — bare tags get base styling. Variants via class or @include.
|
|
133
|
+
// ----------------------------------------------------------------------------
|
|
134
|
+
:where(button) {
|
|
135
|
+
@include b.btn(primary);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:where(
|
|
139
|
+
input[type="text"],
|
|
140
|
+
input[type="email"],
|
|
141
|
+
input[type="password"],
|
|
142
|
+
input[type="search"],
|
|
143
|
+
input[type="tel"],
|
|
144
|
+
input[type="url"],
|
|
145
|
+
input[type="number"],
|
|
146
|
+
input[type="date"],
|
|
147
|
+
input[type="time"],
|
|
148
|
+
input[type="datetime-local"]
|
|
149
|
+
) {
|
|
150
|
+
@include f.input-base;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
:where(select) { @include f.select-base; }
|
|
154
|
+
:where(textarea) { @include f.textarea-base; }
|
|
155
|
+
:where(label) { @include f.label-base; }
|
|
156
|
+
|
|
157
|
+
:where(fieldset) {
|
|
158
|
+
border: 1px solid m.color(border-default);
|
|
159
|
+
border-radius: m.radius(md);
|
|
160
|
+
padding: m.space(4);
|
|
161
|
+
margin-block: m.space(3);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
:where(legend) {
|
|
165
|
+
padding-inline: m.space(2);
|
|
166
|
+
font-weight: m.font-weight(semibold);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ----------------------------------------------------------------------------
|
|
170
|
+
// INTERACTIVE
|
|
171
|
+
// ----------------------------------------------------------------------------
|
|
172
|
+
:where(details) {
|
|
173
|
+
margin-block: m.space(2);
|
|
174
|
+
|
|
175
|
+
> :where(summary) {
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
padding: m.space(2);
|
|
178
|
+
font-weight: m.font-weight(medium);
|
|
179
|
+
border-radius: m.radius(md);
|
|
180
|
+
@include m.transition(background-color);
|
|
181
|
+
|
|
182
|
+
&:hover {
|
|
183
|
+
background: m.color(interactive-hover);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
> :where(summary) + * {
|
|
188
|
+
padding: m.space(2);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ----------------------------------------------------------------------------
|
|
193
|
+
// V0.8 NATIVE COMPONENTS — sensible defaults for <dialog>, <progress>
|
|
194
|
+
// ----------------------------------------------------------------------------
|
|
195
|
+
// Round out Tier 3 for the v0.8 zero-JS component slate. Pair with the
|
|
196
|
+
// existing component mixins (cia.modal, cia.progress) when richer styling
|
|
197
|
+
// is needed.
|
|
198
|
+
|
|
199
|
+
:where(dialog) {
|
|
200
|
+
@include o.modal-base;
|
|
201
|
+
border: 0;
|
|
202
|
+
margin: auto;
|
|
203
|
+
|
|
204
|
+
&::backdrop {
|
|
205
|
+
background: rgba(0, 0, 0, 0.5);
|
|
206
|
+
backdrop-filter: blur(2px);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
:where(progress) {
|
|
211
|
+
inline-size: 100%;
|
|
212
|
+
block-size: 0.5rem;
|
|
213
|
+
appearance: none;
|
|
214
|
+
border: 0;
|
|
215
|
+
border-radius: m.radius(full);
|
|
216
|
+
background: m.color(surface-muted);
|
|
217
|
+
overflow: hidden;
|
|
218
|
+
|
|
219
|
+
&::-webkit-progress-bar {
|
|
220
|
+
background: m.color(surface-muted);
|
|
221
|
+
border-radius: m.radius(full);
|
|
222
|
+
}
|
|
223
|
+
&::-webkit-progress-value {
|
|
224
|
+
background: m.color(action-primary-default);
|
|
225
|
+
border-radius: inherit;
|
|
226
|
+
@include m.transition(inline-size, slow);
|
|
227
|
+
}
|
|
228
|
+
&::-moz-progress-bar {
|
|
229
|
+
background: m.color(action-primary-default);
|
|
230
|
+
border-radius: inherit;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-recipe-slug
|
|
3
|
+
description: One sentence describing what this recipe builds.
|
|
4
|
+
category: overlay
|
|
5
|
+
complexity: medium
|
|
6
|
+
cia-version: ">=1.0.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<!--
|
|
10
|
+
Copy this file to <your-slug>.md (no leading underscore) and fill in each
|
|
11
|
+
section. Required: name, description, category, complexity, cia-version
|
|
12
|
+
frontmatter + all H2 sections below up to "Framework examples". Optional
|
|
13
|
+
sections (Variants, Pitfalls, Related recipes) can be dropped if empty.
|
|
14
|
+
|
|
15
|
+
See ./README.md for the full schema spec.
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
## Use this when
|
|
19
|
+
|
|
20
|
+
A short paragraph (1-3 sentences) describing the consumer scenario. If the
|
|
21
|
+
reader's situation doesn't match what you describe, they should bail and
|
|
22
|
+
look elsewhere. Be specific about what this recipe IS and ISN'T.
|
|
23
|
+
|
|
24
|
+
## Structure (raw HTML)
|
|
25
|
+
|
|
26
|
+
The markup with `data-slot` attributes for consumer hooks. Framework-agnostic;
|
|
27
|
+
the consumer adapts to JSX / template / Svelte syntax.
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<element data-cia-recipe="my-recipe-slug">
|
|
31
|
+
<slot data-slot="title"></slot>
|
|
32
|
+
<slot data-slot="body"></slot>
|
|
33
|
+
</element>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Styling (cia mixins)
|
|
37
|
+
|
|
38
|
+
```scss
|
|
39
|
+
// MyThing.module.scss — component stylesheet, so import the zero-emit barrel.
|
|
40
|
+
@use 'css-is-awesome/api' as cia;
|
|
41
|
+
|
|
42
|
+
.my-thing {
|
|
43
|
+
@include cia.some-mixin(variant);
|
|
44
|
+
}
|
|
45
|
+
.my-thing [data-slot="title"] {
|
|
46
|
+
@include cia.type(heading-2);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Show the minimum to make it work. Cross-link to mixin docs for parameter
|
|
51
|
+
detail. Use consumer-chosen class names (`my-thing`), never `cia-*`.
|
|
52
|
+
|
|
53
|
+
**Two imports, two jobs.** Component stylesheets always `@use
|
|
54
|
+
'css-is-awesome/api'` — it is zero-emit, so it is safe inside a
|
|
55
|
+
`.module.scss` under Next.js CSS Modules pure mode. The emitting bundle
|
|
56
|
+
(`@use 'css-is-awesome'`) belongs in the app's root/global stylesheet, where
|
|
57
|
+
it prints the `:root` tokens exactly once. If a recipe needs a mixin that
|
|
58
|
+
emits at the root itself (e.g. `cia.print-base`, which emits `:root` +
|
|
59
|
+
`@page`), say so in prose and show it in a global stylesheet — `/api` still
|
|
60
|
+
forwards it.
|
|
61
|
+
|
|
62
|
+
## Interactivity
|
|
63
|
+
|
|
64
|
+
Describe the behavior. Prefer native browser primitives (`<dialog>`, popover
|
|
65
|
+
API, `:has()`, radio + `:nth-of-type()`). JS only where the native primitive
|
|
66
|
+
genuinely can't do the job.
|
|
67
|
+
|
|
68
|
+
- Native: which APIs / pseudo-classes do the work
|
|
69
|
+
- JS: when consumer needs a script, what it does, how small it can be
|
|
70
|
+
- Edge cases: SSR safety, hydration timing, mobile gestures
|
|
71
|
+
|
|
72
|
+
## A11y checklist
|
|
73
|
+
|
|
74
|
+
Concrete, testable items. Each item references the WCAG SC or ARIA pattern.
|
|
75
|
+
|
|
76
|
+
- [ ] item 1 — (WCAG 2.2 SC X.X.X reference or ARIA pattern URL)
|
|
77
|
+
- [ ] item 2
|
|
78
|
+
- [ ] item 3
|
|
79
|
+
|
|
80
|
+
## Framework examples
|
|
81
|
+
|
|
82
|
+
Minimum 4 subsections: React, Vue, Svelte, vanilla (Web Component preferred
|
|
83
|
+
for vanilla). Each example must be runnable code, not pseudocode.
|
|
84
|
+
|
|
85
|
+
### React
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
// runnable React example
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Vue
|
|
92
|
+
|
|
93
|
+
```vue
|
|
94
|
+
<!-- runnable Vue example -->
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Svelte
|
|
98
|
+
|
|
99
|
+
```svelte
|
|
100
|
+
<!-- runnable Svelte example -->
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Vanilla (Web Component)
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
// runnable Web Component example
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Variants
|
|
110
|
+
|
|
111
|
+
(optional) Common adaptations. One sub-block per variant with the styling delta.
|
|
112
|
+
|
|
113
|
+
## Pitfalls
|
|
114
|
+
|
|
115
|
+
(optional) Known gotchas — SSR, browser compat, focus management edge cases.
|
|
116
|
+
|
|
117
|
+
## Related recipes
|
|
118
|
+
|
|
119
|
+
(optional) Cross-link to other recipes.
|