xyne-components 0.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.
@@ -0,0 +1,801 @@
1
+ /* ─── /styles/tokens.css ─── */
2
+ /**
3
+ * Xyne Design System — CSS Custom Properties
4
+ *
5
+ * Light mode tokens are on :root.
6
+ * Dark mode is applied by either:
7
+ * • [data-theme="dark"] attribute on a parent element (explicit control)
8
+ * • @media (prefers-color-scheme: dark) (system default)
9
+ *
10
+ * Override any variable to theme components:
11
+ * :root { --xc-color-brand: #your-color; }
12
+ */
13
+
14
+ /* ════════════════════════════════════════════════════════════════
15
+ STATIC TOKENS — same in light and dark
16
+ ════════════════════════════════════════════════════════════════ */
17
+
18
+ :root {
19
+ /* ─── Brand / Orange Scale ─────────────────────────────────── */
20
+ --xc-color-orange-50: #fff7ed;
21
+ --xc-color-orange-100: #ffedd4;
22
+ --xc-color-orange-200: #ffd6a8;
23
+ --xc-color-orange-300: #ffb86a;
24
+ --xc-color-orange-400: #ff8904;
25
+ --xc-color-orange-500: #fe6d36;
26
+ --xc-color-orange-600: #ea580c;
27
+ --xc-color-orange-700: #c2410c;
28
+
29
+ /* ─── Gray Scale ───────────────────────────────────────────── */
30
+ --xc-color-gray-25: #f6f8fa;
31
+ --xc-color-gray-50: #f9fafb;
32
+ --xc-color-gray-100: #f2f4f7;
33
+ --xc-color-gray-200: #e4e7ec;
34
+ --xc-color-gray-300: #d0d5dd;
35
+ --xc-color-gray-400: #98a2b3;
36
+ --xc-color-gray-500: #667085;
37
+ --xc-color-gray-600: #475467;
38
+ --xc-color-gray-700: #344054;
39
+ --xc-color-gray-800: #1d2939;
40
+ --xc-color-gray-900: #101828;
41
+
42
+ /* ─── Status Scales ────────────────────────────────────────── */
43
+ --xc-color-red-50: #fef3f2;
44
+ --xc-color-red-500: #f04438;
45
+ --xc-color-red-600: #d92d20;
46
+ --xc-color-red-700: #b42318;
47
+ --xc-color-green-50: #ecfdf3;
48
+ --xc-color-green-500: #12b76a;
49
+ --xc-color-green-600: #039855;
50
+ --xc-color-green-700: #027a48;
51
+ --xc-color-yellow-50: #fffaeb;
52
+ --xc-color-yellow-500: #f79009;
53
+ --xc-color-yellow-600: #dc6803;
54
+ --xc-color-yellow-700: #b54708;
55
+ --xc-color-blue-50: #eff8ff;
56
+ --xc-color-blue-500: #2e90fa;
57
+ --xc-color-blue-600: #1570ef;
58
+ --xc-color-blue-700: #175cd3;
59
+ --xc-color-purple-50: #f9f5ff;
60
+ --xc-color-purple-500: #9e77ed;
61
+ --xc-color-purple-600: #7f56d9;
62
+ --xc-color-purple-700: #6941c6;
63
+ --xc-color-teal-50: #f0fdf9;
64
+ --xc-color-teal-500: #15b79e;
65
+ --xc-color-teal-600: #0e9384;
66
+ --xc-color-teal-700: #107569;
67
+
68
+ /* ─── Border Radius ────────────────────────────────────────── */
69
+ --xc-radius-xs: 2px;
70
+ --xc-radius-sm: 4px;
71
+ --xc-radius-md: 8px;
72
+ --xc-radius-lg: 12px;
73
+ --xc-radius-xl: 16px;
74
+ --xc-radius-full: 9999px;
75
+
76
+ /* ─── Spacing ──────────────────────────────────────────────── */
77
+ --xc-space-0: 0px;
78
+ --xc-space-1: 2px;
79
+ --xc-space-2: 4px;
80
+ --xc-space-3: 6px;
81
+ --xc-space-4: 8px;
82
+ --xc-space-5: 10px;
83
+ --xc-space-6: 12px;
84
+ --xc-space-7: 14px;
85
+ --xc-space-8: 16px;
86
+ --xc-space-9: 18px;
87
+ --xc-space-10: 20px;
88
+ --xc-space-12: 24px;
89
+ --xc-space-16: 32px;
90
+
91
+ /* ─── Typography ───────────────────────────────────────────── */
92
+ /* Requires Inter to be loaded by the consumer. Fallback chain provided. */
93
+ --xc-font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
94
+ --xc-font-weight-regular: 400;
95
+ --xc-font-weight-medium: 500;
96
+ --xc-font-weight-semibold: 600;
97
+ --xc-font-weight-bold: 700;
98
+
99
+ --xc-font-size-2xs: 10px;
100
+ --xc-font-size-xs: 11px;
101
+ --xc-font-size-sm: 12px;
102
+ --xc-font-size-md: 14px;
103
+ --xc-font-size-lg: 16px;
104
+ --xc-font-size-xl: 18px;
105
+
106
+ --xc-line-height-2xs: 14px;
107
+ --xc-line-height-xs: 16px;
108
+ --xc-line-height-sm: 18px;
109
+ --xc-line-height-md: 20px;
110
+ --xc-line-height-lg: 24px;
111
+ --xc-line-height-xl: 28px;
112
+ }
113
+
114
+ /* ════════════════════════════════════════════════════════════════
115
+ LIGHT MODE (default)
116
+ ════════════════════════════════════════════════════════════════ */
117
+
118
+ :root,
119
+ [data-theme="light"] {
120
+ /* ─── Text ─────────────────────────────────────────────────── */
121
+ --xc-color-text-primary: #101828;
122
+ --xc-color-text-secondary: #475467;
123
+ --xc-color-text-tertiary: #667085;
124
+ --xc-color-text-disabled: #c9d0db;
125
+ --xc-color-text-brand: #e8601a;
126
+ --xc-color-text-inverse: #f1f5f9;
127
+ --xc-color-text-error: #d92d20;
128
+ --xc-color-text-success: #039855;
129
+ --xc-color-text-warning: #b54708;
130
+
131
+ /* ─── Backgrounds ──────────────────────────────────────────── */
132
+ --xc-color-bg-white: #ffffff;
133
+ --xc-color-bg-subtle: #f9fafb;
134
+ --xc-color-bg-surface-hover: #f1f5f9;
135
+ --xc-color-bg-brand: #fff4ee;
136
+ --xc-color-bg-error: #fef3f2;
137
+ --xc-color-bg-success: #ecfdf3;
138
+ --xc-color-bg-warning: #fffaeb;
139
+ --xc-color-bg-neutral: #f9fafb;
140
+ --xc-color-bg-purple: #f9f5ff;
141
+ --xc-color-bg-blue: #eff8ff;
142
+ --xc-color-bg-teal: #f0fdf9;
143
+
144
+ /* ─── Borders ──────────────────────────────────────────────── */
145
+ --xc-color-border-default: #d6dce6;
146
+ --xc-color-border-subtle: #f1f5f9;
147
+ --xc-color-border-strong: #98a2b3;
148
+ --xc-color-border-brand: #fe6d36;
149
+ --xc-color-border-error: #fda29b;
150
+
151
+ /* ─── Shadows ──────────────────────────────────────────────── */
152
+ --xc-shadow-xs: 0 1px 2px 0 rgba(16, 24, 40, 0.05);
153
+ --xc-shadow-sm: 0 1px 3px 0 rgba(16, 24, 40, 0.1), 0 1px 2px -1px rgba(16, 24, 40, 0.1);
154
+ --xc-shadow-md: 0 4px 6px -1px rgba(16, 24, 40, 0.1), 0 2px 4px -2px rgba(16, 24, 40, 0.1);
155
+ --xc-shadow-pressed: inset 0 0 4px 0 rgba(0, 0, 0, 0.15);
156
+ }
157
+
158
+ /* ════════════════════════════════════════════════════════════════
159
+ DARK MODE
160
+ Supports both explicit [data-theme="dark"] and system preference.
161
+ data-theme takes precedence when set.
162
+ ════════════════════════════════════════════════════════════════ */
163
+
164
+ @media (prefers-color-scheme: dark) {
165
+ :root:not([data-theme="light"]) {
166
+ /* ─── Text ─────────────────────────────────────────────── */
167
+ --xc-color-text-primary: #f2f4f7;
168
+ --xc-color-text-secondary: #c9d0db;
169
+ --xc-color-text-tertiary: #98a2b3;
170
+ --xc-color-text-disabled: #475467;
171
+ --xc-color-text-brand: #ff8d4e;
172
+ --xc-color-text-inverse: #101828;
173
+ --xc-color-text-error: #f97066;
174
+ --xc-color-text-success: #47cd89;
175
+ --xc-color-text-warning: #fdb022;
176
+
177
+ /* ─── Backgrounds ──────────────────────────────────────── */
178
+ --xc-color-bg-white: #0e121b;
179
+ --xc-color-bg-subtle: #181b25;
180
+ --xc-color-bg-surface-hover: #1d2126;
181
+ --xc-color-bg-brand: #2d1505;
182
+ --xc-color-bg-error: #2a0d0a;
183
+ --xc-color-bg-success: #052e16;
184
+ --xc-color-bg-warning: #2b1706;
185
+ --xc-color-bg-neutral: #181b25;
186
+ --xc-color-bg-purple: #1a0533;
187
+ --xc-color-bg-blue: #0a1e3d;
188
+ --xc-color-bg-teal: #042019;
189
+
190
+ /* ─── Borders ──────────────────────────────────────────── */
191
+ --xc-color-border-default: #2b303b;
192
+ --xc-color-border-subtle: #1d2126;
193
+ --xc-color-border-strong: #475467;
194
+ --xc-color-border-brand: #fe6d36;
195
+ --xc-color-border-error: #f04438;
196
+
197
+ /* ─── Shadows ──────────────────────────────────────────── */
198
+ --xc-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
199
+ --xc-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4);
200
+ --xc-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
201
+ --xc-shadow-pressed: inset 0 0 4px 0 rgba(0, 0, 0, 0.4);
202
+ }
203
+ }
204
+
205
+ [data-theme="dark"] {
206
+ /* ─── Text ─────────────────────────────────────────────────── */
207
+ --xc-color-text-primary: #f2f4f7;
208
+ --xc-color-text-secondary: #c9d0db;
209
+ --xc-color-text-tertiary: #98a2b3;
210
+ --xc-color-text-disabled: #475467;
211
+ --xc-color-text-brand: #ff8d4e;
212
+ --xc-color-text-inverse: #101828;
213
+ --xc-color-text-error: #f97066;
214
+ --xc-color-text-success: #47cd89;
215
+ --xc-color-text-warning: #fdb022;
216
+
217
+ /* ─── Backgrounds ──────────────────────────────────────────── */
218
+ --xc-color-bg-white: #0e121b;
219
+ --xc-color-bg-subtle: #181b25;
220
+ --xc-color-bg-brand: #2d1505;
221
+ --xc-color-bg-error: #2a0d0a;
222
+ --xc-color-bg-success: #052e16;
223
+ --xc-color-bg-warning: #2b1706;
224
+ --xc-color-bg-neutral: #181b25;
225
+ --xc-color-bg-purple: #1a0533;
226
+ --xc-color-bg-blue: #0a1e3d;
227
+ --xc-color-bg-teal: #042019;
228
+
229
+ /* ─── Borders ──────────────────────────────────────────────── */
230
+ --xc-color-border-default: #2b303b;
231
+ --xc-color-border-subtle: #1d2126;
232
+ --xc-color-border-strong: #475467;
233
+ --xc-color-border-brand: #fe6d36;
234
+ --xc-color-border-error: #f04438;
235
+
236
+ /* ─── Shadows ──────────────────────────────────────────────── */
237
+ --xc-shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
238
+ --xc-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.4);
239
+ --xc-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
240
+ --xc-shadow-pressed: inset 0 0 4px 0 rgba(0, 0, 0, 0.4);
241
+ }
242
+
243
+
244
+ /* ─── /Badge/badge.css ─── */
245
+ /**
246
+ * Badge — Figma nodes 2227:204 (badge), 2271:218 (dot)
247
+ *
248
+ * Two types:
249
+ * "badge" — compact pill with count/text + optional 12×12 icon slot
250
+ * "dot" — tiny 6×6 status dot with border
251
+ *
252
+ * Themed via CSS custom properties on the element:
253
+ * --xc-badge-bg, --xc-badge-fg, --xc-badge-dot-fill, --xc-badge-dot-stroke
254
+ * Override these in parent context to change colors.
255
+ */
256
+
257
+ /* ═══════════════════════════════════════════════════════════════
258
+ Component-level variables (defaults match Figma)
259
+ ═══════════════════════════════════════════════════════════════ */
260
+
261
+ .xc-badge {
262
+ /* Figma badge/bg → #e8601a, badge/fg → #f6f8fa */
263
+ --xc-badge-bg: var(--xc-color-orange-600, #e8601a);
264
+ --xc-badge-fg: var(--xc-color-gray-25, #f6f8fa);
265
+ --xc-badge-padding-x: 4px; /* Figma badge/padding-x */
266
+ --xc-badge-padding-y: 2px; /* Figma badge/padding-y */
267
+ --xc-badge-corner-radius: 4px; /* Figma badge/corner-radius */
268
+ --xc-badge-font-size: 12px; /* Figma badge/font-size */
269
+
270
+ /* Dot sub-component defaults */
271
+ --xc-badge-dot-fill: var(--xc-color-orange-600, #e8601a);
272
+ --xc-badge-dot-stroke: #ffffff;
273
+ --xc-badge-dot-stroke-width: 1.5px;
274
+ --xc-badge-dot-size: 6px;
275
+ }
276
+
277
+ /* ═══════════════════════════════════════════════════════════════
278
+ TYPE: badge — Figma node 2227:204
279
+ ═══════════════════════════════════════════════════════════════ */
280
+
281
+ .xc-badge[data-variant="badge"] {
282
+ /* Layout — Figma: flex, gap 4, align center, justify center */
283
+ display: inline-flex;
284
+ flex-direction: row;
285
+ align-items: center;
286
+ justify-content: center;
287
+ gap: var(--xc-space-2); /* 4px — Figma gap */
288
+
289
+ /* Box — Figma: min-h 6, min-w 16, px badge/padding-x, py badge/padding-y */
290
+ min-height: 6px;
291
+ min-width: 16px;
292
+ padding-left: var(--xc-badge-padding-x); /* 4px */
293
+ padding-right: var(--xc-badge-padding-x); /* 4px */
294
+ padding-top: var(--xc-badge-padding-y); /* 2px */
295
+ padding-bottom: var(--xc-badge-padding-y); /* 2px */
296
+ border-radius: var(--xc-badge-corner-radius); /* 4px */
297
+
298
+ /* Colors — Figma: badge/bg, badge/fg */
299
+ background-color: var(--xc-badge-bg);
300
+ color: var(--xc-badge-fg);
301
+
302
+ /* Typography */
303
+ font-family: var(--xc-font-family);
304
+ font-weight: var(--xc-font-weight-medium); /* 500 */
305
+ font-size: var(--xc-badge-font-size); /* 12px */
306
+ line-height: 14px; /* Figma: 14px fixed */
307
+ letter-spacing: 0.3px; /* Figma: 0.3px */
308
+ font-style: normal;
309
+ white-space: nowrap;
310
+ box-sizing: border-box;
311
+ }
312
+
313
+ /* ── Icon slot — Figma: 12×12, flex-shrink 0 ─────────────────── */
314
+
315
+ .xc-badge__icon {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ flex-shrink: 0;
320
+ width: 12px;
321
+ height: 12px;
322
+ }
323
+
324
+ /* ═══════════════════════════════════════════════════════════════
325
+ TYPE: dot — Figma node 2271:218
326
+ ═══════════════════════════════════════════════════════════════ */
327
+
328
+ .xc-badge[data-variant="dot"] {
329
+ /* Figma: 6×6 (badge/dot/size), min 6×6 */
330
+ display: inline-block;
331
+ width: var(--xc-badge-dot-size); /* 6px */
332
+ height: var(--xc-badge-dot-size); /* 6px */
333
+ min-width: 6px;
334
+ min-height: 6px;
335
+
336
+ /* Colors — Figma: badge/dot/fill, badge/dot/stroke + stroke-width */
337
+ background-color: var(--xc-badge-dot-fill);
338
+ border: var(--xc-badge-dot-stroke-width) solid var(--xc-badge-dot-stroke);
339
+
340
+ /* Shape — Figma: badge/corner-radius 4px */
341
+ border-radius: var(--xc-badge-corner-radius); /* 4px */
342
+ box-sizing: border-box;
343
+ }
344
+
345
+
346
+ /* ─── /Directory/directory.css ─── */
347
+ /**
348
+ * Directory — Figma nodes 2311:3469 (opened), 2311:3470 (closed)
349
+ *
350
+ * A collapsible folder/section with a Label header and child content.
351
+ *
352
+ * Structure:
353
+ * .xc-directory — outer container (flex-col)
354
+ * .xc-directory__header — clickable Label row
355
+ * .xc-directory__leading — 16×16 icon slot (folder icon)
356
+ * .xc-directory__text — label text group
357
+ * .xc-directory__label — label text
358
+ * .xc-directory__trailing — 16×16 icon slot (chevron)
359
+ * .xc-directory__content — children container (only when opened)
360
+ *
361
+ * Types via data-type:
362
+ * "opened" — header text primary, children visible, pb 12px
363
+ * "closed" — header text secondary, children hidden
364
+ *
365
+ * Hover is CSS-only on the header row.
366
+ */
367
+
368
+ /* ═══════════════════════════════════════════════════════════════
369
+ CONTAINER
370
+ ═══════════════════════════════════════════════════════════════ */
371
+
372
+ .xc-directory {
373
+ /* Figma: flex-col, gap 4px, items-start, full width */
374
+ display: flex;
375
+ flex-direction: column;
376
+ align-items: flex-start;
377
+ gap: var(--xc-space-2); /* 4px — Figma gap */
378
+ width: 100%;
379
+ box-sizing: border-box;
380
+ }
381
+
382
+ /* opened → padding-bottom 12px (Figma: pb spacing/12) */
383
+ .xc-directory[data-variant="opened"] {
384
+ padding-bottom: var(--xc-space-6); /* 12px */
385
+ }
386
+
387
+ /* ═══════════════════════════════════════════════════════════════
388
+ HEADER — clickable label row
389
+ Figma: flex, gap 8, align center, overflow clip, px 8, py 4, radius 8
390
+ ═══════════════════════════════════════════════════════════════ */
391
+
392
+ .xc-directory__header {
393
+ display: flex;
394
+ flex-direction: row;
395
+ align-items: center;
396
+ gap: var(--xc-space-4); /* 8px — Figma gap */
397
+ overflow: clip;
398
+ padding-left: var(--xc-space-4); /* 8px — Figma px */
399
+ padding-right: var(--xc-space-4); /* 8px */
400
+ padding-top: var(--xc-space-2); /* 4px — Figma py */
401
+ padding-bottom: var(--xc-space-2); /* 4px */
402
+ border-radius: var(--xc-radius-md); /* 8px */
403
+ width: 100%;
404
+
405
+ /* Reset */
406
+ box-sizing: border-box;
407
+ border: none;
408
+ background: transparent;
409
+ cursor: pointer;
410
+ user-select: none;
411
+ font-family: var(--xc-font-family);
412
+ text-decoration: none;
413
+ text-align: left;
414
+ transition: background-color 100ms ease;
415
+ }
416
+
417
+ .xc-directory__header:focus-visible {
418
+ outline: 2px solid var(--xc-color-border-brand);
419
+ outline-offset: -2px;
420
+ }
421
+
422
+ /* ── Header slots ────────────────────────────────────────────── */
423
+
424
+ /* Leading slot — Figma: 16×16, shrink 0, overflow clip */
425
+ .xc-directory__leading {
426
+ display: flex;
427
+ align-items: center;
428
+ justify-content: center;
429
+ flex-shrink: 0;
430
+ width: 16px;
431
+ height: 16px;
432
+ overflow: clip;
433
+ }
434
+
435
+ /* Text group — Figma: flex-col, gap 0, items-start, justify-center, max-w 240 */
436
+ .xc-directory__text {
437
+ display: flex;
438
+ flex-direction: column;
439
+ align-items: flex-start;
440
+ justify-content: center;
441
+ flex-shrink: 0;
442
+ max-width: 240px;
443
+ }
444
+
445
+ /* Label text — Figma: Inter Medium 500, 14px/20px, letter-spacing 0, max-w 264, ellipsis */
446
+ .xc-directory__label {
447
+ display: block;
448
+ font-family: var(--xc-font-family);
449
+ font-weight: var(--xc-font-weight-medium); /* 500 */
450
+ font-size: var(--xc-font-size-md); /* 14px */
451
+ line-height: var(--xc-line-height-md); /* 20px */
452
+ letter-spacing: 0;
453
+ font-style: normal;
454
+ max-width: 264px;
455
+ white-space: nowrap;
456
+ overflow: hidden;
457
+ text-overflow: ellipsis;
458
+ }
459
+
460
+ /* Trailing slot — Figma: 16×16, shrink 0, overflow clip */
461
+ .xc-directory__trailing {
462
+ display: flex;
463
+ align-items: center;
464
+ justify-content: center;
465
+ flex-shrink: 0;
466
+ width: 16px;
467
+ height: 16px;
468
+ overflow: clip;
469
+ }
470
+
471
+ /* ═══════════════════════════════════════════════════════════════
472
+ CHILDREN CONTAINER
473
+ Figma: flex-col, gap 0, items-start, full width
474
+ ═══════════════════════════════════════════════════════════════ */
475
+
476
+ .xc-directory__content {
477
+ display: flex;
478
+ flex-direction: column;
479
+ align-items: flex-start;
480
+ gap: 0;
481
+ width: 100%;
482
+ }
483
+
484
+ /* ═══════════════════════════════════════════════════════════════
485
+ VARIANTS — data-variant driven
486
+ ═══════════════════════════════════════════════════════════════ */
487
+
488
+ /* opened — Figma: text color #101828 (text/primary) */
489
+ .xc-directory[data-variant="opened"] .xc-directory__label {
490
+ color: var(--xc-color-text-primary); /* #101828 */
491
+ }
492
+
493
+ /* closed — Figma: text color #475467 (text/secondary) */
494
+ .xc-directory[data-variant="closed"] .xc-directory__label {
495
+ color: var(--xc-color-text-secondary); /* #475467 */
496
+ }
497
+
498
+ /* ═══════════════════════════════════════════════════════════════
499
+ STATES — CSS-only hover on header
500
+ Figma: bg #f1f5f9 (bg/surface-hover)
501
+ ═══════════════════════════════════════════════════════════════ */
502
+
503
+ .xc-directory__header:hover {
504
+ background-color: var(--xc-color-bg-surface-hover); /* #f1f5f9 */
505
+ }
506
+
507
+
508
+ /* ─── /Label/label.css ─── */
509
+ /**
510
+ * Label — Figma nodes 2223:99, 2223:107, 2313:3525, 2313:3532
511
+ *
512
+ * A disclosure / navigation label with leading + trailing icon slots.
513
+ *
514
+ * Types (via data-type attribute):
515
+ * "opened" — text color primary (#101828)
516
+ * "closed" — text color secondary (#475467)
517
+ *
518
+ * Hover is CSS-only (:hover → bg surface-hover #f1f5f9).
519
+ */
520
+
521
+ .xc-label {
522
+ /* Layout — Figma: auto-layout row, gap 8, align center, clip content */
523
+ display: flex;
524
+ flex-direction: row;
525
+ align-items: center;
526
+ gap: var(--xc-space-4); /* 8px — Figma gap */
527
+ overflow: clip;
528
+
529
+ /* Box — Figma: px 8, py 4, border-radius 8 */
530
+ padding-left: var(--xc-space-4); /* 8px */
531
+ padding-right: var(--xc-space-4); /* 8px */
532
+ padding-top: var(--xc-space-2); /* 4px */
533
+ padding-bottom: var(--xc-space-2); /* 4px */
534
+ border-radius: var(--xc-radius-md); /* 8px */
535
+
536
+ /* Reset */
537
+ box-sizing: border-box;
538
+ border: none;
539
+ background: transparent;
540
+ cursor: pointer;
541
+ user-select: none;
542
+ font-family: var(--xc-font-family);
543
+ text-decoration: none;
544
+ transition: background-color 100ms ease;
545
+ }
546
+
547
+ .xc-label:focus-visible {
548
+ outline: 2px solid var(--xc-color-border-brand);
549
+ outline-offset: -2px;
550
+ }
551
+
552
+ /* ── Slots ───────────────────────────────────────────────────── */
553
+
554
+ /* Leading slot — Figma: 16×16, flex-shrink 0 */
555
+ .xc-label__leading {
556
+ display: flex;
557
+ align-items: center;
558
+ justify-content: center;
559
+ flex-shrink: 0;
560
+ width: 16px;
561
+ height: 16px;
562
+ }
563
+
564
+ /* Text group — Figma: flex-col, gap 0, items-start, justify-center, max-w 240 */
565
+ .xc-label__text {
566
+ display: flex;
567
+ flex-direction: column;
568
+ align-items: flex-start;
569
+ justify-content: center;
570
+ flex-shrink: 0;
571
+ max-width: 240px;
572
+ }
573
+
574
+ /* Label text — Figma: Inter Medium 500, 14px/20px, letter-spacing 0, max-w 264, ellipsis */
575
+ .xc-label__content {
576
+ display: block;
577
+ font-family: var(--xc-font-family);
578
+ font-weight: var(--xc-font-weight-medium); /* 500 */
579
+ font-size: var(--xc-font-size-md); /* 14px */
580
+ line-height: var(--xc-line-height-md); /* 20px */
581
+ letter-spacing: 0;
582
+ font-style: normal;
583
+ max-width: 264px;
584
+ white-space: nowrap;
585
+ overflow: hidden;
586
+ text-overflow: ellipsis;
587
+ }
588
+
589
+ /* Trailing slot — Figma: 16×16, flex-shrink 0 */
590
+ .xc-label__trailing {
591
+ display: flex;
592
+ align-items: center;
593
+ justify-content: center;
594
+ flex-shrink: 0;
595
+ width: 16px;
596
+ height: 16px;
597
+ }
598
+
599
+ /* ═══════════════════════════════════════════════════════════════
600
+ VARIANTS — data-variant driven
601
+ ═══════════════════════════════════════════════════════════════ */
602
+
603
+ /* opened — Figma: text color #101828 (text/primary) */
604
+ .xc-label[data-variant="opened"] .xc-label__content {
605
+ color: var(--xc-color-text-primary); /* #101828 */
606
+ }
607
+
608
+ /* closed — Figma: text color #475467 (text/secondary) */
609
+ .xc-label[data-variant="closed"] .xc-label__content {
610
+ color: var(--xc-color-text-secondary); /* #475467 */
611
+ }
612
+
613
+ /* ═══════════════════════════════════════════════════════════════
614
+ STATES — CSS-only hover
615
+ ═══════════════════════════════════════════════════════════════ */
616
+
617
+ /* Hovered — Figma: bg #f1f5f9 (bg/surface-hover) */
618
+ .xc-label:hover {
619
+ background-color: var(--xc-color-bg-surface-hover); /* #f1f5f9 */
620
+ }
621
+
622
+
623
+ /* ─── /ListItem/list-item.css ─── */
624
+ /**
625
+ * ListItem — Figma node 2221:16
626
+ *
627
+ * States driven by data attributes (not class modifiers):
628
+ * [data-selected] — selected state
629
+ * [data-active] — active/keyboard-highlighted state
630
+ * [data-disabled] — disabled state
631
+ *
632
+ * Hover and press are driven by CSS :hover / :active automatically.
633
+ */
634
+
635
+ .xc-list-item {
636
+ display: flex;
637
+ flex-direction: row;
638
+ align-items: center;
639
+ overflow: hidden;
640
+ gap: var(--xc-space-4); /* 8px — Figma gap */
641
+ padding-left: var(--xc-space-8); /* 16px — Figma padding-left */
642
+ padding-right: var(--xc-space-4); /* 8px — Figma padding-right */
643
+ padding-top: 0;
644
+ padding-bottom: 0;
645
+ border-radius: var(--xc-radius-md); /* 8px */
646
+ min-height: 28px;
647
+ cursor: pointer;
648
+ user-select: none;
649
+ box-sizing: border-box;
650
+ font-family: var(--xc-font-family);
651
+ text-decoration: none;
652
+ border: none;
653
+ background: transparent;
654
+ width: 100%;
655
+ text-align: left;
656
+ transition: background-color 100ms ease;
657
+ position: relative;
658
+ }
659
+
660
+ .xc-list-item:focus-visible {
661
+ outline: 2px solid var(--xc-color-border-brand);
662
+ outline-offset: -2px;
663
+ }
664
+
665
+ /* ── Bar (left vertical accent, 1px wide) ────────────────────── */
666
+
667
+ .xc-list-item__bar {
668
+ display: block;
669
+ flex-shrink: 0;
670
+ width: 1px;
671
+ align-self: stretch; /* full height — default / disabled / active */
672
+ background-color: var(--xc-color-border-default); /* #d6dce6 */
673
+ }
674
+
675
+ /* ── Slots ───────────────────────────────────────────────────── */
676
+
677
+ .xc-list-item__leading,
678
+ .xc-list-item__trailing {
679
+ display: flex;
680
+ align-items: center;
681
+ justify-content: center;
682
+ flex-shrink: 0;
683
+ width: 16px;
684
+ height: 16px;
685
+ color: inherit;
686
+ }
687
+
688
+ .xc-list-item__trailing {
689
+ margin-left: auto;
690
+ }
691
+
692
+ /* ── Text group ──────────────────────────────────────────────── */
693
+
694
+ .xc-list-item__text {
695
+ display: flex;
696
+ flex-direction: column;
697
+ flex: 1;
698
+ min-width: 0;
699
+ max-width: 240px;
700
+ padding-top: var(--xc-space-2); /* 4px */
701
+ padding-bottom: var(--xc-space-2); /* 4px */
702
+ }
703
+
704
+ .xc-list-item__label {
705
+ display: block;
706
+ font-size: var(--xc-font-size-md); /* 14px */
707
+ line-height: var(--xc-line-height-md); /* 20px */
708
+ letter-spacing: 0;
709
+ font-weight: var(--xc-font-weight-regular); /* 400 */
710
+ color: var(--xc-color-text-secondary); /* #475467 */
711
+ white-space: nowrap;
712
+ overflow: hidden;
713
+ text-overflow: ellipsis;
714
+ }
715
+
716
+ .xc-list-item__subtext {
717
+ display: block;
718
+ font-size: var(--xc-font-size-sm); /* 12px */
719
+ line-height: var(--xc-line-height-2xs); /* 14px */
720
+ letter-spacing: 0;
721
+ font-weight: var(--xc-font-weight-regular);
722
+ color: var(--xc-color-text-tertiary); /* #667085 — same across all states */
723
+ white-space: nowrap;
724
+ overflow: hidden;
725
+ text-overflow: ellipsis;
726
+ }
727
+
728
+ /* ════════════════════════════════════════════════════════════════
729
+ STATES — data-attribute driven, no class modifiers
730
+ ════════════════════════════════════════════════════════════════ */
731
+
732
+ /* ── Hovered (CSS :hover) ────────────────────────────────────── */
733
+
734
+ .xc-list-item:hover:not([data-selected]):not([data-disabled]) {
735
+ background-color: var(--xc-color-bg-brand); /* #fff4ee */
736
+ }
737
+
738
+ .xc-list-item:hover:not([data-selected]):not([data-disabled]) .xc-list-item__label {
739
+ color: var(--xc-color-text-brand); /* #e8601a */
740
+ font-weight: var(--xc-font-weight-medium); /* 500 */
741
+ }
742
+
743
+ .xc-list-item:hover:not([data-selected]):not([data-disabled]) .xc-list-item__bar {
744
+ align-self: auto;
745
+ height: 20px;
746
+ background-color: var(--xc-color-border-subtle); /* #f1f5f9 */
747
+ }
748
+
749
+ /* ── Pressed (CSS :active) ───────────────────────────────────── */
750
+
751
+ .xc-list-item:active:not([data-disabled]) {
752
+ background-color: var(--xc-color-orange-500); /* #fe6d36 */
753
+ box-shadow: var(--xc-shadow-pressed); /* inset 0 0 4px rgba(0,0,0,0.15) */
754
+ }
755
+
756
+ .xc-list-item:active:not([data-disabled]) .xc-list-item__label {
757
+ color: var(--xc-color-text-inverse); /* #f1f5f9 */
758
+ font-weight: var(--xc-font-weight-medium);
759
+ }
760
+
761
+ .xc-list-item:active:not([data-disabled]) .xc-list-item__bar {
762
+ align-self: auto;
763
+ height: 20px;
764
+ background-color: var(--xc-color-gray-25); /* #f6f8fa */
765
+ }
766
+
767
+ /* ── Selected [data-selected] ────────────────────────────────── */
768
+
769
+ .xc-list-item[data-selected] {
770
+ background-color: var(--xc-color-orange-500); /* #fe6d36 */
771
+ }
772
+
773
+ .xc-list-item[data-selected] .xc-list-item__label {
774
+ color: var(--xc-color-text-inverse); /* #f1f5f9 */
775
+ font-weight: var(--xc-font-weight-medium); /* 500 */
776
+ }
777
+
778
+ .xc-list-item[data-selected] .xc-list-item__bar {
779
+ align-self: auto;
780
+ height: 20px;
781
+ background-color: var(--xc-color-gray-25); /* #f6f8fa */
782
+ }
783
+
784
+ /* ── Disabled [data-disabled] ────────────────────────────────── */
785
+
786
+ .xc-list-item[data-disabled] {
787
+ cursor: not-allowed;
788
+ pointer-events: none;
789
+ }
790
+
791
+ .xc-list-item[data-disabled] .xc-list-item__label {
792
+ color: var(--xc-color-text-disabled); /* #c9d0db */
793
+ font-weight: var(--xc-font-weight-regular);
794
+ }
795
+
796
+ /* ── Active [data-active] — keyboard highlight ───────────────── */
797
+
798
+ .xc-list-item[data-active]:not([data-selected]) .xc-list-item__label {
799
+ color: var(--xc-color-text-primary); /* #101828 */
800
+ font-weight: var(--xc-font-weight-medium); /* 500 */
801
+ }