@gtivr4/a1-design-system-react 0.2.4 → 0.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtivr4/a1-design-system-react",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "description": "React components for the A1 token-driven design system.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,6 +9,16 @@
9
9
  box-sizing: border-box;
10
10
  }
11
11
 
12
+ /* ─── Root typeface ──────────────────────────────────────────────────────────
13
+ Apply the design system body font to the document so unscoped elements
14
+ inherit the correct typeface without requiring any A1 component to be
15
+ rendered first. Without this, the browser default (serif) is used until a
16
+ component's own CSS loads. */
17
+
18
+ body {
19
+ font-family: var(--component-paragraph-font-family);
20
+ }
21
+
12
22
  /* ─── Form field interaction tokens — light mode defaults ────────────────────
13
23
  Single source of truth for hover, active, and read-only states across all
14
24
  form field components. Overridden in every dark-mode context below.
@@ -0,0 +1,205 @@
1
+ import { Fragment, useId, useState } from "react";
2
+ import { useLabel } from "../labels/Labels.jsx";
3
+ import { MessageBadge } from "../message/Message.jsx";
4
+ import { Icon } from "../icon/Icon.jsx";
5
+ import "./choice-group.css";
6
+
7
+ const SIZES = ["compact", "default", "comfortable"];
8
+
9
+ const BP_MIN = { xs: 0, sm: 481, md: 641, lg: 1025, xl: 1441 };
10
+
11
+ export function ChoiceGroup({
12
+ label,
13
+ hint,
14
+ error,
15
+ success,
16
+ size = "default",
17
+ columns,
18
+ multiple = false,
19
+ required = false,
20
+ name,
21
+ options = [],
22
+ sections,
23
+ value,
24
+ defaultValue,
25
+ onChange,
26
+ id: providedId,
27
+ className = "",
28
+ ...props
29
+ }) {
30
+ const autoId = useId();
31
+ const id = providedId ?? autoId;
32
+ const hintId = `${id}-hint`;
33
+ const errorId = `${id}-error`;
34
+ const successId = `${id}-success`;
35
+
36
+ const resolvedSize = SIZES.includes(size) ? size : "default";
37
+
38
+ const defaultVal = defaultValue ?? (multiple ? [] : null);
39
+ const [internalValue, setInternalValue] = useState(defaultVal);
40
+ const currentValue = value !== undefined ? value : internalValue;
41
+
42
+ function handleChange(optionValue, checked) {
43
+ if (multiple) {
44
+ const next = checked
45
+ ? [...(currentValue ?? []), optionValue]
46
+ : (currentValue ?? []).filter(v => v !== optionValue);
47
+ if (value === undefined) setInternalValue(next);
48
+ onChange?.(next);
49
+ } else {
50
+ if (value === undefined) setInternalValue(optionValue);
51
+ onChange?.(optionValue);
52
+ }
53
+ }
54
+
55
+ const isFixedNumber = typeof columns === "number" && columns > 0;
56
+ const isResponsiveObj = columns !== null && typeof columns === "object";
57
+ const isFixedColumns = isFixedNumber || isResponsiveObj;
58
+
59
+ const responsiveClass = isResponsiveObj
60
+ ? `a1-cg-${autoId.replace(/[^a-zA-Z0-9_-]/g, "")}`
61
+ : null;
62
+
63
+ const responsiveStyle = isResponsiveObj
64
+ ? Object.entries(columns)
65
+ .filter(([bp, n]) => bp in BP_MIN && typeof n === "number" && n > 0)
66
+ .sort(([a], [b]) => BP_MIN[a] - BP_MIN[b])
67
+ .map(([bp, n]) => {
68
+ const min = BP_MIN[bp];
69
+ const rule = `.${responsiveClass} { --a1-cg-columns: ${n}; }`;
70
+ return min === 0 ? rule : `@media (min-width: ${min}px) { .${responsiveClass} { --a1-cg-columns: ${n}; } }`;
71
+ })
72
+ .join("\n")
73
+ : null;
74
+
75
+ const classes = [
76
+ "a1-choice-group",
77
+ resolvedSize !== "default" && `a1-choice-group--${resolvedSize}`,
78
+ multiple ? "a1-choice-group--multiple" : "a1-choice-group--single",
79
+ isFixedColumns && "a1-choice-group--fixed-columns",
80
+ responsiveClass,
81
+ error && "a1-choice-group--error",
82
+ success && "a1-choice-group--success",
83
+ required && "a1-choice-group--required",
84
+ className,
85
+ ].filter(Boolean).join(" ");
86
+
87
+ const messageId = error ? errorId : success ? successId : hint ? hintId : null;
88
+ const describedBy = messageId || undefined;
89
+ const requiredText = useLabel("field.required", "Required");
90
+ const groupName = name ?? id;
91
+
92
+ const inlineStyle = isFixedNumber ? { "--a1-cg-columns": columns } : undefined;
93
+
94
+ function renderOption(option) {
95
+ const isDisabled = option.disabled ?? false;
96
+ const isChecked = multiple
97
+ ? (currentValue ?? []).includes(option.value)
98
+ : currentValue === option.value;
99
+ const itemId = `${id}-${option.value}`;
100
+ return (
101
+ <label
102
+ key={option.value}
103
+ htmlFor={itemId}
104
+ className={[
105
+ "a1-choice-item",
106
+ isDisabled && "a1-choice-item--disabled",
107
+ ].filter(Boolean).join(" ")}
108
+ >
109
+ <input
110
+ type={multiple ? "checkbox" : "radio"}
111
+ id={itemId}
112
+ className="a1-choice-item__input"
113
+ name={multiple ? (name ?? id) : groupName}
114
+ value={option.value}
115
+ checked={isChecked}
116
+ disabled={isDisabled}
117
+ onChange={(e) => handleChange(option.value, e.target.checked)}
118
+ />
119
+ {option.icon && (
120
+ <span className="a1-choice-item__icon" aria-hidden="true">
121
+ <Icon name={option.icon} />
122
+ </span>
123
+ )}
124
+ <span className="a1-choice-item__content">
125
+ <span className="a1-choice-item__label">{option.label}</span>
126
+ {option.subtext && (
127
+ <span className="a1-choice-item__subtext">{option.subtext}</span>
128
+ )}
129
+ </span>
130
+ <span className="a1-choice-item__indicator" aria-hidden="true" />
131
+ </label>
132
+ );
133
+ }
134
+
135
+ function renderItems(opts, ariaLabelledBy) {
136
+ return (
137
+ <div
138
+ className="a1-choice-group__items"
139
+ role="group"
140
+ aria-labelledby={ariaLabelledBy}
141
+ >
142
+ {opts.map(renderOption)}
143
+ </div>
144
+ );
145
+ }
146
+
147
+ return (
148
+ <>
149
+ {responsiveStyle && <style>{responsiveStyle}</style>}
150
+ <fieldset
151
+ className={classes}
152
+ aria-describedby={describedBy}
153
+ style={inlineStyle}
154
+ {...props}
155
+ >
156
+ {label && (
157
+ <legend className="a1-choice-group__legend">
158
+ <span className="a1-choice-group__legend-inner">
159
+ {label}
160
+ {required && resolvedSize === "comfortable" ? (
161
+ <MessageBadge status="info" subtle>{requiredText}</MessageBadge>
162
+ ) : required ? (
163
+ <span className="a1-field__asterisk" aria-hidden="true"> *</span>
164
+ ) : null}
165
+ </span>
166
+ </legend>
167
+ )}
168
+ {!error && !success && hint && (
169
+ <p className="a1-choice-group__message a1-choice-group__message--hint" id={hintId}>
170
+ {hint}
171
+ </p>
172
+ )}
173
+ {sections
174
+ ? sections.map((section, i) => (
175
+ <Fragment key={section.label ?? i}>
176
+ {i > 0 && <hr className="a1-choice-group__section-divider" aria-hidden="true" />}
177
+ <div className="a1-choice-group__section">
178
+ {section.label && (
179
+ <p
180
+ className="a1-choice-group__section-label"
181
+ id={`${id}-section-${i}`}
182
+ >
183
+ {section.label}
184
+ </p>
185
+ )}
186
+ {renderItems(section.options, section.label ? `${id}-section-${i}` : undefined)}
187
+ </div>
188
+ </Fragment>
189
+ ))
190
+ : renderItems(options, undefined)
191
+ }
192
+ {error && (
193
+ <p className="a1-choice-group__message a1-choice-group__message--error" id={errorId} role="alert">
194
+ {error}
195
+ </p>
196
+ )}
197
+ {!error && success && (
198
+ <p className="a1-choice-group__message a1-choice-group__message--success" id={successId}>
199
+ {success}
200
+ </p>
201
+ )}
202
+ </fieldset>
203
+ </>
204
+ );
205
+ }
@@ -0,0 +1,332 @@
1
+ /* ─── ChoiceGroup ──────────────────────────────────────────────────────────── */
2
+
3
+ .a1-choice-group {
4
+ border: none;
5
+ margin: 0;
6
+ padding: 0;
7
+ min-width: 0;
8
+
9
+ /* Tile size defaults (default) */
10
+ --a1-cg-padding: var(--component-choice-group-default-padding);
11
+ --a1-cg-icon-size: var(--component-choice-group-default-icon-size);
12
+ --a1-cg-indicator-size: var(--component-choice-group-default-indicator-size);
13
+ --a1-cg-content-gap: var(--component-choice-group-default-content-gap);
14
+ --a1-cg-min-width: var(--component-choice-group-default-min-width);
15
+ --a1-cg-label-size: var(--semantic-font-size-body-md);
16
+ --a1-cg-subtext-size: var(--semantic-font-size-body-sm);
17
+ --a1-cg-legend-size: var(--semantic-font-size-body-sm);
18
+ --a1-cg-section-label-size: var(--semantic-font-size-body-xs);
19
+
20
+ /* Gap between tiles — tracks size */
21
+ --a1-cg-gap: var(--component-choice-group-gap-md);
22
+
23
+ /* Spacing between legend/messages and the items container */
24
+ --a1-cg-group-gap: var(--component-choice-group-default-group-gap);
25
+ --a1-cg-items-top-gap: var(--component-choice-group-default-items-top-gap);
26
+
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: var(--a1-cg-group-gap);
30
+ }
31
+
32
+ /* ─── Tile sizes — affect only tile padding and child element sizes ─────────── */
33
+
34
+ .a1-choice-group--compact {
35
+ --a1-cg-padding: var(--component-choice-group-compact-padding);
36
+ --a1-cg-icon-size: var(--component-choice-group-compact-icon-size);
37
+ --a1-cg-indicator-size: var(--component-choice-group-compact-indicator-size);
38
+ --a1-cg-content-gap: var(--component-choice-group-compact-content-gap);
39
+ --a1-cg-min-width: var(--component-choice-group-compact-min-width);
40
+ --a1-cg-label-size: var(--semantic-font-size-body-sm);
41
+ --a1-cg-subtext-size: var(--semantic-font-size-body-xs);
42
+ --a1-cg-legend-size: var(--semantic-font-size-body-xs);
43
+ --a1-cg-gap: var(--component-choice-group-gap-sm);
44
+ --a1-cg-group-gap: var(--component-choice-group-compact-group-gap);
45
+ --a1-cg-items-top-gap: var(--component-choice-group-compact-items-top-gap);
46
+ }
47
+
48
+ .a1-choice-group--comfortable {
49
+ --a1-cg-padding: var(--component-choice-group-comfortable-padding);
50
+ --a1-cg-icon-size: var(--component-choice-group-comfortable-icon-size);
51
+ --a1-cg-indicator-size: var(--component-choice-group-comfortable-indicator-size);
52
+ --a1-cg-content-gap: var(--component-choice-group-comfortable-content-gap);
53
+ --a1-cg-min-width: var(--component-choice-group-comfortable-min-width);
54
+ --a1-cg-label-size: var(--semantic-font-size-body-lg);
55
+ --a1-cg-subtext-size: var(--semantic-font-size-body-md);
56
+ --a1-cg-legend-size: var(--semantic-font-size-body-md);
57
+ --a1-cg-section-label-size: var(--semantic-font-size-body-sm);
58
+ --a1-cg-gap: var(--component-choice-group-gap-lg);
59
+ --a1-cg-group-gap: var(--component-choice-group-comfortable-group-gap);
60
+ --a1-cg-items-top-gap: var(--component-choice-group-comfortable-items-top-gap);
61
+ }
62
+
63
+ @media (--bp-md-up) {
64
+ .a1-choice-group--comfortable {
65
+ --a1-cg-legend-size: var(--semantic-font-size-body-lg);
66
+ }
67
+ }
68
+
69
+ /* ─── Legend ────────────────────────────────────────────────────────────────── */
70
+
71
+ .a1-choice-group__legend {
72
+ display: block;
73
+ width: 100%;
74
+ padding: 0;
75
+ font-family: var(--component-paragraph-font-family);
76
+ font-size: var(--a1-cg-legend-size);
77
+ font-weight: var(--component-field-label-font-weight);
78
+ color: var(--semantic-color-text-default);
79
+ line-height: var(--semantic-font-line-height-body);
80
+ }
81
+
82
+ .a1-choice-group__legend-inner {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: var(--base-spacing-6);
86
+ }
87
+
88
+ /* ─── Group messages (hint / error / success) ────────────────────────────────── */
89
+
90
+ .a1-choice-group__message {
91
+ margin: 0;
92
+ font-family: var(--component-paragraph-font-family);
93
+ font-size: var(--a1-cg-legend-size);
94
+ line-height: var(--semantic-font-line-height-body);
95
+ }
96
+
97
+ .a1-choice-group__message--hint { color: var(--semantic-color-text-muted); }
98
+ .a1-choice-group__message--error {
99
+ color: var(--semantic-color-status-error-background);
100
+ font-weight: var(--base-font-weight-medium);
101
+ }
102
+ .a1-choice-group__message--success {
103
+ color: var(--semantic-color-status-success-background);
104
+ font-weight: var(--base-font-weight-medium);
105
+ }
106
+
107
+ /* ─── Sections ───────────────────────────────────────────────────────────────── */
108
+
109
+ .a1-choice-group__section-divider {
110
+ border: none;
111
+ border-top: 1px solid var(--semantic-color-border-subtle);
112
+ margin: var(--a1-cg-gap) 0 0;
113
+ padding: 0;
114
+ }
115
+
116
+ .a1-choice-group__section {
117
+ display: flex;
118
+ flex-direction: column;
119
+ }
120
+
121
+ .a1-choice-group__section-label {
122
+ margin: 0 0 var(--a1-cg-items-top-gap);
123
+ font-family: var(--component-paragraph-font-family);
124
+ font-size: var(--a1-cg-section-label-size);
125
+ font-weight: var(--base-font-weight-semibold);
126
+ color: var(--semantic-color-text-muted);
127
+ line-height: var(--semantic-font-line-height-body);
128
+ }
129
+
130
+ /* Items inside a section — the section label handles the top spacing */
131
+ .a1-choice-group__section .a1-choice-group__items {
132
+ margin-top: 0;
133
+ }
134
+
135
+ /* ─── Items flex layout ─────────────────────────────────────────────────────── */
136
+
137
+ .a1-choice-group__items {
138
+ display: flex;
139
+ flex-wrap: wrap;
140
+ gap: var(--a1-cg-gap);
141
+ margin-top: var(--a1-cg-items-top-gap);
142
+ }
143
+
144
+ /* Fixed column count when --a1-cg-columns is set */
145
+ .a1-choice-group--fixed-columns .a1-choice-group__items > .a1-choice-item {
146
+ flex: 0 0 calc((100% - (var(--a1-cg-columns) - 1) * var(--a1-cg-gap)) / var(--a1-cg-columns));
147
+ }
148
+
149
+ /* ─── Choice item (card tile) ───────────────────────────────────────────────── */
150
+
151
+ .a1-choice-item {
152
+ position: relative;
153
+ display: flex;
154
+ flex-direction: column;
155
+ flex: 1 1 var(--a1-cg-min-width);
156
+ gap: var(--a1-cg-content-gap);
157
+ overflow: hidden;
158
+ /* Start padding offsets all content clear of the indicator in the top-start corner */
159
+ padding-block: var(--a1-cg-padding);
160
+ padding-inline-end: var(--a1-cg-padding);
161
+ padding-inline-start: calc(var(--a1-cg-padding) + var(--a1-cg-indicator-size) + var(--base-spacing-8));
162
+ border: var(--component-choice-group-border-width) solid var(--semantic-color-border-subtle);
163
+ border-radius: var(--component-choice-group-border-radius);
164
+ background-color: var(--semantic-color-surface-page);
165
+ cursor: pointer;
166
+ transition:
167
+ border-color var(--semantic-motion-duration-fast) var(--semantic-motion-easing-standard),
168
+ background-color var(--semantic-motion-duration-fast) var(--semantic-motion-easing-standard),
169
+ box-shadow var(--semantic-motion-duration-fast) var(--semantic-motion-easing-standard);
170
+ }
171
+
172
+ .a1-choice-item--disabled {
173
+ cursor: not-allowed;
174
+ opacity: 0.5;
175
+ background-color: var(--semantic-color-surface-raised);
176
+ }
177
+
178
+ .a1-choice-item--disabled .a1-choice-item__input {
179
+ pointer-events: none;
180
+ }
181
+
182
+ /* Hover (unselected, non-disabled) */
183
+ .a1-choice-item:not(.a1-choice-item--disabled):not(:has(.a1-choice-item__input:checked)):hover {
184
+ border-color: var(--semantic-color-action-border);
185
+ background-color: var(--semantic-color-action-surface);
186
+ }
187
+
188
+ /* Selected */
189
+ .a1-choice-item:not(.a1-choice-item--disabled):has(.a1-choice-item__input:checked) {
190
+ border-color: var(--semantic-color-action-background);
191
+ background-color: var(--semantic-color-action-surface);
192
+ box-shadow: inset 0 0 0 1px var(--semantic-color-action-background);
193
+ }
194
+
195
+ /* Selected hover */
196
+ .a1-choice-item:not(.a1-choice-item--disabled):has(.a1-choice-item__input:checked):hover {
197
+ border-color: var(--semantic-color-action-background-hover);
198
+ box-shadow: inset 0 0 0 1px var(--semantic-color-action-background-hover);
199
+ }
200
+
201
+ /* Focus ring on card when hidden input receives keyboard focus */
202
+ .a1-choice-item:has(.a1-choice-item__input:focus-visible) {
203
+ outline: var(--component-field-focus-ring-width) solid var(--component-field-focus-ring-color);
204
+ outline-offset: 2px;
205
+ }
206
+
207
+ /* ─── Hidden input ──────────────────────────────────────────────────────────── */
208
+
209
+ .a1-choice-item__input {
210
+ position: absolute;
211
+ width: 1px;
212
+ height: 1px;
213
+ padding: 0;
214
+ margin: -1px;
215
+ overflow: hidden;
216
+ clip: rect(0, 0, 0, 0);
217
+ white-space: nowrap;
218
+ border: 0;
219
+ }
220
+
221
+ /* ─── Icon ──────────────────────────────────────────────────────────────────── */
222
+
223
+ .a1-choice-item__icon {
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: center;
227
+ width: var(--a1-cg-icon-size);
228
+ height: var(--a1-cg-icon-size);
229
+ color: var(--semantic-color-action-background);
230
+ flex-shrink: 0;
231
+ }
232
+
233
+ .a1-choice-item__icon .a1-icon {
234
+ font-size: var(--a1-cg-icon-size);
235
+ }
236
+
237
+ /* ─── Label and subtext ─────────────────────────────────────────────────────── */
238
+
239
+ .a1-choice-item__content {
240
+ display: flex;
241
+ flex-direction: column;
242
+ gap: var(--base-spacing-2);
243
+ flex: 1;
244
+ min-width: 0;
245
+ }
246
+
247
+ .a1-choice-item__label {
248
+ font-family: var(--component-paragraph-font-family);
249
+ font-size: var(--a1-cg-label-size);
250
+ font-weight: var(--base-font-weight-medium);
251
+ color: var(--semantic-color-text-default);
252
+ line-height: var(--semantic-font-line-height-body);
253
+ overflow-wrap: break-word;
254
+ }
255
+
256
+ .a1-choice-item__subtext {
257
+ font-family: var(--component-paragraph-font-family);
258
+ font-size: var(--a1-cg-subtext-size);
259
+ font-weight: var(--base-font-weight-regular);
260
+ color: var(--semantic-color-text-muted);
261
+ line-height: var(--semantic-font-line-height-body);
262
+ overflow-wrap: break-word;
263
+ }
264
+
265
+ /* ─── Selection indicator ───────────────────────────────────────────────────── */
266
+
267
+ .a1-choice-item__indicator {
268
+ position: absolute;
269
+ top: calc(var(--a1-cg-padding) + var(--base-spacing-4));
270
+ inset-inline-start: var(--a1-cg-padding);
271
+ width: var(--a1-cg-indicator-size);
272
+ height: var(--a1-cg-indicator-size);
273
+ border: 1.5px solid var(--semantic-color-border-default);
274
+ background-color: var(--semantic-color-surface-page);
275
+ background-repeat: no-repeat;
276
+ background-position: center;
277
+ transition:
278
+ border-color var(--semantic-motion-duration-fast),
279
+ background-color var(--semantic-motion-duration-fast);
280
+ }
281
+
282
+ /* Single-select (radio) — circle */
283
+ .a1-choice-group--single .a1-choice-item__indicator {
284
+ border-radius: 50%;
285
+ }
286
+
287
+ /* Multi-select (checkbox) — rounded square */
288
+ .a1-choice-group--multiple .a1-choice-item__indicator {
289
+ border-radius: var(--base-radius-sm);
290
+ }
291
+
292
+ /* Hover indicator border (unselected only) */
293
+ .a1-choice-item:not(.a1-choice-item--disabled):not(:has(.a1-choice-item__input:checked)):hover
294
+ .a1-choice-item__indicator {
295
+ border-color: var(--semantic-color-action-background);
296
+ }
297
+
298
+ /* Selected indicator — filled */
299
+ .a1-choice-item:has(.a1-choice-item__input:checked) .a1-choice-item__indicator {
300
+ border-color: var(--semantic-color-action-background);
301
+ background-color: var(--semantic-color-action-background);
302
+ }
303
+
304
+ /* Radio selected: white dot */
305
+ .a1-choice-group--single
306
+ .a1-choice-item:has(.a1-choice-item__input:checked)
307
+ .a1-choice-item__indicator {
308
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Ccircle cx='5' cy='5' r='3' fill='%23ffffff'/%3E%3C/svg%3E");
309
+ background-size: 100%;
310
+ }
311
+
312
+ /* Checkbox selected: white checkmark */
313
+ .a1-choice-group--multiple
314
+ .a1-choice-item:has(.a1-choice-item__input:checked)
315
+ .a1-choice-item__indicator {
316
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpolyline points='2,6 5,9.5 10,3' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
317
+ background-size: 80%;
318
+ }
319
+
320
+ /* ─── Error state ───────────────────────────────────────────────────────────── */
321
+
322
+ .a1-choice-group--error
323
+ .a1-choice-item:not(.a1-choice-item--disabled):not(:has(.a1-choice-item__input:checked)) {
324
+ border-color: var(--semantic-color-status-error-border);
325
+ box-shadow: inset 0 0 0 1px var(--semantic-color-status-error-border);
326
+ }
327
+
328
+ .a1-choice-group--error
329
+ .a1-choice-item:not(.a1-choice-item--disabled):not(:has(.a1-choice-item__input:checked))
330
+ .a1-choice-item__indicator {
331
+ border-color: var(--semantic-color-status-error-border);
332
+ }
@@ -104,7 +104,7 @@
104
104
  }
105
105
 
106
106
  .a1-dt-filters__chip-icon {
107
- font-size: 18px;
107
+ font-size: var(--component-menu-item-icon-size);
108
108
  flex-shrink: 0;
109
109
  margin-inline-start: -2px;
110
110
  }
@@ -134,7 +134,7 @@
134
134
  border-radius: 9999px;
135
135
  background: var(--semantic-color-action-background);
136
136
  color: var(--semantic-color-action-foreground);
137
- font-size: 11px;
137
+ font-size: var(--component-tab-count-font-size);
138
138
  font-weight: 600;
139
139
  line-height: 1;
140
140
  margin-inline-start: var(--base-spacing-4);
@@ -263,7 +263,7 @@
263
263
  border-radius: 9999px;
264
264
  background: var(--semantic-color-action-background);
265
265
  color: var(--semantic-color-action-foreground);
266
- font-size: 10px;
266
+ font-size: var(--semantic-font-size-body-xs);
267
267
  font-weight: 600;
268
268
  letter-spacing: 0.02em;
269
269
  user-select: none;
@@ -272,7 +272,7 @@
272
272
  .a1-data-table--compact .a1-data-table__avatar {
273
273
  width: 22px;
274
274
  height: 22px;
275
- font-size: 9px;
275
+ font-size: var(--component-notification-font-size);
276
276
  }
277
277
 
278
278
  .a1-data-table__actions {
@@ -2,7 +2,7 @@ import "../../themes.css";
2
2
  import "../../color-scheme.css";
3
3
  import "./section.css";
4
4
 
5
- const VALID_PADDING = ["lg", "md", "sm", "none"];
5
+ const VALID_PADDING = ["lg", "md", "sm", "xs", "none"];
6
6
  const VALID_SURFACES = ["page", "panel", "raised"];
7
7
  const VALID_GAPS = ["xs", "sm", "md", "lg"];
8
8
  const VALID_GRADIENTS = ["accent", "highlight", "info", "success", "warn"];
@@ -217,6 +217,11 @@
217
217
  padding: 0;
218
218
  }
219
219
 
220
+ .a1-section--padding-xs {
221
+ padding-block: var(--base-spacing-16);
222
+ padding-inline: var(--base-spacing-16);
223
+ }
224
+
220
225
  .a1-section--padding-sm {
221
226
  padding-block: var(--base-spacing-32);
222
227
  padding-inline: var(--base-spacing-24);
@@ -233,12 +238,14 @@
233
238
  }
234
239
 
235
240
  @media (--bp-md-down) {
241
+ .a1-section--padding-xs { padding-block: var(--base-spacing-12); padding-inline: var(--base-spacing-12); }
236
242
  .a1-section--padding-sm { padding-block: var(--base-spacing-24); padding-inline: var(--base-spacing-16); }
237
243
  .a1-section--padding-md { padding-block: var(--base-spacing-40); padding-inline: var(--base-spacing-24); }
238
244
  .a1-section--padding-lg { padding-block: var(--base-spacing-64); padding-inline: var(--base-spacing-40); }
239
245
  }
240
246
 
241
247
  @media (--bp-sm-down) {
248
+ .a1-section--padding-xs { padding-block: var(--base-spacing-8); padding-inline: var(--base-spacing-8); }
242
249
  .a1-section--padding-sm { padding-block: var(--base-spacing-16); padding-inline: var(--base-spacing-12); }
243
250
  .a1-section--padding-md { padding-block: var(--base-spacing-24); padding-inline: var(--base-spacing-16); }
244
251
  .a1-section--padding-lg { padding-block: var(--base-spacing-40); padding-inline: var(--base-spacing-24); }
@@ -251,6 +258,7 @@
251
258
 
252
259
  /* xs: base, no media query */
253
260
  .a1-section--xs-padding-none { padding: 0; }
261
+ .a1-section--xs-padding-xs { padding-block: var(--base-spacing-16); padding-inline: var(--base-spacing-16); }
254
262
  .a1-section--xs-padding-sm { padding-block: var(--base-spacing-32); padding-inline: var(--base-spacing-24); }
255
263
  .a1-section--xs-padding-md { padding-block: var(--base-spacing-64); padding-inline: var(--base-spacing-40); }
256
264
  .a1-section--xs-padding-lg { padding-block: var(--base-spacing-96); padding-inline: var(--base-spacing-64); }
@@ -258,6 +266,7 @@
258
266
  /* sm: ≥481px */
259
267
  @media (--bp-sm-up) {
260
268
  .a1-section--sm-padding-none { padding: 0; }
269
+ .a1-section--sm-padding-xs { padding-block: var(--base-spacing-16); padding-inline: var(--base-spacing-16); }
261
270
  .a1-section--sm-padding-sm { padding-block: var(--base-spacing-32); padding-inline: var(--base-spacing-24); }
262
271
  .a1-section--sm-padding-md { padding-block: var(--base-spacing-64); padding-inline: var(--base-spacing-40); }
263
272
  .a1-section--sm-padding-lg { padding-block: var(--base-spacing-96); padding-inline: var(--base-spacing-64); }
@@ -266,6 +275,7 @@
266
275
  /* md: ≥769px */
267
276
  @media (min-width: 769px) {
268
277
  .a1-section--md-padding-none { padding: 0; }
278
+ .a1-section--md-padding-xs { padding-block: var(--base-spacing-12); padding-inline: var(--base-spacing-12); }
269
279
  .a1-section--md-padding-sm { padding-block: var(--base-spacing-24); padding-inline: var(--base-spacing-16); }
270
280
  .a1-section--md-padding-md { padding-block: var(--base-spacing-40); padding-inline: var(--base-spacing-24); }
271
281
  .a1-section--md-padding-lg { padding-block: var(--base-spacing-64); padding-inline: var(--base-spacing-40); }
@@ -274,6 +284,7 @@
274
284
  /* lg: ≥1025px */
275
285
  @media (--bp-lg-up) {
276
286
  .a1-section--lg-padding-none { padding: 0; }
287
+ .a1-section--lg-padding-xs { padding-block: var(--base-spacing-16); padding-inline: var(--base-spacing-16); }
277
288
  .a1-section--lg-padding-sm { padding-block: var(--base-spacing-32); padding-inline: var(--base-spacing-24); }
278
289
  .a1-section--lg-padding-md { padding-block: var(--base-spacing-64); padding-inline: var(--base-spacing-40); }
279
290
  .a1-section--lg-padding-lg { padding-block: var(--base-spacing-96); padding-inline: var(--base-spacing-64); }
@@ -105,6 +105,6 @@
105
105
 
106
106
  .a1-token-item__check {
107
107
  flex-shrink: 0;
108
- font-size: 16px;
108
+ font-size: var(--semantic-font-size-body-md);
109
109
  color: var(--semantic-color-text-accent);
110
110
  }