@neuravision/construct 1.1.2 → 1.1.3
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,497 @@
|
|
|
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: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
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-hover-bg: color-mix(in srgb, var(--color-slate-0) 8%, transparent);
|
|
282
|
+
--_branded-active-bg: color-mix(in srgb, var(--color-slate-0) 12%, transparent);
|
|
283
|
+
--_branded-badge-bg: color-mix(in srgb, var(--color-slate-0) 15%, transparent);
|
|
284
|
+
background: var(--color-slate-900);
|
|
285
|
+
color: var(--color-text-inverse);
|
|
286
|
+
box-shadow: none;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-sidebar {
|
|
290
|
+
background: transparent;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-sidebar__header {
|
|
294
|
+
border-bottom-color: var(--color-slate-700);
|
|
295
|
+
color: var(--color-slate-0);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item {
|
|
299
|
+
color: var(--color-slate-300);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
@media (hover: hover) {
|
|
303
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item:hover {
|
|
304
|
+
background: var(--_branded-hover-bg);
|
|
305
|
+
color: var(--color-slate-0);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item--active,
|
|
310
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item[aria-current='page'] {
|
|
311
|
+
background: var(--_branded-active-bg);
|
|
312
|
+
color: var(--color-slate-0);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item__badge {
|
|
316
|
+
background: var(--_branded-badge-bg);
|
|
317
|
+
color: var(--color-slate-100);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item--active .ct-nav-item__badge,
|
|
321
|
+
.ct-app-shell-v2--sidebar-branded .ct-app-shell-v2__sidebar .ct-nav-item[aria-current='page'] .ct-nav-item__badge {
|
|
322
|
+
background: var(--color-brand-primary);
|
|
323
|
+
color: var(--color-text-inverse);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
/* ── Modifier: Glass Effect ── */
|
|
328
|
+
/* Subtle frosted glass on surfaces — optional modern flourish. */
|
|
329
|
+
|
|
330
|
+
.ct-app-shell-v2--glass > .ct-app-shell-v2__sidebar,
|
|
331
|
+
.ct-app-shell-v2--glass > .ct-app-shell-v2__body,
|
|
332
|
+
.ct-app-shell-v2--glass > .ct-app-shell-v2__header {
|
|
333
|
+
background: color-mix(in srgb, var(--ct-v2-surface-bg) 85%, transparent);
|
|
334
|
+
backdrop-filter: blur(16px) saturate(180%);
|
|
335
|
+
-webkit-backdrop-filter: blur(16px) saturate(180%);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
/* ── Backdrop (Mobile Sidebar Overlay) ── */
|
|
340
|
+
|
|
341
|
+
.ct-app-shell-v2__backdrop {
|
|
342
|
+
position: fixed;
|
|
343
|
+
inset: 0;
|
|
344
|
+
background: var(--color-overlay-scrim);
|
|
345
|
+
z-index: calc(var(--z-overlay) - 1);
|
|
346
|
+
opacity: 0;
|
|
347
|
+
visibility: hidden;
|
|
348
|
+
pointer-events: none;
|
|
349
|
+
transition:
|
|
350
|
+
opacity var(--ct-v2-transition-duration) var(--ct-v2-transition-easing),
|
|
351
|
+
visibility var(--ct-v2-transition-duration) var(--ct-v2-transition-easing);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
/* ── Transitions ── */
|
|
356
|
+
|
|
357
|
+
/* Delay grid shrink on collapse so labels fade out first */
|
|
358
|
+
.ct-app-shell-v2[data-sidebar-state='collapsed'] {
|
|
359
|
+
transition-delay: 120ms;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
/* ── Responsive: Tablet (768–1199px) ── */
|
|
364
|
+
|
|
365
|
+
@media (max-width: 1199px) {
|
|
366
|
+
/* Auto-collapse sidebar to rail when no explicit state */
|
|
367
|
+
.ct-app-shell-v2:not([data-sidebar-state]) {
|
|
368
|
+
--_v2-sidebar-w: var(--ct-v2-sidebar-rail-width);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* Panel becomes floating overlay on tablet */
|
|
372
|
+
.ct-app-shell-v2[data-panel-state='open'] .ct-app-shell-v2__panel {
|
|
373
|
+
position: fixed;
|
|
374
|
+
inset-block: var(--ct-v2-gap);
|
|
375
|
+
inset-inline-end: var(--ct-v2-gap);
|
|
376
|
+
width: min(var(--ct-v2-panel-width), calc(100vw - 2 * var(--ct-v2-gap)));
|
|
377
|
+
z-index: var(--z-overlay);
|
|
378
|
+
visibility: visible;
|
|
379
|
+
background: var(--ct-v2-surface-bg);
|
|
380
|
+
border-radius: var(--ct-v2-radius);
|
|
381
|
+
box-shadow: var(--shadow-lg);
|
|
382
|
+
border-inline-start: none;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
/* ── Responsive: Mobile (<768px) ── */
|
|
388
|
+
|
|
389
|
+
@media (max-width: 767px) {
|
|
390
|
+
.ct-app-shell-v2 {
|
|
391
|
+
--ct-v2-gap: var(--space-3);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* Auto-hide sidebar */
|
|
395
|
+
.ct-app-shell-v2:not([data-sidebar-state]) {
|
|
396
|
+
grid-template-columns: 1fr;
|
|
397
|
+
grid-template-areas: 'body';
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.ct-app-shell-v2:not([data-sidebar-state]) > .ct-app-shell-v2__sidebar {
|
|
401
|
+
display: none;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* Expanded sidebar = floating overlay with rounded corners */
|
|
405
|
+
.ct-app-shell-v2[data-sidebar-state='expanded'] {
|
|
406
|
+
grid-template-columns: 1fr;
|
|
407
|
+
grid-template-areas: 'body';
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.ct-app-shell-v2[data-sidebar-state='expanded'] > .ct-app-shell-v2__sidebar {
|
|
411
|
+
position: fixed;
|
|
412
|
+
inset-block: var(--ct-v2-gap);
|
|
413
|
+
inset-inline-start: var(--ct-v2-gap);
|
|
414
|
+
width: min(var(--ct-v2-sidebar-width), calc(100vw - 2 * var(--ct-v2-gap)));
|
|
415
|
+
z-index: var(--z-overlay);
|
|
416
|
+
visibility: visible;
|
|
417
|
+
opacity: 1;
|
|
418
|
+
box-shadow: var(--shadow-lg);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.ct-app-shell-v2[data-sidebar-state='expanded'] > .ct-app-shell-v2__backdrop {
|
|
422
|
+
opacity: 1;
|
|
423
|
+
visibility: visible;
|
|
424
|
+
pointer-events: auto;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/* Collapsed sidebar = hidden on mobile */
|
|
428
|
+
.ct-app-shell-v2[data-sidebar-state='collapsed'] {
|
|
429
|
+
grid-template-columns: 1fr;
|
|
430
|
+
grid-template-areas: 'body';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.ct-app-shell-v2[data-sidebar-state='collapsed'] > .ct-app-shell-v2__sidebar {
|
|
434
|
+
visibility: hidden;
|
|
435
|
+
overflow: hidden;
|
|
436
|
+
opacity: 0;
|
|
437
|
+
width: 0;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/* Hidden sidebar on mobile */
|
|
441
|
+
.ct-app-shell-v2[data-sidebar-state='hidden'] > .ct-app-shell-v2__sidebar {
|
|
442
|
+
display: none;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/* Panel = floating overlay on mobile */
|
|
446
|
+
.ct-app-shell-v2[data-panel-state='open'] .ct-app-shell-v2__panel {
|
|
447
|
+
position: fixed;
|
|
448
|
+
inset-block: var(--ct-v2-gap);
|
|
449
|
+
inset-inline-end: var(--ct-v2-gap);
|
|
450
|
+
width: min(var(--ct-v2-panel-width), calc(100vw - 2 * var(--ct-v2-gap)));
|
|
451
|
+
z-index: var(--z-overlay);
|
|
452
|
+
visibility: visible;
|
|
453
|
+
background: var(--ct-v2-surface-bg);
|
|
454
|
+
border-radius: var(--ct-v2-radius);
|
|
455
|
+
box-shadow: var(--shadow-lg);
|
|
456
|
+
border-inline-start: none;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* With-header collapses to single column on mobile */
|
|
460
|
+
.ct-app-shell-v2--with-header {
|
|
461
|
+
grid-template-columns: 1fr;
|
|
462
|
+
grid-template-areas:
|
|
463
|
+
'header'
|
|
464
|
+
'body';
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.ct-app-shell-v2--sidebar-full-height.ct-app-shell-v2--with-header {
|
|
468
|
+
grid-template-areas:
|
|
469
|
+
'header'
|
|
470
|
+
'body';
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/* Sidebar-right falls back to standard on mobile */
|
|
474
|
+
.ct-app-shell-v2--sidebar-right {
|
|
475
|
+
grid-template-columns: 1fr;
|
|
476
|
+
grid-template-areas: 'body';
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.ct-app-shell-v2--sidebar-right.ct-app-shell-v2--with-header {
|
|
480
|
+
grid-template-areas:
|
|
481
|
+
'header'
|
|
482
|
+
'body';
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
/* ── Reduced Motion ── */
|
|
488
|
+
|
|
489
|
+
@media (prefers-reduced-motion: reduce) {
|
|
490
|
+
.ct-app-shell-v2,
|
|
491
|
+
.ct-app-shell-v2[data-sidebar-state],
|
|
492
|
+
.ct-app-shell-v2__sidebar,
|
|
493
|
+
.ct-app-shell-v2__panel,
|
|
494
|
+
.ct-app-shell-v2__backdrop {
|
|
495
|
+
transition: none;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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