@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.
- package/components/_shell-shared.css +78 -0
- package/components/app-shell-v2.css +503 -0
- package/components/app-shell.css +405 -0
- package/components/banner.css +1 -1
- package/components/button.css +2 -2
- package/components/chip.css +9 -9
- package/components/combobox.css +1 -2
- package/components/datepicker.css +15 -3
- package/components/file-upload.css +6 -0
- package/components/index.css +3 -0
- package/components/navbar.css +46 -19
- package/components/table.css +3 -3
- package/package.json +1 -1
|
@@ -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
|
+
}
|
package/components/banner.css
CHANGED
|
@@ -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-
|
|
147
|
+
--ct-banner-accent: var(--color-state-success-text);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/* ---- Appearance: Accents ---- */
|
package/components/button.css
CHANGED
|
@@ -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-
|
|
92
|
-
--ct-button-bg-active: var(--color-
|
|
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
|
}
|
package/components/chip.css
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
167
|
-
--ct-chip-border: var(--color-
|
|
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-
|
|
174
|
-
--ct-chip-border: var(--color-
|
|
175
|
-
--ct-chip-color: var(--color-
|
|
176
|
-
--ct-chip-accent: var(--color-
|
|
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 {
|
package/components/combobox.css
CHANGED
|
@@ -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-
|
|
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:
|
|
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
|
-
|
|
24
|
-
|
|
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 {
|
package/components/index.css
CHANGED
package/components/navbar.css
CHANGED
|
@@ -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
|
-
--
|
|
491
|
-
--
|
|
492
|
-
|
|
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(--
|
|
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(--
|
|
502
|
-
color: var(--
|
|
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(--
|
|
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(--
|
|
528
|
+
color: var(--_dark-text-muted);
|
|
516
529
|
}
|
|
517
530
|
|
|
518
531
|
.ct-navbar--dark .ct-navbar__toggle {
|
|
519
|
-
color: var(--
|
|
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(--
|
|
537
|
+
background: var(--_dark-bg-hover);
|
|
525
538
|
}
|
|
526
539
|
}
|
|
527
540
|
|
|
528
541
|
.ct-navbar--dark .ct-navbar__mobile-menu {
|
|
529
|
-
background: var(--
|
|
530
|
-
border-color: var(--
|
|
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(--
|
|
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(--
|
|
540
|
-
color: var(--
|
|
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(--
|
|
546
|
-
color: var(--
|
|
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(--
|
|
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
|
-
|
|
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 ────────────────────────────────────────────────── */
|
package/components/table.css
CHANGED
|
@@ -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:
|
|
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:
|
|
120
|
+
text-align: end;
|
|
121
121
|
font-variant-numeric: tabular-nums;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
.ct-table__cell--actions {
|
|
125
|
-
text-align:
|
|
125
|
+
text-align: end;
|
|
126
126
|
white-space: nowrap;
|
|
127
127
|
}
|
|
128
128
|
|