@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,139 @@
1
+ .ct-table-wrap {
2
+ border: var(--border-thin) solid var(--color-border-subtle);
3
+ border-radius: var(--radius-md);
4
+ background: var(--color-bg-elevated);
5
+ overflow-x: auto;
6
+ overflow-y: hidden;
7
+ -webkit-overflow-scrolling: touch;
8
+ }
9
+
10
+ .ct-table {
11
+ width: 100%;
12
+ border-collapse: collapse;
13
+ }
14
+
15
+ .ct-table th,
16
+ .ct-table td {
17
+ padding: var(--space-4) var(--space-5);
18
+ border-bottom: var(--border-thin) solid var(--color-border-subtle);
19
+ text-align: left;
20
+ }
21
+
22
+ .ct-table thead th {
23
+ background: var(--color-bg-surface);
24
+ color: var(--color-text-secondary);
25
+ font-weight: var(--font-weight-semibold);
26
+ }
27
+
28
+ @media (hover: hover) {
29
+ .ct-table tbody tr:hover {
30
+ background: var(--color-bg-muted);
31
+ }
32
+ }
33
+
34
+ .ct-table--striped tbody tr:nth-child(even) {
35
+ background: var(--color-bg-surface);
36
+ }
37
+
38
+ @media (hover: hover) {
39
+ .ct-table--striped tbody tr:hover {
40
+ background: var(--color-bg-muted);
41
+ }
42
+ }
43
+
44
+ .ct-table--compact th,
45
+ .ct-table--compact td {
46
+ padding: var(--space-3) var(--space-4);
47
+ }
48
+
49
+ .ct-table__sort {
50
+ appearance: none;
51
+ border: none;
52
+ background: transparent;
53
+ padding: 0;
54
+ font: inherit;
55
+ color: inherit;
56
+ display: inline-flex;
57
+ align-items: center;
58
+ gap: var(--space-2);
59
+ cursor: pointer;
60
+ width: 100%;
61
+ justify-content: flex-start;
62
+ }
63
+
64
+ .ct-table__sort-indicator {
65
+ display: inline-flex;
66
+ flex-direction: column;
67
+ align-items: center;
68
+ justify-content: center;
69
+ gap: 1px;
70
+ width: var(--icon-sm);
71
+ height: var(--icon-sm);
72
+ }
73
+
74
+ .ct-table__sort-indicator::before,
75
+ .ct-table__sort-indicator::after {
76
+ content: '';
77
+ display: block;
78
+ width: 8px;
79
+ height: 5px;
80
+ background-color: var(--color-text-muted);
81
+ opacity: var(--opacity-disabled);
82
+ -webkit-mask-repeat: no-repeat;
83
+ mask-repeat: no-repeat;
84
+ -webkit-mask-size: contain;
85
+ mask-size: contain;
86
+ -webkit-mask-position: center;
87
+ mask-position: center;
88
+ }
89
+
90
+ .ct-table__sort-indicator::before {
91
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M4 0L8 5H0z'/%3E%3C/svg%3E");
92
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M4 0L8 5H0z'/%3E%3C/svg%3E");
93
+ }
94
+
95
+ .ct-table__sort-indicator::after {
96
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M4 5L0 0h8z'/%3E%3C/svg%3E");
97
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 5'%3E%3Cpath d='M4 5L0 0h8z'/%3E%3C/svg%3E");
98
+ }
99
+
100
+ th[aria-sort='ascending'] .ct-table__sort-indicator::before {
101
+ background-color: var(--color-text-secondary);
102
+ opacity: 1;
103
+ }
104
+
105
+ th[aria-sort='descending'] .ct-table__sort-indicator::after {
106
+ background-color: var(--color-text-secondary);
107
+ opacity: 1;
108
+ }
109
+
110
+ .ct-table__cell--numeric .ct-table__sort {
111
+ justify-content: flex-end;
112
+ }
113
+
114
+ .ct-table__cell--checkbox {
115
+ width: var(--space-8);
116
+ text-align: center;
117
+ }
118
+
119
+ .ct-table__cell--numeric {
120
+ text-align: right;
121
+ font-variant-numeric: tabular-nums;
122
+ }
123
+
124
+ .ct-table__cell--actions {
125
+ text-align: right;
126
+ white-space: nowrap;
127
+ }
128
+
129
+ .ct-table__title {
130
+ display: block;
131
+ font-weight: var(--font-weight-medium);
132
+ }
133
+
134
+ .ct-table__meta {
135
+ display: block;
136
+ margin-top: var(--space-1);
137
+ font-size: var(--font-size-xs);
138
+ color: var(--color-text-muted);
139
+ }
@@ -0,0 +1,147 @@
1
+ /* ── Tabs ── */
2
+
3
+ .ct-tabs {
4
+ --ct-tabs-gap: var(--space-4);
5
+ --ct-tabs-trigger-padding-x: var(--space-5);
6
+ --ct-tabs-trigger-padding-y: var(--space-4);
7
+ --ct-tabs-trigger-font-size: var(--font-size-sm);
8
+ --ct-tabs-trigger-line-height: var(--line-height-sm);
9
+ --ct-tabs-indicator-size: 2px;
10
+ --ct-tabs-indicator-color: var(--color-brand-primary);
11
+
12
+ display: grid;
13
+ gap: var(--ct-tabs-gap);
14
+ }
15
+
16
+ .ct-tabs__list {
17
+ display: inline-flex;
18
+ flex-wrap: wrap;
19
+ gap: var(--space-2);
20
+ border-bottom: var(--border-thin) solid var(--color-border-subtle);
21
+ }
22
+
23
+ .ct-tabs__trigger {
24
+ appearance: none;
25
+ border: none;
26
+ background: none;
27
+ position: relative;
28
+ padding: var(--ct-tabs-trigger-padding-y) var(--ct-tabs-trigger-padding-x);
29
+ color: var(--color-text-secondary);
30
+ font-size: var(--ct-tabs-trigger-font-size);
31
+ line-height: var(--ct-tabs-trigger-line-height);
32
+ font-weight: var(--font-weight-medium);
33
+ cursor: pointer;
34
+ transition: color var(--duration-fast) var(--easing-standard),
35
+ background var(--duration-fast) var(--easing-standard);
36
+ }
37
+
38
+ .ct-tabs__trigger::after {
39
+ content: '';
40
+ position: absolute;
41
+ inset-inline: 0;
42
+ inset-block-end: 0;
43
+ height: var(--ct-tabs-indicator-size);
44
+ background: transparent;
45
+ transition: background var(--duration-fast) var(--easing-standard);
46
+ }
47
+
48
+ @media (hover: hover) {
49
+ .ct-tabs__trigger:hover {
50
+ color: var(--color-text-primary);
51
+ background: var(--color-bg-muted);
52
+ }
53
+ }
54
+
55
+ .ct-tabs__trigger:focus-visible {
56
+ outline: 2px solid var(--color-focus-ring);
57
+ outline-offset: -2px;
58
+ border-radius: var(--radius-sm);
59
+ }
60
+
61
+ .ct-tabs__trigger[aria-selected='true'],
62
+ .ct-tabs__trigger[data-state='active'] {
63
+ color: var(--color-text-primary);
64
+ }
65
+
66
+ .ct-tabs__trigger[aria-selected='true']::after,
67
+ .ct-tabs__trigger[data-state='active']::after {
68
+ background: var(--ct-tabs-indicator-color);
69
+ }
70
+
71
+ .ct-tabs__trigger:disabled,
72
+ .ct-tabs__trigger[aria-disabled='true'] {
73
+ color: var(--color-text-muted);
74
+ opacity: var(--opacity-disabled);
75
+ cursor: not-allowed;
76
+ pointer-events: none;
77
+ }
78
+
79
+ .ct-tabs__panel {
80
+ padding: var(--space-4) 0;
81
+ }
82
+
83
+ /* Tab size variants */
84
+
85
+ .ct-tabs--sm {
86
+ --ct-tabs-trigger-padding-x: var(--space-4);
87
+ --ct-tabs-trigger-padding-y: var(--space-3);
88
+ --ct-tabs-trigger-font-size: var(--font-size-xs);
89
+ --ct-tabs-trigger-line-height: var(--line-height-xs);
90
+ }
91
+
92
+ .ct-tabs--lg {
93
+ --ct-tabs-trigger-padding-x: var(--space-6);
94
+ --ct-tabs-trigger-padding-y: var(--space-5);
95
+ --ct-tabs-trigger-font-size: var(--font-size-md);
96
+ --ct-tabs-trigger-line-height: var(--line-height-md);
97
+ }
98
+
99
+ /* Vertical orientation */
100
+
101
+ .ct-tabs--vertical {
102
+ grid-template-columns: auto 1fr;
103
+ }
104
+
105
+ .ct-tabs--vertical .ct-tabs__list {
106
+ flex-direction: column;
107
+ border-bottom: none;
108
+ border-inline-end: var(--border-thin) solid var(--color-border-subtle);
109
+ }
110
+
111
+ .ct-tabs--vertical .ct-tabs__trigger::after {
112
+ inset-inline: auto;
113
+ inset-inline-end: 0;
114
+ inset-block: 0;
115
+ width: var(--ct-tabs-indicator-size);
116
+ height: auto;
117
+ }
118
+
119
+ /* Pill variant */
120
+
121
+ .ct-tabs--pill .ct-tabs__list {
122
+ border-bottom: none;
123
+ background: var(--color-bg-muted);
124
+ border-radius: var(--radius-md);
125
+ padding: var(--space-1);
126
+ }
127
+
128
+ .ct-tabs--pill .ct-tabs__trigger {
129
+ border-radius: var(--radius-sm);
130
+ }
131
+
132
+ .ct-tabs--pill .ct-tabs__trigger::after {
133
+ display: none;
134
+ }
135
+
136
+ .ct-tabs--pill .ct-tabs__trigger[aria-selected='true'],
137
+ .ct-tabs--pill .ct-tabs__trigger[data-state='active'] {
138
+ background: var(--color-bg-elevated);
139
+ box-shadow: var(--shadow-sm);
140
+ }
141
+
142
+ @media (prefers-reduced-motion: reduce) {
143
+ .ct-tabs__trigger,
144
+ .ct-tabs__trigger::after {
145
+ transition: none;
146
+ }
147
+ }
@@ -0,0 +1,16 @@
1
+ :where(.ct-textarea) {
2
+ min-height: var(--ct-textarea-height, 120px);
3
+ padding: var(--ct-control-padding-y, var(--space-4))
4
+ var(--ct-control-padding-x, var(--space-5));
5
+ resize: vertical;
6
+ }
7
+
8
+ .ct-textarea.ct-control--sm {
9
+ --ct-textarea-height: 96px;
10
+ --ct-control-padding-y: var(--space-3);
11
+ }
12
+
13
+ .ct-textarea.ct-control--lg {
14
+ --ct-textarea-height: 160px;
15
+ --ct-control-padding-y: var(--space-5);
16
+ }
@@ -0,0 +1,71 @@
1
+ .ct-toast-region {
2
+ position: fixed;
3
+ inset-block-start: var(--space-8);
4
+ inset-inline-end: var(--space-8);
5
+ display: grid;
6
+ gap: var(--space-4);
7
+ z-index: var(--z-toast);
8
+ max-width: min(420px, 90vw);
9
+ }
10
+
11
+ .ct-toast {
12
+ --ct-toast-accent: var(--color-brand-accent);
13
+
14
+ display: grid;
15
+ grid-template-columns: auto 1fr auto;
16
+ gap: var(--space-4);
17
+ align-items: start;
18
+ padding: var(--space-5) var(--space-6);
19
+ border-radius: var(--radius-md);
20
+ background: var(--color-bg-elevated);
21
+ border: var(--border-thin) solid var(--color-border-subtle);
22
+ border-inline-start: var(--border-thick) solid var(--ct-toast-accent);
23
+ box-shadow: var(--shadow-md);
24
+ color: var(--color-text-primary);
25
+ transition: opacity var(--duration-fast) var(--easing-standard),
26
+ transform var(--duration-fast) var(--easing-standard);
27
+ }
28
+
29
+ .ct-toast[data-state='closed'] {
30
+ opacity: 0;
31
+ transform: translateY(8px);
32
+ }
33
+
34
+ .ct-toast__title {
35
+ font-weight: var(--font-weight-semibold);
36
+ }
37
+
38
+ .ct-toast__description {
39
+ color: var(--color-text-secondary);
40
+ font-size: var(--font-size-sm);
41
+ }
42
+
43
+ .ct-toast[data-variant='info'] {
44
+ --ct-toast-accent: var(--color-state-info);
45
+ background: var(--color-state-info-surface);
46
+ border-color: var(--color-state-info-border);
47
+ }
48
+
49
+ .ct-toast[data-variant='success'] {
50
+ --ct-toast-accent: var(--color-state-success);
51
+ background: var(--color-state-success-surface);
52
+ border-color: var(--color-state-success-border);
53
+ }
54
+
55
+ .ct-toast[data-variant='warning'] {
56
+ --ct-toast-accent: var(--color-state-warning);
57
+ background: var(--color-state-warning-surface);
58
+ border-color: var(--color-state-warning-border);
59
+ }
60
+
61
+ .ct-toast[data-variant='danger'] {
62
+ --ct-toast-accent: var(--color-state-danger);
63
+ background: var(--color-state-danger-surface);
64
+ border-color: var(--color-state-danger-border);
65
+ }
66
+
67
+ @media (prefers-reduced-motion: reduce) {
68
+ .ct-toast {
69
+ transition: none;
70
+ }
71
+ }
@@ -0,0 +1,196 @@
1
+ /* ── Toggle Group ── */
2
+
3
+ .ct-toggle-group {
4
+ --ct-toggle-group-bg: var(--color-bg-surface);
5
+ --ct-toggle-group-border: var(--color-border-default);
6
+ --ct-toggle-group-radius: var(--radius-control);
7
+ --ct-toggle-group-item-padding-x: var(--space-5);
8
+ --ct-toggle-group-item-padding-y: var(--space-3);
9
+ --ct-toggle-group-item-font-size: var(--font-size-sm);
10
+ --ct-toggle-group-item-line-height: var(--line-height-sm);
11
+ --ct-toggle-group-item-color: var(--color-text-secondary);
12
+ --ct-toggle-group-item-bg-active: var(--color-brand-primary);
13
+ --ct-toggle-group-item-color-active: var(--color-text-inverse);
14
+ --ct-toggle-group-item-bg-hover: var(--color-bg-muted);
15
+ --ct-toggle-group-item-min-height: var(--control-height-md);
16
+ --ct-toggle-group-gap: 0;
17
+
18
+ display: inline-flex;
19
+ gap: var(--ct-toggle-group-gap);
20
+ border-radius: var(--ct-toggle-group-radius);
21
+ border: var(--border-thin) solid var(--ct-toggle-group-border);
22
+ background: var(--ct-toggle-group-bg);
23
+ max-width: 100%;
24
+ overflow-x: auto;
25
+ overflow-y: hidden;
26
+ -webkit-overflow-scrolling: touch;
27
+ scrollbar-width: none;
28
+ }
29
+
30
+ .ct-toggle-group::-webkit-scrollbar {
31
+ display: none;
32
+ }
33
+
34
+ /* ── Item ── */
35
+
36
+ .ct-toggle-group__item {
37
+ appearance: none;
38
+ border: none;
39
+ background: transparent;
40
+ min-height: var(--ct-toggle-group-item-min-height);
41
+ padding: var(--ct-toggle-group-item-padding-y) var(--ct-toggle-group-item-padding-x);
42
+ color: var(--ct-toggle-group-item-color);
43
+ font-size: var(--ct-toggle-group-item-font-size);
44
+ line-height: var(--ct-toggle-group-item-line-height);
45
+ font-weight: var(--font-weight-medium);
46
+ cursor: pointer;
47
+ white-space: nowrap;
48
+ display: inline-flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ gap: var(--space-2);
52
+ border-inline-end: var(--border-thin) solid var(--ct-toggle-group-border);
53
+ transition: background var(--duration-fast) var(--easing-standard),
54
+ color var(--duration-fast) var(--easing-standard);
55
+ }
56
+
57
+ .ct-toggle-group__item:last-child {
58
+ border-inline-end: none;
59
+ }
60
+
61
+ @media (hover: hover) {
62
+ .ct-toggle-group__item:hover {
63
+ background: var(--ct-toggle-group-item-bg-hover);
64
+ }
65
+ }
66
+
67
+ /* Active state – aria-pressed for multi-select, aria-checked for single-select */
68
+ .ct-toggle-group__item[aria-pressed='true'],
69
+ .ct-toggle-group__item[aria-checked='true'] {
70
+ background: var(--ct-toggle-group-item-bg-active);
71
+ color: var(--ct-toggle-group-item-color-active);
72
+ }
73
+
74
+ .ct-toggle-group__item:focus-visible {
75
+ outline: 2px solid var(--color-focus-ring);
76
+ outline-offset: -2px;
77
+ z-index: 1;
78
+ }
79
+
80
+ .ct-toggle-group__item:disabled,
81
+ .ct-toggle-group__item[aria-disabled='true'] {
82
+ opacity: var(--opacity-disabled);
83
+ cursor: not-allowed;
84
+ }
85
+
86
+ /* ── Icon element (inside icon+text items) ── */
87
+
88
+ .ct-toggle-group__icon {
89
+ width: 1em;
90
+ height: 1em;
91
+ display: inline-flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ flex-shrink: 0;
95
+ }
96
+
97
+ /* ── Icon-only item ── */
98
+
99
+ .ct-toggle-group__item--icon {
100
+ aspect-ratio: 1;
101
+ padding: var(--ct-toggle-group-item-padding-y);
102
+ }
103
+
104
+ /* ── Size variants ── */
105
+
106
+ .ct-toggle-group--sm {
107
+ --ct-toggle-group-item-min-height: var(--control-height-sm);
108
+ --ct-toggle-group-item-padding-x: var(--space-4);
109
+ --ct-toggle-group-item-padding-y: var(--space-2);
110
+ --ct-toggle-group-item-font-size: var(--font-size-xs);
111
+ --ct-toggle-group-item-line-height: var(--line-height-xs);
112
+ }
113
+
114
+ .ct-toggle-group--lg {
115
+ --ct-toggle-group-item-min-height: var(--control-height-lg);
116
+ --ct-toggle-group-item-padding-x: var(--space-6);
117
+ --ct-toggle-group-item-padding-y: var(--space-4);
118
+ --ct-toggle-group-item-font-size: var(--font-size-md);
119
+ --ct-toggle-group-item-line-height: var(--line-height-md);
120
+ }
121
+
122
+ /* ── Outlined variant ── */
123
+
124
+ .ct-toggle-group--outlined {
125
+ background: transparent;
126
+ }
127
+
128
+ .ct-toggle-group--outlined .ct-toggle-group__item[aria-pressed='true'],
129
+ .ct-toggle-group--outlined .ct-toggle-group__item[aria-checked='true'] {
130
+ background: var(--color-bg-muted);
131
+ color: var(--color-brand-primary);
132
+ }
133
+
134
+ /* ── Vertical orientation ── */
135
+
136
+ .ct-toggle-group--vertical {
137
+ flex-direction: column;
138
+ }
139
+
140
+ .ct-toggle-group--vertical .ct-toggle-group__item {
141
+ border-inline-end: none;
142
+ border-block-end: var(--border-thin) solid var(--ct-toggle-group-border);
143
+ }
144
+
145
+ .ct-toggle-group--vertical .ct-toggle-group__item:last-child {
146
+ border-block-end: none;
147
+ }
148
+
149
+ /* ── Separated variant ── */
150
+
151
+ .ct-toggle-group--separated {
152
+ --ct-toggle-group-gap: var(--space-2);
153
+ border: none;
154
+ background: transparent;
155
+ overflow: visible;
156
+ }
157
+
158
+ .ct-toggle-group--separated .ct-toggle-group__item {
159
+ border: var(--border-thin) solid var(--ct-toggle-group-border);
160
+ border-radius: var(--ct-toggle-group-radius);
161
+ border-inline-end: var(--border-thin) solid var(--ct-toggle-group-border);
162
+ }
163
+
164
+ /* ── Full-width variant ── */
165
+
166
+ .ct-toggle-group--full {
167
+ display: flex;
168
+ width: 100%;
169
+ }
170
+
171
+ .ct-toggle-group--full .ct-toggle-group__item {
172
+ flex: 1;
173
+ }
174
+
175
+ /* ── Wrap variant ── */
176
+
177
+ .ct-toggle-group--wrap {
178
+ flex-wrap: wrap;
179
+ overflow: visible;
180
+ }
181
+
182
+ .ct-toggle-group--wrap .ct-toggle-group__item {
183
+ border-block-end: var(--border-thin) solid var(--ct-toggle-group-border);
184
+ }
185
+
186
+ .ct-toggle-group--wrap .ct-toggle-group__item:last-child {
187
+ border-block-end: none;
188
+ }
189
+
190
+ /* ── Reduced motion ── */
191
+
192
+ @media (prefers-reduced-motion: reduce) {
193
+ .ct-toggle-group__item {
194
+ transition: none;
195
+ }
196
+ }