@neuravision/construct 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/components/README.md +566 -0
  4. package/components/_keyframes.css +23 -0
  5. package/components/_shared.css +120 -0
  6. package/components/accordion.css +124 -0
  7. package/components/alert.css +67 -0
  8. package/components/avatar.css +127 -0
  9. package/components/badge.css +67 -0
  10. package/components/banner.css +247 -0
  11. package/components/breadcrumbs.css +152 -0
  12. package/components/button.css +145 -0
  13. package/components/card.css +76 -0
  14. package/components/checkbox.css +120 -0
  15. package/components/chip.css +361 -0
  16. package/components/combobox.css +385 -0
  17. package/components/components.css +2 -0
  18. package/components/data-table.css +93 -0
  19. package/components/datepicker.css +268 -0
  20. package/components/divider.css +73 -0
  21. package/components/drawer.css +167 -0
  22. package/components/dropdown.css +401 -0
  23. package/components/empty-state.css +97 -0
  24. package/components/field.css +42 -0
  25. package/components/file-upload.css +111 -0
  26. package/components/icon.css +31 -0
  27. package/components/index.css +49 -0
  28. package/components/input.css +64 -0
  29. package/components/list.css +474 -0
  30. package/components/modal.css +164 -0
  31. package/components/navbar.css +587 -0
  32. package/components/pagination.css +131 -0
  33. package/components/popover.css +231 -0
  34. package/components/progress-bar.css +56 -0
  35. package/components/select-menu.css +267 -0
  36. package/components/select.css +30 -0
  37. package/components/sidebar.css +183 -0
  38. package/components/skeleton.css +38 -0
  39. package/components/skip-link.css +38 -0
  40. package/components/slider.css +305 -0
  41. package/components/spinner.css +72 -0
  42. package/components/switch.css +82 -0
  43. package/components/table.css +139 -0
  44. package/components/tabs.css +147 -0
  45. package/components/textarea.css +16 -0
  46. package/components/toast.css +71 -0
  47. package/components/toggle-group.css +196 -0
  48. package/components/toolbar.css +222 -0
  49. package/components/tooltip.css +124 -0
  50. package/docs/guidelines.md +141 -0
  51. package/foundations.css +299 -0
  52. package/package.json +66 -0
  53. package/tokens/README.md +179 -0
  54. package/tokens/tokens.css +434 -0
  55. package/tokens/tokens.js +1188 -0
  56. package/tokens/tokens.json +810 -0
  57. package/tokens/tokens.ts +1188 -0
@@ -0,0 +1,49 @@
1
+ @import '../tokens/tokens.css';
2
+
3
+ /* Shared design tokens and base control styles */
4
+ @import './_shared.css';
5
+ @import './_keyframes.css';
6
+
7
+ /* Components */
8
+ @import './button.css';
9
+ @import './field.css';
10
+ @import './textarea.css';
11
+ @import './select.css';
12
+ @import './select-menu.css';
13
+ @import './input.css';
14
+ @import './checkbox.css';
15
+ @import './switch.css';
16
+ @import './card.css';
17
+ @import './table.css';
18
+ @import './modal.css';
19
+ @import './toast.css';
20
+ @import './tooltip.css';
21
+ @import './tabs.css';
22
+ @import './dropdown.css';
23
+ @import './pagination.css';
24
+ @import './breadcrumbs.css';
25
+ @import './data-table.css';
26
+ @import './datepicker.css';
27
+ @import './badge.css';
28
+ @import './alert.css';
29
+ @import './banner.css';
30
+ @import './chip.css';
31
+ @import './file-upload.css';
32
+ @import './spinner.css';
33
+ @import './skeleton.css';
34
+ @import './icon.css';
35
+ @import './progress-bar.css';
36
+ @import './toolbar.css';
37
+ @import './sidebar.css';
38
+ @import './toggle-group.css';
39
+ @import './accordion.css';
40
+ @import './avatar.css';
41
+ @import './empty-state.css';
42
+ @import './divider.css';
43
+ @import './slider.css';
44
+ @import './popover.css';
45
+ @import './combobox.css';
46
+ @import './skip-link.css';
47
+ @import './drawer.css';
48
+ @import './navbar.css';
49
+ @import './list.css';
@@ -0,0 +1,64 @@
1
+ .ct-input--with-icon {
2
+ padding-left: calc(var(--space-8) + var(--space-4));
3
+ }
4
+
5
+ .ct-input-wrap {
6
+ position: relative;
7
+ display: flex;
8
+ align-items: center;
9
+ }
10
+
11
+ .ct-input-wrap .ct-input {
12
+ width: 100%;
13
+ }
14
+
15
+ .ct-input__icon {
16
+ position: absolute;
17
+ inset-inline-start: var(--space-4);
18
+ width: var(--icon-md);
19
+ height: var(--icon-md);
20
+ color: var(--color-text-muted);
21
+ pointer-events: none;
22
+ }
23
+
24
+ .ct-input-group {
25
+ position: relative;
26
+ display: flex;
27
+ align-items: stretch;
28
+ }
29
+
30
+ .ct-input-group > .ct-input {
31
+ width: 100%;
32
+ min-width: 0;
33
+ }
34
+
35
+ .ct-input-group__addon {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ padding: 0 var(--space-4);
39
+ background: var(--color-bg-surface);
40
+ border: var(--border-thin) solid var(--ct-control-border);
41
+ color: var(--color-text-muted);
42
+ font-size: var(--font-size-sm);
43
+ white-space: nowrap;
44
+ }
45
+
46
+ .ct-input-group__addon:first-child {
47
+ border-inline-end: none;
48
+ border-radius: var(--ct-control-radius) 0 0 var(--ct-control-radius);
49
+ }
50
+
51
+ .ct-input-group__addon:last-child {
52
+ border-inline-start: none;
53
+ border-radius: 0 var(--ct-control-radius) var(--ct-control-radius) 0;
54
+ }
55
+
56
+ .ct-input-group > .ct-input:not(:first-child) {
57
+ border-start-start-radius: 0;
58
+ border-end-start-radius: 0;
59
+ }
60
+
61
+ .ct-input-group > .ct-input:not(:last-child) {
62
+ border-start-end-radius: 0;
63
+ border-end-end-radius: 0;
64
+ }
@@ -0,0 +1,474 @@
1
+ /* ── List ─────────────────────────────────────────── */
2
+
3
+ .ct-list {
4
+ --ct-list-padding: var(--space-2);
5
+ --ct-list-gap: 0;
6
+ --ct-list-radius: var(--radius-lg);
7
+ --ct-list-bg: transparent;
8
+ --ct-list-border: none;
9
+
10
+ --ct-list-item-padding-x: var(--space-4);
11
+ --ct-list-item-padding-y: var(--space-3);
12
+ --ct-list-item-gap: var(--space-5);
13
+ --ct-list-item-radius: var(--radius-md);
14
+ --ct-list-item-bg: transparent;
15
+ --ct-list-item-bg-hover: var(--color-bg-muted);
16
+ --ct-list-item-bg-active: var(--color-bg-subtle);
17
+ --ct-list-item-border: none;
18
+
19
+ --ct-list-item-title-size: var(--font-size-sm);
20
+ --ct-list-item-title-weight: var(--font-weight-medium);
21
+ --ct-list-item-title-color: var(--color-text-primary);
22
+ --ct-list-item-desc-size: var(--font-size-xs);
23
+ --ct-list-item-desc-color: var(--color-text-secondary);
24
+ --ct-list-item-meta-size: var(--font-size-xs);
25
+ --ct-list-item-meta-color: var(--color-text-muted);
26
+
27
+ --ct-list-divider-color: var(--color-border-subtle);
28
+ --ct-list-divider-inset: calc(var(--ct-list-item-padding-x) + var(--icon-md) + var(--ct-list-item-gap));
29
+
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: var(--ct-list-gap);
33
+ padding: var(--ct-list-padding);
34
+ margin: 0;
35
+ background: var(--ct-list-bg);
36
+ border: var(--ct-list-border);
37
+ border-radius: var(--ct-list-radius);
38
+ list-style: none;
39
+ }
40
+
41
+ /* ── Header ── */
42
+
43
+ .ct-list__header {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ gap: var(--space-3);
48
+ padding: var(--ct-list-item-padding-y) var(--ct-list-item-padding-x);
49
+ }
50
+
51
+ .ct-list__title {
52
+ margin: 0;
53
+ font-size: var(--font-size-sm);
54
+ font-weight: var(--font-weight-semibold);
55
+ line-height: var(--line-height-sm);
56
+ color: var(--color-text-primary);
57
+ }
58
+
59
+ .ct-list__header-action {
60
+ font-size: var(--font-size-xs);
61
+ font-weight: var(--font-weight-medium);
62
+ color: var(--color-brand-primary);
63
+ text-decoration: none;
64
+ cursor: pointer;
65
+ transition: color var(--duration-fast) var(--easing-standard);
66
+ }
67
+
68
+ @media (hover: hover) {
69
+ .ct-list__header-action:hover {
70
+ color: var(--color-brand-primary-hover);
71
+ }
72
+ }
73
+
74
+ .ct-list__header-action:focus-visible {
75
+ outline: 2px solid var(--color-focus-ring);
76
+ outline-offset: 2px;
77
+ border-radius: var(--radius-sm);
78
+ }
79
+
80
+ /* ── Item ── */
81
+
82
+ .ct-list__item {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: var(--ct-list-item-gap);
86
+ padding: var(--ct-list-item-padding-y) var(--ct-list-item-padding-x);
87
+ background: var(--ct-list-item-bg);
88
+ border: var(--ct-list-item-border);
89
+ border-radius: var(--ct-list-item-radius);
90
+ min-height: 0;
91
+ text-decoration: none;
92
+ color: inherit;
93
+ }
94
+
95
+ /* ── Item Slots ── */
96
+
97
+ .ct-list__item-leading {
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ flex-shrink: 0;
102
+ color: var(--color-text-secondary);
103
+ }
104
+
105
+ .ct-list__item-leading > svg {
106
+ width: var(--icon-md);
107
+ height: var(--icon-md);
108
+ }
109
+
110
+ .ct-list__item-content {
111
+ flex: 1;
112
+ min-width: 0;
113
+ display: flex;
114
+ flex-direction: column;
115
+ gap: var(--space-1);
116
+ }
117
+
118
+ .ct-list__item-title {
119
+ font-size: var(--ct-list-item-title-size);
120
+ font-weight: var(--ct-list-item-title-weight);
121
+ line-height: var(--line-height-sm);
122
+ color: var(--ct-list-item-title-color);
123
+ overflow: hidden;
124
+ text-overflow: ellipsis;
125
+ white-space: nowrap;
126
+ }
127
+
128
+ .ct-list__item-description {
129
+ font-size: var(--ct-list-item-desc-size);
130
+ line-height: var(--line-height-xs);
131
+ color: var(--ct-list-item-desc-color);
132
+ overflow: hidden;
133
+ text-overflow: ellipsis;
134
+ display: -webkit-box;
135
+ -webkit-line-clamp: 2;
136
+ -webkit-box-orient: vertical;
137
+ }
138
+
139
+ .ct-list__item-meta {
140
+ font-size: var(--ct-list-item-meta-size);
141
+ line-height: var(--line-height-xs);
142
+ color: var(--ct-list-item-meta-color);
143
+ }
144
+
145
+ .ct-list__item-trailing {
146
+ display: flex;
147
+ align-items: center;
148
+ gap: var(--space-2);
149
+ flex-shrink: 0;
150
+ margin-inline-start: auto;
151
+ color: var(--color-text-secondary);
152
+ }
153
+
154
+ .ct-list__item-trailing > svg {
155
+ width: var(--icon-md);
156
+ height: var(--icon-md);
157
+ }
158
+
159
+ /* ── Interactive Items ── */
160
+
161
+ .ct-list__item--interactive {
162
+ cursor: pointer;
163
+ transition: background var(--duration-fast) var(--easing-standard),
164
+ color var(--duration-fast) var(--easing-standard);
165
+ }
166
+
167
+ @media (hover: hover) {
168
+ .ct-list__item--interactive:hover {
169
+ background: var(--ct-list-item-bg-hover);
170
+ }
171
+ }
172
+
173
+ .ct-list__item--interactive:active {
174
+ background: var(--ct-list-item-bg-active);
175
+ }
176
+
177
+ .ct-list__item--interactive:focus-visible {
178
+ outline: 2px solid var(--color-focus-ring);
179
+ outline-offset: -2px;
180
+ border-radius: var(--ct-list-item-radius);
181
+ }
182
+
183
+ /* ── Clickable Items (stretched link pattern) ── */
184
+
185
+ .ct-list__item--clickable {
186
+ position: relative;
187
+ cursor: pointer;
188
+ transition: background var(--duration-fast) var(--easing-standard);
189
+ }
190
+
191
+ @media (hover: hover) {
192
+ .ct-list__item--clickable:hover {
193
+ background: var(--ct-list-item-bg-hover);
194
+ }
195
+ }
196
+
197
+ .ct-list__item--clickable:active {
198
+ background: var(--ct-list-item-bg-active);
199
+ }
200
+
201
+ .ct-list__item--clickable .ct-list__item-title a {
202
+ text-decoration: none;
203
+ color: inherit;
204
+ }
205
+
206
+ .ct-list__item--clickable .ct-list__item-title a::after {
207
+ content: '';
208
+ position: absolute;
209
+ inset: 0;
210
+ border-radius: var(--ct-list-item-radius);
211
+ }
212
+
213
+ .ct-list__item--clickable .ct-list__item-title a:focus-visible::after {
214
+ outline: 2px solid var(--color-focus-ring);
215
+ outline-offset: -2px;
216
+ }
217
+
218
+ /* ── Active / Highlighted ── */
219
+
220
+ .ct-list__item--active,
221
+ .ct-list__item[data-state='active'] {
222
+ background: var(--ct-list-item-bg-active);
223
+ }
224
+
225
+ .ct-list__item--active .ct-list__item-title,
226
+ .ct-list__item[data-state='active'] .ct-list__item-title {
227
+ color: var(--color-brand-primary);
228
+ font-weight: var(--font-weight-semibold);
229
+ }
230
+
231
+ /* ── Selected Items (Listbox) ── */
232
+
233
+ .ct-list__item[aria-selected='true'] {
234
+ background: var(--ct-list-item-bg-active);
235
+ }
236
+
237
+ .ct-list__item[aria-selected='true'] .ct-list__item-title {
238
+ color: var(--color-brand-primary);
239
+ font-weight: var(--font-weight-semibold);
240
+ }
241
+
242
+ /* ── Disabled Items ── */
243
+
244
+ .ct-list__item[aria-disabled='true'] {
245
+ opacity: var(--opacity-disabled);
246
+ cursor: not-allowed;
247
+ pointer-events: none;
248
+ }
249
+
250
+ /* ── Dividers ── */
251
+
252
+ .ct-list__divider {
253
+ height: 1px;
254
+ background: var(--ct-list-divider-color);
255
+ border: none;
256
+ margin: 0 var(--ct-list-item-padding-x);
257
+ padding: 0;
258
+ list-style: none;
259
+ }
260
+
261
+ .ct-list__divider--inset {
262
+ margin-inline-start: var(--ct-list-divider-inset);
263
+ }
264
+
265
+ /* ── Empty State ── */
266
+
267
+ .ct-list__empty {
268
+ padding: var(--space-8) var(--ct-list-item-padding-x);
269
+ text-align: center;
270
+ color: var(--color-text-muted);
271
+ font-size: var(--ct-list-item-desc-size);
272
+ }
273
+
274
+ /* ── Size: Small ── */
275
+
276
+ .ct-list--sm {
277
+ --ct-list-item-padding-x: var(--space-3);
278
+ --ct-list-item-padding-y: var(--space-2);
279
+ --ct-list-item-gap: var(--space-3);
280
+ --ct-list-item-title-size: var(--font-size-xs);
281
+ --ct-list-item-desc-size: var(--font-size-2xs);
282
+ --ct-list-item-meta-size: var(--font-size-2xs);
283
+ }
284
+
285
+ .ct-list--sm .ct-list__item-leading > svg {
286
+ width: var(--icon-sm);
287
+ height: var(--icon-sm);
288
+ }
289
+
290
+ .ct-list--sm .ct-list__title {
291
+ font-size: var(--font-size-xs);
292
+ }
293
+
294
+ /* ── Size: Large ── */
295
+
296
+ .ct-list--lg {
297
+ --ct-list-item-padding-x: var(--space-5);
298
+ --ct-list-item-padding-y: var(--space-4);
299
+ --ct-list-item-gap: var(--space-5);
300
+ --ct-list-item-title-size: var(--font-size-md);
301
+ --ct-list-item-desc-size: var(--font-size-sm);
302
+ --ct-list-item-meta-size: var(--font-size-xs);
303
+ }
304
+
305
+ .ct-list--lg .ct-list__item-leading > svg {
306
+ width: var(--icon-lg);
307
+ height: var(--icon-lg);
308
+ }
309
+
310
+ .ct-list--lg .ct-list__title {
311
+ font-size: var(--font-size-md);
312
+ }
313
+
314
+ /* ── Dense ── */
315
+
316
+ .ct-list--dense {
317
+ --ct-list-item-padding-x: var(--space-3);
318
+ --ct-list-item-padding-y: var(--space-1);
319
+ --ct-list-item-gap: var(--space-3);
320
+ --ct-list-item-title-size: var(--font-size-xs);
321
+ --ct-list-item-desc-size: var(--font-size-2xs);
322
+ }
323
+
324
+ /* ── Bordered ── */
325
+
326
+ .ct-list--bordered {
327
+ --ct-list-gap: var(--space-2);
328
+ --ct-list-item-border: var(--border-thin) solid var(--color-border-subtle);
329
+ }
330
+
331
+ /* ── Flush ── */
332
+
333
+ .ct-list--flush {
334
+ --ct-list-padding: 0;
335
+ --ct-list-radius: 0;
336
+ --ct-list-border: none;
337
+ --ct-list-item-radius: 0;
338
+ }
339
+
340
+ /* ── Striped ── */
341
+
342
+ .ct-list--striped .ct-list__item:nth-child(even of .ct-list__item) {
343
+ background: var(--color-bg-surface);
344
+ }
345
+
346
+ /* ── Navigation List ── */
347
+
348
+ .ct-list--nav .ct-list__item {
349
+ cursor: pointer;
350
+ transition: background var(--duration-fast) var(--easing-standard),
351
+ color var(--duration-fast) var(--easing-standard);
352
+ }
353
+
354
+ @media (hover: hover) {
355
+ .ct-list--nav .ct-list__item:hover {
356
+ background: var(--ct-list-item-bg-hover);
357
+ }
358
+ }
359
+
360
+ .ct-list--nav .ct-list__item:focus-visible {
361
+ outline: 2px solid var(--color-focus-ring);
362
+ outline-offset: -2px;
363
+ border-radius: var(--ct-list-item-radius);
364
+ }
365
+
366
+ .ct-list--nav .ct-list__item[aria-current] {
367
+ background: var(--ct-list-item-bg-active);
368
+ }
369
+
370
+ .ct-list--nav .ct-list__item[aria-current] .ct-list__item-title {
371
+ color: var(--color-brand-primary);
372
+ font-weight: var(--font-weight-semibold);
373
+ }
374
+
375
+ /* ── Selectable (Listbox) – keyboard ── */
376
+
377
+ .ct-list--selectable .ct-list__item {
378
+ cursor: pointer;
379
+ transition: background var(--duration-fast) var(--easing-standard);
380
+ }
381
+
382
+ @media (hover: hover) {
383
+ .ct-list--selectable .ct-list__item:hover {
384
+ background: var(--ct-list-item-bg-hover);
385
+ }
386
+ }
387
+
388
+ .ct-list--selectable .ct-list__item:focus-visible {
389
+ outline: 2px solid var(--color-focus-ring);
390
+ outline-offset: -2px;
391
+ border-radius: var(--ct-list-item-radius);
392
+ }
393
+
394
+ /* ── Grid Layout (P2) ── */
395
+
396
+ .ct-list--grid {
397
+ display: grid;
398
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
399
+ gap: var(--space-4);
400
+ }
401
+
402
+ .ct-list--grid .ct-list__item {
403
+ flex-direction: column;
404
+ align-items: flex-start;
405
+ text-align: start;
406
+ }
407
+
408
+ /* ── Drag Handle (P2) ── */
409
+
410
+ .ct-list__item-drag {
411
+ display: flex;
412
+ align-items: center;
413
+ cursor: grab;
414
+ color: var(--color-text-muted);
415
+ flex-shrink: 0;
416
+ touch-action: none;
417
+ }
418
+
419
+ .ct-list__item-drag:active {
420
+ cursor: grabbing;
421
+ }
422
+
423
+ .ct-list__item-drag > svg {
424
+ width: var(--icon-sm);
425
+ height: var(--icon-sm);
426
+ }
427
+
428
+ /* ── Loading / Skeleton (P2) ── */
429
+
430
+ .ct-list__item--skeleton .ct-list__item-leading,
431
+ .ct-list__item--skeleton .ct-list__item-title,
432
+ .ct-list__item--skeleton .ct-list__item-description,
433
+ .ct-list__item--skeleton .ct-list__item-trailing {
434
+ background: var(--color-bg-muted);
435
+ border-radius: var(--radius-sm);
436
+ color: transparent;
437
+ animation: ct-skeleton var(--ct-skeleton-duration) ease-in-out infinite;
438
+ pointer-events: none;
439
+ }
440
+
441
+ .ct-list__item--skeleton .ct-list__item-leading {
442
+ width: 32px;
443
+ height: 32px;
444
+ border-radius: 50%;
445
+ }
446
+
447
+ .ct-list__item--skeleton .ct-list__item-title {
448
+ width: 60%;
449
+ height: 1em;
450
+ }
451
+
452
+ .ct-list__item--skeleton .ct-list__item-description {
453
+ width: 80%;
454
+ height: 0.85em;
455
+ }
456
+
457
+ /* ── Reduced Motion ── */
458
+
459
+ @media (prefers-reduced-motion: reduce) {
460
+ .ct-list__item--interactive,
461
+ .ct-list__item--clickable,
462
+ .ct-list--nav .ct-list__item,
463
+ .ct-list--selectable .ct-list__item,
464
+ .ct-list__header-action {
465
+ transition: none;
466
+ }
467
+
468
+ .ct-list__item--skeleton .ct-list__item-leading,
469
+ .ct-list__item--skeleton .ct-list__item-title,
470
+ .ct-list__item--skeleton .ct-list__item-description,
471
+ .ct-list__item--skeleton .ct-list__item-trailing {
472
+ animation: none;
473
+ }
474
+ }