gbs-add-block 2.0.3 → 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.
- package/.gbs/skills/gbs-components/references/styling.md +35 -10
- package/README.md +22 -7
- package/package.json +1 -1
- package/source/beta-components/accordion/styles.css +5 -5
- package/source/beta-components/alert/styles.css +4 -4
- package/source/beta-components/avatar/styles.css +226 -227
- package/source/beta-components/badge/styles.css +7 -7
- package/source/beta-components/breadcrumb/styles.css +5 -4
- package/source/beta-components/button/styles.css +5 -4
- package/source/beta-components/card/styles.css +5 -4
- package/source/beta-components/checkbox/styles.css +5 -4
- package/source/beta-components/combobox/styles.css +4 -4
- package/source/beta-components/data-grid/styles.css +7 -8
- package/source/beta-components/date-picker/styles.css +4 -4
- package/source/beta-components/dialog/styles.css +5 -4
- package/source/beta-components/file-uploader/styles.css +5 -4
- package/source/beta-components/input/styles.css +5 -4
- package/source/beta-components/menu/styles.css +5 -4
- package/source/beta-components/modal/styles.css +5 -4
- package/source/beta-components/number-input/styles.css +5 -5
- package/source/beta-components/popover/styles.css +5 -4
- package/source/beta-components/progress/styles.css +1 -2
- package/source/beta-components/radio-group/styles.css +270 -270
- package/source/beta-components/skeleton/styles.css +5 -4
- package/source/beta-components/spinner/styles.css +174 -174
- package/source/beta-components/switch/styles.css +229 -229
- package/source/beta-components/tabs/styles.css +264 -264
- package/source/beta-components/textarea/styles.css +5 -4
- package/source/beta-components/toaster/styles.css +1 -2
- package/source/beta-components/tooltip/styles.css +5 -4
|
@@ -1,270 +1,270 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Radio and RadioGroup styles.
|
|
3
|
-
*
|
|
4
|
-
* The button is the native <input type="radio"> with `appearance: none`, so
|
|
5
|
-
* keeps native behavior: arrow keys roam the group, one tab stop, and the
|
|
6
|
-
* group validates as one required field. Tokens read the shared --gbs-*
|
|
7
|
-
* variables when they are set on an ancestor (set them on :root to theme
|
|
8
|
-
* component at once). Rules live in the `
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@layer
|
|
14
|
-
.rd-root,
|
|
15
|
-
.rd-group {
|
|
16
|
-
--rd-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
|
|
17
|
-
--rd-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
|
|
18
|
-
--rd-border: var(--gbs-border-control, light-dark(#a1a1aa, #52525b));
|
|
19
|
-
--rd-card-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
|
|
20
|
-
--rd-input-bg: var(--gbs-input-bg, var(--dg-input-bg, light-dark(#ffffff, #121216)));
|
|
21
|
-
--rd-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
|
|
22
|
-
--rd-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
|
|
23
|
-
--rd-accent-soft: var(--gbs-accent-soft, var(--dg-accent-soft, light-dark(#eff6ff, #172554)));
|
|
24
|
-
--rd-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
|
|
25
|
-
--rd-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
|
|
26
|
-
--rd-radius: var(--gbs-radius, var(--dg-radius, 8px));
|
|
27
|
-
--rd-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
|
|
28
|
-
--rd-size: 16px;
|
|
29
|
-
|
|
30
|
-
color-scheme: inherit;
|
|
31
|
-
font-size: var(--rd-font-size);
|
|
32
|
-
line-height: 1.4;
|
|
33
|
-
color: var(--rd-fg);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
:where(.dark, [data-theme="dark"]) :is(.rd-root, .rd-group) {
|
|
37
|
-
color-scheme: dark;
|
|
38
|
-
}
|
|
39
|
-
:where(.light, [data-theme="light"]) :is(.rd-root, .rd-group) {
|
|
40
|
-
color-scheme: light;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
:where(.rd-root, .rd-group) *,
|
|
44
|
-
:where(.rd-root, .rd-group) *::before,
|
|
45
|
-
:where(.rd-root, .rd-group) *::after {
|
|
46
|
-
box-sizing: border-box;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/* ---------------------------------------------------------------- radio */
|
|
50
|
-
|
|
51
|
-
.rd-root {
|
|
52
|
-
display: flex;
|
|
53
|
-
align-items: flex-start;
|
|
54
|
-
gap: 8px;
|
|
55
|
-
min-width: 0;
|
|
56
|
-
}
|
|
57
|
-
.rd-root[data-size="sm"] {
|
|
58
|
-
--rd-size: 14px;
|
|
59
|
-
--rd-font-size: 12px;
|
|
60
|
-
}
|
|
61
|
-
.rd-root[data-size="lg"] {
|
|
62
|
-
--rd-size: 20px;
|
|
63
|
-
--rd-font-size: 14px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.rd-control {
|
|
67
|
-
position: relative;
|
|
68
|
-
display: inline-flex;
|
|
69
|
-
flex: none;
|
|
70
|
-
align-items: center;
|
|
71
|
-
justify-content: center;
|
|
72
|
-
/* Line the button up with the first line of the label. */
|
|
73
|
-
height: calc(var(--rd-font-size) * 1.4);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.rd-input {
|
|
77
|
-
width: var(--rd-size);
|
|
78
|
-
height: var(--rd-size);
|
|
79
|
-
margin: 0;
|
|
80
|
-
border: 1px solid var(--rd-border);
|
|
81
|
-
border-radius: 50%;
|
|
82
|
-
appearance: none;
|
|
83
|
-
background: var(--rd-input-bg);
|
|
84
|
-
cursor: pointer;
|
|
85
|
-
transition:
|
|
86
|
-
border-color 120ms ease,
|
|
87
|
-
background-color 120ms ease;
|
|
88
|
-
}
|
|
89
|
-
.rd-input:hover:not(:disabled) {
|
|
90
|
-
border-color: var(--rd-accent);
|
|
91
|
-
}
|
|
92
|
-
.rd-input:checked {
|
|
93
|
-
border-color: var(--rd-accent);
|
|
94
|
-
border-width: 2px;
|
|
95
|
-
}
|
|
96
|
-
.rd-input:focus-visible {
|
|
97
|
-
outline: 2px solid var(--rd-focus);
|
|
98
|
-
outline-offset: 2px;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/* The dot is a separate element rather than a border trick, so its size can
|
|
102
|
-
follow the control's and it can animate in. */
|
|
103
|
-
.rd-dot {
|
|
104
|
-
position: absolute;
|
|
105
|
-
width: calc(var(--rd-size) / 2);
|
|
106
|
-
height: calc(var(--rd-size) / 2);
|
|
107
|
-
border-radius: 50%;
|
|
108
|
-
background: var(--rd-accent);
|
|
109
|
-
scale: 0;
|
|
110
|
-
transition: scale 120ms ease;
|
|
111
|
-
pointer-events: none;
|
|
112
|
-
}
|
|
113
|
-
.rd-input:checked ~ .rd-dot {
|
|
114
|
-
scale: 1;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.rd-root[data-invalid] .rd-input {
|
|
118
|
-
border-color: var(--rd-danger);
|
|
119
|
-
}
|
|
120
|
-
/* Only the button dims. Fading the whole choice takes its label below the
|
|
121
|
-
contrast floor, and someone still has to be able to read the option they
|
|
122
|
-
cannot pick. */
|
|
123
|
-
.rd-input:disabled {
|
|
124
|
-
opacity: 0.5;
|
|
125
|
-
cursor: not-allowed;
|
|
126
|
-
}
|
|
127
|
-
.rd-root[data-disabled] .rd-dot {
|
|
128
|
-
opacity: 0.5;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.rd-text {
|
|
132
|
-
display: flex;
|
|
133
|
-
flex-direction: column;
|
|
134
|
-
gap: 2px;
|
|
135
|
-
min-width: 0;
|
|
136
|
-
}
|
|
137
|
-
.rd-label {
|
|
138
|
-
font-weight: 500;
|
|
139
|
-
cursor: pointer;
|
|
140
|
-
}
|
|
141
|
-
.rd-root[data-disabled] .rd-label {
|
|
142
|
-
color: var(--rd-muted);
|
|
143
|
-
cursor: not-allowed;
|
|
144
|
-
}
|
|
145
|
-
.rd-description {
|
|
146
|
-
color: var(--rd-muted);
|
|
147
|
-
text-wrap: pretty;
|
|
148
|
-
}
|
|
149
|
-
.rd-error {
|
|
150
|
-
color: var(--rd-danger);
|
|
151
|
-
text-wrap: pretty;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* ----------------------------------------------------------------- card */
|
|
155
|
-
|
|
156
|
-
.rd-root[data-variant="card"] {
|
|
157
|
-
position: relative;
|
|
158
|
-
align-items: flex-start;
|
|
159
|
-
padding: 12px;
|
|
160
|
-
border: 1px solid var(--rd-card-border);
|
|
161
|
-
border-radius: var(--rd-radius);
|
|
162
|
-
background: var(--rd-input-bg);
|
|
163
|
-
cursor: pointer;
|
|
164
|
-
transition:
|
|
165
|
-
border-color 120ms ease,
|
|
166
|
-
background-color 120ms ease;
|
|
167
|
-
}
|
|
168
|
-
.rd-root[data-variant="card"]:hover:not([data-disabled]) {
|
|
169
|
-
background: var(--rd-hover);
|
|
170
|
-
}
|
|
171
|
-
.rd-root[data-variant="card"][data-checked] {
|
|
172
|
-
border-color: var(--rd-accent);
|
|
173
|
-
background: var(--rd-accent-soft);
|
|
174
|
-
}
|
|
175
|
-
/* Muted grey clears 4.5:1 on white but only reaches 4.44:1 on the tinted
|
|
176
|
-
background of a selected card, so it moves a step towards the text colour
|
|
177
|
-
there rather than the description quietly failing contrast. */
|
|
178
|
-
.rd-root[data-variant="card"][data-checked] .rd-description {
|
|
179
|
-
color: color-mix(in oklab, var(--rd-muted) 72%, var(--rd-fg));
|
|
180
|
-
}
|
|
181
|
-
/* The whole tile is the target: the input covers it, so a press anywhere
|
|
182
|
-
lands on the radio itself rather than on a label that forwards it. */
|
|
183
|
-
.rd-root[data-variant="card"] .rd-input::after {
|
|
184
|
-
content: "";
|
|
185
|
-
position: absolute;
|
|
186
|
-
inset: 0;
|
|
187
|
-
border-radius: var(--rd-radius);
|
|
188
|
-
}
|
|
189
|
-
.rd-root[data-variant="card"]:has(.rd-input:focus-visible) {
|
|
190
|
-
outline: 2px solid var(--rd-focus);
|
|
191
|
-
outline-offset: 2px;
|
|
192
|
-
}
|
|
193
|
-
.rd-root[data-variant="card"] .rd-input:focus-visible {
|
|
194
|
-
outline: none;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/* ---------------------------------------------------------------- group */
|
|
198
|
-
|
|
199
|
-
.rd-group {
|
|
200
|
-
display: flex;
|
|
201
|
-
flex-direction: column;
|
|
202
|
-
gap: 8px;
|
|
203
|
-
min-width: 0;
|
|
204
|
-
margin: 0;
|
|
205
|
-
padding: 0;
|
|
206
|
-
border: 0;
|
|
207
|
-
}
|
|
208
|
-
.rd-legend {
|
|
209
|
-
padding: 0;
|
|
210
|
-
font-weight: 500;
|
|
211
|
-
}
|
|
212
|
-
.rd-legend[data-required]::after {
|
|
213
|
-
content: " *";
|
|
214
|
-
color: var(--rd-danger);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
.rd-items {
|
|
218
|
-
display: flex;
|
|
219
|
-
flex-direction: column;
|
|
220
|
-
gap: 8px;
|
|
221
|
-
min-width: 0;
|
|
222
|
-
}
|
|
223
|
-
.rd-group[data-orientation="horizontal"] .rd-items {
|
|
224
|
-
flex-flow: row wrap;
|
|
225
|
-
gap: 16px;
|
|
226
|
-
}
|
|
227
|
-
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-items {
|
|
228
|
-
gap: 8px;
|
|
229
|
-
}
|
|
230
|
-
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-root {
|
|
231
|
-
flex: 1 1 180px;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.rd-clear {
|
|
235
|
-
align-self: flex-start;
|
|
236
|
-
padding: 0;
|
|
237
|
-
border: 0;
|
|
238
|
-
background: none;
|
|
239
|
-
color: var(--rd-accent);
|
|
240
|
-
font: inherit;
|
|
241
|
-
text-decoration: underline;
|
|
242
|
-
text-underline-offset: 2px;
|
|
243
|
-
cursor: pointer;
|
|
244
|
-
}
|
|
245
|
-
.rd-clear:focus-visible {
|
|
246
|
-
outline: 2px solid var(--rd-focus);
|
|
247
|
-
outline-offset: 2px;
|
|
248
|
-
border-radius: 3px;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
@media (prefers-reduced-motion: reduce) {
|
|
252
|
-
.rd-input,
|
|
253
|
-
.rd-dot,
|
|
254
|
-
.rd-root[data-variant="card"] {
|
|
255
|
-
transition: none;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
@media (forced-colors: active) {
|
|
260
|
-
.rd-input {
|
|
261
|
-
border: 1px solid CanvasText;
|
|
262
|
-
}
|
|
263
|
-
.rd-dot {
|
|
264
|
-
background: Highlight;
|
|
265
|
-
}
|
|
266
|
-
.rd-root[data-variant="card"][data-checked] {
|
|
267
|
-
border-color: Highlight;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Radio and RadioGroup styles.
|
|
3
|
+
*
|
|
4
|
+
* The button is the native <input type="radio"> with `appearance: none`, so
|
|
5
|
+
* it keeps native behavior: arrow keys roam the group, one tab stop, and the
|
|
6
|
+
* whole group validates as one required field. Tokens read the shared --gbs-*
|
|
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.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
@layer gbs {
|
|
14
|
+
.rd-root,
|
|
15
|
+
.rd-group {
|
|
16
|
+
--rd-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
|
|
17
|
+
--rd-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
|
|
18
|
+
--rd-border: var(--gbs-border-control, light-dark(#a1a1aa, #52525b));
|
|
19
|
+
--rd-card-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
|
|
20
|
+
--rd-input-bg: var(--gbs-input-bg, var(--dg-input-bg, light-dark(#ffffff, #121216)));
|
|
21
|
+
--rd-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
|
|
22
|
+
--rd-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
|
|
23
|
+
--rd-accent-soft: var(--gbs-accent-soft, var(--dg-accent-soft, light-dark(#eff6ff, #172554)));
|
|
24
|
+
--rd-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
|
|
25
|
+
--rd-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
|
|
26
|
+
--rd-radius: var(--gbs-radius, var(--dg-radius, 8px));
|
|
27
|
+
--rd-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
|
|
28
|
+
--rd-size: 16px;
|
|
29
|
+
|
|
30
|
+
color-scheme: inherit;
|
|
31
|
+
font-size: var(--rd-font-size);
|
|
32
|
+
line-height: 1.4;
|
|
33
|
+
color: var(--rd-fg);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
:where(.dark, [data-theme="dark"]) :is(.rd-root, .rd-group) {
|
|
37
|
+
color-scheme: dark;
|
|
38
|
+
}
|
|
39
|
+
:where(.light, [data-theme="light"]) :is(.rd-root, .rd-group) {
|
|
40
|
+
color-scheme: light;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:where(.rd-root, .rd-group) *,
|
|
44
|
+
:where(.rd-root, .rd-group) *::before,
|
|
45
|
+
:where(.rd-root, .rd-group) *::after {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ---------------------------------------------------------------- radio */
|
|
50
|
+
|
|
51
|
+
.rd-root {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: flex-start;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
}
|
|
57
|
+
.rd-root[data-size="sm"] {
|
|
58
|
+
--rd-size: 14px;
|
|
59
|
+
--rd-font-size: 12px;
|
|
60
|
+
}
|
|
61
|
+
.rd-root[data-size="lg"] {
|
|
62
|
+
--rd-size: 20px;
|
|
63
|
+
--rd-font-size: 14px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.rd-control {
|
|
67
|
+
position: relative;
|
|
68
|
+
display: inline-flex;
|
|
69
|
+
flex: none;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
/* Line the button up with the first line of the label. */
|
|
73
|
+
height: calc(var(--rd-font-size) * 1.4);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.rd-input {
|
|
77
|
+
width: var(--rd-size);
|
|
78
|
+
height: var(--rd-size);
|
|
79
|
+
margin: 0;
|
|
80
|
+
border: 1px solid var(--rd-border);
|
|
81
|
+
border-radius: 50%;
|
|
82
|
+
appearance: none;
|
|
83
|
+
background: var(--rd-input-bg);
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
transition:
|
|
86
|
+
border-color 120ms ease,
|
|
87
|
+
background-color 120ms ease;
|
|
88
|
+
}
|
|
89
|
+
.rd-input:hover:not(:disabled) {
|
|
90
|
+
border-color: var(--rd-accent);
|
|
91
|
+
}
|
|
92
|
+
.rd-input:checked {
|
|
93
|
+
border-color: var(--rd-accent);
|
|
94
|
+
border-width: 2px;
|
|
95
|
+
}
|
|
96
|
+
.rd-input:focus-visible {
|
|
97
|
+
outline: 2px solid var(--rd-focus);
|
|
98
|
+
outline-offset: 2px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* The dot is a separate element rather than a border trick, so its size can
|
|
102
|
+
follow the control's and it can animate in. */
|
|
103
|
+
.rd-dot {
|
|
104
|
+
position: absolute;
|
|
105
|
+
width: calc(var(--rd-size) / 2);
|
|
106
|
+
height: calc(var(--rd-size) / 2);
|
|
107
|
+
border-radius: 50%;
|
|
108
|
+
background: var(--rd-accent);
|
|
109
|
+
scale: 0;
|
|
110
|
+
transition: scale 120ms ease;
|
|
111
|
+
pointer-events: none;
|
|
112
|
+
}
|
|
113
|
+
.rd-input:checked ~ .rd-dot {
|
|
114
|
+
scale: 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.rd-root[data-invalid] .rd-input {
|
|
118
|
+
border-color: var(--rd-danger);
|
|
119
|
+
}
|
|
120
|
+
/* Only the button dims. Fading the whole choice takes its label below the
|
|
121
|
+
contrast floor, and someone still has to be able to read the option they
|
|
122
|
+
cannot pick. */
|
|
123
|
+
.rd-input:disabled {
|
|
124
|
+
opacity: 0.5;
|
|
125
|
+
cursor: not-allowed;
|
|
126
|
+
}
|
|
127
|
+
.rd-root[data-disabled] .rd-dot {
|
|
128
|
+
opacity: 0.5;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.rd-text {
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
gap: 2px;
|
|
135
|
+
min-width: 0;
|
|
136
|
+
}
|
|
137
|
+
.rd-label {
|
|
138
|
+
font-weight: 500;
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
}
|
|
141
|
+
.rd-root[data-disabled] .rd-label {
|
|
142
|
+
color: var(--rd-muted);
|
|
143
|
+
cursor: not-allowed;
|
|
144
|
+
}
|
|
145
|
+
.rd-description {
|
|
146
|
+
color: var(--rd-muted);
|
|
147
|
+
text-wrap: pretty;
|
|
148
|
+
}
|
|
149
|
+
.rd-error {
|
|
150
|
+
color: var(--rd-danger);
|
|
151
|
+
text-wrap: pretty;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* ----------------------------------------------------------------- card */
|
|
155
|
+
|
|
156
|
+
.rd-root[data-variant="card"] {
|
|
157
|
+
position: relative;
|
|
158
|
+
align-items: flex-start;
|
|
159
|
+
padding: 12px;
|
|
160
|
+
border: 1px solid var(--rd-card-border);
|
|
161
|
+
border-radius: var(--rd-radius);
|
|
162
|
+
background: var(--rd-input-bg);
|
|
163
|
+
cursor: pointer;
|
|
164
|
+
transition:
|
|
165
|
+
border-color 120ms ease,
|
|
166
|
+
background-color 120ms ease;
|
|
167
|
+
}
|
|
168
|
+
.rd-root[data-variant="card"]:hover:not([data-disabled]) {
|
|
169
|
+
background: var(--rd-hover);
|
|
170
|
+
}
|
|
171
|
+
.rd-root[data-variant="card"][data-checked] {
|
|
172
|
+
border-color: var(--rd-accent);
|
|
173
|
+
background: var(--rd-accent-soft);
|
|
174
|
+
}
|
|
175
|
+
/* Muted grey clears 4.5:1 on white but only reaches 4.44:1 on the tinted
|
|
176
|
+
background of a selected card, so it moves a step towards the text colour
|
|
177
|
+
there rather than the description quietly failing contrast. */
|
|
178
|
+
.rd-root[data-variant="card"][data-checked] .rd-description {
|
|
179
|
+
color: color-mix(in oklab, var(--rd-muted) 72%, var(--rd-fg));
|
|
180
|
+
}
|
|
181
|
+
/* The whole tile is the target: the input covers it, so a press anywhere
|
|
182
|
+
lands on the radio itself rather than on a label that forwards it. */
|
|
183
|
+
.rd-root[data-variant="card"] .rd-input::after {
|
|
184
|
+
content: "";
|
|
185
|
+
position: absolute;
|
|
186
|
+
inset: 0;
|
|
187
|
+
border-radius: var(--rd-radius);
|
|
188
|
+
}
|
|
189
|
+
.rd-root[data-variant="card"]:has(.rd-input:focus-visible) {
|
|
190
|
+
outline: 2px solid var(--rd-focus);
|
|
191
|
+
outline-offset: 2px;
|
|
192
|
+
}
|
|
193
|
+
.rd-root[data-variant="card"] .rd-input:focus-visible {
|
|
194
|
+
outline: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* ---------------------------------------------------------------- group */
|
|
198
|
+
|
|
199
|
+
.rd-group {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
gap: 8px;
|
|
203
|
+
min-width: 0;
|
|
204
|
+
margin: 0;
|
|
205
|
+
padding: 0;
|
|
206
|
+
border: 0;
|
|
207
|
+
}
|
|
208
|
+
.rd-legend {
|
|
209
|
+
padding: 0;
|
|
210
|
+
font-weight: 500;
|
|
211
|
+
}
|
|
212
|
+
.rd-legend[data-required]::after {
|
|
213
|
+
content: " *";
|
|
214
|
+
color: var(--rd-danger);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.rd-items {
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
gap: 8px;
|
|
221
|
+
min-width: 0;
|
|
222
|
+
}
|
|
223
|
+
.rd-group[data-orientation="horizontal"] .rd-items {
|
|
224
|
+
flex-flow: row wrap;
|
|
225
|
+
gap: 16px;
|
|
226
|
+
}
|
|
227
|
+
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-items {
|
|
228
|
+
gap: 8px;
|
|
229
|
+
}
|
|
230
|
+
.rd-group[data-variant="card"][data-orientation="horizontal"] .rd-root {
|
|
231
|
+
flex: 1 1 180px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.rd-clear {
|
|
235
|
+
align-self: flex-start;
|
|
236
|
+
padding: 0;
|
|
237
|
+
border: 0;
|
|
238
|
+
background: none;
|
|
239
|
+
color: var(--rd-accent);
|
|
240
|
+
font: inherit;
|
|
241
|
+
text-decoration: underline;
|
|
242
|
+
text-underline-offset: 2px;
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
}
|
|
245
|
+
.rd-clear:focus-visible {
|
|
246
|
+
outline: 2px solid var(--rd-focus);
|
|
247
|
+
outline-offset: 2px;
|
|
248
|
+
border-radius: 3px;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@media (prefers-reduced-motion: reduce) {
|
|
252
|
+
.rd-input,
|
|
253
|
+
.rd-dot,
|
|
254
|
+
.rd-root[data-variant="card"] {
|
|
255
|
+
transition: none;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@media (forced-colors: active) {
|
|
260
|
+
.rd-input {
|
|
261
|
+
border: 1px solid CanvasText;
|
|
262
|
+
}
|
|
263
|
+
.rd-dot {
|
|
264
|
+
background: Highlight;
|
|
265
|
+
}
|
|
266
|
+
.rd-root[data-variant="card"][data-checked] {
|
|
267
|
+
border-color: Highlight;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -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 `
|
|
7
|
-
*
|
|
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
|
|
12
|
+
@layer gbs {
|
|
12
13
|
.sk-root,
|
|
13
14
|
.em-root {
|
|
14
15
|
--sk-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
|