@neuravision/construct 1.1.2 → 1.1.4

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,78 @@
1
+ /* ── Shared App Shell: Rail Mode ────────────────────────────────── */
2
+ /* Common sidebar rail-mode styles used by App Shell V1 and V2. */
3
+ /* Crosses component boundary: shells orchestrate child layout. */
4
+ /* ─────────────────────────────────────────────────────────────── */
5
+
6
+
7
+ /* ── Collapsed: Hide Labels & Badges ── */
8
+
9
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-nav-item__label,
10
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-nav-item__badge,
11
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-sidebar__header span,
12
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-sidebar__header strong {
13
+ opacity: 0;
14
+ width: 0;
15
+ overflow: hidden;
16
+ white-space: nowrap;
17
+ /* Collapsing: labels fade out first, then width snaps */
18
+ transition:
19
+ opacity 120ms ease-in-out,
20
+ width 0ms linear 120ms;
21
+ }
22
+
23
+
24
+ /* ── Expanded: Restore Labels & Badges ── */
25
+
26
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-nav-item__label,
27
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-nav-item__badge,
28
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-sidebar__header span,
29
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-sidebar__header strong {
30
+ opacity: 1;
31
+ width: auto;
32
+ /* Expanding: labels fade in after sidebar width finishes growing */
33
+ transition: opacity 120ms ease-in-out 250ms;
34
+ }
35
+
36
+
37
+ /* ── Collapsed: Center Nav Items (Icon-Only) ── */
38
+
39
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-nav-item {
40
+ justify-content: center;
41
+ padding-inline: var(--space-3);
42
+ }
43
+
44
+
45
+ /* ── Tablet: Auto-Collapse to Rail ── */
46
+
47
+ @media (max-width: 1199px) {
48
+ :is(.ct-app-shell, .ct-app-shell-v2):not([data-sidebar-state]) .ct-nav-item__label,
49
+ :is(.ct-app-shell, .ct-app-shell-v2):not([data-sidebar-state]) .ct-nav-item__badge,
50
+ :is(.ct-app-shell, .ct-app-shell-v2):not([data-sidebar-state]) .ct-sidebar__header span,
51
+ :is(.ct-app-shell, .ct-app-shell-v2):not([data-sidebar-state]) .ct-sidebar__header strong {
52
+ opacity: 0;
53
+ width: 0;
54
+ overflow: hidden;
55
+ white-space: nowrap;
56
+ }
57
+
58
+ :is(.ct-app-shell, .ct-app-shell-v2):not([data-sidebar-state]) .ct-nav-item {
59
+ justify-content: center;
60
+ padding-inline: var(--space-3);
61
+ }
62
+ }
63
+
64
+
65
+ /* ── Reduced Motion ── */
66
+
67
+ @media (prefers-reduced-motion: reduce) {
68
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-nav-item__label,
69
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-nav-item__badge,
70
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-sidebar__header span,
71
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='collapsed'] .ct-sidebar__header strong,
72
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-nav-item__label,
73
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-nav-item__badge,
74
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-sidebar__header span,
75
+ :is(.ct-app-shell, .ct-app-shell-v2)[data-sidebar-state='expanded'] .ct-sidebar__header strong {
76
+ transition: none;
77
+ }
78
+ }
@@ -0,0 +1,503 @@
1
+ /* ── App Shell V2: Floating Canvas ─────────────────────────────── */
2
+ /* All chrome floats as elevated surfaces on a tinted canvas, */
3
+ /* separated by space and shadow — not borders. */
4
+ /* */
5
+ /* Architecture: */
6
+ /* 2-column CSS Grid: [sidebar] [body] */
7
+ /* Body is a flex container: [main] + optional [panel] */
8
+ /* Surfaces have rounded corners + elevation — zero hard edges. */
9
+ /* */
10
+ /* ╭─────────────────────────────────────────────────────╮ */
11
+ /* │ canvas background │ */
12
+ /* │ ╭────────╮ ╭──────────────────────────────────╮ │ */
13
+ /* │ │ │ │ toolbar (optional, sticky) │ │ */
14
+ /* │ │ Side- │ ├───────────────────┬──────────────│ │ */
15
+ /* │ │ bar │ │ main (scrolls) │ panel │ │ */
16
+ /* │ │ │ │ │ (optional) │ │ */
17
+ /* │ ╰────────╯ ╰───────────────────┴──────────────╯ │ */
18
+ /* ╰─────────────────────────────────────────────────────╯ */
19
+ /* */
20
+ /* Shell breakpoints: */
21
+ /* Mobile: <768px */
22
+ /* Tablet: 768–1199px */
23
+ /* Desktop: >=1200px */
24
+ /* ─────────────────────────────────────────────────────────────── */
25
+
26
+ .ct-app-shell-v2 {
27
+ /* ── Public Tokens ── */
28
+ --ct-v2-sidebar-width: 260px;
29
+ --ct-v2-sidebar-rail-width: 64px;
30
+ --ct-v2-panel-width: 340px;
31
+ --ct-v2-gap: var(--space-4);
32
+ --ct-v2-radius: var(--radius-lg);
33
+ --ct-v2-canvas-bg: var(--color-bg-muted);
34
+ --ct-v2-surface-bg: var(--color-bg-canvas);
35
+ --ct-v2-surface-shadow: var(--shadow-xs);
36
+ --ct-v2-transition-duration: 250ms;
37
+ --ct-v2-transition-easing: cubic-bezier(0.32, 0.72, 0, 1);
38
+
39
+ /* ── Internal ── */
40
+ --_v2-sidebar-w: var(--ct-v2-sidebar-width);
41
+
42
+ display: grid;
43
+ grid-template-columns: var(--_v2-sidebar-w) 1fr;
44
+ grid-template-areas: 'sidebar body';
45
+ gap: var(--ct-v2-gap);
46
+ padding: var(--ct-v2-gap);
47
+ height: 100vh;
48
+ height: 100dvh;
49
+ overflow: hidden;
50
+ background: var(--ct-v2-canvas-bg);
51
+ transition: grid-template-columns var(--ct-v2-transition-duration) var(--ct-v2-transition-easing);
52
+ }
53
+
54
+
55
+ /* ── Floating Surface ── */
56
+ /* Shared elevated-card look for all chrome panels. */
57
+
58
+ .ct-app-shell-v2__sidebar,
59
+ .ct-app-shell-v2__body,
60
+ .ct-app-shell-v2__header {
61
+ background: var(--ct-v2-surface-bg);
62
+ border-radius: var(--ct-v2-radius);
63
+ box-shadow: var(--ct-v2-surface-shadow);
64
+ overflow: hidden;
65
+ }
66
+
67
+
68
+ /* ── Grid Area Assignment ── */
69
+
70
+ .ct-app-shell-v2__sidebar { grid-area: sidebar; }
71
+ .ct-app-shell-v2__body { grid-area: body; }
72
+ .ct-app-shell-v2__header { grid-area: header; }
73
+
74
+
75
+ /* ── Sidebar ── */
76
+
77
+ .ct-app-shell-v2__sidebar {
78
+ overflow-y: auto;
79
+ overflow-x: hidden;
80
+ min-height: 0;
81
+ min-width: 0;
82
+ transition: opacity var(--ct-v2-transition-duration) var(--ct-v2-transition-easing);
83
+ }
84
+
85
+ /* Sidebar child component fills its slot — override default sidebar chrome */
86
+ .ct-app-shell-v2__sidebar > .ct-sidebar {
87
+ width: 100%;
88
+ height: 100%;
89
+ background: transparent;
90
+ border-inline-end: none;
91
+ border-radius: 0;
92
+ }
93
+
94
+
95
+ /* ── Body (Main + Panel container) ── */
96
+
97
+ .ct-app-shell-v2__body {
98
+ display: flex;
99
+ min-width: 0;
100
+ min-height: 0;
101
+ }
102
+
103
+
104
+ /* ── Main ── */
105
+
106
+ .ct-app-shell-v2__main {
107
+ flex: 1;
108
+ min-width: 0;
109
+ min-height: 0;
110
+ overflow-y: auto;
111
+ display: flex;
112
+ flex-direction: column;
113
+ }
114
+
115
+
116
+ /* ── Panel ── */
117
+
118
+ .ct-app-shell-v2__panel {
119
+ width: var(--ct-v2-panel-width);
120
+ flex-shrink: 0;
121
+ overflow-y: auto;
122
+ overflow-x: hidden;
123
+ min-height: 0;
124
+ border-inline-start: var(--border-thin) solid var(--color-border-subtle);
125
+ transition:
126
+ width var(--ct-v2-transition-duration) var(--ct-v2-transition-easing),
127
+ visibility 0s linear var(--ct-v2-transition-duration);
128
+ }
129
+
130
+ .ct-app-shell-v2:not([data-panel-state='open']) .ct-app-shell-v2__panel {
131
+ visibility: hidden;
132
+ width: 0;
133
+ min-width: 0;
134
+ overflow: hidden;
135
+ border-inline-start: none;
136
+ }
137
+
138
+
139
+ /* ── Footer (inside main or body) ── */
140
+
141
+ .ct-app-shell-v2__footer {
142
+ flex-shrink: 0;
143
+ border-top: var(--border-thin) solid var(--color-border-subtle);
144
+ }
145
+
146
+
147
+ /* ── Toolbar (inside main — replaces full-width header) ── */
148
+
149
+ .ct-app-shell-v2__toolbar {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: space-between;
153
+ gap: var(--space-4);
154
+ padding: var(--space-4) var(--space-6);
155
+ border-bottom: var(--border-thin) solid var(--color-border-subtle);
156
+ flex-shrink: 0;
157
+ }
158
+
159
+ .ct-app-shell-v2__toolbar--sticky {
160
+ position: sticky;
161
+ top: 0;
162
+ z-index: 1;
163
+ background: var(--ct-v2-surface-bg);
164
+ }
165
+
166
+
167
+ /* ── Sidebar States ── */
168
+
169
+ .ct-app-shell-v2[data-sidebar-state='expanded'] {
170
+ --_v2-sidebar-w: var(--ct-v2-sidebar-width);
171
+ }
172
+
173
+ .ct-app-shell-v2[data-sidebar-state='collapsed'] {
174
+ --_v2-sidebar-w: var(--ct-v2-sidebar-rail-width);
175
+ }
176
+
177
+ .ct-app-shell-v2[data-sidebar-state='hidden'] {
178
+ --_v2-sidebar-w: 0px;
179
+ grid-template-columns: 1fr;
180
+ grid-template-areas: 'body';
181
+ }
182
+
183
+ .ct-app-shell-v2[data-sidebar-state='hidden'].ct-app-shell-v2--with-header {
184
+ grid-template-rows: auto 1fr;
185
+ grid-template-columns: 1fr;
186
+ grid-template-areas:
187
+ 'header'
188
+ 'body';
189
+ }
190
+
191
+ .ct-app-shell-v2[data-sidebar-state='hidden'] > .ct-app-shell-v2__sidebar {
192
+ visibility: hidden;
193
+ overflow: hidden;
194
+ opacity: 0;
195
+ width: 0;
196
+ padding: 0;
197
+ margin: 0;
198
+ }
199
+
200
+
201
+ /* ── Panel State ── */
202
+
203
+ .ct-app-shell-v2[data-panel-state='open'] .ct-app-shell-v2__panel {
204
+ visibility: visible;
205
+ transition:
206
+ width var(--ct-v2-transition-duration) var(--ct-v2-transition-easing),
207
+ visibility 0s linear 0s;
208
+ }
209
+
210
+
211
+
212
+ /* ── Header Variant (Optional Full-Width Floating Bar) ── */
213
+
214
+ .ct-app-shell-v2--with-header {
215
+ grid-template-rows: auto 1fr;
216
+ grid-template-columns: var(--_v2-sidebar-w) 1fr;
217
+ grid-template-areas:
218
+ 'header header'
219
+ 'sidebar body';
220
+ }
221
+
222
+ /* Navbar inside header — strip its own background/border */
223
+ .ct-app-shell-v2__header > .ct-navbar {
224
+ background: transparent;
225
+ border-bottom: none;
226
+ box-shadow: none;
227
+ }
228
+
229
+
230
+ /* ── Sidebar Full Height + Header ── */
231
+
232
+ .ct-app-shell-v2--sidebar-full-height.ct-app-shell-v2--with-header {
233
+ grid-template-areas:
234
+ 'sidebar header'
235
+ 'sidebar body';
236
+ }
237
+
238
+
239
+ /* ── Modifier: No Sidebar ── */
240
+
241
+ .ct-app-shell-v2--no-sidebar {
242
+ grid-template-columns: 1fr;
243
+ grid-template-areas: 'body';
244
+ }
245
+
246
+ .ct-app-shell-v2--no-sidebar.ct-app-shell-v2--with-header {
247
+ grid-template-areas:
248
+ 'header'
249
+ 'body';
250
+ }
251
+
252
+ .ct-app-shell-v2--no-sidebar > .ct-app-shell-v2__sidebar {
253
+ display: none;
254
+ }
255
+
256
+
257
+ /* ── Modifier: Sidebar Right ── */
258
+
259
+ .ct-app-shell-v2--sidebar-right {
260
+ grid-template-columns: 1fr var(--_v2-sidebar-w);
261
+ grid-template-areas: 'body sidebar';
262
+ }
263
+
264
+ .ct-app-shell-v2--sidebar-right.ct-app-shell-v2--with-header {
265
+ grid-template-areas:
266
+ 'header header'
267
+ 'body sidebar';
268
+ }
269
+
270
+ .ct-app-shell-v2--sidebar-right.ct-app-shell-v2--sidebar-full-height.ct-app-shell-v2--with-header {
271
+ grid-template-areas:
272
+ 'header sidebar'
273
+ 'body sidebar';
274
+ }
275
+
276
+
277
+ /* ── Modifier: Sidebar Branded (Dark) ── */
278
+ /* Tinted sidebar surface — Slack / Linear / Discord aesthetic. */
279
+
280
+ .ct-app-shell-v2--sidebar-branded > .ct-app-shell-v2__sidebar {
281
+ --_branded-bg: var(--color-slate-900);
282
+ --_branded-border: var(--color-slate-700);
283
+ --_branded-text: var(--color-slate-300);
284
+ --_branded-text-strong: var(--color-slate-0);
285
+ --_branded-text-muted: var(--color-slate-100);
286
+ --_branded-hover-bg: color-mix(in srgb, var(--_branded-text-strong) 8%, transparent);
287
+ --_branded-active-bg: color-mix(in srgb, var(--_branded-text-strong) 12%, transparent);
288
+ --_branded-badge-bg: color-mix(in srgb, var(--_branded-text-strong) 15%, transparent);
289
+
290
+ background: var(--_branded-bg);
291
+ color: var(--color-text-inverse);
292
+ box-shadow: none;
293
+ }
294
+
295
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-sidebar {
296
+ background: transparent;
297
+ }
298
+
299
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-sidebar__header {
300
+ border-bottom-color: var(--_branded-border);
301
+ color: var(--_branded-text-strong);
302
+ }
303
+
304
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item {
305
+ color: var(--_branded-text);
306
+ }
307
+
308
+ @media (hover: hover) {
309
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item:hover {
310
+ background: var(--_branded-hover-bg);
311
+ color: var(--_branded-text-strong);
312
+ }
313
+ }
314
+
315
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item--active,
316
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item[aria-current='page'] {
317
+ background: var(--_branded-active-bg);
318
+ color: var(--_branded-text-strong);
319
+ }
320
+
321
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item__badge {
322
+ background: var(--_branded-badge-bg);
323
+ color: var(--_branded-text-muted);
324
+ }
325
+
326
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item--active .ct-nav-item__badge,
327
+ .ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item[aria-current='page'] .ct-nav-item__badge {
328
+ background: var(--color-brand-primary);
329
+ color: var(--color-text-inverse);
330
+ }
331
+
332
+
333
+ /* ── Modifier: Glass Effect ── */
334
+ /* Subtle frosted glass on surfaces — optional modern flourish. */
335
+
336
+ .ct-app-shell-v2--glass > .ct-app-shell-v2__sidebar,
337
+ .ct-app-shell-v2--glass > .ct-app-shell-v2__body,
338
+ .ct-app-shell-v2--glass > .ct-app-shell-v2__header {
339
+ background: color-mix(in srgb, var(--ct-v2-surface-bg) 85%, transparent);
340
+ backdrop-filter: blur(16px) saturate(180%);
341
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
342
+ }
343
+
344
+
345
+ /* ── Backdrop (Mobile Sidebar Overlay) ── */
346
+
347
+ .ct-app-shell-v2__backdrop {
348
+ position: fixed;
349
+ inset: 0;
350
+ background: var(--color-overlay-scrim);
351
+ z-index: calc(var(--z-overlay) - 1);
352
+ opacity: 0;
353
+ visibility: hidden;
354
+ pointer-events: none;
355
+ transition:
356
+ opacity var(--ct-v2-transition-duration) var(--ct-v2-transition-easing),
357
+ visibility var(--ct-v2-transition-duration) var(--ct-v2-transition-easing);
358
+ }
359
+
360
+
361
+ /* ── Transitions ── */
362
+
363
+ /* Delay grid shrink on collapse so labels fade out first */
364
+ .ct-app-shell-v2[data-sidebar-state='collapsed'] {
365
+ transition-delay: 120ms;
366
+ }
367
+
368
+
369
+ /* ── Responsive: Tablet (768–1199px) ── */
370
+
371
+ @media (max-width: 1199px) {
372
+ /* Auto-collapse sidebar to rail when no explicit state */
373
+ .ct-app-shell-v2:not([data-sidebar-state]) {
374
+ --_v2-sidebar-w: var(--ct-v2-sidebar-rail-width);
375
+ }
376
+
377
+ /* Panel becomes floating overlay on tablet */
378
+ .ct-app-shell-v2[data-panel-state='open'] .ct-app-shell-v2__panel {
379
+ position: fixed;
380
+ inset-block: var(--ct-v2-gap);
381
+ inset-inline-end: var(--ct-v2-gap);
382
+ width: min(var(--ct-v2-panel-width), calc(100vw - 2 * var(--ct-v2-gap)));
383
+ z-index: var(--z-overlay);
384
+ visibility: visible;
385
+ background: var(--ct-v2-surface-bg);
386
+ border-radius: var(--ct-v2-radius);
387
+ box-shadow: var(--shadow-lg);
388
+ border-inline-start: none;
389
+ }
390
+ }
391
+
392
+
393
+ /* ── Responsive: Mobile (<768px) ── */
394
+
395
+ @media (max-width: 767px) {
396
+ .ct-app-shell-v2 {
397
+ --ct-v2-gap: var(--space-3);
398
+ }
399
+
400
+ /* Auto-hide sidebar */
401
+ .ct-app-shell-v2:not([data-sidebar-state]) {
402
+ grid-template-columns: 1fr;
403
+ grid-template-areas: 'body';
404
+ }
405
+
406
+ .ct-app-shell-v2:not([data-sidebar-state]) > .ct-app-shell-v2__sidebar {
407
+ display: none;
408
+ }
409
+
410
+ /* Expanded sidebar = floating overlay with rounded corners */
411
+ .ct-app-shell-v2[data-sidebar-state='expanded'] {
412
+ grid-template-columns: 1fr;
413
+ grid-template-areas: 'body';
414
+ }
415
+
416
+ .ct-app-shell-v2[data-sidebar-state='expanded'] > .ct-app-shell-v2__sidebar {
417
+ position: fixed;
418
+ inset-block: var(--ct-v2-gap);
419
+ inset-inline-start: var(--ct-v2-gap);
420
+ width: min(var(--ct-v2-sidebar-width), calc(100vw - 2 * var(--ct-v2-gap)));
421
+ z-index: var(--z-overlay);
422
+ visibility: visible;
423
+ opacity: 1;
424
+ box-shadow: var(--shadow-lg);
425
+ }
426
+
427
+ .ct-app-shell-v2[data-sidebar-state='expanded'] > .ct-app-shell-v2__backdrop {
428
+ opacity: 1;
429
+ visibility: visible;
430
+ pointer-events: auto;
431
+ }
432
+
433
+ /* Collapsed sidebar = hidden on mobile */
434
+ .ct-app-shell-v2[data-sidebar-state='collapsed'] {
435
+ grid-template-columns: 1fr;
436
+ grid-template-areas: 'body';
437
+ }
438
+
439
+ .ct-app-shell-v2[data-sidebar-state='collapsed'] > .ct-app-shell-v2__sidebar {
440
+ visibility: hidden;
441
+ overflow: hidden;
442
+ opacity: 0;
443
+ width: 0;
444
+ }
445
+
446
+ /* Hidden sidebar on mobile */
447
+ .ct-app-shell-v2[data-sidebar-state='hidden'] > .ct-app-shell-v2__sidebar {
448
+ display: none;
449
+ }
450
+
451
+ /* Panel = floating overlay on mobile */
452
+ .ct-app-shell-v2[data-panel-state='open'] .ct-app-shell-v2__panel {
453
+ position: fixed;
454
+ inset-block: var(--ct-v2-gap);
455
+ inset-inline-end: var(--ct-v2-gap);
456
+ width: min(var(--ct-v2-panel-width), calc(100vw - 2 * var(--ct-v2-gap)));
457
+ z-index: var(--z-overlay);
458
+ visibility: visible;
459
+ background: var(--ct-v2-surface-bg);
460
+ border-radius: var(--ct-v2-radius);
461
+ box-shadow: var(--shadow-lg);
462
+ border-inline-start: none;
463
+ }
464
+
465
+ /* With-header collapses to single column on mobile */
466
+ .ct-app-shell-v2--with-header {
467
+ grid-template-columns: 1fr;
468
+ grid-template-areas:
469
+ 'header'
470
+ 'body';
471
+ }
472
+
473
+ .ct-app-shell-v2--sidebar-full-height.ct-app-shell-v2--with-header {
474
+ grid-template-areas:
475
+ 'header'
476
+ 'body';
477
+ }
478
+
479
+ /* Sidebar-right falls back to standard on mobile */
480
+ .ct-app-shell-v2--sidebar-right {
481
+ grid-template-columns: 1fr;
482
+ grid-template-areas: 'body';
483
+ }
484
+
485
+ .ct-app-shell-v2--sidebar-right.ct-app-shell-v2--with-header {
486
+ grid-template-areas:
487
+ 'header'
488
+ 'body';
489
+ }
490
+ }
491
+
492
+
493
+ /* ── Reduced Motion ── */
494
+
495
+ @media (prefers-reduced-motion: reduce) {
496
+ .ct-app-shell-v2,
497
+ .ct-app-shell-v2[data-sidebar-state],
498
+ .ct-app-shell-v2__sidebar,
499
+ .ct-app-shell-v2__panel,
500
+ .ct-app-shell-v2__backdrop {
501
+ transition: none;
502
+ }
503
+ }
@@ -0,0 +1,405 @@
1
+ /* ── App Shell ─────────────────────────────────────────────────── */
2
+ /* CSS Grid layout shell that orchestrates Navbar, Sidebar, */
3
+ /* Main content, optional Panel, and optional Footer. */
4
+ /* */
5
+ /* Shell breakpoints (component-specific, differ from --bp-*): */
6
+ /* Mobile: <768px */
7
+ /* Tablet: 768–1199px */
8
+ /* Desktop: 1200–1439px */
9
+ /* Wide: >=1440px */
10
+ /* ────────────────────────────────────────────────────────────── */
11
+
12
+ .ct-app-shell {
13
+ /* ── Public Tokens ── */
14
+ --ct-sidebar-width: 260px;
15
+ --ct-sidebar-rail-width: 56px;
16
+ --ct-panel-width: 320px;
17
+ --ct-header-height: auto;
18
+ --ct-footer-height: auto;
19
+ --ct-shell-transition-duration: 200ms;
20
+ --ct-shell-transition-easing: ease-out;
21
+
22
+ /* ── Internal Variables ── */
23
+ --_sidebar-width: var(--ct-sidebar-width);
24
+ --_panel-width: 0px;
25
+
26
+ display: grid;
27
+ grid-template-rows: auto 1fr auto;
28
+ grid-template-columns: var(--_sidebar-width) 1fr var(--_panel-width);
29
+ grid-template-areas:
30
+ 'header header header'
31
+ 'sidebar main panel'
32
+ 'footer footer footer';
33
+ height: 100vh;
34
+ height: 100dvh;
35
+ overflow: hidden;
36
+ }
37
+
38
+
39
+ /* ── Element Grid Placement ── */
40
+
41
+ .ct-app-shell__header {
42
+ grid-area: header;
43
+ z-index: var(--z-sticky);
44
+ min-width: 0;
45
+ }
46
+
47
+ .ct-app-shell__sidebar {
48
+ grid-area: sidebar;
49
+ overflow-y: auto;
50
+ overflow-x: hidden;
51
+ min-height: 0;
52
+ min-width: 0;
53
+ }
54
+
55
+ .ct-app-shell__main {
56
+ grid-area: main;
57
+ overflow-y: auto;
58
+ min-height: 0;
59
+ min-width: 0;
60
+ /* Use tabindex="0" (not "-1") in markup — main is a scrollable container
61
+ and must be keyboard-reachable so users can scroll with arrow keys / PgUp / PgDown
62
+ even when no focusable children are present (axe: scrollable-region-focusable). */
63
+ }
64
+
65
+ .ct-app-shell__panel {
66
+ grid-area: panel;
67
+ overflow-y: auto;
68
+ overflow-x: hidden;
69
+ min-height: 0;
70
+ min-width: 0;
71
+ }
72
+
73
+ .ct-app-shell__footer {
74
+ grid-area: footer;
75
+ }
76
+
77
+
78
+ /* ── Sidebar States ── */
79
+
80
+ .ct-app-shell[data-sidebar-state='expanded'] {
81
+ --_sidebar-width: var(--ct-sidebar-width, 260px);
82
+ }
83
+
84
+ .ct-app-shell[data-sidebar-state='collapsed'] {
85
+ --_sidebar-width: var(--ct-sidebar-rail-width, 56px);
86
+ }
87
+
88
+ .ct-app-shell[data-sidebar-state='hidden'] {
89
+ --_sidebar-width: 0px;
90
+ }
91
+
92
+ .ct-app-shell[data-sidebar-state='hidden'] > .ct-app-shell__sidebar {
93
+ visibility: hidden;
94
+ overflow: hidden;
95
+ border-inline-start: none;
96
+ border-inline-end: none;
97
+ }
98
+
99
+ /* Sidebar inside app-shell fills its grid cell */
100
+ .ct-app-shell__sidebar > .ct-sidebar {
101
+ width: 100%;
102
+ height: 100%;
103
+ border-inline-end: none;
104
+ }
105
+
106
+ /* The grid area itself gets the sidebar border */
107
+ .ct-app-shell__sidebar {
108
+ border-inline-end: var(--border-thin) solid var(--color-border-subtle);
109
+ }
110
+
111
+
112
+ /* ── Panel State ── */
113
+
114
+ .ct-app-shell[data-panel-state='open'] {
115
+ --_panel-width: var(--ct-panel-width, 320px);
116
+ }
117
+
118
+ .ct-app-shell[data-panel-state='open'] > .ct-app-shell__panel {
119
+ visibility: visible;
120
+ }
121
+
122
+ .ct-app-shell:not([data-panel-state='open']) > .ct-app-shell__panel {
123
+ visibility: hidden;
124
+ overflow: hidden;
125
+ }
126
+
127
+ .ct-app-shell__panel {
128
+ border-inline-start: var(--border-thin) solid var(--color-border-subtle);
129
+ }
130
+
131
+ .ct-app-shell:not([data-panel-state='open']) > .ct-app-shell__panel {
132
+ border-inline-start: none;
133
+ }
134
+
135
+
136
+ /* ── Header Variant: Sidebar Full Height ── */
137
+
138
+ .ct-app-shell--sidebar-full-height {
139
+ grid-template-areas:
140
+ 'sidebar header header'
141
+ 'sidebar main panel'
142
+ 'sidebar footer footer';
143
+ }
144
+
145
+
146
+ /* ── Modifier: No Sidebar ── */
147
+
148
+ .ct-app-shell--no-sidebar {
149
+ grid-template-columns: 1fr var(--_panel-width);
150
+ grid-template-areas:
151
+ 'header header'
152
+ 'main panel'
153
+ 'footer footer';
154
+ }
155
+
156
+ .ct-app-shell--no-sidebar > .ct-app-shell__sidebar {
157
+ display: none;
158
+ }
159
+
160
+ /* --no-sidebar takes precedence over --sidebar-right */
161
+ .ct-app-shell--no-sidebar.ct-app-shell--sidebar-right {
162
+ grid-template-columns: 1fr var(--_panel-width);
163
+ grid-template-areas:
164
+ 'header header'
165
+ 'main panel'
166
+ 'footer footer';
167
+ }
168
+
169
+
170
+ /* ── Modifier: Sidebar Right ── */
171
+
172
+ .ct-app-shell--sidebar-right {
173
+ grid-template-columns: 1fr var(--_panel-width) var(--_sidebar-width);
174
+ grid-template-areas:
175
+ 'header header header'
176
+ 'main panel sidebar'
177
+ 'footer footer footer';
178
+ }
179
+
180
+ .ct-app-shell--sidebar-right > .ct-app-shell__sidebar {
181
+ border-inline-end: none;
182
+ border-inline-start: var(--border-thin) solid var(--color-border-subtle);
183
+ }
184
+
185
+ .ct-app-shell--sidebar-right > .ct-app-shell__panel {
186
+ border-inline-start: var(--border-thin) solid var(--color-border-subtle);
187
+ border-inline-end: none;
188
+ }
189
+
190
+ .ct-app-shell--sidebar-right.ct-app-shell--sidebar-full-height {
191
+ grid-template-areas:
192
+ 'header header sidebar'
193
+ 'main panel sidebar'
194
+ 'footer footer sidebar';
195
+ }
196
+
197
+
198
+ /* ── Modifier: Footer Sticky ── */
199
+
200
+ .ct-app-shell--footer-sticky > .ct-app-shell__footer {
201
+ border-top: var(--border-thin) solid var(--color-border-subtle);
202
+ }
203
+
204
+
205
+ /* ── Page Header ── */
206
+
207
+ .ct-app-shell__page-header {
208
+ display: flex;
209
+ align-items: center;
210
+ justify-content: space-between;
211
+ gap: var(--space-4);
212
+ padding: var(--space-5) var(--space-6);
213
+ border-bottom: var(--border-thin) solid var(--color-border-subtle);
214
+ flex-shrink: 0;
215
+ }
216
+
217
+ .ct-app-shell__page-header--sticky {
218
+ position: sticky;
219
+ top: 0;
220
+ z-index: 1;
221
+ background: var(--color-bg-canvas);
222
+ }
223
+
224
+
225
+
226
+ /* ── Backdrop (Mobile Sidebar Overlay) ── */
227
+
228
+ .ct-app-shell__backdrop {
229
+ position: fixed;
230
+ inset: 0;
231
+ background: var(--color-overlay-scrim);
232
+ z-index: calc(var(--z-overlay) - 1);
233
+ opacity: 0;
234
+ visibility: hidden;
235
+ pointer-events: none;
236
+ transition:
237
+ opacity var(--ct-shell-transition-duration) var(--ct-shell-transition-easing),
238
+ visibility var(--ct-shell-transition-duration) var(--ct-shell-transition-easing);
239
+ }
240
+
241
+
242
+ /* ── Transitions ── */
243
+ /* Single base transition — state selectors only override delay to avoid */
244
+ /* conflicts when sidebar + panel states are active simultaneously. */
245
+
246
+ .ct-app-shell {
247
+ transition: grid-template-columns var(--ct-shell-transition-duration) var(--ct-shell-transition-easing);
248
+ }
249
+
250
+ /* Collapsing: delay grid shrink so labels fade out first */
251
+ .ct-app-shell[data-sidebar-state='collapsed'] {
252
+ transition-delay: 120ms;
253
+ }
254
+
255
+
256
+ /* ── Bottom Navigation ── */
257
+
258
+ .ct-app-shell__bottom-nav {
259
+ display: none;
260
+ }
261
+
262
+
263
+ /* ── Responsive: Tablet (768–1199px) ── */
264
+
265
+ @media (max-width: 1199px) { /* < lg breakpoint (1200px) */
266
+ /* Auto-collapse sidebar to rail when no explicit state is set */
267
+ .ct-app-shell:not([data-sidebar-state]) {
268
+ --_sidebar-width: var(--ct-sidebar-rail-width, 56px);
269
+ }
270
+
271
+ /* Panel becomes overlay on tablet */
272
+ .ct-app-shell[data-panel-state='open'] {
273
+ --_panel-width: 0px;
274
+ }
275
+
276
+ .ct-app-shell[data-panel-state='open'] > .ct-app-shell__panel {
277
+ position: fixed;
278
+ inset-block: 0;
279
+ inset-inline-end: 0;
280
+ width: min(var(--ct-panel-width, 320px), 100vw);
281
+ z-index: var(--z-overlay);
282
+ visibility: visible;
283
+ background: var(--color-bg-elevated);
284
+ box-shadow: var(--shadow-lg);
285
+ }
286
+ }
287
+
288
+
289
+ /* ── Responsive: Mobile (<768px) ── */
290
+
291
+ @media (max-width: 767px) { /* < tablet breakpoint (768px) */
292
+ /* Auto-hide sidebar when no explicit state is set */
293
+ .ct-app-shell:not([data-sidebar-state]) {
294
+ --_sidebar-width: 0px;
295
+ }
296
+
297
+ .ct-app-shell:not([data-sidebar-state]) > .ct-app-shell__sidebar {
298
+ visibility: hidden;
299
+ overflow: hidden;
300
+ border-inline-end: none;
301
+ }
302
+
303
+ /* Expanded sidebar on mobile = fixed overlay */
304
+ .ct-app-shell[data-sidebar-state='expanded'] {
305
+ --_sidebar-width: 0px;
306
+ }
307
+
308
+ .ct-app-shell[data-sidebar-state='expanded'] > .ct-app-shell__sidebar {
309
+ position: fixed;
310
+ inset-block: 0;
311
+ inset-inline-start: 0;
312
+ width: var(--ct-sidebar-width, 260px);
313
+ z-index: var(--z-overlay);
314
+ visibility: visible;
315
+ background: var(--color-bg-elevated);
316
+ box-shadow: var(--shadow-lg);
317
+ }
318
+
319
+ /* Sidebar-right: overlay slides in from inline-end */
320
+ .ct-app-shell--sidebar-right[data-sidebar-state='expanded'] > .ct-app-shell__sidebar {
321
+ inset-inline-start: auto;
322
+ inset-inline-end: 0;
323
+ }
324
+
325
+ /* Show backdrop when sidebar overlay is open */
326
+ .ct-app-shell[data-sidebar-state='expanded'] > .ct-app-shell__backdrop {
327
+ opacity: 1;
328
+ visibility: visible;
329
+ pointer-events: auto;
330
+ }
331
+
332
+ /* Collapsed sidebar on mobile = hidden */
333
+ .ct-app-shell[data-sidebar-state='collapsed'] {
334
+ --_sidebar-width: 0px;
335
+ }
336
+
337
+ .ct-app-shell[data-sidebar-state='collapsed'] > .ct-app-shell__sidebar {
338
+ visibility: hidden;
339
+ overflow: hidden;
340
+ border-inline-end: none;
341
+ }
342
+
343
+ /* Panel overlay on mobile */
344
+ .ct-app-shell[data-panel-state='open'] {
345
+ --_panel-width: 0px;
346
+ }
347
+
348
+ .ct-app-shell[data-panel-state='open'] > .ct-app-shell__panel {
349
+ position: fixed;
350
+ inset-block: 0;
351
+ inset-inline-end: 0;
352
+ width: min(var(--ct-panel-width, 320px), 100vw);
353
+ z-index: var(--z-overlay);
354
+ visibility: visible;
355
+ background: var(--color-bg-elevated);
356
+ box-shadow: var(--shadow-lg);
357
+ border-inline-start: none;
358
+ }
359
+
360
+ /* Bottom nav: show on mobile when modifier is active */
361
+ .ct-app-shell--bottom-nav > .ct-app-shell__bottom-nav {
362
+ display: flex;
363
+ justify-content: space-around;
364
+ align-items: center;
365
+ padding: var(--space-2) 0;
366
+ background: var(--color-bg-surface);
367
+ border-top: var(--border-thin) solid var(--color-border-subtle);
368
+ grid-area: footer;
369
+ }
370
+
371
+ /* When bottom-nav is active, hide footer to avoid grid-area collision */
372
+ .ct-app-shell--bottom-nav > .ct-app-shell__footer {
373
+ display: none;
374
+ }
375
+
376
+ /* When bottom-nav is active, hide sidebar completely on mobile */
377
+ .ct-app-shell--bottom-nav {
378
+ --_sidebar-width: 0px;
379
+ }
380
+
381
+ .ct-app-shell--bottom-nav > .ct-app-shell__sidebar {
382
+ display: none;
383
+ }
384
+
385
+ /* Full-height variant falls back to standard on mobile */
386
+ .ct-app-shell--sidebar-full-height {
387
+ grid-template-areas:
388
+ 'header header header'
389
+ 'sidebar main panel'
390
+ 'footer footer footer';
391
+ }
392
+ }
393
+
394
+
395
+ /* ── Reduced Motion ── */
396
+
397
+ @media (prefers-reduced-motion: reduce) {
398
+ .ct-app-shell,
399
+ .ct-app-shell[data-sidebar-state],
400
+ .ct-app-shell__sidebar,
401
+ .ct-app-shell__panel,
402
+ .ct-app-shell__backdrop {
403
+ transition: none;
404
+ }
405
+ }
@@ -144,7 +144,7 @@
144
144
 
145
145
  /* Solid + success needs darker green for WCAG AA contrast with inverse text */
146
146
  .ct-banner.ct-banner--solid[data-variant='success'] {
147
- --ct-banner-accent: var(--color-green-700);
147
+ --ct-banner-accent: var(--color-state-success-text);
148
148
  }
149
149
 
150
150
  /* ---- Appearance: Accents ---- */
@@ -88,8 +88,8 @@
88
88
 
89
89
  .ct-button--danger {
90
90
  --ct-button-bg: var(--color-state-danger);
91
- --ct-button-bg-hover: var(--color-red-600);
92
- --ct-button-bg-active: var(--color-red-700);
91
+ --ct-button-bg-hover: color-mix(in srgb, var(--color-state-danger) 85%, black);
92
+ --ct-button-bg-active: color-mix(in srgb, var(--color-state-danger) 70%, black);
93
93
  --ct-button-border: transparent;
94
94
  --ct-button-color: var(--color-text-inverse);
95
95
  }
@@ -98,14 +98,14 @@
98
98
  .ct-chip--info {
99
99
  --ct-chip-bg: var(--color-state-info-surface);
100
100
  --ct-chip-border: var(--color-state-info-border);
101
- --ct-chip-color: var(--color-ocean-700);
101
+ --ct-chip-color: var(--color-state-info-text);
102
102
  --ct-chip-accent: var(--color-state-info);
103
103
  }
104
104
 
105
105
  .ct-chip--success {
106
106
  --ct-chip-bg: var(--color-state-success-surface);
107
107
  --ct-chip-border: var(--color-state-success-border);
108
- --ct-chip-color: var(--color-green-700);
108
+ --ct-chip-color: var(--color-state-success-text);
109
109
  --ct-chip-accent: var(--color-state-success);
110
110
  }
111
111
 
@@ -119,7 +119,7 @@
119
119
  .ct-chip--danger {
120
120
  --ct-chip-bg: var(--color-state-danger-surface);
121
121
  --ct-chip-border: var(--color-state-danger-border);
122
- --ct-chip-color: var(--color-red-700);
122
+ --ct-chip-color: var(--color-state-danger-text);
123
123
  --ct-chip-accent: var(--color-state-danger);
124
124
  }
125
125
 
@@ -163,17 +163,17 @@
163
163
  }
164
164
 
165
165
  .ct-chip--solid.ct-chip--success {
166
- --ct-chip-bg: var(--color-green-700);
167
- --ct-chip-border: var(--color-green-700);
166
+ --ct-chip-bg: var(--color-state-success-text);
167
+ --ct-chip-border: var(--color-state-success-text);
168
168
  --ct-chip-color: var(--color-text-inverse);
169
169
  --ct-chip-accent: var(--color-text-inverse);
170
170
  }
171
171
 
172
172
  .ct-chip--solid.ct-chip--warning {
173
- --ct-chip-bg: var(--color-amber-500);
174
- --ct-chip-border: var(--color-amber-500);
175
- --ct-chip-color: var(--color-amber-900);
176
- --ct-chip-accent: var(--color-amber-900);
173
+ --ct-chip-bg: var(--color-state-warning-text);
174
+ --ct-chip-border: var(--color-state-warning-text);
175
+ --ct-chip-color: var(--color-text-inverse);
176
+ --ct-chip-accent: var(--color-text-inverse);
177
177
  }
178
178
 
179
179
  .ct-chip--solid.ct-chip--danger {
@@ -348,8 +348,7 @@
348
348
  border-top: var(--border-thin) solid var(--color-border-subtle);
349
349
  border-radius: 0 0 var(--radius-md) var(--radius-md);
350
350
  box-shadow: none;
351
- border-left: none;
352
- border-right: none;
351
+ border-inline: none;
353
352
  border-bottom: none;
354
353
  }
355
354
 
@@ -16,12 +16,23 @@
16
16
  background: var(--color-bg-elevated);
17
17
  box-shadow: var(--shadow-dropdown);
18
18
  z-index: var(--z-dropdown);
19
- display: none;
19
+ display: grid;
20
+ gap: var(--space-4);
21
+ opacity: 0;
22
+ visibility: hidden;
23
+ transform: translateY(4px);
24
+ transition: opacity var(--duration-fast) var(--easing-standard),
25
+ transform var(--duration-fast) var(--easing-standard),
26
+ visibility 0s linear var(--duration-fast);
20
27
  }
21
28
 
22
29
  .ct-datepicker[data-state='open'] .ct-datepicker__popover {
23
- display: grid;
24
- gap: var(--space-4);
30
+ opacity: 1;
31
+ visibility: visible;
32
+ transform: translateY(0);
33
+ transition: opacity var(--duration-fast) var(--easing-standard),
34
+ transform var(--duration-fast) var(--easing-standard),
35
+ visibility 0s linear 0s;
25
36
  }
26
37
 
27
38
  /* ── Header ─────────────────────────────────────────────────────── */
@@ -260,6 +271,7 @@
260
271
  /* ── Reduced motion ─────────────────────────────────────────────── */
261
272
 
262
273
  @media (prefers-reduced-motion: reduce) {
274
+ .ct-datepicker__popover,
263
275
  .ct-datepicker__day,
264
276
  .ct-datepicker__month,
265
277
  .ct-datepicker__year {
@@ -109,3 +109,9 @@
109
109
  color: var(--color-state-danger);
110
110
  font-size: var(--font-size-sm);
111
111
  }
112
+
113
+ @media (prefers-reduced-motion: reduce) {
114
+ .ct-file-upload__dropzone {
115
+ transition: none;
116
+ }
117
+ }
@@ -46,4 +46,7 @@
46
46
  @import './skip-link.css';
47
47
  @import './drawer.css';
48
48
  @import './navbar.css';
49
+ @import './app-shell.css';
50
+ @import './app-shell-v2.css';
51
+ @import './_shell-shared.css';
49
52
  @import './list.css';
@@ -40,6 +40,12 @@
40
40
 
41
41
  /* ── Brand ──────────────────────────────────────────────────────── */
42
42
 
43
+ .ct-navbar__brand-wrapper {
44
+ display: flex;
45
+ align-items: center;
46
+ flex-shrink: 0;
47
+ }
48
+
43
49
  .ct-navbar__brand {
44
50
  display: inline-flex;
45
51
  align-items: center;
@@ -487,24 +493,31 @@
487
493
  /* ── Dark ──────────────────────────────────────────────────────── */
488
494
 
489
495
  .ct-navbar--dark {
490
- --ct-navbar-bg: var(--color-slate-900);
491
- --ct-navbar-border-color: var(--color-slate-800);
492
- color: var(--color-text-inverse);
496
+ --_dark-bg: var(--color-slate-900);
497
+ --_dark-bg-hover: var(--color-slate-800);
498
+ --_dark-border: var(--color-slate-800);
499
+ --_dark-text: var(--color-slate-300);
500
+ --_dark-text-strong: var(--color-text-inverse);
501
+ --_dark-text-muted: var(--color-slate-400);
502
+
503
+ --ct-navbar-bg: var(--_dark-bg);
504
+ --ct-navbar-border-color: var(--_dark-border);
505
+ color: var(--_dark-text-strong);
493
506
  }
494
507
 
495
508
  .ct-navbar--dark .ct-navbar__link {
496
- color: var(--color-slate-300);
509
+ color: var(--_dark-text);
497
510
  }
498
511
 
499
512
  @media (hover: hover) {
500
513
  .ct-navbar--dark .ct-navbar__link:hover {
501
- background: var(--color-slate-800);
502
- color: var(--color-text-inverse);
514
+ background: var(--_dark-bg-hover);
515
+ color: var(--_dark-text-strong);
503
516
  }
504
517
  }
505
518
 
506
519
  .ct-navbar--dark .ct-navbar__link[aria-current='page'] {
507
- color: var(--color-text-inverse);
520
+ color: var(--_dark-text-strong);
508
521
  }
509
522
 
510
523
  .ct-navbar--dark .ct-navbar__link[aria-current='page']::after {
@@ -512,48 +525,62 @@
512
525
  }
513
526
 
514
527
  .ct-navbar--dark .ct-navbar__link-chevron {
515
- color: var(--color-slate-400);
528
+ color: var(--_dark-text-muted);
516
529
  }
517
530
 
518
531
  .ct-navbar--dark .ct-navbar__toggle {
519
- color: var(--color-text-inverse);
532
+ color: var(--_dark-text-strong);
520
533
  }
521
534
 
522
535
  @media (hover: hover) {
523
536
  .ct-navbar--dark .ct-navbar__toggle:hover {
524
- background: var(--color-slate-800);
537
+ background: var(--_dark-bg-hover);
525
538
  }
526
539
  }
527
540
 
528
541
  .ct-navbar--dark .ct-navbar__mobile-menu {
529
- background: var(--color-slate-900);
530
- border-color: var(--color-slate-800);
542
+ background: var(--_dark-bg);
543
+ border-color: var(--_dark-border);
531
544
  }
532
545
 
533
546
  .ct-navbar--dark .ct-navbar__mobile-menu .ct-navbar__link {
534
- color: var(--color-slate-300);
547
+ color: var(--_dark-text);
535
548
  }
536
549
 
537
550
  @media (hover: hover) {
538
551
  .ct-navbar--dark .ct-navbar__mobile-menu .ct-navbar__link:hover {
539
- background: var(--color-slate-800);
540
- color: var(--color-text-inverse);
552
+ background: var(--_dark-bg-hover);
553
+ color: var(--_dark-text-strong);
541
554
  }
542
555
  }
543
556
 
544
557
  .ct-navbar--dark .ct-navbar__mobile-menu .ct-navbar__link[aria-current='page'] {
545
- background: var(--color-slate-800);
546
- color: var(--color-text-inverse);
558
+ background: var(--_dark-bg-hover);
559
+ color: var(--_dark-text-strong);
547
560
  }
548
561
 
549
562
  .ct-navbar--dark .ct-navbar__actions .ct-button {
550
- color: var(--color-text-inverse);
563
+ color: var(--_dark-text-strong);
551
564
  }
552
565
 
553
566
  /* ── Center Nav ────────────────────────────────────────────────── */
554
567
 
568
+ .ct-navbar--center .ct-navbar__brand-wrapper {
569
+ flex: 1;
570
+ }
571
+
555
572
  .ct-navbar--center .ct-navbar__nav {
556
- margin-inline: auto;
573
+ justify-content: center;
574
+ }
575
+
576
+ .ct-navbar--center .ct-navbar__actions {
577
+ flex: 1;
578
+ justify-content: flex-end;
579
+ margin-inline-start: 0;
580
+ }
581
+
582
+ .ct-navbar--center .ct-navbar__spacer {
583
+ display: none;
557
584
  }
558
585
 
559
586
  /* ── Responsive ────────────────────────────────────────────────── */
@@ -16,7 +16,7 @@
16
16
  .ct-table td {
17
17
  padding: var(--space-4) var(--space-5);
18
18
  border-bottom: var(--border-thin) solid var(--color-border-subtle);
19
- text-align: left;
19
+ text-align: start;
20
20
  }
21
21
 
22
22
  .ct-table thead th {
@@ -117,12 +117,12 @@ th[aria-sort='descending'] .ct-table__sort-indicator::after {
117
117
  }
118
118
 
119
119
  .ct-table__cell--numeric {
120
- text-align: right;
120
+ text-align: end;
121
121
  font-variant-numeric: tabular-nums;
122
122
  }
123
123
 
124
124
  .ct-table__cell--actions {
125
- text-align: right;
125
+ text-align: end;
126
126
  white-space: nowrap;
127
127
  }
128
128
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuravision/construct",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Construct Design System - Accessible, token-based design system for modern web applications",
5
5
  "license": "MIT",
6
6
  "repository": {