@nonoun/native-ui 0.2.3 → 0.2.5
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-lean.css +288 -169
- package/dist/components.css +290 -176
- 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 +2892 -2484
- 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 +367 -170
- package/dist/native-ui.css +369 -177
- package/dist/native-ui.js +3 -6
- package/dist/register-all.js +1 -1
- package/dist/ui-icon-element.js +95 -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.25rem;
|
|
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;
|
|
@@ -4071,8 +4161,11 @@
|
|
|
4071
4161
|
/* WHY: Connector draws from below the header to the bottom of the group.
|
|
4072
4162
|
Only shown when header contains an icon. Scoped via :has(). */
|
|
4073
4163
|
|
|
4164
|
+
/* WHY: Insets account for the summary's padding-inline so the connector
|
|
4165
|
+
line passes through the icon center and child text aligns with header text. */
|
|
4074
4166
|
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)) {
|
|
4075
|
-
--_group-
|
|
4167
|
+
--_group-pad: calc(var(--_space-k) * var(--_space));
|
|
4168
|
+
--_group-line-inset: calc(var(--_group-pad) + var(--_icon-size) / 2);
|
|
4076
4169
|
--_group-child-inset: calc(var(--_icon-size) + var(--_space) * 2);
|
|
4077
4170
|
}
|
|
4078
4171
|
|
|
@@ -4118,6 +4211,73 @@
|
|
|
4118
4211
|
margin-inline-start: var(--_group-child-inset, 0);
|
|
4119
4212
|
}
|
|
4120
4213
|
|
|
4214
|
+
/* ── Nav Group Flyout (collapsed sidebar) ── */
|
|
4215
|
+
/* WHY: In collapsed mode, summary click opens a ui-listbox popover to the right
|
|
4216
|
+
instead of expanding the <details>. Same pattern as sidebar-trigger menus. */
|
|
4217
|
+
|
|
4218
|
+
:where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
|
|
4219
|
+
position: fixed;
|
|
4220
|
+
position-area: inline-end span-block-end;
|
|
4221
|
+
position-try-fallbacks: --nav-flyout-flip-up;
|
|
4222
|
+
margin: 0 0 0 var(--ui-popover-gap);
|
|
4223
|
+
min-width: 200px;
|
|
4224
|
+
max-height: var(--ui-popover-max-height);
|
|
4225
|
+
overflow-y: auto;
|
|
4226
|
+
}
|
|
4227
|
+
|
|
4228
|
+
@position-try --nav-flyout-flip-up {
|
|
4229
|
+
position-area: inline-end span-block-start;
|
|
4230
|
+
}
|
|
4231
|
+
|
|
4232
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
4233
|
+
/* WHY: Nav components own their own collapsed behavior via @container.
|
|
4234
|
+
The sidebar aside declares container-name: sidebar. When it shrinks
|
|
4235
|
+
to 48px (icon rail), nav responds to the width — not to [collapsed].
|
|
4236
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
4237
|
+
|
|
4238
|
+
@container sidebar (max-width: 80px) {
|
|
4239
|
+
|
|
4240
|
+
/* Nav items hide entirely — only group headers (with icons) remain. */
|
|
4241
|
+
:where(ui-nav-item) {
|
|
4242
|
+
display: none;
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
/* Summary shrinks to icon-only. Reduced inline padding wraps tightly
|
|
4246
|
+
around the icon; parent align-items: center handles horizontal centering. */
|
|
4247
|
+
:where(ui-nav-group) > :where(details) > :where(summary) {
|
|
4248
|
+
padding-inline: var(--_space);
|
|
4249
|
+
border-radius: var(--_radius);
|
|
4250
|
+
}
|
|
4251
|
+
|
|
4252
|
+
/* Hide chevron — no expand/collapse in icon rail (flyout instead). */
|
|
4253
|
+
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
4254
|
+
display: none;
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4257
|
+
/* Hide vertical connector line and sliding indicator. */
|
|
4258
|
+
:where(ui-nav-group)::after,
|
|
4259
|
+
:where(ui-nav-group)::before {
|
|
4260
|
+
display: none;
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
/* Header collapses to icon-only. font-size: 0 hides text nodes
|
|
4264
|
+
(can't be targeted by CSS). Icon overrides back to normal below. */
|
|
4265
|
+
:where(ui-nav-group-header) {
|
|
4266
|
+
flex: 0 0 auto;
|
|
4267
|
+
font-size: 0;
|
|
4268
|
+
gap: 0;
|
|
4269
|
+
}
|
|
4270
|
+
|
|
4271
|
+
:where(ui-nav-group-header) :where(ui-icon) {
|
|
4272
|
+
font-size: var(--_font-size, 1rem);
|
|
4273
|
+
}
|
|
4274
|
+
|
|
4275
|
+
/* Collapse inter-group spacing in icon rail. */
|
|
4276
|
+
:where(ui-nav-group) + :where(ui-nav-group) {
|
|
4277
|
+
margin-block-start: 0;
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
|
|
4121
4281
|
}
|
|
4122
4282
|
|
|
4123
4283
|
@layer ui {
|
|
@@ -4258,27 +4418,15 @@
|
|
|
4258
4418
|
}
|
|
4259
4419
|
|
|
4260
4420
|
/* ── 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
4421
|
|
|
4265
4422
|
: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
4423
|
background: var(--_surface);
|
|
4277
4424
|
border-color: var(--_surface);
|
|
4278
4425
|
}
|
|
4279
4426
|
|
|
4280
|
-
:where(ui-radio
|
|
4427
|
+
:where(ui-radio)[aria-checked="true"]::after {
|
|
4281
4428
|
background: var(--_surface-ink);
|
|
4429
|
+
transform: translateY(-50%) scale(1);
|
|
4282
4430
|
}
|
|
4283
4431
|
|
|
4284
4432
|
/* ── Hover ── */
|
|
@@ -4296,12 +4444,6 @@
|
|
|
4296
4444
|
|
|
4297
4445
|
:where(ui-radio)[aria-checked="true"]:hover::before,
|
|
4298
4446
|
: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
4447
|
background: var(--_surface-hover);
|
|
4306
4448
|
border-color: var(--_surface-hover);
|
|
4307
4449
|
}
|
|
@@ -4314,11 +4456,6 @@
|
|
|
4314
4456
|
}
|
|
4315
4457
|
|
|
4316
4458
|
: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
4459
|
background: var(--_surface-active);
|
|
4323
4460
|
border-color: var(--_surface-active);
|
|
4324
4461
|
}
|
|
@@ -4417,16 +4554,12 @@
|
|
|
4417
4554
|
/* 0% = track-height (circle), 100% = full width */
|
|
4418
4555
|
width: calc(var(--_track-height) + (100% - var(--_track-height)) * var(--_progress));
|
|
4419
4556
|
border-radius: calc(var(--_track-height) / 2);
|
|
4420
|
-
background: var(--
|
|
4557
|
+
background: var(--_surface);
|
|
4421
4558
|
|
|
4422
4559
|
transition:
|
|
4423
4560
|
background var(--_duration) var(--_easing);
|
|
4424
4561
|
}
|
|
4425
4562
|
|
|
4426
|
-
:where(ui-range)[intent]::after {
|
|
4427
|
-
background: var(--_surface);
|
|
4428
|
-
}
|
|
4429
|
-
|
|
4430
4563
|
/* ── Thumb ── */
|
|
4431
4564
|
|
|
4432
4565
|
:where(ui-range) > :where(.ui-range-thumb) {
|
|
@@ -4438,8 +4571,8 @@
|
|
|
4438
4571
|
width: var(--_thumb-size);
|
|
4439
4572
|
height: var(--_thumb-size);
|
|
4440
4573
|
border-radius: 50%;
|
|
4441
|
-
background: var(--
|
|
4442
|
-
border: 2px solid var(--
|
|
4574
|
+
background: var(--_surface-ink);
|
|
4575
|
+
border: 2px solid var(--_surface);
|
|
4443
4576
|
box-shadow: var(--ui-shadow-sm);
|
|
4444
4577
|
pointer-events: none;
|
|
4445
4578
|
|
|
@@ -4449,11 +4582,6 @@
|
|
|
4449
4582
|
border-color var(--_duration) var(--_easing);
|
|
4450
4583
|
}
|
|
4451
4584
|
|
|
4452
|
-
:where(ui-range)[intent] > :where(.ui-range-thumb) {
|
|
4453
|
-
background: var(--_surface-ink);
|
|
4454
|
-
border-color: var(--_surface);
|
|
4455
|
-
}
|
|
4456
|
-
|
|
4457
4585
|
/* ── Focus ── */
|
|
4458
4586
|
|
|
4459
4587
|
:where(ui-range):focus-visible > :where(.ui-range-thumb),
|
|
@@ -4466,22 +4594,11 @@
|
|
|
4466
4594
|
|
|
4467
4595
|
:where(ui-range):hover::after,
|
|
4468
4596
|
: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
4597
|
background: var(--_surface-hover);
|
|
4475
4598
|
}
|
|
4476
4599
|
|
|
4477
4600
|
:where(ui-range):hover > :where(.ui-range-thumb),
|
|
4478
4601
|
: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
4602
|
border-color: var(--_surface-hover);
|
|
4486
4603
|
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--_surface);
|
|
4487
4604
|
}
|
|
@@ -4489,19 +4606,10 @@
|
|
|
4489
4606
|
/* ── Active (dragging) ── */
|
|
4490
4607
|
|
|
4491
4608
|
:where(ui-range)[pressed]::after {
|
|
4492
|
-
background: var(--accent-surface-active);
|
|
4493
|
-
}
|
|
4494
|
-
|
|
4495
|
-
:where(ui-range)[intent][pressed]::after {
|
|
4496
4609
|
background: var(--_surface-active);
|
|
4497
4610
|
}
|
|
4498
4611
|
|
|
4499
4612
|
: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
4613
|
border-color: var(--_surface-active);
|
|
4506
4614
|
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--_surface);
|
|
4507
4615
|
}
|
|
@@ -5056,22 +5164,13 @@
|
|
|
5056
5164
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
5057
5165
|
|
|
5058
5166
|
:where(ui-switch)[aria-checked="true"]::before {
|
|
5059
|
-
background: var(--
|
|
5060
|
-
border-color: var(--
|
|
5167
|
+
background: var(--_surface);
|
|
5168
|
+
border-color: var(--_surface);
|
|
5061
5169
|
}
|
|
5062
5170
|
|
|
5063
5171
|
:where(ui-switch)[aria-checked="true"]::after {
|
|
5064
5172
|
/* Slide thumb to the right via translateX — GPU composited */
|
|
5065
5173
|
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
5174
|
background: var(--_surface-ink);
|
|
5076
5175
|
}
|
|
5077
5176
|
|
|
@@ -5090,12 +5189,6 @@
|
|
|
5090
5189
|
|
|
5091
5190
|
:where(ui-switch)[aria-checked="true"]:hover::before,
|
|
5092
5191
|
: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
5192
|
background: var(--_surface-hover);
|
|
5100
5193
|
border-color: var(--_surface-hover);
|
|
5101
5194
|
}
|
|
@@ -5108,11 +5201,6 @@
|
|
|
5108
5201
|
}
|
|
5109
5202
|
|
|
5110
5203
|
: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
5204
|
background: var(--_surface-active);
|
|
5117
5205
|
border-color: var(--_surface-active);
|
|
5118
5206
|
}
|
|
@@ -6572,7 +6660,7 @@
|
|
|
6572
6660
|
|
|
6573
6661
|
:where(ui-layout-chat) :where(.layout-resize-handle):hover,
|
|
6574
6662
|
:where(ui-layout-chat[resizing]) :where(.layout-resize-handle) {
|
|
6575
|
-
background: var(--
|
|
6663
|
+
background: var(--_border-muted);
|
|
6576
6664
|
}
|
|
6577
6665
|
|
|
6578
6666
|
}
|
|
@@ -6634,7 +6722,7 @@
|
|
|
6634
6722
|
|
|
6635
6723
|
:where(ui-layout-inspector) :where(.layout-resize-handle):hover,
|
|
6636
6724
|
:where(ui-layout-inspector[resizing]) :where(.layout-resize-handle) {
|
|
6637
|
-
background: var(--
|
|
6725
|
+
background: var(--_border-muted);
|
|
6638
6726
|
}
|
|
6639
6727
|
|
|
6640
6728
|
}
|
|
@@ -6661,16 +6749,16 @@
|
|
|
6661
6749
|
content: '';
|
|
6662
6750
|
width: var(--ui-layout-sidebar-width);
|
|
6663
6751
|
flex-shrink: 0;
|
|
6664
|
-
background: var(--
|
|
6665
|
-
border-right: 1px solid var(--
|
|
6752
|
+
background: var(--_body);
|
|
6753
|
+
border-right: 1px solid var(--_border-muted);
|
|
6666
6754
|
}
|
|
6667
6755
|
|
|
6668
6756
|
:where(ui-layout-sidebar):not([data-ready])[collapsed]::before {
|
|
6669
6757
|
content: '';
|
|
6670
6758
|
width: 48px;
|
|
6671
6759
|
flex-shrink: 0;
|
|
6672
|
-
background: var(--
|
|
6673
|
-
border-right: 1px solid var(--
|
|
6760
|
+
background: var(--_body);
|
|
6761
|
+
border-right: 1px solid var(--_border-muted);
|
|
6674
6762
|
}
|
|
6675
6763
|
|
|
6676
6764
|
/* ── Content Column ── */
|
|
@@ -6686,16 +6774,23 @@
|
|
|
6686
6774
|
}
|
|
6687
6775
|
|
|
6688
6776
|
/* ── Sidebar Aside ── */
|
|
6777
|
+
/* WHY: position: relative creates the containing block for absolute
|
|
6778
|
+
header/footer overlays. Content fills the full height and scrolls
|
|
6779
|
+
underneath the pinned header/footer. */
|
|
6689
6780
|
|
|
6690
6781
|
:where(ui-layout-sidebar) > :where([slot="sidebar"]) {
|
|
6782
|
+
--_sidebar-header-height: 0px;
|
|
6783
|
+
--_sidebar-footer-height: 0px;
|
|
6784
|
+
|
|
6785
|
+
container-name: sidebar;
|
|
6786
|
+
container-type: inline-size;
|
|
6787
|
+
position: sticky;
|
|
6788
|
+
top: 0;
|
|
6691
6789
|
width: var(--ui-layout-sidebar-width);
|
|
6692
6790
|
min-width: 160px;
|
|
6693
6791
|
max-width: 400px;
|
|
6694
6792
|
height: 100dvh;
|
|
6695
|
-
|
|
6696
|
-
top: 0;
|
|
6697
|
-
display: flex;
|
|
6698
|
-
flex-direction: column;
|
|
6793
|
+
display: block;
|
|
6699
6794
|
transition: width var(--_duration) var(--_easing), min-width var(--_duration) var(--_easing);
|
|
6700
6795
|
overflow: hidden;
|
|
6701
6796
|
z-index: 10;
|
|
@@ -6707,7 +6802,9 @@
|
|
|
6707
6802
|
}
|
|
6708
6803
|
|
|
6709
6804
|
/* ── Collapsed Icon Rail ── */
|
|
6710
|
-
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
6805
|
+
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
6806
|
+
[collapsed] drives the aside to 48px which triggers @container sidebar queries
|
|
6807
|
+
in this file and in child component CSS (ui-nav.css, etc.). */
|
|
6711
6808
|
|
|
6712
6809
|
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) {
|
|
6713
6810
|
width: 48px;
|
|
@@ -6728,11 +6825,7 @@
|
|
|
6728
6825
|
|
|
6729
6826
|
:where(ui-layout-sidebar) :where(.layout-resize-handle):hover,
|
|
6730
6827
|
: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;
|
|
6828
|
+
background: var(--_border-muted);
|
|
6736
6829
|
}
|
|
6737
6830
|
|
|
6738
6831
|
/* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
|
|
@@ -6746,47 +6839,88 @@
|
|
|
6746
6839
|
}
|
|
6747
6840
|
|
|
6748
6841
|
/* ── Sidebar Header ── */
|
|
6842
|
+
/* WHY: Absolute-positioned overlay pinned to top of aside. Content scrolls
|
|
6843
|
+
underneath it. z-index: 2 sits above content (z-index: 0). */
|
|
6749
6844
|
|
|
6750
6845
|
:where(ui-layout-sidebar-header) {
|
|
6846
|
+
position: absolute;
|
|
6847
|
+
top: 0;
|
|
6848
|
+
left: 0;
|
|
6849
|
+
right: 0;
|
|
6850
|
+
z-index: 2;
|
|
6751
6851
|
display: flex;
|
|
6752
|
-
|
|
6753
|
-
min-height: var(--ui-layout-bar-height);
|
|
6754
|
-
gap: calc(var(--_space) * 2);
|
|
6755
|
-
padding-block: var(--_space);
|
|
6756
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6757
|
-
flex-shrink: 0;
|
|
6852
|
+
flex-direction: column;
|
|
6758
6853
|
}
|
|
6759
6854
|
|
|
6760
6855
|
/* ── Sidebar Content ── */
|
|
6856
|
+
/* WHY: Full height of the aside, scrollable. Padding-block offsets keep
|
|
6857
|
+
content from starting behind header / ending behind footer.
|
|
6858
|
+
Fade-out alpha mask dissolves content edges under the overlays. */
|
|
6761
6859
|
|
|
6762
6860
|
:where(ui-layout-sidebar-content) {
|
|
6763
6861
|
display: flex;
|
|
6764
6862
|
flex-direction: column;
|
|
6765
|
-
|
|
6766
|
-
padding-block: var(--
|
|
6767
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6768
|
-
flex: 1;
|
|
6769
|
-
min-height: 0;
|
|
6863
|
+
padding-block-start: var(--_sidebar-header-height);
|
|
6864
|
+
padding-block-end: var(--_sidebar-footer-height);
|
|
6770
6865
|
width: 100%;
|
|
6866
|
+
height: 100%;
|
|
6867
|
+
overflow-y: auto;
|
|
6868
|
+
scrollbar-width: none;
|
|
6869
|
+
}
|
|
6870
|
+
|
|
6871
|
+
/* WHY: When header is present, fade top edge. Content dissolves as it
|
|
6872
|
+
scrolls under the header — transparent at top, fully visible by 1.25×
|
|
6873
|
+
the header height. No opaque header background needed. */
|
|
6874
|
+
:where(ui-layout-sidebar-content)[data-has-header] {
|
|
6875
|
+
mask-image: linear-gradient(
|
|
6876
|
+
to bottom,
|
|
6877
|
+
transparent 0,
|
|
6878
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
6879
|
+
black 100%
|
|
6880
|
+
);
|
|
6881
|
+
}
|
|
6882
|
+
|
|
6883
|
+
/* WHY: When footer is present, fade bottom edge. */
|
|
6884
|
+
:where(ui-layout-sidebar-content)[data-has-footer] {
|
|
6885
|
+
mask-image: linear-gradient(
|
|
6886
|
+
to bottom,
|
|
6887
|
+
black 0,
|
|
6888
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
6889
|
+
transparent 100%
|
|
6890
|
+
);
|
|
6891
|
+
}
|
|
6892
|
+
|
|
6893
|
+
/* WHY: When both header AND footer are present, fade both edges. */
|
|
6894
|
+
:where(ui-layout-sidebar-content)[data-has-header][data-has-footer] {
|
|
6895
|
+
mask-image: linear-gradient(
|
|
6896
|
+
to bottom,
|
|
6897
|
+
transparent 0,
|
|
6898
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
6899
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
6900
|
+
transparent 100%
|
|
6901
|
+
);
|
|
6771
6902
|
}
|
|
6772
6903
|
|
|
6773
6904
|
/* ── Sidebar Footer ── */
|
|
6905
|
+
/* WHY: Absolute-positioned overlay pinned to bottom of aside. */
|
|
6774
6906
|
|
|
6775
6907
|
:where(ui-layout-sidebar-footer) {
|
|
6908
|
+
position: absolute;
|
|
6909
|
+
bottom: 0;
|
|
6910
|
+
left: 0;
|
|
6911
|
+
right: 0;
|
|
6912
|
+
z-index: 2;
|
|
6776
6913
|
display: flex;
|
|
6777
|
-
|
|
6778
|
-
min-height: var(--ui-layout-bar-height);
|
|
6779
|
-
gap: calc(var(--_space) * 2);
|
|
6780
|
-
padding-block: var(--_space);
|
|
6781
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6782
|
-
flex-shrink: 0;
|
|
6914
|
+
flex-direction: column;
|
|
6783
6915
|
}
|
|
6784
6916
|
|
|
6785
|
-
/* ── Sidebar
|
|
6786
|
-
/* WHY:
|
|
6787
|
-
|
|
6917
|
+
/* ── Sidebar Item ── */
|
|
6918
|
+
/* WHY: Universal sidebar row element. Provides inline padding for any content
|
|
6919
|
+
(buttons, links, icons). When a child ui-listbox[popover] is present, JS
|
|
6920
|
+
wires PopoverController for click-to-toggle menu behavior.
|
|
6921
|
+
Absorbs the old ui-layout-sidebar-trigger role — one element for all rows. */
|
|
6788
6922
|
|
|
6789
|
-
:where(ui-layout-sidebar-
|
|
6923
|
+
:where(ui-layout-sidebar-item) {
|
|
6790
6924
|
display: flex;
|
|
6791
6925
|
align-items: center;
|
|
6792
6926
|
flex: 1;
|
|
@@ -6802,31 +6936,47 @@
|
|
|
6802
6936
|
user-select: none;
|
|
6803
6937
|
border: none;
|
|
6804
6938
|
background: none;
|
|
6805
|
-
padding: var(--_space);
|
|
6939
|
+
padding-block: var(--_space);
|
|
6940
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
6806
6941
|
border-radius: var(--_radius);
|
|
6807
6942
|
transition: color var(--_duration) var(--_easing);
|
|
6808
6943
|
}
|
|
6809
6944
|
|
|
6810
|
-
:
|
|
6811
|
-
|
|
6945
|
+
/* WHY: Items in header/footer match the breadcrumb bar height so the
|
|
6946
|
+
first sidebar row aligns horizontally with the breadcrumb. */
|
|
6947
|
+
:where(ui-layout-sidebar-header) > :where(ui-layout-sidebar-item),
|
|
6948
|
+
:where(ui-layout-sidebar-footer) > :where(ui-layout-sidebar-item) {
|
|
6949
|
+
min-height: var(--ui-layout-bar-height);
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6952
|
+
:where(ui-layout-sidebar-item):hover,
|
|
6953
|
+
:where(ui-layout-sidebar-item)[force-hover] {
|
|
6812
6954
|
color: var(--_ink-strong);
|
|
6813
6955
|
}
|
|
6814
6956
|
|
|
6815
|
-
:where(ui-layout-sidebar-
|
|
6816
|
-
:where(ui-layout-sidebar-
|
|
6957
|
+
:where(ui-layout-sidebar-item):focus-visible,
|
|
6958
|
+
:where(ui-layout-sidebar-item)[force-focus-visible] {
|
|
6817
6959
|
outline: 2px solid var(--ui-focus-ring);
|
|
6818
6960
|
outline-offset: -2px;
|
|
6819
6961
|
}
|
|
6820
6962
|
|
|
6821
6963
|
/* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
|
|
6822
|
-
:where(ui-layout-sidebar-
|
|
6964
|
+
:where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
|
|
6823
6965
|
margin-inline-start: auto;
|
|
6824
6966
|
flex-shrink: 0;
|
|
6825
6967
|
color: var(--_ink-muted);
|
|
6826
6968
|
}
|
|
6827
6969
|
|
|
6970
|
+
/* WHY: When the item wraps a sub-component (e.g. ui-button) that provides
|
|
6971
|
+
its own icon, hide [slot="icon"] in expanded mode — it only serves as the
|
|
6972
|
+
bare collapsed-rail representation. Items without sub-components (just
|
|
6973
|
+
icon + label + trailing) keep [slot="icon"] visible in both modes. */
|
|
6974
|
+
:where(ui-layout-sidebar-item:has(> ui-button)) > :where([slot="icon"]) {
|
|
6975
|
+
display: none;
|
|
6976
|
+
}
|
|
6977
|
+
|
|
6828
6978
|
/* WHY: Title text truncates when sidebar narrows during resize. */
|
|
6829
|
-
:where(ui-layout-sidebar-
|
|
6979
|
+
:where(ui-layout-sidebar-item) > :where([slot="label"]) {
|
|
6830
6980
|
flex: 1;
|
|
6831
6981
|
min-width: 0;
|
|
6832
6982
|
white-space: nowrap;
|
|
@@ -6834,25 +6984,67 @@
|
|
|
6834
6984
|
text-overflow: ellipsis;
|
|
6835
6985
|
}
|
|
6836
6986
|
|
|
6837
|
-
/* ──
|
|
6838
|
-
/* WHY: Popover opens to the right of the sidebar
|
|
6987
|
+
/* ── Item Popover ── */
|
|
6988
|
+
/* WHY: Popover opens to the right of the sidebar item.
|
|
6839
6989
|
Default: top-aligned, grows downward (span-block-end).
|
|
6840
6990
|
Flip: bottom-aligned, grows upward (span-block-start). */
|
|
6841
6991
|
|
|
6842
|
-
:where(ui-layout-sidebar-
|
|
6992
|
+
:where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
|
|
6843
6993
|
position: fixed;
|
|
6844
6994
|
position-area: inline-end span-block-end;
|
|
6845
|
-
position-try-fallbacks: --flip-up;
|
|
6995
|
+
position-try-fallbacks: --sidebar-item-flip-up;
|
|
6846
6996
|
margin: 0 0 0 var(--ui-popover-gap);
|
|
6847
6997
|
min-width: 200px;
|
|
6848
6998
|
max-height: var(--ui-popover-max-height);
|
|
6849
6999
|
overflow-y: auto;
|
|
6850
7000
|
}
|
|
6851
7001
|
|
|
6852
|
-
@position-try --flip-up {
|
|
7002
|
+
@position-try --sidebar-item-flip-up {
|
|
6853
7003
|
position-area: inline-end span-block-start;
|
|
6854
7004
|
}
|
|
6855
7005
|
|
|
7006
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
7007
|
+
/* WHY: Each component owns its own collapsed behavior via @container.
|
|
7008
|
+
The aside is the container (container-name: sidebar). When it shrinks
|
|
7009
|
+
to 48px (icon rail), components respond to the width, not to [collapsed].
|
|
7010
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
7011
|
+
|
|
7012
|
+
@container sidebar (max-width: 80px) {
|
|
7013
|
+
|
|
7014
|
+
/* Resize handle — no dragging in icon rail */
|
|
7015
|
+
:where(.layout-resize-handle) {
|
|
7016
|
+
display: none;
|
|
7017
|
+
}
|
|
7018
|
+
|
|
7019
|
+
/* Header/footer — center content horizontally */
|
|
7020
|
+
:where(ui-layout-sidebar-header),
|
|
7021
|
+
:where(ui-layout-sidebar-footer) {
|
|
7022
|
+
align-items: center;
|
|
7023
|
+
}
|
|
7024
|
+
|
|
7025
|
+
/* Content — center items in the 48px rail */
|
|
7026
|
+
:where(ui-layout-sidebar-content) {
|
|
7027
|
+
align-items: center;
|
|
7028
|
+
}
|
|
7029
|
+
|
|
7030
|
+
/* Item — shrink to icon-only. Show [slot="icon"], hide everything else.
|
|
7031
|
+
WHY: Sidebar items can contain complex children (buttons with slots,
|
|
7032
|
+
links, etc.). Rather than overriding sub-component styles, the item
|
|
7033
|
+
provides its own bare icon via [slot="icon"] for the collapsed rail. */
|
|
7034
|
+
:where(ui-layout-sidebar-item) {
|
|
7035
|
+
flex: 0 0 auto;
|
|
7036
|
+
padding-inline: var(--_space);
|
|
7037
|
+
}
|
|
7038
|
+
|
|
7039
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
7040
|
+
display: block;
|
|
7041
|
+
}
|
|
7042
|
+
|
|
7043
|
+
:where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
|
|
7044
|
+
display: none;
|
|
7045
|
+
}
|
|
7046
|
+
}
|
|
7047
|
+
|
|
6856
7048
|
}
|
|
6857
7049
|
|
|
6858
7050
|
@layer ui {
|