@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,268 @@
1
+ /* ─── Datepicker ────────────────────────────────────────────────── */
2
+
3
+ .ct-datepicker {
4
+ position: relative;
5
+ display: inline-block;
6
+ }
7
+
8
+ .ct-datepicker__popover {
9
+ position: absolute;
10
+ inset-block-start: calc(100% + var(--space-2));
11
+ inset-inline-start: 0;
12
+ width: min(90vw, var(--ct-popover-width));
13
+ padding: var(--space-5);
14
+ border-radius: var(--radius-md);
15
+ border: var(--border-thin) solid var(--color-border-subtle);
16
+ background: var(--color-bg-elevated);
17
+ box-shadow: var(--shadow-dropdown);
18
+ z-index: var(--z-dropdown);
19
+ display: none;
20
+ }
21
+
22
+ .ct-datepicker[data-state='open'] .ct-datepicker__popover {
23
+ display: grid;
24
+ gap: var(--space-4);
25
+ }
26
+
27
+ /* ── Header ─────────────────────────────────────────────────────── */
28
+
29
+ .ct-datepicker__header {
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ gap: var(--space-4);
34
+ }
35
+
36
+ .ct-datepicker__title {
37
+ font-weight: var(--font-weight-semibold);
38
+ cursor: pointer;
39
+ border: none;
40
+ background: transparent;
41
+ color: var(--color-text-primary);
42
+ padding: var(--space-1) var(--space-3);
43
+ border-radius: var(--radius-sm);
44
+ font-size: inherit;
45
+ line-height: inherit;
46
+ }
47
+
48
+ @media (hover: hover) {
49
+ .ct-datepicker__title:hover {
50
+ background: var(--color-bg-muted);
51
+ }
52
+ }
53
+
54
+ .ct-datepicker__title:focus-visible {
55
+ outline: var(--border-medium) solid var(--color-focus-ring);
56
+ outline-offset: 2px;
57
+ }
58
+
59
+ /* ── Day grid ───────────────────────────────────────────────────── */
60
+
61
+ .ct-datepicker__grid {
62
+ display: grid;
63
+ grid-template-columns: repeat(7, minmax(0, 1fr));
64
+ gap: var(--space-2);
65
+ text-align: center;
66
+ justify-items: center;
67
+ }
68
+
69
+ .ct-datepicker__row {
70
+ display: contents;
71
+ }
72
+
73
+ .ct-datepicker__weekday {
74
+ font-size: var(--font-size-xs);
75
+ color: var(--color-text-muted);
76
+ }
77
+
78
+ .ct-datepicker__day {
79
+ width: min(100%, var(--ct-date-day-size));
80
+ aspect-ratio: 1;
81
+ border-radius: var(--radius-sm);
82
+ border: none;
83
+ background: transparent;
84
+ color: var(--color-text-primary);
85
+ display: inline-flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ cursor: pointer;
89
+ font-size: var(--font-size-sm);
90
+ transition: background var(--duration-fast) var(--easing-standard),
91
+ color var(--duration-fast) var(--easing-standard);
92
+ }
93
+
94
+ @media (hover: hover) {
95
+ .ct-datepicker__day:hover {
96
+ background: var(--color-bg-muted);
97
+ }
98
+ }
99
+
100
+ .ct-datepicker__day:focus-visible {
101
+ outline: var(--border-medium) solid var(--color-focus-ring);
102
+ outline-offset: 2px;
103
+ }
104
+
105
+ .ct-datepicker__day[aria-selected='true'] {
106
+ background: var(--color-brand-primary);
107
+ color: var(--color-text-inverse);
108
+ }
109
+
110
+ .ct-datepicker__day[data-outside='true'] {
111
+ color: var(--color-text-muted);
112
+ }
113
+
114
+ .ct-datepicker__day[data-today='true'] {
115
+ border: var(--border-thin) solid var(--color-brand-accent);
116
+ }
117
+
118
+ .ct-datepicker__day:disabled {
119
+ opacity: var(--opacity-disabled);
120
+ cursor: not-allowed;
121
+ }
122
+
123
+ /* ── Keyboard highlight ─────────────────────────────────────────── */
124
+
125
+ .ct-datepicker__day[data-highlighted] {
126
+ outline: var(--border-medium) solid var(--color-focus-ring);
127
+ outline-offset: -2px;
128
+ }
129
+
130
+ /* ── Unavailable days ───────────────────────────────────────────── */
131
+
132
+ .ct-datepicker__day[data-unavailable] {
133
+ text-decoration: line-through;
134
+ color: var(--color-text-muted);
135
+ cursor: not-allowed;
136
+ pointer-events: none;
137
+ }
138
+
139
+ /* ── Range selection ────────────────────────────────────────────── */
140
+
141
+ .ct-datepicker__day[data-in-range] {
142
+ background: var(--color-brand-primary-surface, color-mix(in srgb, var(--color-brand-primary) 12%, transparent));
143
+ border-radius: 0;
144
+ }
145
+
146
+ .ct-datepicker__day[data-range-start] {
147
+ background: var(--color-brand-primary);
148
+ color: var(--color-text-inverse);
149
+ border-radius: var(--radius-sm) 0 0 var(--radius-sm);
150
+ }
151
+
152
+ .ct-datepicker__day[data-range-end] {
153
+ background: var(--color-brand-primary);
154
+ color: var(--color-text-inverse);
155
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
156
+ }
157
+
158
+ .ct-datepicker__day[data-range-start][data-range-end] {
159
+ border-radius: var(--radius-sm);
160
+ }
161
+
162
+ /* ── Month grid (3×4) ───────────────────────────────────────────── */
163
+
164
+ .ct-datepicker__month-grid {
165
+ display: grid;
166
+ grid-template-columns: repeat(3, 1fr);
167
+ gap: var(--space-3);
168
+ text-align: center;
169
+ }
170
+
171
+ .ct-datepicker__month {
172
+ appearance: none;
173
+ border: none;
174
+ background: transparent;
175
+ color: var(--color-text-primary);
176
+ padding: var(--space-3) var(--space-2);
177
+ border-radius: var(--radius-sm);
178
+ cursor: pointer;
179
+ font-size: var(--font-size-sm);
180
+ transition: background var(--duration-fast) var(--easing-standard),
181
+ color var(--duration-fast) var(--easing-standard);
182
+ }
183
+
184
+ @media (hover: hover) {
185
+ .ct-datepicker__month:hover {
186
+ background: var(--color-bg-muted);
187
+ }
188
+ }
189
+
190
+ .ct-datepicker__month:focus-visible {
191
+ outline: var(--border-medium) solid var(--color-focus-ring);
192
+ outline-offset: 2px;
193
+ }
194
+
195
+ .ct-datepicker__month[aria-selected='true'] {
196
+ background: var(--color-brand-primary);
197
+ color: var(--color-text-inverse);
198
+ }
199
+
200
+ .ct-datepicker__month[data-highlighted] {
201
+ outline: var(--border-medium) solid var(--color-focus-ring);
202
+ outline-offset: -2px;
203
+ }
204
+
205
+ .ct-datepicker__month:disabled {
206
+ opacity: var(--opacity-disabled);
207
+ cursor: not-allowed;
208
+ pointer-events: none;
209
+ }
210
+
211
+ /* ── Year grid (3×4) ────────────────────────────────────────────── */
212
+
213
+ .ct-datepicker__year-grid {
214
+ display: grid;
215
+ grid-template-columns: repeat(3, 1fr);
216
+ gap: var(--space-3);
217
+ text-align: center;
218
+ }
219
+
220
+ .ct-datepicker__year {
221
+ appearance: none;
222
+ border: none;
223
+ background: transparent;
224
+ color: var(--color-text-primary);
225
+ padding: var(--space-3) var(--space-2);
226
+ border-radius: var(--radius-sm);
227
+ cursor: pointer;
228
+ font-size: var(--font-size-sm);
229
+ transition: background var(--duration-fast) var(--easing-standard),
230
+ color var(--duration-fast) var(--easing-standard);
231
+ }
232
+
233
+ @media (hover: hover) {
234
+ .ct-datepicker__year:hover {
235
+ background: var(--color-bg-muted);
236
+ }
237
+ }
238
+
239
+ .ct-datepicker__year:focus-visible {
240
+ outline: var(--border-medium) solid var(--color-focus-ring);
241
+ outline-offset: 2px;
242
+ }
243
+
244
+ .ct-datepicker__year[aria-selected='true'] {
245
+ background: var(--color-brand-primary);
246
+ color: var(--color-text-inverse);
247
+ }
248
+
249
+ .ct-datepicker__year[data-highlighted] {
250
+ outline: var(--border-medium) solid var(--color-focus-ring);
251
+ outline-offset: -2px;
252
+ }
253
+
254
+ .ct-datepicker__year:disabled {
255
+ opacity: var(--opacity-disabled);
256
+ cursor: not-allowed;
257
+ pointer-events: none;
258
+ }
259
+
260
+ /* ── Reduced motion ─────────────────────────────────────────────── */
261
+
262
+ @media (prefers-reduced-motion: reduce) {
263
+ .ct-datepicker__day,
264
+ .ct-datepicker__month,
265
+ .ct-datepicker__year {
266
+ transition: none;
267
+ }
268
+ }
@@ -0,0 +1,73 @@
1
+ /* ── Divider ── */
2
+
3
+ .ct-divider {
4
+ --ct-divider-color: var(--color-border-default);
5
+ --ct-divider-width: 1px;
6
+ --ct-divider-spacing: var(--space-4);
7
+
8
+ border: none;
9
+ background: var(--ct-divider-color);
10
+ height: var(--ct-divider-width);
11
+ width: 100%;
12
+ margin-block: var(--ct-divider-spacing);
13
+ }
14
+
15
+ /* Vertical */
16
+
17
+ .ct-divider--vertical {
18
+ width: var(--ct-divider-width);
19
+ height: auto;
20
+ align-self: stretch;
21
+ margin-block: 0;
22
+ margin-inline: var(--ct-divider-spacing);
23
+ }
24
+
25
+ /* Color variants */
26
+
27
+ .ct-divider--strong {
28
+ --ct-divider-color: var(--color-border-strong);
29
+ }
30
+
31
+ .ct-divider--muted {
32
+ --ct-divider-color: var(--color-border-muted);
33
+ }
34
+
35
+ /* Spacing variants */
36
+
37
+ .ct-divider--sm {
38
+ --ct-divider-spacing: var(--space-1);
39
+ }
40
+
41
+ .ct-divider--lg {
42
+ --ct-divider-spacing: var(--space-8);
43
+ }
44
+
45
+ .ct-divider--none {
46
+ --ct-divider-spacing: 0;
47
+ }
48
+
49
+ /* Labeled */
50
+
51
+ .ct-divider--labeled {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: var(--space-4);
55
+ background: none;
56
+ height: auto;
57
+ }
58
+
59
+ .ct-divider--labeled::before,
60
+ .ct-divider--labeled::after {
61
+ content: '';
62
+ flex: 1;
63
+ height: var(--ct-divider-width);
64
+ background: var(--ct-divider-color);
65
+ }
66
+
67
+ .ct-divider__label {
68
+ color: var(--color-text-secondary);
69
+ font-size: var(--font-size-sm);
70
+ font-weight: var(--font-weight-medium);
71
+ line-height: 1;
72
+ white-space: nowrap;
73
+ }
@@ -0,0 +1,167 @@
1
+ /* ── Drawer ────────────────────────────────────────── */
2
+
3
+ .ct-drawer {
4
+ --ct-drawer-size: 400px;
5
+
6
+ position: fixed;
7
+ inset: 0;
8
+ z-index: var(--z-modal);
9
+ pointer-events: none;
10
+ }
11
+
12
+ .ct-drawer::before {
13
+ content: '';
14
+ position: absolute;
15
+ inset: 0;
16
+ background: var(--color-overlay-scrim);
17
+ opacity: 0;
18
+ visibility: hidden;
19
+ transition: opacity var(--duration-normal) var(--easing-standard),
20
+ visibility var(--duration-normal) var(--easing-standard);
21
+ }
22
+
23
+ .ct-drawer[data-state='open'] {
24
+ pointer-events: auto;
25
+ }
26
+
27
+ .ct-drawer[data-state='open']::before {
28
+ opacity: 1;
29
+ visibility: visible;
30
+ }
31
+
32
+ .ct-drawer__panel {
33
+ position: absolute;
34
+ display: flex;
35
+ flex-direction: column;
36
+ background: var(--color-bg-elevated);
37
+ box-shadow: var(--shadow-modal);
38
+ color: var(--color-text-primary);
39
+ overflow: hidden;
40
+ visibility: hidden;
41
+ inset-block: 0;
42
+ inset-inline-end: 0;
43
+ width: min(var(--ct-drawer-size), 100vw);
44
+ border-inline-start: var(--border-thin) solid var(--color-border-subtle);
45
+ border-radius: var(--radius-lg) 0 0 var(--radius-lg);
46
+ translate: 100% 0;
47
+ transition: translate var(--duration-normal) var(--easing-standard),
48
+ visibility 0s linear var(--duration-normal);
49
+ }
50
+
51
+ .ct-drawer[data-state='open'] .ct-drawer__panel {
52
+ visibility: visible;
53
+ translate: 0 0;
54
+ transition: translate var(--duration-normal) var(--easing-standard),
55
+ visibility 0s linear 0s;
56
+ }
57
+
58
+ /* Side: left */
59
+
60
+ .ct-drawer--left .ct-drawer__panel {
61
+ inset-inline-end: auto;
62
+ inset-inline-start: 0;
63
+ border-inline-start: none;
64
+ border-inline-end: var(--border-thin) solid var(--color-border-subtle);
65
+ border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
66
+ translate: -100% 0;
67
+ }
68
+
69
+ /* Side: bottom */
70
+
71
+ .ct-drawer--bottom .ct-drawer__panel {
72
+ inset-block: auto 0;
73
+ inset-inline: 0;
74
+ width: 100%;
75
+ height: min(var(--ct-drawer-size), 80vh);
76
+ border-inline-start: none;
77
+ border-block-start: var(--border-thin) solid var(--color-border-subtle);
78
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
79
+ translate: 0 100%;
80
+ }
81
+
82
+ /* Side: top */
83
+
84
+ .ct-drawer--top .ct-drawer__panel {
85
+ inset-block: 0 auto;
86
+ inset-inline: 0;
87
+ width: 100%;
88
+ height: min(var(--ct-drawer-size), 80vh);
89
+ border-inline-start: none;
90
+ border-block-end: var(--border-thin) solid var(--color-border-subtle);
91
+ border-radius: 0 0 var(--radius-lg) var(--radius-lg);
92
+ translate: 0 -100%;
93
+ }
94
+
95
+ /* Sizes */
96
+
97
+ .ct-drawer--sm {
98
+ --ct-drawer-size: 320px;
99
+ }
100
+
101
+ .ct-drawer--lg {
102
+ --ct-drawer-size: 560px;
103
+ }
104
+
105
+ .ct-drawer--full {
106
+ --ct-drawer-size: 100vw;
107
+ }
108
+
109
+ .ct-drawer--full .ct-drawer__panel {
110
+ border: none;
111
+ border-radius: 0;
112
+ }
113
+
114
+ .ct-drawer--full.ct-drawer--bottom .ct-drawer__panel,
115
+ .ct-drawer--full.ct-drawer--top .ct-drawer__panel {
116
+ height: 100vh;
117
+ }
118
+
119
+ /* Content sections */
120
+
121
+ .ct-drawer__header {
122
+ display: flex;
123
+ align-items: center;
124
+ justify-content: space-between;
125
+ gap: var(--space-4);
126
+ padding: var(--space-7) var(--space-7) var(--space-4);
127
+ border-bottom: var(--border-thin) solid var(--color-border-subtle);
128
+ flex-shrink: 0;
129
+ }
130
+
131
+ .ct-drawer__body {
132
+ padding: var(--space-6) var(--space-7);
133
+ display: grid;
134
+ gap: var(--space-4);
135
+ overflow-y: auto;
136
+ flex: 1;
137
+ min-height: 0;
138
+ }
139
+
140
+ .ct-drawer__footer {
141
+ padding: var(--space-5) var(--space-7) var(--space-6);
142
+ border-top: var(--border-thin) solid var(--color-border-subtle);
143
+ display: flex;
144
+ justify-content: flex-end;
145
+ gap: var(--space-3);
146
+ flex-wrap: wrap;
147
+ flex-shrink: 0;
148
+ }
149
+
150
+ /* Responsive: left/right drawers expand to full width on small viewports */
151
+
152
+ @media (max-width: 599px) { /* < sm breakpoint (600px) */
153
+ .ct-drawer:not(.ct-drawer--bottom):not(.ct-drawer--top):not(.ct-drawer--full) .ct-drawer__panel {
154
+ width: 100vw;
155
+ border-radius: 0;
156
+ border-inline: none;
157
+ }
158
+ }
159
+
160
+ /* Reduced motion */
161
+
162
+ @media (prefers-reduced-motion: reduce) {
163
+ .ct-drawer::before,
164
+ .ct-drawer__panel {
165
+ transition: none;
166
+ }
167
+ }