@nonoun/native-ui 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui-kbd/index.d.ts +3 -0
- package/dist/components/ui-kbd/index.d.ts.map +1 -0
- package/dist/components/ui-kbd/ui-kbd-element.d.ts +5 -0
- package/dist/components/ui-kbd/ui-kbd-element.d.ts.map +1 -0
- package/dist/components/ui-kbd/ui-kbd.d.ts +3 -0
- package/dist/components/ui-kbd/ui-kbd.d.ts.map +1 -0
- package/dist/components/ui-nav/ui-nav-group-element.d.ts +8 -0
- package/dist/components/ui-nav/ui-nav-group-element.d.ts.map +1 -1
- package/dist/components/ui-nav/ui-nav-group-header-element.d.ts.map +1 -1
- package/dist/components-lean.css +319 -226
- package/dist/components.css +321 -233
- package/dist/containers/ui-layout-sidebar/index.d.ts +1 -1
- package/dist/containers/ui-layout-sidebar/index.d.ts.map +1 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-element.d.ts +4 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-element.d.ts.map +1 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-item-element.d.ts +10 -0
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-item-element.d.ts.map +1 -0
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-item.d.ts +3 -0
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-item.d.ts.map +1 -0
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar.d.ts +1 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar.d.ts.map +1 -1
- package/dist/custom-elements.json +2507 -2099
- package/dist/foundation.css +79 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/native-ui-lean.css +398 -227
- package/dist/native-ui.css +400 -234
- package/dist/native-ui.js +3 -6
- package/dist/register-all.js +1 -1
- package/dist/ui-icon-element.js +100 -7
- package/package.json +1 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-trigger-element.d.ts +0 -8
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-trigger-element.d.ts.map +0 -1
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-trigger.d.ts +0 -3
- package/dist/containers/ui-layout-sidebar/ui-layout-sidebar-trigger.d.ts.map +0 -1
package/dist/native-ui.css
CHANGED
|
@@ -1267,6 +1267,54 @@
|
|
|
1267
1267
|
display: none;
|
|
1268
1268
|
}
|
|
1269
1269
|
|
|
1270
|
+
/* WHY: Custom elements render as unstyled inline text until define() runs.
|
|
1271
|
+
visibility:hidden preserves layout — no reflow when the element upgrades.
|
|
1272
|
+
Only targets elements that call define(); CSS-only containers are excluded
|
|
1273
|
+
(they never become :defined so would be permanently hidden). */
|
|
1274
|
+
:where(
|
|
1275
|
+
ui-accordion, ui-accordion-item,
|
|
1276
|
+
ui-avatar,
|
|
1277
|
+
ui-badge,
|
|
1278
|
+
ui-breadcrumb, ui-breadcrumb-item,
|
|
1279
|
+
ui-button,
|
|
1280
|
+
ui-calendar,
|
|
1281
|
+
ui-card,
|
|
1282
|
+
ui-chat-input,
|
|
1283
|
+
ui-checkbox,
|
|
1284
|
+
ui-combobox,
|
|
1285
|
+
ui-command, ui-command-empty, ui-command-group, ui-command-input, ui-command-item, ui-command-list,
|
|
1286
|
+
ui-controller,
|
|
1287
|
+
ui-dialog,
|
|
1288
|
+
ui-drawer,
|
|
1289
|
+
ui-field,
|
|
1290
|
+
ui-icon,
|
|
1291
|
+
ui-input,
|
|
1292
|
+
ui-input-otp,
|
|
1293
|
+
ui-kbd,
|
|
1294
|
+
ui-layout-chat,
|
|
1295
|
+
ui-layout-inspector,
|
|
1296
|
+
ui-layout-sidebar, ui-layout-sidebar-item,
|
|
1297
|
+
ui-listbox,
|
|
1298
|
+
ui-nav, ui-nav-group, ui-nav-group-header, ui-nav-item,
|
|
1299
|
+
ui-option, ui-option-group, ui-option-group-header,
|
|
1300
|
+
ui-pagination,
|
|
1301
|
+
ui-radio, ui-radio-group,
|
|
1302
|
+
ui-range,
|
|
1303
|
+
ui-section,
|
|
1304
|
+
ui-segment, ui-segmented-control,
|
|
1305
|
+
ui-select,
|
|
1306
|
+
ui-slide, ui-slideshow,
|
|
1307
|
+
ui-switch,
|
|
1308
|
+
ui-tab, ui-tab-panel, ui-tab-panels, ui-tabs,
|
|
1309
|
+
ui-table, ui-table-body, ui-table-cell, ui-table-head, ui-table-header, ui-table-row,
|
|
1310
|
+
ui-textarea,
|
|
1311
|
+
ui-toolbar,
|
|
1312
|
+
ui-tooltip,
|
|
1313
|
+
ui-tree, ui-tree-item
|
|
1314
|
+
):not(:defined) {
|
|
1315
|
+
visibility: hidden;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1270
1318
|
/* ── Document Defaults ── */
|
|
1271
1319
|
|
|
1272
1320
|
:where(:root) {
|
|
@@ -1460,7 +1508,7 @@
|
|
|
1460
1508
|
--ui-tooltip-max-width: 20rem;
|
|
1461
1509
|
|
|
1462
1510
|
/* Popover (select / combobox / command) */
|
|
1463
|
-
--ui-popover-max-height:
|
|
1511
|
+
--ui-popover-max-height: calc(100dvh - 2rem);
|
|
1464
1512
|
--ui-popover-gap: 0.25rem;
|
|
1465
1513
|
|
|
1466
1514
|
/* Drawer */
|
|
@@ -1493,6 +1541,18 @@
|
|
|
1493
1541
|
--ui-badge-size-xl: 1.375rem;
|
|
1494
1542
|
--ui-badge-dot: 0.5rem;
|
|
1495
1543
|
|
|
1544
|
+
/* Kbd */
|
|
1545
|
+
--ui-kbd-font-xs: 0.625rem;
|
|
1546
|
+
--ui-kbd-font-sm: 0.6875rem;
|
|
1547
|
+
--ui-kbd-font-md: 0.6875rem;
|
|
1548
|
+
--ui-kbd-font-lg: 0.75rem;
|
|
1549
|
+
--ui-kbd-font-xl: 0.8125rem;
|
|
1550
|
+
--ui-kbd-size-xs: 1rem;
|
|
1551
|
+
--ui-kbd-size-sm: 1.125rem;
|
|
1552
|
+
--ui-kbd-size-md: 1.25rem;
|
|
1553
|
+
--ui-kbd-size-lg: 1.375rem;
|
|
1554
|
+
--ui-kbd-size-xl: 1.5rem;
|
|
1555
|
+
|
|
1496
1556
|
/* Group header (option-group, table category) */
|
|
1497
1557
|
--ui-group-header-font: 0.625rem;
|
|
1498
1558
|
|
|
@@ -1606,6 +1666,8 @@
|
|
|
1606
1666
|
/* ── Intent (maps to color token families) ── */
|
|
1607
1667
|
|
|
1608
1668
|
:root {
|
|
1669
|
+
--_body: var(--neutral-body);
|
|
1670
|
+
|
|
1609
1671
|
--_card: var(--neutral-card);
|
|
1610
1672
|
--_card-hover: var(--neutral-card-hover);
|
|
1611
1673
|
|
|
@@ -1657,6 +1719,22 @@
|
|
|
1657
1719
|
--_ink-disabled: var(--neutral-ink-disabled);
|
|
1658
1720
|
}
|
|
1659
1721
|
|
|
1722
|
+
/* ── Toggle control defaults ── */
|
|
1723
|
+
/* WHY: Checkboxes, radios, switches, and range sliders use accent-colored
|
|
1724
|
+
surface fills for their checked/active states by default.
|
|
1725
|
+
[intent] selectors below override --_surface when an explicit intent is set. */
|
|
1726
|
+
|
|
1727
|
+
:where(ui-checkbox, ui-radio, ui-switch, ui-range) {
|
|
1728
|
+
--_surface: var(--accent-surface);
|
|
1729
|
+
--_surface-hover: var(--accent-surface-hover);
|
|
1730
|
+
--_surface-active: var(--accent-surface-active);
|
|
1731
|
+
--_surface-disabled: var(--accent-surface-disabled);
|
|
1732
|
+
--_surface-ink: var(--accent-surface-ink);
|
|
1733
|
+
--_surface-ink-hover: var(--accent-surface-ink-hover);
|
|
1734
|
+
--_surface-ink-active: var(--accent-surface-ink-active);
|
|
1735
|
+
--_surface-ink-disabled: var(--accent-surface-ink-disabled);
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1660
1738
|
:where([intent="neutral"]) {
|
|
1661
1739
|
--_card: var(--neutral-card);
|
|
1662
1740
|
--_card-hover: var(--neutral-card-hover);
|
|
@@ -2369,7 +2447,7 @@
|
|
|
2369
2447
|
font-weight: var(--_font-weight);
|
|
2370
2448
|
|
|
2371
2449
|
border-radius: var(--_radius);
|
|
2372
|
-
border: 1px solid var(--_border-color, var(--
|
|
2450
|
+
border: 1px solid var(--_border-color, var(--_border-muted));
|
|
2373
2451
|
|
|
2374
2452
|
background: var(--_background, var(--_button));
|
|
2375
2453
|
color: var(--_color, var(--_ink));
|
|
@@ -2386,17 +2464,17 @@
|
|
|
2386
2464
|
|
|
2387
2465
|
:where(ui-button):hover,
|
|
2388
2466
|
:where(ui-button)[force-hover] {
|
|
2389
|
-
background: var(--_background-hover, var(--
|
|
2467
|
+
background: var(--_background-hover, var(--_button-hover));
|
|
2390
2468
|
color: var(--_color-hover, var(--_ink-hover));
|
|
2391
|
-
border-color: var(--_border-color-hover, var(--
|
|
2469
|
+
border-color: var(--_border-color-hover, var(--_border-hover));
|
|
2392
2470
|
}
|
|
2393
2471
|
|
|
2394
2472
|
:where(ui-button):active,
|
|
2395
2473
|
:where(ui-button)[pressed],
|
|
2396
2474
|
:where(ui-button)[force-active] {
|
|
2397
|
-
background: var(--_background-active, var(--
|
|
2475
|
+
background: var(--_background-active, var(--_button-active));
|
|
2398
2476
|
color: var(--_color-active, var(--_ink-active));
|
|
2399
|
-
border-color: var(--_border-color-active, var(--
|
|
2477
|
+
border-color: var(--_border-color-active, var(--_border-active));
|
|
2400
2478
|
}
|
|
2401
2479
|
|
|
2402
2480
|
:where(ui-button):focus-visible,
|
|
@@ -2406,9 +2484,9 @@
|
|
|
2406
2484
|
}
|
|
2407
2485
|
|
|
2408
2486
|
:where(ui-button)[aria-disabled="true"] {
|
|
2409
|
-
background: var(--_background-disabled, var(--
|
|
2487
|
+
background: var(--_background-disabled, var(--_button-disabled));
|
|
2410
2488
|
color: var(--_color-disabled, var(--_ink-disabled));
|
|
2411
|
-
border-color: var(--_border-color-disabled, var(--
|
|
2489
|
+
border-color: var(--_border-color-disabled, var(--_border-muted));
|
|
2412
2490
|
cursor: not-allowed;
|
|
2413
2491
|
pointer-events: none;
|
|
2414
2492
|
}
|
|
@@ -2981,34 +3059,25 @@
|
|
|
2981
3059
|
}
|
|
2982
3060
|
|
|
2983
3061
|
/* ── Checked State ── */
|
|
2984
|
-
/* WHY: Default checked fill uses accent
|
|
2985
|
-
|
|
3062
|
+
/* WHY: Default checked fill uses --_surface (accent by default via
|
|
3063
|
+
intent="accent" being the implicit default for toggle controls).
|
|
2986
3064
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
2987
3065
|
|
|
2988
3066
|
:where(ui-checkbox)[aria-checked="true"]::before {
|
|
2989
|
-
background: var(--accent-surface);
|
|
2990
|
-
border-color: var(--accent-surface);
|
|
2991
|
-
}
|
|
2992
|
-
|
|
2993
|
-
:where(ui-checkbox)[aria-checked="true"]::after {
|
|
2994
|
-
background: var(--accent-surface-ink);
|
|
2995
|
-
transform: translateY(-50%) scale(1);
|
|
2996
|
-
}
|
|
2997
|
-
|
|
2998
|
-
:where(ui-checkbox)[intent][aria-checked="true"]::before {
|
|
2999
3067
|
background: var(--_surface);
|
|
3000
3068
|
border-color: var(--_surface);
|
|
3001
3069
|
}
|
|
3002
3070
|
|
|
3003
|
-
:where(ui-checkbox)[
|
|
3071
|
+
:where(ui-checkbox)[aria-checked="true"]::after {
|
|
3004
3072
|
background: var(--_surface-ink);
|
|
3073
|
+
transform: translateY(-50%) scale(1);
|
|
3005
3074
|
}
|
|
3006
3075
|
|
|
3007
3076
|
/* ── Indeterminate State ── */
|
|
3008
3077
|
|
|
3009
3078
|
:where(ui-checkbox)[aria-checked="mixed"]::before {
|
|
3010
|
-
background: var(--
|
|
3011
|
-
border-color: var(--
|
|
3079
|
+
background: var(--_surface);
|
|
3080
|
+
border-color: var(--_surface);
|
|
3012
3081
|
}
|
|
3013
3082
|
|
|
3014
3083
|
:where(ui-checkbox)[aria-checked="mixed"]::after {
|
|
@@ -3016,17 +3085,8 @@
|
|
|
3016
3085
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z'/%3E%3C/svg%3E");
|
|
3017
3086
|
mask-size: 75%;
|
|
3018
3087
|
-webkit-mask-size: 75%;
|
|
3019
|
-
background: var(--accent-surface-ink);
|
|
3020
|
-
transform: translateY(-50%) scale(1);
|
|
3021
|
-
}
|
|
3022
|
-
|
|
3023
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]::before {
|
|
3024
|
-
background: var(--_surface);
|
|
3025
|
-
border-color: var(--_surface);
|
|
3026
|
-
}
|
|
3027
|
-
|
|
3028
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]::after {
|
|
3029
3088
|
background: var(--_surface-ink);
|
|
3089
|
+
transform: translateY(-50%) scale(1);
|
|
3030
3090
|
}
|
|
3031
3091
|
|
|
3032
3092
|
/* ── Hover ── */
|
|
@@ -3046,14 +3106,6 @@
|
|
|
3046
3106
|
:where(ui-checkbox)[aria-checked="mixed"]:hover::before,
|
|
3047
3107
|
:where(ui-checkbox)[aria-checked="true"][force-hover]::before,
|
|
3048
3108
|
:where(ui-checkbox)[aria-checked="mixed"][force-hover]::before {
|
|
3049
|
-
background: var(--accent-surface-hover);
|
|
3050
|
-
border-color: var(--accent-surface-hover);
|
|
3051
|
-
}
|
|
3052
|
-
|
|
3053
|
-
:where(ui-checkbox)[intent][aria-checked="true"]:hover::before,
|
|
3054
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]:hover::before,
|
|
3055
|
-
:where(ui-checkbox)[intent][aria-checked="true"][force-hover]::before,
|
|
3056
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"][force-hover]::before {
|
|
3057
3109
|
background: var(--_surface-hover);
|
|
3058
3110
|
border-color: var(--_surface-hover);
|
|
3059
3111
|
}
|
|
@@ -3067,12 +3119,6 @@
|
|
|
3067
3119
|
|
|
3068
3120
|
:where(ui-checkbox)[aria-checked="true"][pressed]::before,
|
|
3069
3121
|
:where(ui-checkbox)[aria-checked="mixed"][pressed]::before {
|
|
3070
|
-
background: var(--accent-surface-active);
|
|
3071
|
-
border-color: var(--accent-surface-active);
|
|
3072
|
-
}
|
|
3073
|
-
|
|
3074
|
-
:where(ui-checkbox)[intent][aria-checked="true"][pressed]::before,
|
|
3075
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"][pressed]::before {
|
|
3076
3122
|
background: var(--_surface-active);
|
|
3077
3123
|
border-color: var(--_surface-active);
|
|
3078
3124
|
}
|
|
@@ -3726,6 +3772,45 @@
|
|
|
3726
3772
|
|
|
3727
3773
|
}
|
|
3728
3774
|
|
|
3775
|
+
@layer ui {
|
|
3776
|
+
|
|
3777
|
+
/* ╭──────────────────────────────────────────────────────────╮
|
|
3778
|
+
│ ui-kbd │
|
|
3779
|
+
│ Keyboard shortcut indicator. Own font/size scale │
|
|
3780
|
+
│ (like ui-badge) — zero-attribute = md. │
|
|
3781
|
+
╰──────────────────────────────────────────────────────────╯ */
|
|
3782
|
+
|
|
3783
|
+
:where(ui-kbd) {
|
|
3784
|
+
--_icon-size: 1.125em;
|
|
3785
|
+
|
|
3786
|
+
display: inline-flex;
|
|
3787
|
+
align-items: center;
|
|
3788
|
+
justify-content: center;
|
|
3789
|
+
font-family: ui-monospace, monospace;
|
|
3790
|
+
font-size: var(--ui-kbd-font-md);
|
|
3791
|
+
line-height: 1;
|
|
3792
|
+
min-height: var(--ui-kbd-size-md);
|
|
3793
|
+
padding-inline: 0.4em;
|
|
3794
|
+
border-radius: 0.5em;
|
|
3795
|
+
background: var(--_ground, var(--_body));
|
|
3796
|
+
border: 1px solid var(--_border-muted);
|
|
3797
|
+
color: var(--_ink-muted);
|
|
3798
|
+
white-space: nowrap;
|
|
3799
|
+
user-select: none;
|
|
3800
|
+
flex-shrink: 0;
|
|
3801
|
+
vertical-align: baseline;
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
/* ── Sizes ── */
|
|
3805
|
+
|
|
3806
|
+
:where(ui-kbd[size="xs"]) { font-size: var(--ui-kbd-font-xs); min-height: var(--ui-kbd-size-xs); }
|
|
3807
|
+
:where(ui-kbd[size="sm"]) { font-size: var(--ui-kbd-font-sm); min-height: var(--ui-kbd-size-sm); }
|
|
3808
|
+
:where(ui-kbd[size="md"]) { font-size: var(--ui-kbd-font-md); min-height: var(--ui-kbd-size-md); }
|
|
3809
|
+
:where(ui-kbd[size="lg"]) { font-size: var(--ui-kbd-font-lg); min-height: var(--ui-kbd-size-lg); }
|
|
3810
|
+
:where(ui-kbd[size="xl"]) { font-size: var(--ui-kbd-font-xl); min-height: var(--ui-kbd-size-xl); }
|
|
3811
|
+
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3729
3814
|
@layer ui {
|
|
3730
3815
|
|
|
3731
3816
|
/* ── Listbox Base ── */
|
|
@@ -3866,11 +3951,14 @@
|
|
|
3866
3951
|
│ Uses ui-nav-item / ui-nav-group for children. │
|
|
3867
3952
|
╰──────────────────────────────────────────────────────────╯ */
|
|
3868
3953
|
|
|
3954
|
+
/* WHY: ui-nav is a transparent flex wrapper — no inline padding.
|
|
3955
|
+
Inline padding is owned by leaf items (nav-item, summary).
|
|
3956
|
+
Block padding is owned by nav-group margins. */
|
|
3869
3957
|
:where(ui-nav) {
|
|
3870
3958
|
display: flex;
|
|
3871
3959
|
flex-direction: column;
|
|
3872
3960
|
gap: 0;
|
|
3873
|
-
padding:
|
|
3961
|
+
padding: 0;
|
|
3874
3962
|
outline: none;
|
|
3875
3963
|
}
|
|
3876
3964
|
|
|
@@ -3885,6 +3973,7 @@
|
|
|
3885
3973
|
display: flex;
|
|
3886
3974
|
align-items: center;
|
|
3887
3975
|
gap: calc(var(--_space) * 2);
|
|
3976
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
3888
3977
|
|
|
3889
3978
|
min-height: var(--_min-height);
|
|
3890
3979
|
|
|
@@ -3984,6 +4073,7 @@
|
|
|
3984
4073
|
display: flex;
|
|
3985
4074
|
align-items: center;
|
|
3986
4075
|
gap: calc(var(--_space) * 2);
|
|
4076
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
3987
4077
|
cursor: pointer;
|
|
3988
4078
|
user-select: none;
|
|
3989
4079
|
list-style: none;
|
|
@@ -4018,6 +4108,18 @@
|
|
|
4018
4108
|
user-select: none;
|
|
4019
4109
|
}
|
|
4020
4110
|
|
|
4111
|
+
/* WHY: Fixed-size icon well — matches ui-layout-sidebar-item [slot="icon"].
|
|
4112
|
+
All sidebar icons align on the same 1.5rem column regardless of icon size.
|
|
4113
|
+
JS wraps the first <ui-icon> child in a .icon-well span during setup(). */
|
|
4114
|
+
:where(ui-nav-group-header) > :where(.icon-well) {
|
|
4115
|
+
display: inline-flex;
|
|
4116
|
+
align-items: center;
|
|
4117
|
+
justify-content: center;
|
|
4118
|
+
width: 1.5rem;
|
|
4119
|
+
height: 1.5rem;
|
|
4120
|
+
flex-shrink: 0;
|
|
4121
|
+
}
|
|
4122
|
+
|
|
4021
4123
|
/* ── Chevron icon (right side of summary) ── */
|
|
4022
4124
|
|
|
4023
4125
|
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
@@ -4071,12 +4173,16 @@
|
|
|
4071
4173
|
/* WHY: Connector draws from below the header to the bottom of the group.
|
|
4072
4174
|
Only shown when header contains an icon. Scoped via :has(). */
|
|
4073
4175
|
|
|
4074
|
-
:
|
|
4075
|
-
|
|
4076
|
-
|
|
4176
|
+
/* WHY: Insets account for the summary's padding-inline so the connector
|
|
4177
|
+
line passes through the icon center and child text aligns with header text. */
|
|
4178
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)) {
|
|
4179
|
+
--_group-pad: calc(var(--_space-k) * var(--_space));
|
|
4180
|
+
--_group-icon-well: 1.5rem;
|
|
4181
|
+
--_group-line-inset: calc(var(--_group-pad) + var(--_group-icon-well) / 2);
|
|
4182
|
+
--_group-child-inset: calc(var(--_group-icon-well) + var(--_space) * 2);
|
|
4077
4183
|
}
|
|
4078
4184
|
|
|
4079
|
-
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(
|
|
4185
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open]))::after {
|
|
4080
4186
|
content: '';
|
|
4081
4187
|
position: absolute;
|
|
4082
4188
|
inset-inline-start: var(--_group-line-inset);
|
|
@@ -4091,7 +4197,7 @@
|
|
|
4091
4197
|
/* WHY: A ::before pseudo on the group slides along the connector line.
|
|
4092
4198
|
JS sets --_indicator-index; :state(has-selection) gates visibility. */
|
|
4093
4199
|
|
|
4094
|
-
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(
|
|
4200
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
|
|
4095
4201
|
content: '';
|
|
4096
4202
|
position: absolute;
|
|
4097
4203
|
z-index: 1;
|
|
@@ -4118,6 +4224,73 @@
|
|
|
4118
4224
|
margin-inline-start: var(--_group-child-inset, 0);
|
|
4119
4225
|
}
|
|
4120
4226
|
|
|
4227
|
+
/* ── Nav Group Flyout (collapsed sidebar) ── */
|
|
4228
|
+
/* WHY: In collapsed mode, summary click opens a ui-listbox popover to the right
|
|
4229
|
+
instead of expanding the <details>. Same pattern as sidebar-trigger menus. */
|
|
4230
|
+
|
|
4231
|
+
:where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
|
|
4232
|
+
position: fixed;
|
|
4233
|
+
position-area: inline-end span-block-end;
|
|
4234
|
+
position-try-fallbacks: --nav-flyout-flip-up;
|
|
4235
|
+
margin: 0 0 0 var(--ui-popover-gap);
|
|
4236
|
+
min-width: 200px;
|
|
4237
|
+
max-height: var(--ui-popover-max-height);
|
|
4238
|
+
overflow-y: auto;
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
@position-try --nav-flyout-flip-up {
|
|
4242
|
+
position-area: inline-end span-block-start;
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
4246
|
+
/* WHY: Nav components own their own collapsed behavior via @container.
|
|
4247
|
+
The sidebar aside declares container-name: sidebar. When it shrinks
|
|
4248
|
+
to 48px (icon rail), nav responds to the width — not to [collapsed].
|
|
4249
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
4250
|
+
|
|
4251
|
+
@container sidebar (max-width: 80px) {
|
|
4252
|
+
|
|
4253
|
+
/* Nav items hide entirely — only group headers (with icons) remain. */
|
|
4254
|
+
:where(ui-nav-item) {
|
|
4255
|
+
display: none;
|
|
4256
|
+
}
|
|
4257
|
+
|
|
4258
|
+
/* Summary shrinks to icon-only. Reduced inline padding wraps tightly
|
|
4259
|
+
around the icon; parent align-items: center handles horizontal centering. */
|
|
4260
|
+
:where(ui-nav-group) > :where(details) > :where(summary) {
|
|
4261
|
+
padding-inline: var(--_space);
|
|
4262
|
+
border-radius: var(--_radius);
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
/* Hide chevron — no expand/collapse in icon rail (flyout instead). */
|
|
4266
|
+
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
4267
|
+
display: none;
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
/* Hide vertical connector line and sliding indicator. */
|
|
4271
|
+
:where(ui-nav-group)::after,
|
|
4272
|
+
:where(ui-nav-group)::before {
|
|
4273
|
+
display: none;
|
|
4274
|
+
}
|
|
4275
|
+
|
|
4276
|
+
/* Header collapses to icon-only. font-size: 0 hides text nodes
|
|
4277
|
+
(can't be targeted by CSS). Icon overrides back to normal below. */
|
|
4278
|
+
:where(ui-nav-group-header) {
|
|
4279
|
+
flex: 0 0 auto;
|
|
4280
|
+
font-size: 0;
|
|
4281
|
+
gap: 0;
|
|
4282
|
+
}
|
|
4283
|
+
|
|
4284
|
+
:where(ui-nav-group-header) :where(.icon-well) :where(ui-icon) {
|
|
4285
|
+
font-size: var(--_font-size, 1rem);
|
|
4286
|
+
}
|
|
4287
|
+
|
|
4288
|
+
/* Collapse inter-group spacing in icon rail. */
|
|
4289
|
+
:where(ui-nav-group) + :where(ui-nav-group) {
|
|
4290
|
+
margin-block-start: 0;
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
|
|
4121
4294
|
}
|
|
4122
4295
|
|
|
4123
4296
|
@layer ui {
|
|
@@ -4258,27 +4431,15 @@
|
|
|
4258
4431
|
}
|
|
4259
4432
|
|
|
4260
4433
|
/* ── Selected ── */
|
|
4261
|
-
/* WHY: Default selected fill uses accent so radio is visually distinct
|
|
4262
|
-
without needing intent="accent". Unchecked borders stay neutral.
|
|
4263
|
-
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
4264
4434
|
|
|
4265
4435
|
:where(ui-radio)[aria-checked="true"]::before {
|
|
4266
|
-
background: var(--accent-surface);
|
|
4267
|
-
border-color: var(--accent-surface);
|
|
4268
|
-
}
|
|
4269
|
-
|
|
4270
|
-
:where(ui-radio)[aria-checked="true"]::after {
|
|
4271
|
-
background: var(--accent-surface-ink);
|
|
4272
|
-
transform: translateY(-50%) scale(1);
|
|
4273
|
-
}
|
|
4274
|
-
|
|
4275
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"]::before {
|
|
4276
4436
|
background: var(--_surface);
|
|
4277
4437
|
border-color: var(--_surface);
|
|
4278
4438
|
}
|
|
4279
4439
|
|
|
4280
|
-
:where(ui-radio
|
|
4440
|
+
:where(ui-radio)[aria-checked="true"]::after {
|
|
4281
4441
|
background: var(--_surface-ink);
|
|
4442
|
+
transform: translateY(-50%) scale(1);
|
|
4282
4443
|
}
|
|
4283
4444
|
|
|
4284
4445
|
/* ── Hover ── */
|
|
@@ -4296,12 +4457,6 @@
|
|
|
4296
4457
|
|
|
4297
4458
|
:where(ui-radio)[aria-checked="true"]:hover::before,
|
|
4298
4459
|
:where(ui-radio)[aria-checked="true"][force-hover]::before {
|
|
4299
|
-
background: var(--accent-surface-hover);
|
|
4300
|
-
border-color: var(--accent-surface-hover);
|
|
4301
|
-
}
|
|
4302
|
-
|
|
4303
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"]:hover::before,
|
|
4304
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"][force-hover]::before {
|
|
4305
4460
|
background: var(--_surface-hover);
|
|
4306
4461
|
border-color: var(--_surface-hover);
|
|
4307
4462
|
}
|
|
@@ -4314,11 +4469,6 @@
|
|
|
4314
4469
|
}
|
|
4315
4470
|
|
|
4316
4471
|
:where(ui-radio)[aria-checked="true"][pressed]::before {
|
|
4317
|
-
background: var(--accent-surface-active);
|
|
4318
|
-
border-color: var(--accent-surface-active);
|
|
4319
|
-
}
|
|
4320
|
-
|
|
4321
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"][pressed]::before {
|
|
4322
4472
|
background: var(--_surface-active);
|
|
4323
4473
|
border-color: var(--_surface-active);
|
|
4324
4474
|
}
|
|
@@ -4417,16 +4567,12 @@
|
|
|
4417
4567
|
/* 0% = track-height (circle), 100% = full width */
|
|
4418
4568
|
width: calc(var(--_track-height) + (100% - var(--_track-height)) * var(--_progress));
|
|
4419
4569
|
border-radius: calc(var(--_track-height) / 2);
|
|
4420
|
-
background: var(--
|
|
4570
|
+
background: var(--_surface);
|
|
4421
4571
|
|
|
4422
4572
|
transition:
|
|
4423
4573
|
background var(--_duration) var(--_easing);
|
|
4424
4574
|
}
|
|
4425
4575
|
|
|
4426
|
-
:where(ui-range)[intent]::after {
|
|
4427
|
-
background: var(--_surface);
|
|
4428
|
-
}
|
|
4429
|
-
|
|
4430
4576
|
/* ── Thumb ── */
|
|
4431
4577
|
|
|
4432
4578
|
:where(ui-range) > :where(.ui-range-thumb) {
|
|
@@ -4438,8 +4584,8 @@
|
|
|
4438
4584
|
width: var(--_thumb-size);
|
|
4439
4585
|
height: var(--_thumb-size);
|
|
4440
4586
|
border-radius: 50%;
|
|
4441
|
-
background: var(--
|
|
4442
|
-
border: 2px solid var(--
|
|
4587
|
+
background: var(--_surface-ink);
|
|
4588
|
+
border: 2px solid var(--_surface);
|
|
4443
4589
|
box-shadow: var(--ui-shadow-sm);
|
|
4444
4590
|
pointer-events: none;
|
|
4445
4591
|
|
|
@@ -4449,11 +4595,6 @@
|
|
|
4449
4595
|
border-color var(--_duration) var(--_easing);
|
|
4450
4596
|
}
|
|
4451
4597
|
|
|
4452
|
-
:where(ui-range)[intent] > :where(.ui-range-thumb) {
|
|
4453
|
-
background: var(--_surface-ink);
|
|
4454
|
-
border-color: var(--_surface);
|
|
4455
|
-
}
|
|
4456
|
-
|
|
4457
4598
|
/* ── Focus ── */
|
|
4458
4599
|
|
|
4459
4600
|
:where(ui-range):focus-visible > :where(.ui-range-thumb),
|
|
@@ -4466,22 +4607,11 @@
|
|
|
4466
4607
|
|
|
4467
4608
|
:where(ui-range):hover::after,
|
|
4468
4609
|
:where(ui-range)[force-hover]::after {
|
|
4469
|
-
background: var(--accent-surface-hover);
|
|
4470
|
-
}
|
|
4471
|
-
|
|
4472
|
-
:where(ui-range)[intent]:hover::after,
|
|
4473
|
-
:where(ui-range)[intent][force-hover]::after {
|
|
4474
4610
|
background: var(--_surface-hover);
|
|
4475
4611
|
}
|
|
4476
4612
|
|
|
4477
4613
|
:where(ui-range):hover > :where(.ui-range-thumb),
|
|
4478
4614
|
:where(ui-range)[force-hover] > :where(.ui-range-thumb) {
|
|
4479
|
-
border-color: var(--accent-surface-hover);
|
|
4480
|
-
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--accent-surface);
|
|
4481
|
-
}
|
|
4482
|
-
|
|
4483
|
-
:where(ui-range)[intent]:hover > :where(.ui-range-thumb),
|
|
4484
|
-
:where(ui-range)[intent][force-hover] > :where(.ui-range-thumb) {
|
|
4485
4615
|
border-color: var(--_surface-hover);
|
|
4486
4616
|
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--_surface);
|
|
4487
4617
|
}
|
|
@@ -4489,19 +4619,10 @@
|
|
|
4489
4619
|
/* ── Active (dragging) ── */
|
|
4490
4620
|
|
|
4491
4621
|
:where(ui-range)[pressed]::after {
|
|
4492
|
-
background: var(--accent-surface-active);
|
|
4493
|
-
}
|
|
4494
|
-
|
|
4495
|
-
:where(ui-range)[intent][pressed]::after {
|
|
4496
4622
|
background: var(--_surface-active);
|
|
4497
4623
|
}
|
|
4498
4624
|
|
|
4499
4625
|
:where(ui-range)[pressed] > :where(.ui-range-thumb) {
|
|
4500
|
-
border-color: var(--accent-surface-active);
|
|
4501
|
-
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--accent-surface);
|
|
4502
|
-
}
|
|
4503
|
-
|
|
4504
|
-
:where(ui-range)[intent][pressed] > :where(.ui-range-thumb) {
|
|
4505
4626
|
border-color: var(--_surface-active);
|
|
4506
4627
|
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--_surface);
|
|
4507
4628
|
}
|
|
@@ -5056,22 +5177,13 @@
|
|
|
5056
5177
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
5057
5178
|
|
|
5058
5179
|
:where(ui-switch)[aria-checked="true"]::before {
|
|
5059
|
-
background: var(--
|
|
5060
|
-
border-color: var(--
|
|
5180
|
+
background: var(--_surface);
|
|
5181
|
+
border-color: var(--_surface);
|
|
5061
5182
|
}
|
|
5062
5183
|
|
|
5063
5184
|
:where(ui-switch)[aria-checked="true"]::after {
|
|
5064
5185
|
/* Slide thumb to the right via translateX — GPU composited */
|
|
5065
5186
|
transform: translateY(-50%) translateX(calc(var(--_track-width) - var(--_thumb-size) - var(--_thumb-offset) * 2));
|
|
5066
|
-
background: var(--accent-surface-ink);
|
|
5067
|
-
}
|
|
5068
|
-
|
|
5069
|
-
:where(ui-switch)[intent][aria-checked="true"]::before {
|
|
5070
|
-
background: var(--_surface);
|
|
5071
|
-
border-color: var(--_surface);
|
|
5072
|
-
}
|
|
5073
|
-
|
|
5074
|
-
:where(ui-switch)[intent][aria-checked="true"]::after {
|
|
5075
5187
|
background: var(--_surface-ink);
|
|
5076
5188
|
}
|
|
5077
5189
|
|
|
@@ -5090,12 +5202,6 @@
|
|
|
5090
5202
|
|
|
5091
5203
|
:where(ui-switch)[aria-checked="true"]:hover::before,
|
|
5092
5204
|
:where(ui-switch)[aria-checked="true"][force-hover]::before {
|
|
5093
|
-
background: var(--accent-surface-hover);
|
|
5094
|
-
border-color: var(--accent-surface-hover);
|
|
5095
|
-
}
|
|
5096
|
-
|
|
5097
|
-
:where(ui-switch)[intent][aria-checked="true"]:hover::before,
|
|
5098
|
-
:where(ui-switch)[intent][aria-checked="true"][force-hover]::before {
|
|
5099
5205
|
background: var(--_surface-hover);
|
|
5100
5206
|
border-color: var(--_surface-hover);
|
|
5101
5207
|
}
|
|
@@ -5108,11 +5214,6 @@
|
|
|
5108
5214
|
}
|
|
5109
5215
|
|
|
5110
5216
|
:where(ui-switch)[aria-checked="true"][pressed]::before {
|
|
5111
|
-
background: var(--accent-surface-active);
|
|
5112
|
-
border-color: var(--accent-surface-active);
|
|
5113
|
-
}
|
|
5114
|
-
|
|
5115
|
-
:where(ui-switch)[intent][aria-checked="true"][pressed]::before {
|
|
5116
5217
|
background: var(--_surface-active);
|
|
5117
5218
|
border-color: var(--_surface-active);
|
|
5118
5219
|
}
|
|
@@ -6572,7 +6673,7 @@
|
|
|
6572
6673
|
|
|
6573
6674
|
:where(ui-layout-chat) :where(.layout-resize-handle):hover,
|
|
6574
6675
|
:where(ui-layout-chat[resizing]) :where(.layout-resize-handle) {
|
|
6575
|
-
background: var(--
|
|
6676
|
+
background: var(--_border-muted);
|
|
6576
6677
|
}
|
|
6577
6678
|
|
|
6578
6679
|
}
|
|
@@ -6634,7 +6735,7 @@
|
|
|
6634
6735
|
|
|
6635
6736
|
:where(ui-layout-inspector) :where(.layout-resize-handle):hover,
|
|
6636
6737
|
:where(ui-layout-inspector[resizing]) :where(.layout-resize-handle) {
|
|
6637
|
-
background: var(--
|
|
6738
|
+
background: var(--_border-muted);
|
|
6638
6739
|
}
|
|
6639
6740
|
|
|
6640
6741
|
}
|
|
@@ -6661,16 +6762,16 @@
|
|
|
6661
6762
|
content: '';
|
|
6662
6763
|
width: var(--ui-layout-sidebar-width);
|
|
6663
6764
|
flex-shrink: 0;
|
|
6664
|
-
background: var(--
|
|
6665
|
-
border-right: 1px solid var(--
|
|
6765
|
+
background: var(--_body);
|
|
6766
|
+
border-right: 1px solid var(--_border-muted);
|
|
6666
6767
|
}
|
|
6667
6768
|
|
|
6668
6769
|
:where(ui-layout-sidebar):not([data-ready])[collapsed]::before {
|
|
6669
6770
|
content: '';
|
|
6670
6771
|
width: 48px;
|
|
6671
6772
|
flex-shrink: 0;
|
|
6672
|
-
background: var(--
|
|
6673
|
-
border-right: 1px solid var(--
|
|
6773
|
+
background: var(--_body);
|
|
6774
|
+
border-right: 1px solid var(--_border-muted);
|
|
6674
6775
|
}
|
|
6675
6776
|
|
|
6676
6777
|
/* ── Content Column ── */
|
|
@@ -6686,16 +6787,23 @@
|
|
|
6686
6787
|
}
|
|
6687
6788
|
|
|
6688
6789
|
/* ── Sidebar Aside ── */
|
|
6790
|
+
/* WHY: position: relative creates the containing block for absolute
|
|
6791
|
+
header/footer overlays. Content fills the full height and scrolls
|
|
6792
|
+
underneath the pinned header/footer. */
|
|
6689
6793
|
|
|
6690
6794
|
:where(ui-layout-sidebar) > :where([slot="sidebar"]) {
|
|
6795
|
+
--_sidebar-header-height: 0px;
|
|
6796
|
+
--_sidebar-footer-height: 0px;
|
|
6797
|
+
|
|
6798
|
+
container-name: sidebar;
|
|
6799
|
+
container-type: inline-size;
|
|
6800
|
+
position: sticky;
|
|
6801
|
+
top: 0;
|
|
6691
6802
|
width: var(--ui-layout-sidebar-width);
|
|
6692
6803
|
min-width: 160px;
|
|
6693
6804
|
max-width: 400px;
|
|
6694
6805
|
height: 100dvh;
|
|
6695
|
-
|
|
6696
|
-
top: 0;
|
|
6697
|
-
display: flex;
|
|
6698
|
-
flex-direction: column;
|
|
6806
|
+
display: block;
|
|
6699
6807
|
transition: width var(--_duration) var(--_easing), min-width var(--_duration) var(--_easing);
|
|
6700
6808
|
overflow: hidden;
|
|
6701
6809
|
z-index: 10;
|
|
@@ -6707,7 +6815,9 @@
|
|
|
6707
6815
|
}
|
|
6708
6816
|
|
|
6709
6817
|
/* ── Collapsed Icon Rail ── */
|
|
6710
|
-
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
6818
|
+
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
6819
|
+
[collapsed] drives the aside to 48px which triggers @container sidebar queries
|
|
6820
|
+
in this file and in child component CSS (ui-nav.css, etc.). */
|
|
6711
6821
|
|
|
6712
6822
|
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) {
|
|
6713
6823
|
width: 48px;
|
|
@@ -6728,11 +6838,7 @@
|
|
|
6728
6838
|
|
|
6729
6839
|
:where(ui-layout-sidebar) :where(.layout-resize-handle):hover,
|
|
6730
6840
|
:where(ui-layout-sidebar) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
|
|
6731
|
-
background: var(--
|
|
6732
|
-
}
|
|
6733
|
-
|
|
6734
|
-
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) :where(.layout-resize-handle) {
|
|
6735
|
-
display: none;
|
|
6841
|
+
background: var(--_border-muted);
|
|
6736
6842
|
}
|
|
6737
6843
|
|
|
6738
6844
|
/* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
|
|
@@ -6745,101 +6851,89 @@
|
|
|
6745
6851
|
padding-left: 0;
|
|
6746
6852
|
}
|
|
6747
6853
|
|
|
6748
|
-
/* ── Collapsed Icon-Rail Content ── */
|
|
6749
|
-
/* WHY: When collapsed, sidebar slot becomes a narrow icon rail.
|
|
6750
|
-
Text and trailing slots are hidden; only icons remain visible.
|
|
6751
|
-
Nav items hide entirely — only group headers (with icons) stay. */
|
|
6752
|
-
|
|
6753
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-content) {
|
|
6754
|
-
align-items: center;
|
|
6755
|
-
padding: 0.5rem;
|
|
6756
|
-
}
|
|
6757
|
-
|
|
6758
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-header),
|
|
6759
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-footer) {
|
|
6760
|
-
justify-content: center;
|
|
6761
|
-
padding-inline: 0.5rem;
|
|
6762
|
-
}
|
|
6763
|
-
|
|
6764
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-trigger) :where([slot="label"]),
|
|
6765
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-trigger) :where([slot="trailing"]) {
|
|
6766
|
-
display: none;
|
|
6767
|
-
}
|
|
6768
|
-
|
|
6769
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-item) {
|
|
6770
|
-
display: none;
|
|
6771
|
-
}
|
|
6772
|
-
|
|
6773
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) > :where(details) > :where(summary) {
|
|
6774
|
-
justify-content: center;
|
|
6775
|
-
}
|
|
6776
|
-
|
|
6777
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
6778
|
-
display: none;
|
|
6779
|
-
}
|
|
6780
|
-
|
|
6781
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group)::after,
|
|
6782
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group)::before {
|
|
6783
|
-
display: none;
|
|
6784
|
-
}
|
|
6785
|
-
|
|
6786
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group-header) {
|
|
6787
|
-
justify-content: center;
|
|
6788
|
-
font-size: 0;
|
|
6789
|
-
gap: 0;
|
|
6790
|
-
}
|
|
6791
|
-
|
|
6792
|
-
/* WHY: Icon keeps its size even though parent font-size is 0. */
|
|
6793
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group-header) :where(ui-icon) {
|
|
6794
|
-
font-size: var(--_font-size, 1rem);
|
|
6795
|
-
}
|
|
6796
|
-
|
|
6797
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) + :where(ui-nav-group) {
|
|
6798
|
-
margin-block-start: 0;
|
|
6799
|
-
}
|
|
6800
|
-
|
|
6801
6854
|
/* ── Sidebar Header ── */
|
|
6855
|
+
/* WHY: Absolute-positioned overlay pinned to top of aside. Content scrolls
|
|
6856
|
+
underneath it. z-index: 2 sits above content (z-index: 0). */
|
|
6802
6857
|
|
|
6803
6858
|
:where(ui-layout-sidebar-header) {
|
|
6859
|
+
position: absolute;
|
|
6860
|
+
top: 0;
|
|
6861
|
+
left: 0;
|
|
6862
|
+
right: 0;
|
|
6863
|
+
z-index: 2;
|
|
6804
6864
|
display: flex;
|
|
6805
|
-
|
|
6806
|
-
min-height: var(--ui-layout-bar-height);
|
|
6807
|
-
gap: calc(var(--_space) * 2);
|
|
6808
|
-
padding-block: var(--_space);
|
|
6809
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6810
|
-
flex-shrink: 0;
|
|
6865
|
+
flex-direction: column;
|
|
6811
6866
|
}
|
|
6812
6867
|
|
|
6813
6868
|
/* ── Sidebar Content ── */
|
|
6869
|
+
/* WHY: Full height of the aside, scrollable. Padding-block offsets keep
|
|
6870
|
+
content from starting behind header / ending behind footer.
|
|
6871
|
+
Fade-out alpha mask dissolves content edges under the overlays. */
|
|
6814
6872
|
|
|
6815
6873
|
:where(ui-layout-sidebar-content) {
|
|
6816
6874
|
display: flex;
|
|
6817
6875
|
flex-direction: column;
|
|
6818
|
-
|
|
6819
|
-
padding-block: var(--
|
|
6820
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6821
|
-
flex: 1;
|
|
6822
|
-
min-height: 0;
|
|
6876
|
+
padding-block-start: var(--_sidebar-header-height);
|
|
6877
|
+
padding-block-end: var(--_sidebar-footer-height);
|
|
6823
6878
|
width: 100%;
|
|
6879
|
+
height: 100%;
|
|
6880
|
+
overflow-y: auto;
|
|
6881
|
+
scrollbar-width: none;
|
|
6882
|
+
}
|
|
6883
|
+
|
|
6884
|
+
/* WHY: When header is present, fade top edge. Content dissolves as it
|
|
6885
|
+
scrolls under the header — transparent at top, fully visible by 1.25×
|
|
6886
|
+
the header height. No opaque header background needed. */
|
|
6887
|
+
:where(ui-layout-sidebar-content)[data-has-header] {
|
|
6888
|
+
mask-image: linear-gradient(
|
|
6889
|
+
to bottom,
|
|
6890
|
+
transparent 0,
|
|
6891
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
6892
|
+
black 100%
|
|
6893
|
+
);
|
|
6894
|
+
}
|
|
6895
|
+
|
|
6896
|
+
/* WHY: When footer is present, fade bottom edge. */
|
|
6897
|
+
:where(ui-layout-sidebar-content)[data-has-footer] {
|
|
6898
|
+
mask-image: linear-gradient(
|
|
6899
|
+
to bottom,
|
|
6900
|
+
black 0,
|
|
6901
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
6902
|
+
transparent 100%
|
|
6903
|
+
);
|
|
6904
|
+
}
|
|
6905
|
+
|
|
6906
|
+
/* WHY: When both header AND footer are present, fade both edges. */
|
|
6907
|
+
:where(ui-layout-sidebar-content)[data-has-header][data-has-footer] {
|
|
6908
|
+
mask-image: linear-gradient(
|
|
6909
|
+
to bottom,
|
|
6910
|
+
transparent 0,
|
|
6911
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
6912
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
6913
|
+
transparent 100%
|
|
6914
|
+
);
|
|
6824
6915
|
}
|
|
6825
6916
|
|
|
6826
6917
|
/* ── Sidebar Footer ── */
|
|
6918
|
+
/* WHY: Absolute-positioned overlay pinned to bottom of aside. */
|
|
6827
6919
|
|
|
6828
6920
|
:where(ui-layout-sidebar-footer) {
|
|
6921
|
+
position: absolute;
|
|
6922
|
+
bottom: 0;
|
|
6923
|
+
left: 0;
|
|
6924
|
+
right: 0;
|
|
6925
|
+
z-index: 2;
|
|
6829
6926
|
display: flex;
|
|
6830
|
-
|
|
6831
|
-
min-height: var(--ui-layout-bar-height);
|
|
6832
|
-
gap: calc(var(--_space) * 2);
|
|
6833
|
-
padding-block: var(--_space);
|
|
6834
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6835
|
-
flex-shrink: 0;
|
|
6927
|
+
flex-direction: column;
|
|
6836
6928
|
}
|
|
6837
6929
|
|
|
6838
|
-
/* ── Sidebar
|
|
6839
|
-
/* WHY:
|
|
6840
|
-
|
|
6930
|
+
/* ── Sidebar Item ── */
|
|
6931
|
+
/* WHY: Universal sidebar row element. Provides inline padding for any content
|
|
6932
|
+
(buttons, links, icons). When a child ui-listbox[popover] is present, JS
|
|
6933
|
+
wires PopoverController for click-to-toggle menu behavior.
|
|
6934
|
+
Absorbs the old ui-layout-sidebar-trigger role — one element for all rows. */
|
|
6841
6935
|
|
|
6842
|
-
:where(ui-layout-sidebar-
|
|
6936
|
+
:where(ui-layout-sidebar-item) {
|
|
6843
6937
|
display: flex;
|
|
6844
6938
|
align-items: center;
|
|
6845
6939
|
flex: 1;
|
|
@@ -6855,31 +6949,61 @@
|
|
|
6855
6949
|
user-select: none;
|
|
6856
6950
|
border: none;
|
|
6857
6951
|
background: none;
|
|
6858
|
-
padding: var(--_space);
|
|
6952
|
+
padding-block: var(--_space);
|
|
6953
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6859
6954
|
border-radius: var(--_radius);
|
|
6860
6955
|
transition: color var(--_duration) var(--_easing);
|
|
6861
6956
|
}
|
|
6862
6957
|
|
|
6863
|
-
:
|
|
6864
|
-
|
|
6958
|
+
/* WHY: Items in header/footer match the breadcrumb bar height so the
|
|
6959
|
+
first sidebar row aligns horizontally with the breadcrumb. */
|
|
6960
|
+
:where(ui-layout-sidebar-header) > :where(ui-layout-sidebar-item),
|
|
6961
|
+
:where(ui-layout-sidebar-footer) > :where(ui-layout-sidebar-item) {
|
|
6962
|
+
min-height: var(--ui-layout-bar-height);
|
|
6963
|
+
}
|
|
6964
|
+
|
|
6965
|
+
:where(ui-layout-sidebar-item):hover,
|
|
6966
|
+
:where(ui-layout-sidebar-item)[force-hover] {
|
|
6865
6967
|
color: var(--_ink-strong);
|
|
6866
6968
|
}
|
|
6867
6969
|
|
|
6868
|
-
:where(ui-layout-sidebar-
|
|
6869
|
-
:where(ui-layout-sidebar-
|
|
6970
|
+
:where(ui-layout-sidebar-item):focus-visible,
|
|
6971
|
+
:where(ui-layout-sidebar-item)[force-focus-visible] {
|
|
6870
6972
|
outline: 2px solid var(--ui-focus-ring);
|
|
6871
6973
|
outline-offset: -2px;
|
|
6872
6974
|
}
|
|
6873
6975
|
|
|
6976
|
+
/* WHY: Fixed-size icon well so all sidebar icons (header logo, nav group icons,
|
|
6977
|
+
standalone icons) center-align on the same column width regardless of intrinsic
|
|
6978
|
+
icon size. 1.5rem matches the sidebar's visual rhythm at default density.
|
|
6979
|
+
Consumer wraps the icon: <span slot="icon"><ui-icon name="..."></ui-icon></span>
|
|
6980
|
+
The wrapper is the well; the icon keeps its own --ui-icon-size dimensions. */
|
|
6981
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
6982
|
+
display: inline-flex;
|
|
6983
|
+
align-items: center;
|
|
6984
|
+
justify-content: center;
|
|
6985
|
+
width: 1.5rem;
|
|
6986
|
+
height: 1.5rem;
|
|
6987
|
+
flex-shrink: 0;
|
|
6988
|
+
}
|
|
6989
|
+
|
|
6874
6990
|
/* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
|
|
6875
|
-
:where(ui-layout-sidebar-
|
|
6991
|
+
:where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
|
|
6876
6992
|
margin-inline-start: auto;
|
|
6877
6993
|
flex-shrink: 0;
|
|
6878
6994
|
color: var(--_ink-muted);
|
|
6879
6995
|
}
|
|
6880
6996
|
|
|
6997
|
+
/* WHY: When the item wraps a sub-component (e.g. ui-button) that provides
|
|
6998
|
+
its own icon, hide [slot="icon"] in expanded mode — it only serves as the
|
|
6999
|
+
bare collapsed-rail representation. Items without sub-components (just
|
|
7000
|
+
icon + label + trailing) keep [slot="icon"] visible in both modes. */
|
|
7001
|
+
:where(ui-layout-sidebar-item:has(> ui-button)) > :where([slot="icon"]) {
|
|
7002
|
+
display: none;
|
|
7003
|
+
}
|
|
7004
|
+
|
|
6881
7005
|
/* WHY: Title text truncates when sidebar narrows during resize. */
|
|
6882
|
-
:where(ui-layout-sidebar-
|
|
7006
|
+
:where(ui-layout-sidebar-item) > :where([slot="label"]) {
|
|
6883
7007
|
flex: 1;
|
|
6884
7008
|
min-width: 0;
|
|
6885
7009
|
white-space: nowrap;
|
|
@@ -6887,25 +7011,67 @@
|
|
|
6887
7011
|
text-overflow: ellipsis;
|
|
6888
7012
|
}
|
|
6889
7013
|
|
|
6890
|
-
/* ──
|
|
6891
|
-
/* WHY: Popover opens to the right of the sidebar
|
|
7014
|
+
/* ── Item Popover ── */
|
|
7015
|
+
/* WHY: Popover opens to the right of the sidebar item.
|
|
6892
7016
|
Default: top-aligned, grows downward (span-block-end).
|
|
6893
7017
|
Flip: bottom-aligned, grows upward (span-block-start). */
|
|
6894
7018
|
|
|
6895
|
-
:where(ui-layout-sidebar-
|
|
7019
|
+
:where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
|
|
6896
7020
|
position: fixed;
|
|
6897
7021
|
position-area: inline-end span-block-end;
|
|
6898
|
-
position-try-fallbacks: --flip-up;
|
|
7022
|
+
position-try-fallbacks: --sidebar-item-flip-up;
|
|
6899
7023
|
margin: 0 0 0 var(--ui-popover-gap);
|
|
6900
7024
|
min-width: 200px;
|
|
6901
7025
|
max-height: var(--ui-popover-max-height);
|
|
6902
7026
|
overflow-y: auto;
|
|
6903
7027
|
}
|
|
6904
7028
|
|
|
6905
|
-
@position-try --flip-up {
|
|
7029
|
+
@position-try --sidebar-item-flip-up {
|
|
6906
7030
|
position-area: inline-end span-block-start;
|
|
6907
7031
|
}
|
|
6908
7032
|
|
|
7033
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
7034
|
+
/* WHY: Each component owns its own collapsed behavior via @container.
|
|
7035
|
+
The aside is the container (container-name: sidebar). When it shrinks
|
|
7036
|
+
to 48px (icon rail), components respond to the width, not to [collapsed].
|
|
7037
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
7038
|
+
|
|
7039
|
+
@container sidebar (max-width: 80px) {
|
|
7040
|
+
|
|
7041
|
+
/* Resize handle — no dragging in icon rail */
|
|
7042
|
+
:where(.layout-resize-handle) {
|
|
7043
|
+
display: none;
|
|
7044
|
+
}
|
|
7045
|
+
|
|
7046
|
+
/* Header/footer — center content horizontally */
|
|
7047
|
+
:where(ui-layout-sidebar-header),
|
|
7048
|
+
:where(ui-layout-sidebar-footer) {
|
|
7049
|
+
align-items: center;
|
|
7050
|
+
}
|
|
7051
|
+
|
|
7052
|
+
/* Content — center items in the 48px rail */
|
|
7053
|
+
:where(ui-layout-sidebar-content) {
|
|
7054
|
+
align-items: center;
|
|
7055
|
+
}
|
|
7056
|
+
|
|
7057
|
+
/* Item — shrink to icon-only. Show [slot="icon"], hide everything else.
|
|
7058
|
+
WHY: Sidebar items can contain complex children (buttons with slots,
|
|
7059
|
+
links, etc.). Rather than overriding sub-component styles, the item
|
|
7060
|
+
provides its own bare icon via [slot="icon"] for the collapsed rail. */
|
|
7061
|
+
:where(ui-layout-sidebar-item) {
|
|
7062
|
+
flex: 0 0 auto;
|
|
7063
|
+
padding-inline: var(--_space);
|
|
7064
|
+
}
|
|
7065
|
+
|
|
7066
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
7067
|
+
display: inline-flex;
|
|
7068
|
+
}
|
|
7069
|
+
|
|
7070
|
+
:where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
|
|
7071
|
+
display: none;
|
|
7072
|
+
}
|
|
7073
|
+
}
|
|
7074
|
+
|
|
6909
7075
|
}
|
|
6910
7076
|
|
|
6911
7077
|
@layer ui {
|