@nonoun/native-app 0.2.0 → 0.2.1

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