gbs-add-block 2.0.4 → 2.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.
Files changed (30) hide show
  1. package/.gbs/skills/gbs-components/references/styling.md +21 -15
  2. package/README.md +22 -7
  3. package/package.json +1 -1
  4. package/source/beta-components/accordion/styles.css +5 -5
  5. package/source/beta-components/alert/styles.css +4 -4
  6. package/source/beta-components/avatar/styles.css +226 -227
  7. package/source/beta-components/badge/styles.css +7 -7
  8. package/source/beta-components/breadcrumb/styles.css +5 -4
  9. package/source/beta-components/button/styles.css +5 -4
  10. package/source/beta-components/card/styles.css +5 -4
  11. package/source/beta-components/checkbox/styles.css +5 -4
  12. package/source/beta-components/combobox/styles.css +4 -4
  13. package/source/beta-components/data-grid/styles.css +7 -8
  14. package/source/beta-components/date-picker/styles.css +4 -4
  15. package/source/beta-components/dialog/styles.css +5 -4
  16. package/source/beta-components/file-uploader/styles.css +5 -4
  17. package/source/beta-components/input/styles.css +5 -4
  18. package/source/beta-components/menu/styles.css +5 -4
  19. package/source/beta-components/modal/styles.css +5 -4
  20. package/source/beta-components/number-input/styles.css +5 -5
  21. package/source/beta-components/popover/styles.css +5 -4
  22. package/source/beta-components/progress/styles.css +1 -2
  23. package/source/beta-components/radio-group/styles.css +270 -270
  24. package/source/beta-components/skeleton/styles.css +5 -4
  25. package/source/beta-components/spinner/styles.css +174 -174
  26. package/source/beta-components/switch/styles.css +229 -229
  27. package/source/beta-components/tabs/styles.css +264 -264
  28. package/source/beta-components/textarea/styles.css +5 -4
  29. package/source/beta-components/toaster/styles.css +1 -2
  30. package/source/beta-components/tooltip/styles.css +5 -4
@@ -113,18 +113,25 @@ exist is silently ignored, so check the list.
113
113
  Classes are joined with `cx` from `shared/core/cx.ts`, which drops falsy values
114
114
  — a conditional that evaluates to `undefined` contributes nothing.
115
115
 
116
- ## 4. Tailwind
116
+ ## 4. Cascade layers and Tailwind
117
117
 
118
- Every `styles.css` declares:
118
+ Every `styles.css` ships its rules in one layer and declares nothing else:
119
119
 
120
120
  ```css
121
- @layer theme, base, components, utilities;
122
- @layer components { /* the component's rules */ }
121
+ @layer gbs { /* the component's rules */ }
123
122
  ```
124
123
 
125
- Component rules live in the `components` layer, so **Tailwind utilities passed
126
- through `className` / `classNames` win** without `!important`. That is the
127
- supported way to adjust spacing, typography and layout.
124
+ Where `gbs` sits is the app's call. Declare the order once in the global CSS;
125
+ anything in a later layer beats the components:
126
+
127
+ ```css
128
+ @layer reset, gbs, app, utilities;
129
+ ```
130
+
131
+ With Tailwind v4, naming `gbs` before `utilities` means **a utility passed
132
+ through `className` / `classNames` wins** without `!important`. Tailwind v3
133
+ needs no line — it emits utilities unlayered, which already outrank a layer.
134
+ A project with no CSS framework needs no line either.
128
135
 
129
136
  ```tsx
130
137
  <Button className="w-full sm:w-auto" classNames={{ content: "gap-3" }}>Save</Button>
@@ -136,17 +143,16 @@ variables or the slots.
136
143
 
137
144
  ## 5. Unlayered resets (Bootstrap, Normalize)
138
145
 
139
- Component rules sit in `@layer components`. Any stylesheet that ships
140
- **unlayered** beats every layered rule regardless of specificity — the cascade
141
- settles layers before specificity. So Bootstrap's Reboot (`button { border-radius: 0 }`,
142
- `button, input, textarea { font-size: inherit }`) overrides our classes, and
143
- import order does not help.
146
+ Any stylesheet that ships **unlayered** beats every layered rule regardless of
147
+ specificity — the cascade settles layers before specificity. So Bootstrap's
148
+ Reboot (`button { border-radius: 0 }`, `button, input, textarea { font-size:
149
+ inherit }`) overrides our classes, and import order does not help.
144
150
 
145
- Fix it in the project's global CSS by giving the reset its own layer, declared
146
- before `components`:
151
+ Fix it in the project's global CSS by giving the reset its own layer, named
152
+ before `gbs`:
147
153
 
148
154
  ```css
149
- @layer bootstrap, theme, base, components, utilities;
155
+ @layer bootstrap, gbs, app, utilities;
150
156
  @import url("bootstrap/dist/css/bootstrap.min.css") layer(bootstrap);
151
157
  ```
152
158
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # GBS Building Blocks 2.0 (v2.0.4)
1
+ # GBS Building Blocks 2.0 (v2.1.0)
2
2
 
3
3
  Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
4
4
 
@@ -33,13 +33,28 @@ Pick a subset with `--for claude,codex`, or `--for none` for just `.gbs/`.
33
33
  Commit the result so everyone's agent picks it up. Re-run to update; a file you
34
34
  have edited is never replaced without `--force`.
35
35
 
36
- ## What's New 🎉 (Ver 2.0.4)
36
+ ## What's New 🎉 (Ver 2.1.0)
37
37
 
38
- - Agent skill: added guidance for projects that load an unlayered CSS reset
39
- such as Bootstrap or Normalize. Component rules live in the `components`
40
- cascade layer, and an unlayered reset outranks every layered rule whatever
41
- its selectors look like, so Bootstrap's Reboot was restyling the Button.
42
- Importing the reset into its own layer fixes it; the skill now says so.
38
+ **The application now owns CSS cascade order.** Component rules moved out of the
39
+ `components` layer into a layer of their own, `gbs`, and the stylesheets no
40
+ longer declare a global layer order.
41
+
42
+ Previously every `styles.css` opened with
43
+ `@layer theme, base, components, utilities;` — a leaf file asserting the order
44
+ of the whole document. Whichever stylesheet the bundler emitted first silently
45
+ won that argument. It also meant a Tailwind v3 build failed outright, and
46
+ Bootstrap's Reboot could not be put in front of the components.
47
+
48
+ - Tailwind **v3** projects now build. Utilities override components there too,
49
+ with no setup.
50
+ - Tailwind **v4** projects add one line to their global CSS:
51
+ `@layer gbs, utilities;` — **without it, utilities no longer override
52
+ component styles.** This is the migration step.
53
+ - Bootstrap, Normalize or any unlayered reset can now be placed before the
54
+ components: `@layer bootstrap, gbs, app, utilities;`
55
+ - Projects with no CSS framework need no change.
56
+
57
+ See the Theming page, "Cascade layers", for the full model.
43
58
 
44
59
  ## Authors
45
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gbs-add-block",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "React Component Library",
5
5
  "type": "module",
6
6
  "files": [
@@ -4,13 +4,13 @@
4
4
  * Each section is a native <details>, so the marker has to be taken off (two
5
5
  * ways: `list-item` display in Firefox, the WebKit pseudo-element elsewhere)
6
6
  * before a chevron of our own goes on. Tokens read the shared --gbs-*
7
- * variables when they are set on an ancestor (set them on :root to theme every
8
- * component at once). Rules live in the `components` layer, so utility classes
9
- * passed through `className` / `classNames` override them.
7
+ * variables when they are set on an ancestor (set them on :root to theme
8
+ * every component at once). Rules live in the `gbs` layer; declare where it
9
+ * sits in your global CSS, e.g. `@layer reset, gbs, app, utilities;`, and
10
+ * anything in a later layer overrides them.
10
11
  */
11
- @layer theme, base, components, utilities;
12
12
 
13
- @layer components {
13
+ @layer gbs {
14
14
  .ac-root {
15
15
  --ac-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
16
16
  --ac-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
@@ -3,12 +3,12 @@
3
3
  *
4
4
  * A banner that sits in the page, tinted by variant. Tokens read the shared
5
5
  * --gbs-* variables when they are set on an ancestor (set them on :root to
6
- * theme every component at once). Rules live in the `components` layer, so
7
- * utility classes passed through `className` / `classNames` override them.
6
+ * theme every component at once). Rules live in the `gbs` layer; declare
7
+ * where it sits in your global CSS, e.g. `@layer reset, gbs, app,
8
+ * utilities;`, and anything in a later layer overrides them.
8
9
  */
9
- @layer theme, base, components, utilities;
10
10
 
11
- @layer components {
11
+ @layer gbs {
12
12
  .al-root {
13
13
  --al-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
14
14
  --al-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
@@ -1,227 +1,226 @@
1
- /*
2
- * Avatar and AvatarGroup styles.
3
- *
4
- * The fallback colour comes from --av-hue-index, which the component sets from
5
- * a hash of the name: the same person is the same colour everywhere, and the
6
- * palette is generated rather than listed, so it follows a themed hue. Tokens
7
- * read the shared --gbs-* variables when they are set on an ancestor (set them
8
- * on :root to theme every component at once). Rules live in the `components`
9
- * layer, so utility classes passed through `className` / `classNames` override
10
- * them.
11
- */
12
- @layer theme, base, components, utilities;
13
-
14
- @layer components {
15
- .av-root,
16
- .av-group,
17
- .av-overflow {
18
- --av-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
19
- --av-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
20
- --av-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
21
- --av-subtle: var(--gbs-subtle, light-dark(#f4f4f5, #1c1c20));
22
- --av-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
23
- --av-success: var(--gbs-success, light-dark(#15803d, #4ade80));
24
- --av-warning: var(--gbs-warning, light-dark(#b45309, #fbbf24));
25
- --av-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
26
- --av-radius: var(--gbs-radius, var(--dg-radius, 8px));
27
- --av-size: 32px;
28
- --av-font-size: 13px;
29
- --av-hue-index: 0;
30
- /* Eight hues, 45° apart, starting at the blue end. */
31
- --av-hue: calc(210 + var(--av-hue-index) * 45);
32
-
33
- color-scheme: inherit;
34
- }
35
-
36
- :where(.dark, [data-theme="dark"]) :is(.av-root, .av-group, .av-overflow) {
37
- color-scheme: dark;
38
- }
39
- :where(.light, [data-theme="light"]) :is(.av-root, .av-group, .av-overflow) {
40
- color-scheme: light;
41
- }
42
-
43
- :where(.av-root, .av-group) *,
44
- :where(.av-root, .av-group) *::before,
45
- :where(.av-root, .av-group) *::after {
46
- box-sizing: border-box;
47
- }
48
-
49
- .av-root {
50
- position: relative;
51
- display: inline-flex;
52
- flex: none;
53
- align-items: center;
54
- justify-content: center;
55
- width: var(--av-size);
56
- height: var(--av-size);
57
- border-radius: 50%;
58
- background: var(--av-subtle);
59
- font-size: var(--av-font-size);
60
- font-weight: 600;
61
- line-height: 1;
62
- overflow: hidden;
63
- user-select: none;
64
- vertical-align: middle;
65
- }
66
- .av-root[data-shape="square"] {
67
- border-radius: var(--av-radius);
68
- overflow: visible;
69
- }
70
- .av-root[data-shape="square"] .av-image,
71
- .av-root[data-shape="square"] .av-fallback {
72
- border-radius: var(--av-radius);
73
- }
74
-
75
- .av-root[data-size="xs"] {
76
- --av-size: 20px;
77
- --av-font-size: 10px;
78
- }
79
- .av-root[data-size="sm"] {
80
- --av-size: 24px;
81
- --av-font-size: 11px;
82
- }
83
- .av-root[data-size="lg"] {
84
- --av-size: 40px;
85
- --av-font-size: 15px;
86
- }
87
- .av-root[data-size="xl"] {
88
- --av-size: 56px;
89
- --av-font-size: 20px;
90
- }
91
-
92
- .av-image {
93
- width: 100%;
94
- height: 100%;
95
- object-fit: cover;
96
- }
97
-
98
- /* `oklch` keeps every hue at the same lightness, so no one person's initials
99
- come out harder to read than another's — which is what a list of hand-picked
100
- hex pairs always ends up doing. */
101
- .av-fallback {
102
- display: flex;
103
- align-items: center;
104
- justify-content: center;
105
- width: 100%;
106
- height: 100%;
107
- background: oklch(from light-dark(oklch(0.93 0.05 0), oklch(0.32 0.06 0)) l c var(--av-hue));
108
- color: oklch(from light-dark(oklch(0.42 0.13 0), oklch(0.88 0.1 0)) l c var(--av-hue));
109
- text-transform: uppercase;
110
- }
111
- .av-fallback > svg {
112
- width: 60%;
113
- height: 60%;
114
- }
115
-
116
- .av-status {
117
- position: absolute;
118
- right: 0;
119
- bottom: 0;
120
- width: 30%;
121
- height: 30%;
122
- min-width: 8px;
123
- min-height: 8px;
124
- border: 2px solid var(--av-bg);
125
- border-radius: 50%;
126
- background: var(--av-muted);
127
- }
128
- .av-root[data-shape="square"] .av-status {
129
- right: -2px;
130
- bottom: -2px;
131
- }
132
- .av-status[data-status="online"] {
133
- background: var(--av-success);
134
- }
135
- .av-status[data-status="away"] {
136
- background: var(--av-warning);
137
- }
138
- .av-status[data-status="busy"] {
139
- background: var(--av-danger);
140
- }
141
-
142
- /* ---------------------------------------------------------------- group */
143
-
144
- .av-group {
145
- display: inline-flex;
146
- align-items: center;
147
- vertical-align: middle;
148
- }
149
- /* Each face overlaps the one before and is ringed in the page colour, so the
150
- stack reads as separate people rather than one smear. */
151
- .av-group > * {
152
- margin-inline-start: calc(var(--av-size) / -4);
153
- box-shadow: 0 0 0 2px var(--av-bg);
154
- }
155
- .av-group > *:first-child {
156
- margin-inline-start: 0;
157
- }
158
-
159
- .av-overflow {
160
- position: relative;
161
- display: inline-flex;
162
- flex: none;
163
- align-items: center;
164
- justify-content: center;
165
- width: var(--av-size);
166
- height: var(--av-size);
167
- border-radius: 50%;
168
- background: var(--av-subtle);
169
- /* Muted grey clears 4.5:1 on the page background but only reaches 4.39:1
170
- on this one, so the count moves a step towards the text colour. */
171
- color: color-mix(in oklab, var(--av-muted) 65%, var(--av-fg));
172
- font-size: calc(var(--av-font-size) - 1px);
173
- font-weight: 600;
174
- font-variant-numeric: tabular-nums;
175
- line-height: 1;
176
- }
177
- .av-overflow[data-shape="square"] {
178
- border-radius: var(--av-radius);
179
- }
180
- .av-group[data-size="xs"],
181
- .av-overflow[data-size="xs"] {
182
- --av-size: 20px;
183
- --av-font-size: 10px;
184
- }
185
- .av-group[data-size="sm"],
186
- .av-overflow[data-size="sm"] {
187
- --av-size: 24px;
188
- --av-font-size: 11px;
189
- }
190
- .av-group[data-size="lg"],
191
- .av-overflow[data-size="lg"] {
192
- --av-size: 40px;
193
- --av-font-size: 15px;
194
- }
195
- .av-group[data-size="xl"],
196
- .av-overflow[data-size="xl"] {
197
- --av-size: 56px;
198
- --av-font-size: 20px;
199
- }
200
- /* The group's size reaches the avatars inside it, unless one sets its own. */
201
- .av-group[data-size="xs"] .av-root:not([data-size]) {
202
- --av-size: 20px;
203
- --av-font-size: 10px;
204
- }
205
- .av-group[data-size="sm"] .av-root:not([data-size]) {
206
- --av-size: 24px;
207
- --av-font-size: 11px;
208
- }
209
- .av-group[data-size="lg"] .av-root:not([data-size]) {
210
- --av-size: 40px;
211
- --av-font-size: 15px;
212
- }
213
- .av-group[data-size="xl"] .av-root:not([data-size]) {
214
- --av-size: 56px;
215
- --av-font-size: 20px;
216
- }
217
-
218
- @media (forced-colors: active) {
219
- .av-root,
220
- .av-overflow {
221
- border: 1px solid CanvasText;
222
- }
223
- .av-status {
224
- border-color: Canvas;
225
- }
226
- }
227
- }
1
+ /*
2
+ * Avatar and AvatarGroup styles.
3
+ *
4
+ * The fallback colour comes from --av-hue-index, which the component sets from
5
+ * a hash of the name: the same person is the same colour everywhere, and the
6
+ * palette is generated rather than listed, so it follows a themed hue. Tokens
7
+ * read the shared --gbs-* variables when they are set on an ancestor (set them
8
+ * on :root to theme every component at once). Rules live in the `components`
9
+ * layer, so utility classes passed through `className` / `classNames` override
10
+ * them.
11
+ */
12
+
13
+ @layer gbs {
14
+ .av-root,
15
+ .av-group,
16
+ .av-overflow {
17
+ --av-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
18
+ --av-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
19
+ --av-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
20
+ --av-subtle: var(--gbs-subtle, light-dark(#f4f4f5, #1c1c20));
21
+ --av-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
22
+ --av-success: var(--gbs-success, light-dark(#15803d, #4ade80));
23
+ --av-warning: var(--gbs-warning, light-dark(#b45309, #fbbf24));
24
+ --av-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
25
+ --av-radius: var(--gbs-radius, var(--dg-radius, 8px));
26
+ --av-size: 32px;
27
+ --av-font-size: 13px;
28
+ --av-hue-index: 0;
29
+ /* Eight hues, 45° apart, starting at the blue end. */
30
+ --av-hue: calc(210 + var(--av-hue-index) * 45);
31
+
32
+ color-scheme: inherit;
33
+ }
34
+
35
+ :where(.dark, [data-theme="dark"]) :is(.av-root, .av-group, .av-overflow) {
36
+ color-scheme: dark;
37
+ }
38
+ :where(.light, [data-theme="light"]) :is(.av-root, .av-group, .av-overflow) {
39
+ color-scheme: light;
40
+ }
41
+
42
+ :where(.av-root, .av-group) *,
43
+ :where(.av-root, .av-group) *::before,
44
+ :where(.av-root, .av-group) *::after {
45
+ box-sizing: border-box;
46
+ }
47
+
48
+ .av-root {
49
+ position: relative;
50
+ display: inline-flex;
51
+ flex: none;
52
+ align-items: center;
53
+ justify-content: center;
54
+ width: var(--av-size);
55
+ height: var(--av-size);
56
+ border-radius: 50%;
57
+ background: var(--av-subtle);
58
+ font-size: var(--av-font-size);
59
+ font-weight: 600;
60
+ line-height: 1;
61
+ overflow: hidden;
62
+ user-select: none;
63
+ vertical-align: middle;
64
+ }
65
+ .av-root[data-shape="square"] {
66
+ border-radius: var(--av-radius);
67
+ overflow: visible;
68
+ }
69
+ .av-root[data-shape="square"] .av-image,
70
+ .av-root[data-shape="square"] .av-fallback {
71
+ border-radius: var(--av-radius);
72
+ }
73
+
74
+ .av-root[data-size="xs"] {
75
+ --av-size: 20px;
76
+ --av-font-size: 10px;
77
+ }
78
+ .av-root[data-size="sm"] {
79
+ --av-size: 24px;
80
+ --av-font-size: 11px;
81
+ }
82
+ .av-root[data-size="lg"] {
83
+ --av-size: 40px;
84
+ --av-font-size: 15px;
85
+ }
86
+ .av-root[data-size="xl"] {
87
+ --av-size: 56px;
88
+ --av-font-size: 20px;
89
+ }
90
+
91
+ .av-image {
92
+ width: 100%;
93
+ height: 100%;
94
+ object-fit: cover;
95
+ }
96
+
97
+ /* `oklch` keeps every hue at the same lightness, so no one person's initials
98
+ come out harder to read than another's — which is what a list of hand-picked
99
+ hex pairs always ends up doing. */
100
+ .av-fallback {
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ width: 100%;
105
+ height: 100%;
106
+ background: oklch(from light-dark(oklch(0.93 0.05 0), oklch(0.32 0.06 0)) l c var(--av-hue));
107
+ color: oklch(from light-dark(oklch(0.42 0.13 0), oklch(0.88 0.1 0)) l c var(--av-hue));
108
+ text-transform: uppercase;
109
+ }
110
+ .av-fallback > svg {
111
+ width: 60%;
112
+ height: 60%;
113
+ }
114
+
115
+ .av-status {
116
+ position: absolute;
117
+ right: 0;
118
+ bottom: 0;
119
+ width: 30%;
120
+ height: 30%;
121
+ min-width: 8px;
122
+ min-height: 8px;
123
+ border: 2px solid var(--av-bg);
124
+ border-radius: 50%;
125
+ background: var(--av-muted);
126
+ }
127
+ .av-root[data-shape="square"] .av-status {
128
+ right: -2px;
129
+ bottom: -2px;
130
+ }
131
+ .av-status[data-status="online"] {
132
+ background: var(--av-success);
133
+ }
134
+ .av-status[data-status="away"] {
135
+ background: var(--av-warning);
136
+ }
137
+ .av-status[data-status="busy"] {
138
+ background: var(--av-danger);
139
+ }
140
+
141
+ /* ---------------------------------------------------------------- group */
142
+
143
+ .av-group {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ vertical-align: middle;
147
+ }
148
+ /* Each face overlaps the one before and is ringed in the page colour, so the
149
+ stack reads as separate people rather than one smear. */
150
+ .av-group > * {
151
+ margin-inline-start: calc(var(--av-size) / -4);
152
+ box-shadow: 0 0 0 2px var(--av-bg);
153
+ }
154
+ .av-group > *:first-child {
155
+ margin-inline-start: 0;
156
+ }
157
+
158
+ .av-overflow {
159
+ position: relative;
160
+ display: inline-flex;
161
+ flex: none;
162
+ align-items: center;
163
+ justify-content: center;
164
+ width: var(--av-size);
165
+ height: var(--av-size);
166
+ border-radius: 50%;
167
+ background: var(--av-subtle);
168
+ /* Muted grey clears 4.5:1 on the page background but only reaches 4.39:1
169
+ on this one, so the count moves a step towards the text colour. */
170
+ color: color-mix(in oklab, var(--av-muted) 65%, var(--av-fg));
171
+ font-size: calc(var(--av-font-size) - 1px);
172
+ font-weight: 600;
173
+ font-variant-numeric: tabular-nums;
174
+ line-height: 1;
175
+ }
176
+ .av-overflow[data-shape="square"] {
177
+ border-radius: var(--av-radius);
178
+ }
179
+ .av-group[data-size="xs"],
180
+ .av-overflow[data-size="xs"] {
181
+ --av-size: 20px;
182
+ --av-font-size: 10px;
183
+ }
184
+ .av-group[data-size="sm"],
185
+ .av-overflow[data-size="sm"] {
186
+ --av-size: 24px;
187
+ --av-font-size: 11px;
188
+ }
189
+ .av-group[data-size="lg"],
190
+ .av-overflow[data-size="lg"] {
191
+ --av-size: 40px;
192
+ --av-font-size: 15px;
193
+ }
194
+ .av-group[data-size="xl"],
195
+ .av-overflow[data-size="xl"] {
196
+ --av-size: 56px;
197
+ --av-font-size: 20px;
198
+ }
199
+ /* The group's size reaches the avatars inside it, unless one sets its own. */
200
+ .av-group[data-size="xs"] .av-root:not([data-size]) {
201
+ --av-size: 20px;
202
+ --av-font-size: 10px;
203
+ }
204
+ .av-group[data-size="sm"] .av-root:not([data-size]) {
205
+ --av-size: 24px;
206
+ --av-font-size: 11px;
207
+ }
208
+ .av-group[data-size="lg"] .av-root:not([data-size]) {
209
+ --av-size: 40px;
210
+ --av-font-size: 15px;
211
+ }
212
+ .av-group[data-size="xl"] .av-root:not([data-size]) {
213
+ --av-size: 56px;
214
+ --av-font-size: 20px;
215
+ }
216
+
217
+ @media (forced-colors: active) {
218
+ .av-root,
219
+ .av-overflow {
220
+ border: 1px solid CanvasText;
221
+ }
222
+ .av-status {
223
+ border-color: Canvas;
224
+ }
225
+ }
226
+ }
@@ -1,15 +1,15 @@
1
1
  /*
2
2
  * Badge and Tag styles.
3
3
  *
4
- * One tinted pill in six variants and three appearances; the variant only ever
5
- * sets --bd-accent, so adding one is a single rule. Tokens read the shared
6
- * --gbs-* variables when they are set on an ancestor (set them on :root to
7
- * theme every component at once). Rules live in the `components` layer, so
8
- * utility classes passed through `className` / `classNames` override them.
4
+ * One tinted pill in six variants and three appearances; the variant only
5
+ * ever sets --bd-accent, so adding one is a single rule. Tokens read the
6
+ * shared --gbs-* variables when they are set on an ancestor (set them on
7
+ * :root to theme every component at once). Rules live in the `gbs` layer;
8
+ * declare where it sits in your global CSS, e.g. `@layer reset, gbs, app,
9
+ * utilities;`, and anything in a later layer overrides them.
9
10
  */
10
- @layer theme, base, components, utilities;
11
11
 
12
- @layer components {
12
+ @layer gbs {
13
13
  .bd-root,
14
14
  .bd-tag {
15
15
  --bd-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
@@ -3,12 +3,13 @@
3
3
  *
4
4
  * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
5
  * (set them on :root to theme every component at once) and fall back to the
6
- * same default palette otherwise. Rules live in the `components` layer, so utility classes passed
7
- * through `className` / `classNames` override them.
6
+ * same default palette otherwise. Rules live in the `gbs` layer. Declare
7
+ * where that sits in your global CSS — e.g. `@layer reset, gbs, app,
8
+ * utilities;` — and anything in a later layer, Tailwind utilities included,
9
+ * overrides them.
8
10
  */
9
- @layer theme, base, components, utilities;
10
11
 
11
- @layer components {
12
+ @layer gbs {
12
13
  .bc-root {
13
14
  --bc-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
14
15
  --bc-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));