@nonoun/native-app 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/{nui-app-panel/nui-app-panel-element.d.ts → app-panel/app-panel-element.d.ts} +3 -3
  2. package/dist/app-panel/app-panel-element.d.ts.map +1 -0
  3. package/dist/custom-elements.json +75 -75
  4. package/dist/index.d.ts +8 -8
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/{nui-app.css → native-app.css} +168 -133
  7. package/dist/{nui-app.js → native-app.js} +32 -32
  8. package/dist/{nui-sidebar/nui-sidebar-element.d.ts → sidebar/sidebar-element.d.ts} +3 -3
  9. package/dist/sidebar/sidebar-element.d.ts.map +1 -0
  10. package/dist/{nui-sidebar/nui-sidebar-group-element.d.ts → sidebar/sidebar-group-element.d.ts} +4 -4
  11. package/dist/sidebar/sidebar-group-element.d.ts.map +1 -0
  12. package/dist/sidebar/sidebar-group-header-element.d.ts +7 -0
  13. package/dist/sidebar/sidebar-group-header-element.d.ts.map +1 -0
  14. package/dist/sidebar/sidebar-item-element.d.ts +10 -0
  15. package/dist/sidebar/sidebar-item-element.d.ts.map +1 -0
  16. package/dist/{nui-sidebar/nui-sidebar-nav-element.d.ts → sidebar/sidebar-nav-element.d.ts} +4 -4
  17. package/dist/sidebar/sidebar-nav-element.d.ts.map +1 -0
  18. package/dist/{nui-sidebar/nui-sidebar-nav-item-element.d.ts → sidebar/sidebar-nav-item-element.d.ts} +4 -4
  19. package/dist/sidebar/sidebar-nav-item-element.d.ts.map +1 -0
  20. package/package.json +1 -1
  21. package/dist/nui-app-panel/nui-app-panel-element.d.ts.map +0 -1
  22. package/dist/nui-sidebar/nui-sidebar-element.d.ts.map +0 -1
  23. package/dist/nui-sidebar/nui-sidebar-group-element.d.ts.map +0 -1
  24. package/dist/nui-sidebar/nui-sidebar-group-header-element.d.ts +0 -7
  25. package/dist/nui-sidebar/nui-sidebar-group-header-element.d.ts.map +0 -1
  26. package/dist/nui-sidebar/nui-sidebar-item-element.d.ts +0 -10
  27. package/dist/nui-sidebar/nui-sidebar-item-element.d.ts.map +0 -1
  28. package/dist/nui-sidebar/nui-sidebar-nav-element.d.ts.map +0 -1
  29. package/dist/nui-sidebar/nui-sidebar-nav-item-element.d.ts.map +0 -1
@@ -1,14 +1,21 @@
1
1
  @layer ui {
2
2
 
3
+ :where(n-sidebar):not(:defined),
4
+ :where(n-sidebar-item):not(:defined),
5
+ :where(n-sidebar-nav):not(:defined),
6
+ :where(n-sidebar-group):not(:defined),
7
+ :where(n-sidebar-group-header):not(:defined),
8
+ :where(n-sidebar-nav-item):not(:defined) { visibility: hidden; }
9
+
3
10
  /* ╭──────────────────────────────────────────────────────────╮
4
- nui-sidebar │
11
+ n-sidebar │
5
12
  │ Full-page layout: collapsible/resizable sidebar aside │
6
13
  │ + content column (breadcrumb, canvas, body, chat). │
7
14
  ╰──────────────────────────────────────────────────────────╯ */
8
15
 
9
16
  /* ── Outer Layout ── */
10
17
 
11
- :where(nui-sidebar) {
18
+ :where(n-sidebar) {
12
19
  display: flex;
13
20
  height: 100dvh;
14
21
  }
@@ -16,15 +23,15 @@
16
23
  /* WHY: Reserve sidebar width before JS builds the DOM — prevents layout shift.
17
24
  Collapsed state is read synchronously in the constructor so CSS matches immediately.
18
25
  Replaced by the real aside once [data-ready] is set. */
19
- :where(nui-sidebar):not([data-ready]):not([collapsed])::before {
26
+ :where(n-sidebar):not([data-ready]):not([collapsed])::before {
20
27
  content: '';
21
- width: var(--ui-layout-sidebar-width);
28
+ width: var(--n-sidebar-width);
22
29
  flex-shrink: 0;
23
30
  background: var(--n-body);
24
31
  border-right: 1px solid var(--n-border-muted);
25
32
  }
26
33
 
27
- :where(nui-sidebar):not([data-ready])[collapsed]::before {
34
+ :where(n-sidebar):not([data-ready])[collapsed]::before {
28
35
  content: '';
29
36
  width: 48px;
30
37
  flex-shrink: 0;
@@ -35,7 +42,7 @@
35
42
  /* ── Content Column ── */
36
43
  /* WHY: Everything except the aside forms a flex column. */
37
44
 
38
- :where(nui-sidebar) > :where(:not([slot])) {
45
+ :where(n-sidebar) > :where(:not([slot])) {
39
46
  flex: 1 1 0%;
40
47
  min-width: 0;
41
48
  min-height: 0;
@@ -49,7 +56,7 @@
49
56
  header/footer overlays. Content fills the full height and scrolls
50
57
  underneath the pinned header/footer. */
51
58
 
52
- :where(nui-sidebar) > :where([slot="sidebar"]) {
59
+ :where(n-sidebar) > :where([slot="sidebar"]) {
53
60
  --n-sidebar-header-height: 0px;
54
61
  --n-sidebar-footer-height: 0px;
55
62
 
@@ -57,7 +64,7 @@
57
64
  container-type: inline-size;
58
65
  position: sticky;
59
66
  top: 0;
60
- width: var(--ui-layout-sidebar-width);
67
+ width: var(--n-sidebar-width);
61
68
  min-width: 160px;
62
69
  max-width: 400px;
63
70
  height: 100dvh;
@@ -68,7 +75,7 @@
68
75
  }
69
76
 
70
77
  /* WHY: Disable width transition while dragging — it fights the pointer. */
71
- :where(nui-sidebar) > :where([slot="sidebar"][resizing]) {
78
+ :where(n-sidebar) > :where([slot="sidebar"][resizing]) {
72
79
  transition: none;
73
80
  }
74
81
 
@@ -77,14 +84,14 @@
77
84
  [collapsed] drives the aside to 48px which triggers @container sidebar queries
78
85
  in this file and in child component CSS. */
79
86
 
80
- :where(nui-sidebar)[collapsed] > :where([slot="sidebar"]) {
87
+ :where(n-sidebar)[collapsed] > :where([slot="sidebar"]) {
81
88
  width: 48px;
82
89
  min-width: 48px;
83
90
  }
84
91
 
85
92
  /* ── Resize Handle ── */
86
93
 
87
- :where(nui-sidebar) :where(.layout-resize-handle) {
94
+ :where(n-sidebar) :where(.layout-resize-handle) {
88
95
  position: absolute;
89
96
  top: 0;
90
97
  right: 0;
@@ -94,18 +101,18 @@
94
101
  z-index: 1;
95
102
  }
96
103
 
97
- :where(nui-sidebar) :where(.layout-resize-handle):hover,
98
- :where(nui-sidebar) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
104
+ :where(n-sidebar) :where(.layout-resize-handle):hover,
105
+ :where(n-sidebar) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
99
106
  background: var(--n-border-muted);
100
107
  }
101
108
 
102
109
  /* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
103
110
 
104
- :where(nui-sidebar)[collapsed] :where(nui-app-canvas) {
111
+ :where(n-sidebar)[collapsed] :where(n-app-canvas) {
105
112
  padding-inline-start: 0;
106
113
  }
107
114
 
108
- :where(nui-sidebar)[collapsed] :where(nui-app-breadcrumb) {
115
+ :where(n-sidebar)[collapsed] :where(n-app-breadcrumb) {
109
116
  padding-inline-start: 0;
110
117
  }
111
118
 
@@ -113,7 +120,7 @@
113
120
  /* WHY: Absolute-positioned overlay pinned to top of aside. Content scrolls
114
121
  underneath it. z-index: 2 sits above content (z-index: 0). */
115
122
 
116
- :where(nui-sidebar-header) {
123
+ :where(n-sidebar-header) {
117
124
  position: absolute;
118
125
  top: 0;
119
126
  left: 0;
@@ -128,7 +135,7 @@
128
135
  content from starting behind header / ending behind footer.
129
136
  Fade-out alpha mask dissolves content edges under the overlays. */
130
137
 
131
- :where(nui-sidebar-content) {
138
+ :where(n-sidebar-content) {
132
139
  display: flex;
133
140
  flex-direction: column;
134
141
  padding-block-start: var(--n-sidebar-header-height);
@@ -142,7 +149,7 @@
142
149
  /* WHY: When header is present, fade top edge. Content dissolves as it
143
150
  scrolls under the header — transparent at top, fully visible by 1.25×
144
151
  the header height. No opaque header background needed. */
145
- :where(nui-sidebar-content)[data-has-header] {
152
+ :where(n-sidebar-content)[data-has-header] {
146
153
  mask-image: linear-gradient(
147
154
  to bottom,
148
155
  transparent 0,
@@ -152,7 +159,7 @@
152
159
  }
153
160
 
154
161
  /* WHY: When footer is present, fade bottom edge. */
155
- :where(nui-sidebar-content)[data-has-footer] {
162
+ :where(n-sidebar-content)[data-has-footer] {
156
163
  mask-image: linear-gradient(
157
164
  to bottom,
158
165
  black 0,
@@ -162,7 +169,7 @@
162
169
  }
163
170
 
164
171
  /* WHY: When both header AND footer are present, fade both edges. */
165
- :where(nui-sidebar-content)[data-has-header][data-has-footer] {
172
+ :where(n-sidebar-content)[data-has-header][data-has-footer] {
166
173
  mask-image: linear-gradient(
167
174
  to bottom,
168
175
  transparent 0,
@@ -175,7 +182,7 @@
175
182
  /* ── Sidebar Footer ── */
176
183
  /* WHY: Absolute-positioned overlay pinned to bottom of aside. */
177
184
 
178
- :where(nui-sidebar-footer) {
185
+ :where(n-sidebar-footer) {
179
186
  position: absolute;
180
187
  bottom: 0;
181
188
  left: 0;
@@ -187,10 +194,10 @@
187
194
 
188
195
  /* ── Sidebar Item ── */
189
196
  /* WHY: Universal sidebar row element. Provides inline padding for any content
190
- (buttons, links, icons). When a child ui-listbox[popover] is present, JS
197
+ (buttons, links, icons). When a child n-listbox[popover] is present, JS
191
198
  wires PopoverController for click-to-toggle menu behavior. */
192
199
 
193
- :where(nui-sidebar-item) {
200
+ :where(n-sidebar-item) {
194
201
  display: flex;
195
202
  align-items: center;
196
203
  flex: 1;
@@ -198,9 +205,9 @@
198
205
  gap: calc(var(--n-space) * 2);
199
206
  min-height: var(--n-size);
200
207
  font-size: var(--n-font-size);
201
- font-weight: var(--ui-font-weight-button);
208
+ font-weight: var(--n-button-font-weight);
202
209
  letter-spacing: var(--n-letter-spacing);
203
- line-height: var(--ui-line-height-control);
210
+ line-height: var(--n-control-line-height);
204
211
  color: var(--n-ink);
205
212
  cursor: pointer;
206
213
  user-select: none;
@@ -214,26 +221,26 @@
214
221
 
215
222
  /* WHY: Items in header/footer match the breadcrumb bar height so the
216
223
  first sidebar row aligns horizontally with the breadcrumb. */
217
- :where(nui-sidebar-header) > :where(nui-sidebar-item),
218
- :where(nui-sidebar-footer) > :where(nui-sidebar-item) {
219
- min-height: var(--ui-layout-bar-height);
224
+ :where(n-sidebar-header) > :where(n-sidebar-item),
225
+ :where(n-sidebar-footer) > :where(n-sidebar-item) {
226
+ min-height: var(--n-sidebar-item-height);
220
227
  }
221
228
 
222
- :where(nui-sidebar-item):hover,
223
- :where(nui-sidebar-item)[force-hover] {
229
+ :where(n-sidebar-item):hover,
230
+ :where(n-sidebar-item)[force-hover] {
224
231
  color: var(--n-ink-strong);
225
232
  }
226
233
 
227
- :where(nui-sidebar-item):focus-visible,
228
- :where(nui-sidebar-item)[force-focus-visible] {
229
- outline: 2px solid var(--ui-focus-ring);
234
+ :where(n-sidebar-item):focus-visible,
235
+ :where(n-sidebar-item)[force-focus-visible] {
236
+ outline: 2px solid var(--n-focus-ring);
230
237
  outline-offset: -2px;
231
238
  }
232
239
 
233
240
  /* WHY: Fixed-size icon well so all sidebar icons center-align on the same
234
241
  column width regardless of intrinsic icon size. 1.5rem matches the sidebar's
235
242
  visual rhythm at default density. */
236
- :where(nui-sidebar-item) > :where([slot="icon"]) {
243
+ :where(n-sidebar-item) > :where([slot="icon"]) {
237
244
  display: inline-flex;
238
245
  align-items: center;
239
246
  justify-content: center;
@@ -243,21 +250,21 @@
243
250
  }
244
251
 
245
252
  /* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
246
- :where(nui-sidebar-item) > :where([slot="trailing"]) {
253
+ :where(n-sidebar-item) > :where([slot="trailing"]) {
247
254
  margin-inline-start: auto;
248
255
  flex-shrink: 0;
249
256
  color: var(--n-ink-muted);
250
257
  }
251
258
 
252
- /* WHY: When the item wraps a sub-component (e.g. ui-button) that provides
259
+ /* WHY: When the item wraps a sub-component (e.g. n-button) that provides
253
260
  its own icon, hide [slot="icon"] in expanded mode — it only serves as the
254
261
  bare collapsed-rail representation. */
255
- :where(nui-sidebar-item:has(> ui-button)) > :where([slot="icon"]) {
262
+ :where(n-sidebar-item:has(> n-button)) > :where([slot="icon"]) {
256
263
  display: none;
257
264
  }
258
265
 
259
266
  /* WHY: Title text truncates when sidebar narrows during resize. */
260
- :where(nui-sidebar-item) > :where([slot="label"]) {
267
+ :where(n-sidebar-item) > :where([slot="label"]) {
261
268
  flex: 1;
262
269
  min-width: 0;
263
270
  white-space: nowrap;
@@ -270,18 +277,18 @@
270
277
  Default: top-aligned, grows downward (span-block-end).
271
278
  Flip: bottom-aligned, grows upward (span-block-start). */
272
279
 
273
- :where(nui-sidebar-item) > :where(ui-listbox[popover]) {
280
+ :where(n-sidebar-item) > :where(n-listbox[popover]) {
274
281
  --n-popover-origin: left center;
275
282
  --n-popover-from: perspective(800px) scale(0.96) rotateY(20deg);
276
283
 
277
284
  position: fixed;
278
285
  position-area: inline-end span-block-end;
279
286
  position-try-fallbacks: --sidebar-item-flip-up;
280
- margin-block: var(--ui-popover-viewport-margin);
287
+ margin-block: var(--n-popover-viewport-margin);
281
288
  margin-inline: 0;
282
- margin-inline-start: var(--ui-popover-gap);
289
+ margin-inline-start: var(--n-popover-gap);
283
290
  min-width: 200px;
284
- max-height: var(--ui-popover-max-height);
291
+ max-height: var(--n-popover-max-height);
285
292
  overflow-y: auto;
286
293
  }
287
294
 
@@ -307,33 +314,33 @@
307
314
  }
308
315
 
309
316
  /* Header/footer — center content horizontally */
310
- :where(nui-sidebar-header),
311
- :where(nui-sidebar-footer) {
317
+ :where(n-sidebar-header),
318
+ :where(n-sidebar-footer) {
312
319
  align-items: center;
313
320
  }
314
321
 
315
322
  /* Content — center items in the 48px rail */
316
- :where(nui-sidebar-content) {
323
+ :where(n-sidebar-content) {
317
324
  align-items: center;
318
325
  }
319
326
 
320
327
  /* Item — shrink to icon-only. */
321
- :where(nui-sidebar-item) {
328
+ :where(n-sidebar-item) {
322
329
  flex: 0 0 auto;
323
330
  padding-inline: var(--n-space);
324
331
  }
325
332
 
326
- :where(nui-sidebar-item) > :where([slot="icon"]) {
333
+ :where(n-sidebar-item) > :where([slot="icon"]) {
327
334
  display: inline-flex;
328
335
  }
329
336
 
330
- :where(nui-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
337
+ :where(n-sidebar-item) > :where(:not([slot="icon"]):not(n-listbox[popover]):not(.nav-group-flyout)) {
331
338
  display: none;
332
339
  }
333
340
 
334
341
  /* WHY: In collapsed mode the sidebar item is a small icon — centering
335
342
  the popover vertically with the anchor is more natural than top-aligning. */
336
- :where(nui-sidebar-item) > :where(ui-listbox[popover]) {
343
+ :where(n-sidebar-item) > :where(n-listbox[popover]) {
337
344
  position-area: inline-end;
338
345
  position-try-fallbacks: --sidebar-item-flip-up, --sidebar-item-flip-down;
339
346
  }
@@ -341,30 +348,36 @@
341
348
 
342
349
 
343
350
  /* ╭──────────────────────────────────────────────────────────╮
344
- nui-sidebar-nav │
351
+ n-sidebar-nav │
345
352
  │ Navigation list with keyboard nav + selection. │
346
353
  │ Transparent wrapper — no visual surface. │
347
- │ Uses nui-sidebar-nav-item / nui-sidebar-group. │
354
+ │ Uses n-sidebar-nav-item / n-sidebar-group. │
348
355
  ╰──────────────────────────────────────────────────────────╯ */
349
356
 
350
- /* WHY: nui-sidebar-nav is a transparent flex wrapper — no inline padding.
357
+ /* WHY: n-sidebar-nav is a transparent flex wrapper — no inline padding.
351
358
  Inline padding is owned by leaf items (nav-item, summary).
352
359
  Block padding is owned by nav-group margins. */
353
- :where(nui-sidebar-nav) {
360
+ :where(n-sidebar-nav) {
354
361
  display: flex;
355
362
  flex-direction: column;
356
363
  gap: 0;
357
364
  padding: 0;
358
365
  outline: none;
366
+ user-select: none;
367
+ }
368
+
369
+ :where(n-sidebar-nav)[aria-disabled="true"] {
370
+ color: var(--n-ink-disabled);
371
+ pointer-events: none;
359
372
  }
360
373
 
361
374
  /* ── Nav Item ── */
362
375
  /* WHY: Nav items share the same visual pattern as options (ghost row,
363
376
  hover/active/selected states). */
364
377
 
365
- :where(nui-sidebar-nav-item) {
366
- --n-font-weight: var(--ui-font-weight-text);
367
- --n-line-height: var(--ui-line-height-control);
378
+ :where(n-sidebar-nav-item) {
379
+ --n-font-weight: var(--n-text-font-weight);
380
+ --n-line-height: var(--n-control-line-height-dense);
368
381
 
369
382
  display: flex;
370
383
  align-items: center;
@@ -392,55 +405,56 @@
392
405
 
393
406
  /* ── Nav Item States ── */
394
407
 
395
- :where(nui-sidebar-nav-item):hover,
396
- :where(nui-sidebar-nav-item)[force-hover] {
408
+ :where(n-sidebar-nav-item):hover,
409
+ :where(n-sidebar-nav-item)[force-hover] {
397
410
  color: var(--n-ink-hover);
398
411
  }
399
412
 
400
- :where(nui-sidebar-nav-item):active,
401
- :where(nui-sidebar-nav-item)[force-active] {
413
+ :where(n-sidebar-nav-item):active,
414
+ :where(n-sidebar-nav-item)[force-active] {
402
415
  color: var(--n-ink-active);
403
416
  }
404
417
 
405
- :where(nui-sidebar-nav-item)[aria-current="page"] {
418
+ :where(n-sidebar-nav-item)[aria-current="page"] {
406
419
  color: var(--n-ink-strong);
407
420
  }
408
421
 
409
- :where(nui-sidebar-nav-item)[aria-disabled="true"] {
422
+ :where(n-sidebar-nav-item)[aria-disabled="true"] {
410
423
  color: var(--n-ink-disabled);
411
424
  cursor: not-allowed;
412
425
  pointer-events: none;
413
426
  }
414
427
 
415
- :where(nui-sidebar-nav-item):focus-visible,
416
- :where(nui-sidebar-nav-item)[force-focus-visible] {
417
- outline: 2px solid var(--ui-focus-ring);
428
+ :where(n-sidebar-nav-item):focus-visible,
429
+ :where(n-sidebar-nav-item)[force-focus-visible] {
430
+ outline: 2px solid var(--n-focus-ring);
418
431
  outline-offset: -2px;
419
432
  }
420
433
 
421
434
  /* ── Nav Group ── */
422
435
  /* WHY: Groups stamp a native <details>/<summary> for collapsible behavior.
423
- DOM structure: nui-sidebar-group > details > summary > nui-sidebar-group-header
424
- > nui-sidebar-nav-item* */
436
+ DOM structure: n-sidebar-group > details > summary > n-sidebar-group-header
437
+ > n-sidebar-nav-item* */
425
438
 
426
- :where(nui-sidebar-group) {
439
+ :where(n-sidebar-group) {
427
440
  --n-indicator-index: 0;
428
441
 
429
442
  display: block;
430
443
  position: relative;
444
+ user-select: none;
431
445
  }
432
446
 
433
- :where(nui-sidebar-group) + :where(nui-sidebar-group) {
447
+ :where(n-sidebar-group) + :where(n-sidebar-group) {
434
448
  margin-block-start: calc(var(--n-space) * 2);
435
449
  }
436
450
 
437
451
  /* ── Details (native disclosure with animated open/close) ── */
438
452
 
439
- :where(nui-sidebar-group) > :where(details) {
453
+ :where(n-sidebar-group) > :where(details) {
440
454
  interpolate-size: allow-keywords;
441
455
  }
442
456
 
443
- :where(nui-sidebar-group) > :where(details)::details-content {
457
+ :where(n-sidebar-group) > :where(details)::details-content {
444
458
  height: 0;
445
459
  overflow: clip;
446
460
  opacity: 0;
@@ -451,14 +465,14 @@
451
465
  content-visibility var(--n-duration) var(--n-easing) allow-discrete;
452
466
  }
453
467
 
454
- :where(nui-sidebar-group) > :where(details[open])::details-content {
468
+ :where(n-sidebar-group) > :where(details[open])::details-content {
455
469
  height: auto;
456
470
  opacity: 1;
457
471
  }
458
472
 
459
473
  /* ── Summary (clickable header row) ── */
460
474
 
461
- :where(nui-sidebar-group) > :where(details) > :where(summary) {
475
+ :where(n-sidebar-group) > :where(details) > :where(summary) {
462
476
  display: flex;
463
477
  align-items: center;
464
478
  gap: calc(var(--n-space) * 2);
@@ -470,11 +484,11 @@
470
484
  }
471
485
 
472
486
  /* WHY: Remove default marker in WebKit */
473
- :where(nui-sidebar-group) > :where(details) > :where(summary)::-webkit-details-marker {
487
+ :where(n-sidebar-group) > :where(details) > :where(summary)::-webkit-details-marker {
474
488
  display: none;
475
489
  }
476
490
 
477
- :where(nui-sidebar-group) > :where(details) > :where(summary)::marker {
491
+ :where(n-sidebar-group) > :where(details) > :where(summary)::marker {
478
492
  display: none;
479
493
  content: '';
480
494
  }
@@ -482,25 +496,25 @@
482
496
  /* ── Nav Group Header ── */
483
497
  /* WHY: Header sits inside <summary>. Bold text with optional icon. */
484
498
 
485
- :where(nui-sidebar-group-header) {
499
+ :where(n-sidebar-group-header) {
486
500
  display: flex;
487
501
  align-items: center;
488
502
  flex: 1;
489
503
  gap: calc(var(--n-space) * 2);
490
504
  min-height: var(--n-size);
491
505
  font-size: var(--n-font-size);
492
- font-weight: var(--ui-font-weight-button);
506
+ font-weight: var(--n-button-font-weight);
493
507
  letter-spacing: var(--n-letter-spacing);
494
- line-height: var(--ui-line-height-control);
508
+ line-height: var(--n-control-line-height);
495
509
  color: var(--n-ink);
496
510
  cursor: pointer;
497
511
  user-select: none;
498
512
  }
499
513
 
500
- /* WHY: Fixed-size icon well — matches nui-sidebar-item [slot="icon"].
514
+ /* WHY: Fixed-size icon well — matches n-sidebar-item [slot="icon"].
501
515
  All sidebar icons align on the same 1.5rem column regardless of icon size.
502
- JS wraps the first <ui-icon> child in a .icon-well span during setup(). */
503
- :where(nui-sidebar-group-header) > :where(.icon-well) {
516
+ JS wraps the first <n-icon> child in a .icon-well span during setup(). */
517
+ :where(n-sidebar-group-header) > :where(.icon-well) {
504
518
  display: inline-flex;
505
519
  align-items: center;
506
520
  justify-content: center;
@@ -511,7 +525,7 @@
511
525
 
512
526
  /* ── Chevron icon (right side of summary) ── */
513
527
 
514
- :where(nui-sidebar-group) > :where(details) > :where(summary)::after {
528
+ :where(n-sidebar-group) > :where(details) > :where(summary)::after {
515
529
  content: '';
516
530
  flex-shrink: 0;
517
531
  width: var(--n-icon-size);
@@ -533,41 +547,41 @@
533
547
  }
534
548
 
535
549
  /* Chevron rotates when open */
536
- :where(nui-sidebar-group) > :where(details[open]) > :where(summary)::after {
550
+ :where(n-sidebar-group) > :where(details[open]) > :where(summary)::after {
537
551
  transform: rotate(180deg);
538
552
  }
539
553
 
540
554
  /* ── Selected group — has a child with aria-current ── */
541
555
 
542
- :where(nui-sidebar-group):state(has-selection) > :where(details) > :where(summary) :where(nui-sidebar-group-header) {
556
+ :where(n-sidebar-group):state(has-selection) > :where(details) > :where(summary) :where(n-sidebar-group-header) {
543
557
  color: var(--n-ink-strong);
544
558
  }
545
559
 
546
560
  /* ── Summary Hover ── */
547
561
 
548
- :where(nui-sidebar-group) > :where(details) > :where(summary):hover :where(nui-sidebar-group-header),
549
- :where(nui-sidebar-group[force-hover]) > :where(details) > :where(summary) :where(nui-sidebar-group-header) {
562
+ :where(n-sidebar-group) > :where(details) > :where(summary):hover :where(n-sidebar-group-header),
563
+ :where(n-sidebar-group[force-hover]) > :where(details) > :where(summary) :where(n-sidebar-group-header) {
550
564
  color: var(--n-ink-strong);
551
565
  }
552
566
 
553
567
  /* ── Summary Focus ── */
554
568
 
555
- :where(nui-sidebar-group) > :where(details) > :where(summary):focus-visible,
556
- :where(nui-sidebar-group[force-focus-visible]) > :where(details) > :where(summary) {
557
- outline: 2px solid var(--ui-focus-ring);
569
+ :where(n-sidebar-group) > :where(details) > :where(summary):focus-visible,
570
+ :where(n-sidebar-group[force-focus-visible]) > :where(details) > :where(summary) {
571
+ outline: 2px solid var(--n-focus-ring);
558
572
  outline-offset: -2px;
559
573
  }
560
574
 
561
575
  /* ── Vertical connector line (icon groups only) ── */
562
576
 
563
- :where(nui-sidebar-group):has(:where(nui-sidebar-group-header) :where(.icon-well)) {
577
+ :where(n-sidebar-group):has(:where(n-sidebar-group-header) :where(.icon-well)) {
564
578
  --n-group-pad: calc(var(--n-space-k) * var(--n-space));
565
579
  --n-group-icon-well: 1.5rem;
566
580
  --n-group-line-inset: calc(var(--n-group-pad) + var(--n-group-icon-well) / 2);
567
581
  --n-group-child-inset: calc(var(--n-group-icon-well) + var(--n-space) * 2);
568
582
  }
569
583
 
570
- :where(nui-sidebar-group):has(:where(nui-sidebar-group-header) :where(.icon-well)):has(:where(details[open]))::after {
584
+ :where(n-sidebar-group):has(:where(n-sidebar-group-header) :where(.icon-well)):has(:where(details[open]))::after {
571
585
  content: '';
572
586
  position: absolute;
573
587
  inset-inline-start: var(--n-group-line-inset);
@@ -580,7 +594,7 @@
580
594
 
581
595
  /* ── Sliding indicator ── */
582
596
 
583
- :where(nui-sidebar-group):has(:where(nui-sidebar-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
597
+ :where(n-sidebar-group):has(:where(n-sidebar-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
584
598
  content: '';
585
599
  position: absolute;
586
600
  z-index: 1;
@@ -600,24 +614,24 @@
600
614
 
601
615
  /* ── Grouped Child Items ── */
602
616
 
603
- :where(nui-sidebar-group) > :where(details) > :where(nui-sidebar-nav-item) {
617
+ :where(n-sidebar-group) > :where(details) > :where(n-sidebar-nav-item) {
604
618
  margin-inline-start: var(--n-group-child-inset, 0);
605
619
  }
606
620
 
607
621
  /* ── Nav Group Flyout (collapsed sidebar) ── */
608
622
 
609
- :where(nui-sidebar-group) > :where(ui-listbox.nav-group-flyout[popover]) {
623
+ :where(n-sidebar-group) > :where(n-listbox.nav-group-flyout[popover]) {
610
624
  --n-popover-origin: left center;
611
625
  --n-popover-from: perspective(800px) scale(0.96) rotateY(20deg);
612
626
 
613
627
  position: fixed;
614
628
  position-area: inline-end span-block-end;
615
629
  position-try-fallbacks: --nav-flyout-flip-up;
616
- margin-block: var(--ui-popover-viewport-margin);
630
+ margin-block: var(--n-popover-viewport-margin);
617
631
  margin-inline: 0;
618
- margin-inline-start: var(--ui-popover-gap);
632
+ margin-inline-start: var(--n-popover-gap);
619
633
  min-width: 200px;
620
- max-height: var(--ui-popover-max-height);
634
+ max-height: var(--n-popover-max-height);
621
635
  overflow-y: auto;
622
636
  }
623
637
 
@@ -634,47 +648,47 @@
634
648
  @container sidebar (max-width: 80px) {
635
649
 
636
650
  /* Nav items hide entirely — only group headers (with icons) remain. */
637
- :where(nui-sidebar-nav-item) {
651
+ :where(n-sidebar-nav-item) {
638
652
  display: none;
639
653
  }
640
654
 
641
655
  /* Summary shrinks to icon-only. */
642
- :where(nui-sidebar-group) > :where(details) > :where(summary) {
656
+ :where(n-sidebar-group) > :where(details) > :where(summary) {
643
657
  padding-inline: var(--n-space);
644
658
  border-radius: var(--n-radius);
645
659
  }
646
660
 
647
661
  /* Hide chevron — no expand/collapse in icon rail (flyout instead). */
648
- :where(nui-sidebar-group) > :where(details) > :where(summary)::after {
662
+ :where(n-sidebar-group) > :where(details) > :where(summary)::after {
649
663
  display: none;
650
664
  }
651
665
 
652
666
  /* Hide vertical connector line and sliding indicator. */
653
- :where(nui-sidebar-group)::after,
654
- :where(nui-sidebar-group)::before {
667
+ :where(n-sidebar-group)::after,
668
+ :where(n-sidebar-group)::before {
655
669
  display: none;
656
670
  }
657
671
 
658
672
  /* Header collapses to icon-only. */
659
- :where(nui-sidebar-group-header) {
673
+ :where(n-sidebar-group-header) {
660
674
  flex: 0 0 auto;
661
675
  font-size: 0;
662
676
  gap: 0;
663
677
  }
664
678
 
665
- :where(nui-sidebar-group-header) :where(.icon-well) :where(ui-icon) {
679
+ :where(n-sidebar-group-header) :where(.icon-well) :where(n-icon) {
666
680
  font-size: var(--n-font-size, 1rem);
667
681
  }
668
682
 
669
683
  /* WHY: In collapsed mode the group is a small icon — centering
670
684
  the flyout vertically with the anchor is more natural. */
671
- :where(nui-sidebar-group) > :where(ui-listbox.nav-group-flyout[popover]) {
685
+ :where(n-sidebar-group) > :where(n-listbox.nav-group-flyout[popover]) {
672
686
  position-area: inline-end;
673
687
  position-try-fallbacks: --nav-flyout-flip-up, --nav-flyout-flip-down;
674
688
  }
675
689
 
676
690
  /* Collapse inter-group spacing in icon rail. */
677
- :where(nui-sidebar-group) + :where(nui-sidebar-group) {
691
+ :where(n-sidebar-group) + :where(n-sidebar-group) {
678
692
  margin-block-start: 0;
679
693
  }
680
694
  }
@@ -684,18 +698,18 @@
684
698
  @layer ui {
685
699
 
686
700
  /* ╭──────────────────────────────────────────────────────────╮
687
- nui-app-breadcrumb │
701
+ n-app-breadcrumb │
688
702
  │ Grid bar with leading / label / trailing slots. │
689
- │ Same slot pattern as ui-header.
703
+ │ Same slot pattern as n-card-header.
690
704
  ╰──────────────────────────────────────────────────────────╯ */
691
705
 
692
706
  /* ── Base ── */
693
707
 
694
- :where(nui-app-breadcrumb) {
708
+ :where(n-app-breadcrumb) {
695
709
  display: grid;
696
710
  grid-template-columns: 1fr;
697
711
  align-items: center;
698
- min-height: var(--ui-layout-bar-height);
712
+ min-height: var(--n-sidebar-item-height);
699
713
  gap: calc(var(--n-space) * 2);
700
714
  padding-block: var(--n-space);
701
715
  padding-inline: calc(var(--n-space-k) * var(--n-space));
@@ -705,30 +719,30 @@
705
719
 
706
720
  /* ── Slots ── */
707
721
 
708
- :where(nui-app-breadcrumb):has(> [slot="leading"]):has(> [slot="trailing"]) {
722
+ :where(n-app-breadcrumb):has(> [slot="leading"]):has(> [slot="trailing"]) {
709
723
  grid-template-columns: auto 1fr auto;
710
724
  }
711
725
 
712
- :where(nui-app-breadcrumb):has(> [slot="leading"]):not(:has(> [slot="trailing"])) {
726
+ :where(n-app-breadcrumb):has(> [slot="leading"]):not(:has(> [slot="trailing"])) {
713
727
  grid-template-columns: auto 1fr;
714
728
  }
715
729
 
716
- :where(nui-app-breadcrumb):not(:has(> [slot="leading"])):has(> [slot="trailing"]) {
730
+ :where(n-app-breadcrumb):not(:has(> [slot="leading"])):has(> [slot="trailing"]) {
717
731
  grid-template-columns: 1fr auto;
718
732
  }
719
733
 
720
- :where(nui-app-breadcrumb) > :where([slot="leading"]) {
734
+ :where(n-app-breadcrumb) > :where([slot="leading"]) {
721
735
  display: flex;
722
736
  align-items: center;
723
737
  gap: calc(var(--n-space) * 2);
724
738
  }
725
739
 
726
- :where(nui-app-breadcrumb) > :where([slot="label"]),
727
- :where(nui-app-breadcrumb) > :where(:not([slot])) {
740
+ :where(n-app-breadcrumb) > :where([slot="label"]),
741
+ :where(n-app-breadcrumb) > :where(:not([slot])) {
728
742
  min-width: 0;
729
743
  }
730
744
 
731
- :where(nui-app-breadcrumb) > :where([slot="trailing"]) {
745
+ :where(n-app-breadcrumb) > :where([slot="trailing"]) {
732
746
  display: flex;
733
747
  align-items: center;
734
748
  gap: calc(var(--n-space) * 2);
@@ -739,12 +753,12 @@
739
753
  @layer ui {
740
754
 
741
755
  /* ╭──────────────────────────────────────────────────────────╮
742
- nui-app-canvas │
756
+ n-app-canvas │
743
757
  │ Structural flex row for body + chat panels. │
744
758
  │ No background, no radius — purely layout. │
745
759
  ╰──────────────────────────────────────────────────────────╯ */
746
760
 
747
- :where(nui-app-canvas) {
761
+ :where(n-app-canvas) {
748
762
  display: flex;
749
763
  flex: 1;
750
764
  min-height: 0;
@@ -755,8 +769,10 @@
755
769
 
756
770
  @layer ui {
757
771
 
772
+ :where(n-app-panel):not(:defined) { visibility: hidden; }
773
+
758
774
  /* ╭──────────────────────────────────────────────────────────╮
759
- nui-app-panel │
775
+ n-app-panel │
760
776
  │ Layout panel — main content surface or collapsible │
761
777
  │ aside. Default: flex-1 scrollable body. [aside]: │
762
778
  │ fixed-width side panel with open/close + resize. │
@@ -764,21 +780,23 @@
764
780
 
765
781
  /* ── Base (shared) ── */
766
782
 
767
- :where(nui-app-panel) {
783
+ :where(n-app-panel) {
784
+ --n-ground: var(--n-panel);
785
+
768
786
  display: flex;
769
787
  flex-direction: column;
770
788
  scrollbar-width: none;
771
- background: var(--n-ground, var(--n-panel));
789
+ background: var(--n-ground);
772
790
  border-radius: var(--n-radius);
773
791
  }
774
792
 
775
- :where(nui-app-panel)[show-scrollbar] {
793
+ :where(n-app-panel)[show-scrollbar] {
776
794
  scrollbar-width: thin;
777
795
  }
778
796
 
779
797
  /* ── Main mode (default) ── */
780
798
 
781
- :where(nui-app-panel):not([aside]) {
799
+ :where(n-app-panel):not([aside]) {
782
800
  flex: 1;
783
801
  min-width: 0;
784
802
  overflow-y: auto;
@@ -787,7 +805,7 @@
787
805
 
788
806
  /* ── Aside mode ── */
789
807
 
790
- :where(nui-app-panel)[aside] {
808
+ :where(n-app-panel)[aside] {
791
809
  position: relative;
792
810
  width: 0;
793
811
  min-width: 0;
@@ -801,7 +819,7 @@
801
819
  margin var(--n-duration) var(--n-easing);
802
820
  }
803
821
 
804
- :where(nui-app-panel)[aside][open] {
822
+ :where(n-app-panel)[aside][open] {
805
823
  width: 360px;
806
824
  min-width: 280px;
807
825
  margin-inline-start: calc(var(--n-space) * 2);
@@ -809,23 +827,23 @@
809
827
  padding: calc(var(--n-space-k) * var(--n-space));
810
828
  }
811
829
 
812
- /* WHY: When ui-chat manages its own sub-container padding and scroll,
830
+ /* WHY: When n-chat manages its own sub-container padding and scroll,
813
831
  the layout container delegates — no own padding, no own scroll.
814
- overflow: visible lets CSS anchor-positioned popovers (ui-select etc.)
832
+ overflow: visible lets CSS anchor-positioned popovers (n-select etc.)
815
833
  resolve through to the top layer. */
816
- :where(nui-app-panel)[aside][open]:has(> ui-chat) {
834
+ :where(n-app-panel)[aside][open]:has(> n-chat) {
817
835
  padding: 0;
818
836
  overflow: visible;
819
837
  }
820
838
 
821
839
  /* WHY: Disable width transition while dragging — it fights the pointer. */
822
- :where(nui-app-panel)[aside][resizing] {
840
+ :where(n-app-panel)[aside][resizing] {
823
841
  transition: none;
824
842
  }
825
843
 
826
844
  /* ── Resize Handle ── */
827
845
 
828
- :where(nui-app-panel)[aside] :where(.layout-resize-handle) {
846
+ :where(n-app-panel)[aside] :where(.layout-resize-handle) {
829
847
  position: absolute;
830
848
  top: 0;
831
849
  left: 0;
@@ -835,9 +853,26 @@
835
853
  z-index: 1;
836
854
  }
837
855
 
838
- :where(nui-app-panel)[aside] :where(.layout-resize-handle):hover,
839
- :where(nui-app-panel)[aside][resizing] :where(.layout-resize-handle) {
856
+ :where(n-app-panel)[aside] :where(.layout-resize-handle):hover,
857
+ :where(n-app-panel)[aside][resizing] :where(.layout-resize-handle) {
840
858
  background: var(--n-border-muted);
841
859
  }
842
860
 
861
+ /* ── Panel sub-container integration ── */
862
+ /* WHY: When n-panel-body is present, delegate overflow to it so
863
+ header/footer stay fixed while body scrolls. */
864
+
865
+ :where(n-app-panel):has(> n-panel-body) {
866
+ overflow: hidden;
867
+ padding: 0;
868
+ }
869
+
870
+ :where(n-app-panel) > :where(n-panel-header) {
871
+ border-bottom: 1px solid var(--n-border-muted);
872
+ }
873
+
874
+ :where(n-app-panel) > :where(n-panel-footer) {
875
+ border-top: 1px solid var(--n-border-muted);
876
+ }
877
+
843
878
  }