@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/components-lean.css
CHANGED
|
@@ -361,7 +361,7 @@
|
|
|
361
361
|
font-weight: var(--_font-weight);
|
|
362
362
|
|
|
363
363
|
border-radius: var(--_radius);
|
|
364
|
-
border: 1px solid var(--_border-color, var(--
|
|
364
|
+
border: 1px solid var(--_border-color, var(--_border-muted));
|
|
365
365
|
|
|
366
366
|
background: var(--_background, var(--_button));
|
|
367
367
|
color: var(--_color, var(--_ink));
|
|
@@ -377,16 +377,16 @@
|
|
|
377
377
|
/* ── States ── */
|
|
378
378
|
|
|
379
379
|
:where(ui-button):hover{
|
|
380
|
-
background: var(--_background-hover, var(--
|
|
380
|
+
background: var(--_background-hover, var(--_button-hover));
|
|
381
381
|
color: var(--_color-hover, var(--_ink-hover));
|
|
382
|
-
border-color: var(--_border-color-hover, var(--
|
|
382
|
+
border-color: var(--_border-color-hover, var(--_border-hover));
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
:where(ui-button):active,
|
|
386
386
|
:where(ui-button)[pressed]{
|
|
387
|
-
background: var(--_background-active, var(--
|
|
387
|
+
background: var(--_background-active, var(--_button-active));
|
|
388
388
|
color: var(--_color-active, var(--_ink-active));
|
|
389
|
-
border-color: var(--_border-color-active, var(--
|
|
389
|
+
border-color: var(--_border-color-active, var(--_border-active));
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
:where(ui-button):focus-visible{
|
|
@@ -395,9 +395,9 @@
|
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
:where(ui-button)[aria-disabled="true"] {
|
|
398
|
-
background: var(--_background-disabled, var(--
|
|
398
|
+
background: var(--_background-disabled, var(--_button-disabled));
|
|
399
399
|
color: var(--_color-disabled, var(--_ink-disabled));
|
|
400
|
-
border-color: var(--_border-color-disabled, var(--
|
|
400
|
+
border-color: var(--_border-color-disabled, var(--_border-muted));
|
|
401
401
|
cursor: not-allowed;
|
|
402
402
|
pointer-events: none;
|
|
403
403
|
}
|
|
@@ -965,34 +965,25 @@
|
|
|
965
965
|
}
|
|
966
966
|
|
|
967
967
|
/* ── Checked State ── */
|
|
968
|
-
/* WHY: Default checked fill uses accent
|
|
969
|
-
|
|
968
|
+
/* WHY: Default checked fill uses --_surface (accent by default via
|
|
969
|
+
intent="accent" being the implicit default for toggle controls).
|
|
970
970
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
971
971
|
|
|
972
972
|
:where(ui-checkbox)[aria-checked="true"]::before {
|
|
973
|
-
background: var(--accent-surface);
|
|
974
|
-
border-color: var(--accent-surface);
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
:where(ui-checkbox)[aria-checked="true"]::after {
|
|
978
|
-
background: var(--accent-surface-ink);
|
|
979
|
-
transform: translateY(-50%) scale(1);
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
:where(ui-checkbox)[intent][aria-checked="true"]::before {
|
|
983
973
|
background: var(--_surface);
|
|
984
974
|
border-color: var(--_surface);
|
|
985
975
|
}
|
|
986
976
|
|
|
987
|
-
:where(ui-checkbox)[
|
|
977
|
+
:where(ui-checkbox)[aria-checked="true"]::after {
|
|
988
978
|
background: var(--_surface-ink);
|
|
979
|
+
transform: translateY(-50%) scale(1);
|
|
989
980
|
}
|
|
990
981
|
|
|
991
982
|
/* ── Indeterminate State ── */
|
|
992
983
|
|
|
993
984
|
:where(ui-checkbox)[aria-checked="mixed"]::before {
|
|
994
|
-
background: var(--
|
|
995
|
-
border-color: var(--
|
|
985
|
+
background: var(--_surface);
|
|
986
|
+
border-color: var(--_surface);
|
|
996
987
|
}
|
|
997
988
|
|
|
998
989
|
:where(ui-checkbox)[aria-checked="mixed"]::after {
|
|
@@ -1000,17 +991,8 @@
|
|
|
1000
991
|
-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");
|
|
1001
992
|
mask-size: 75%;
|
|
1002
993
|
-webkit-mask-size: 75%;
|
|
1003
|
-
background: var(--accent-surface-ink);
|
|
1004
|
-
transform: translateY(-50%) scale(1);
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]::before {
|
|
1008
|
-
background: var(--_surface);
|
|
1009
|
-
border-color: var(--_surface);
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]::after {
|
|
1013
994
|
background: var(--_surface-ink);
|
|
995
|
+
transform: translateY(-50%) scale(1);
|
|
1014
996
|
}
|
|
1015
997
|
|
|
1016
998
|
/* ── Hover ── */
|
|
@@ -1027,13 +1009,6 @@
|
|
|
1027
1009
|
:where(ui-checkbox)[aria-checked="true"]:hover::before,
|
|
1028
1010
|
:where(ui-checkbox)[aria-checked="mixed"]:hover::before
|
|
1029
1011
|
:where(ui-checkbox)[aria-checked="mixed"][force-hover]::before {
|
|
1030
|
-
background: var(--accent-surface-hover);
|
|
1031
|
-
border-color: var(--accent-surface-hover);
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
:where(ui-checkbox)[intent][aria-checked="true"]:hover::before,
|
|
1035
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"]:hover::before
|
|
1036
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"][force-hover]::before {
|
|
1037
1012
|
background: var(--_surface-hover);
|
|
1038
1013
|
border-color: var(--_surface-hover);
|
|
1039
1014
|
}
|
|
@@ -1047,12 +1022,6 @@
|
|
|
1047
1022
|
|
|
1048
1023
|
:where(ui-checkbox)[aria-checked="true"][pressed]::before,
|
|
1049
1024
|
:where(ui-checkbox)[aria-checked="mixed"][pressed]::before {
|
|
1050
|
-
background: var(--accent-surface-active);
|
|
1051
|
-
border-color: var(--accent-surface-active);
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
:where(ui-checkbox)[intent][aria-checked="true"][pressed]::before,
|
|
1055
|
-
:where(ui-checkbox)[intent][aria-checked="mixed"][pressed]::before {
|
|
1056
1025
|
background: var(--_surface-active);
|
|
1057
1026
|
border-color: var(--_surface-active);
|
|
1058
1027
|
}
|
|
@@ -1699,6 +1668,45 @@
|
|
|
1699
1668
|
|
|
1700
1669
|
}
|
|
1701
1670
|
|
|
1671
|
+
@layer ui {
|
|
1672
|
+
|
|
1673
|
+
/* ╭──────────────────────────────────────────────────────────╮
|
|
1674
|
+
│ ui-kbd │
|
|
1675
|
+
│ Keyboard shortcut indicator. Own font/size scale │
|
|
1676
|
+
│ (like ui-badge) — zero-attribute = md. │
|
|
1677
|
+
╰──────────────────────────────────────────────────────────╯ */
|
|
1678
|
+
|
|
1679
|
+
:where(ui-kbd) {
|
|
1680
|
+
--_icon-size: 1.125em;
|
|
1681
|
+
|
|
1682
|
+
display: inline-flex;
|
|
1683
|
+
align-items: center;
|
|
1684
|
+
justify-content: center;
|
|
1685
|
+
font-family: ui-monospace, monospace;
|
|
1686
|
+
font-size: var(--ui-kbd-font-md);
|
|
1687
|
+
line-height: 1;
|
|
1688
|
+
min-height: var(--ui-kbd-size-md);
|
|
1689
|
+
padding-inline: 0.4em;
|
|
1690
|
+
border-radius: 0.5em;
|
|
1691
|
+
background: var(--_ground, var(--_body));
|
|
1692
|
+
border: 1px solid var(--_border-muted);
|
|
1693
|
+
color: var(--_ink-muted);
|
|
1694
|
+
white-space: nowrap;
|
|
1695
|
+
user-select: none;
|
|
1696
|
+
flex-shrink: 0;
|
|
1697
|
+
vertical-align: baseline;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
/* ── Sizes ── */
|
|
1701
|
+
|
|
1702
|
+
:where(ui-kbd[size="xs"]) { font-size: var(--ui-kbd-font-xs); min-height: var(--ui-kbd-size-xs); }
|
|
1703
|
+
:where(ui-kbd[size="sm"]) { font-size: var(--ui-kbd-font-sm); min-height: var(--ui-kbd-size-sm); }
|
|
1704
|
+
:where(ui-kbd[size="md"]) { font-size: var(--ui-kbd-font-md); min-height: var(--ui-kbd-size-md); }
|
|
1705
|
+
:where(ui-kbd[size="lg"]) { font-size: var(--ui-kbd-font-lg); min-height: var(--ui-kbd-size-lg); }
|
|
1706
|
+
:where(ui-kbd[size="xl"]) { font-size: var(--ui-kbd-font-xl); min-height: var(--ui-kbd-size-xl); }
|
|
1707
|
+
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1702
1710
|
@layer ui {
|
|
1703
1711
|
|
|
1704
1712
|
/* ── Listbox Base ── */
|
|
@@ -1836,11 +1844,14 @@
|
|
|
1836
1844
|
│ Uses ui-nav-item / ui-nav-group for children. │
|
|
1837
1845
|
╰──────────────────────────────────────────────────────────╯ */
|
|
1838
1846
|
|
|
1847
|
+
/* WHY: ui-nav is a transparent flex wrapper — no inline padding.
|
|
1848
|
+
Inline padding is owned by leaf items (nav-item, summary).
|
|
1849
|
+
Block padding is owned by nav-group margins. */
|
|
1839
1850
|
:where(ui-nav) {
|
|
1840
1851
|
display: flex;
|
|
1841
1852
|
flex-direction: column;
|
|
1842
1853
|
gap: 0;
|
|
1843
|
-
padding:
|
|
1854
|
+
padding: 0;
|
|
1844
1855
|
outline: none;
|
|
1845
1856
|
}
|
|
1846
1857
|
|
|
@@ -1855,6 +1866,7 @@
|
|
|
1855
1866
|
display: flex;
|
|
1856
1867
|
align-items: center;
|
|
1857
1868
|
gap: calc(var(--_space) * 2);
|
|
1869
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
1858
1870
|
|
|
1859
1871
|
min-height: var(--_min-height);
|
|
1860
1872
|
|
|
@@ -1951,6 +1963,7 @@
|
|
|
1951
1963
|
display: flex;
|
|
1952
1964
|
align-items: center;
|
|
1953
1965
|
gap: calc(var(--_space) * 2);
|
|
1966
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
1954
1967
|
cursor: pointer;
|
|
1955
1968
|
user-select: none;
|
|
1956
1969
|
list-style: none;
|
|
@@ -1985,6 +1998,18 @@
|
|
|
1985
1998
|
user-select: none;
|
|
1986
1999
|
}
|
|
1987
2000
|
|
|
2001
|
+
/* WHY: Fixed-size icon well — matches ui-layout-sidebar-item [slot="icon"].
|
|
2002
|
+
All sidebar icons align on the same 1.5rem column regardless of icon size.
|
|
2003
|
+
JS wraps the first <ui-icon> child in a .icon-well span during setup(). */
|
|
2004
|
+
:where(ui-nav-group-header) > :where(.icon-well) {
|
|
2005
|
+
display: inline-flex;
|
|
2006
|
+
align-items: center;
|
|
2007
|
+
justify-content: center;
|
|
2008
|
+
width: 1.5rem;
|
|
2009
|
+
height: 1.5rem;
|
|
2010
|
+
flex-shrink: 0;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
1988
2013
|
/* ── Chevron icon (right side of summary) ── */
|
|
1989
2014
|
|
|
1990
2015
|
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
@@ -2036,12 +2061,16 @@
|
|
|
2036
2061
|
/* WHY: Connector draws from below the header to the bottom of the group.
|
|
2037
2062
|
Only shown when header contains an icon. Scoped via :has(). */
|
|
2038
2063
|
|
|
2039
|
-
:
|
|
2040
|
-
|
|
2041
|
-
|
|
2064
|
+
/* WHY: Insets account for the summary's padding-inline so the connector
|
|
2065
|
+
line passes through the icon center and child text aligns with header text. */
|
|
2066
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)) {
|
|
2067
|
+
--_group-pad: calc(var(--_space-k) * var(--_space));
|
|
2068
|
+
--_group-icon-well: 1.5rem;
|
|
2069
|
+
--_group-line-inset: calc(var(--_group-pad) + var(--_group-icon-well) / 2);
|
|
2070
|
+
--_group-child-inset: calc(var(--_group-icon-well) + var(--_space) * 2);
|
|
2042
2071
|
}
|
|
2043
2072
|
|
|
2044
|
-
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(
|
|
2073
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open]))::after {
|
|
2045
2074
|
content: '';
|
|
2046
2075
|
position: absolute;
|
|
2047
2076
|
inset-inline-start: var(--_group-line-inset);
|
|
@@ -2056,7 +2085,7 @@
|
|
|
2056
2085
|
/* WHY: A ::before pseudo on the group slides along the connector line.
|
|
2057
2086
|
JS sets --_indicator-index; :state(has-selection) gates visibility. */
|
|
2058
2087
|
|
|
2059
|
-
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(
|
|
2088
|
+
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
|
|
2060
2089
|
content: '';
|
|
2061
2090
|
position: absolute;
|
|
2062
2091
|
z-index: 1;
|
|
@@ -2083,6 +2112,73 @@
|
|
|
2083
2112
|
margin-inline-start: var(--_group-child-inset, 0);
|
|
2084
2113
|
}
|
|
2085
2114
|
|
|
2115
|
+
/* ── Nav Group Flyout (collapsed sidebar) ── */
|
|
2116
|
+
/* WHY: In collapsed mode, summary click opens a ui-listbox popover to the right
|
|
2117
|
+
instead of expanding the <details>. Same pattern as sidebar-trigger menus. */
|
|
2118
|
+
|
|
2119
|
+
:where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
|
|
2120
|
+
position: fixed;
|
|
2121
|
+
position-area: inline-end span-block-end;
|
|
2122
|
+
position-try-fallbacks: --nav-flyout-flip-up;
|
|
2123
|
+
margin: 0 0 0 var(--ui-popover-gap);
|
|
2124
|
+
min-width: 200px;
|
|
2125
|
+
max-height: var(--ui-popover-max-height);
|
|
2126
|
+
overflow-y: auto;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
@position-try --nav-flyout-flip-up {
|
|
2130
|
+
position-area: inline-end span-block-start;
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
2134
|
+
/* WHY: Nav components own their own collapsed behavior via @container.
|
|
2135
|
+
The sidebar aside declares container-name: sidebar. When it shrinks
|
|
2136
|
+
to 48px (icon rail), nav responds to the width — not to [collapsed].
|
|
2137
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
2138
|
+
|
|
2139
|
+
@container sidebar (max-width: 80px) {
|
|
2140
|
+
|
|
2141
|
+
/* Nav items hide entirely — only group headers (with icons) remain. */
|
|
2142
|
+
:where(ui-nav-item) {
|
|
2143
|
+
display: none;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
/* Summary shrinks to icon-only. Reduced inline padding wraps tightly
|
|
2147
|
+
around the icon; parent align-items: center handles horizontal centering. */
|
|
2148
|
+
:where(ui-nav-group) > :where(details) > :where(summary) {
|
|
2149
|
+
padding-inline: var(--_space);
|
|
2150
|
+
border-radius: var(--_radius);
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
/* Hide chevron — no expand/collapse in icon rail (flyout instead). */
|
|
2154
|
+
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
2155
|
+
display: none;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
/* Hide vertical connector line and sliding indicator. */
|
|
2159
|
+
:where(ui-nav-group)::after,
|
|
2160
|
+
:where(ui-nav-group)::before {
|
|
2161
|
+
display: none;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
/* Header collapses to icon-only. font-size: 0 hides text nodes
|
|
2165
|
+
(can't be targeted by CSS). Icon overrides back to normal below. */
|
|
2166
|
+
:where(ui-nav-group-header) {
|
|
2167
|
+
flex: 0 0 auto;
|
|
2168
|
+
font-size: 0;
|
|
2169
|
+
gap: 0;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
:where(ui-nav-group-header) :where(.icon-well) :where(ui-icon) {
|
|
2173
|
+
font-size: var(--_font-size, 1rem);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
/* Collapse inter-group spacing in icon rail. */
|
|
2177
|
+
:where(ui-nav-group) + :where(ui-nav-group) {
|
|
2178
|
+
margin-block-start: 0;
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2086
2182
|
}
|
|
2087
2183
|
|
|
2088
2184
|
@layer ui {
|
|
@@ -2223,27 +2319,15 @@
|
|
|
2223
2319
|
}
|
|
2224
2320
|
|
|
2225
2321
|
/* ── Selected ── */
|
|
2226
|
-
/* WHY: Default selected fill uses accent so radio is visually distinct
|
|
2227
|
-
without needing intent="accent". Unchecked borders stay neutral.
|
|
2228
|
-
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
2229
2322
|
|
|
2230
2323
|
:where(ui-radio)[aria-checked="true"]::before {
|
|
2231
|
-
background: var(--accent-surface);
|
|
2232
|
-
border-color: var(--accent-surface);
|
|
2233
|
-
}
|
|
2234
|
-
|
|
2235
|
-
:where(ui-radio)[aria-checked="true"]::after {
|
|
2236
|
-
background: var(--accent-surface-ink);
|
|
2237
|
-
transform: translateY(-50%) scale(1);
|
|
2238
|
-
}
|
|
2239
|
-
|
|
2240
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"]::before {
|
|
2241
2324
|
background: var(--_surface);
|
|
2242
2325
|
border-color: var(--_surface);
|
|
2243
2326
|
}
|
|
2244
2327
|
|
|
2245
|
-
:where(ui-radio
|
|
2328
|
+
:where(ui-radio)[aria-checked="true"]::after {
|
|
2246
2329
|
background: var(--_surface-ink);
|
|
2330
|
+
transform: translateY(-50%) scale(1);
|
|
2247
2331
|
}
|
|
2248
2332
|
|
|
2249
2333
|
/* ── Hover ── */
|
|
@@ -2258,11 +2342,6 @@
|
|
|
2258
2342
|
}
|
|
2259
2343
|
|
|
2260
2344
|
:where(ui-radio)[aria-checked="true"]:hover::before{
|
|
2261
|
-
background: var(--accent-surface-hover);
|
|
2262
|
-
border-color: var(--accent-surface-hover);
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"]:hover::before{
|
|
2266
2345
|
background: var(--_surface-hover);
|
|
2267
2346
|
border-color: var(--_surface-hover);
|
|
2268
2347
|
}
|
|
@@ -2275,11 +2354,6 @@
|
|
|
2275
2354
|
}
|
|
2276
2355
|
|
|
2277
2356
|
:where(ui-radio)[aria-checked="true"][pressed]::before {
|
|
2278
|
-
background: var(--accent-surface-active);
|
|
2279
|
-
border-color: var(--accent-surface-active);
|
|
2280
|
-
}
|
|
2281
|
-
|
|
2282
|
-
:where(ui-radio-group)[intent] :where(ui-radio)[aria-checked="true"][pressed]::before {
|
|
2283
2357
|
background: var(--_surface-active);
|
|
2284
2358
|
border-color: var(--_surface-active);
|
|
2285
2359
|
}
|
|
@@ -2377,16 +2451,12 @@
|
|
|
2377
2451
|
/* 0% = track-height (circle), 100% = full width */
|
|
2378
2452
|
width: calc(var(--_track-height) + (100% - var(--_track-height)) * var(--_progress));
|
|
2379
2453
|
border-radius: calc(var(--_track-height) / 2);
|
|
2380
|
-
background: var(--
|
|
2454
|
+
background: var(--_surface);
|
|
2381
2455
|
|
|
2382
2456
|
transition:
|
|
2383
2457
|
background var(--_duration) var(--_easing);
|
|
2384
2458
|
}
|
|
2385
2459
|
|
|
2386
|
-
:where(ui-range)[intent]::after {
|
|
2387
|
-
background: var(--_surface);
|
|
2388
|
-
}
|
|
2389
|
-
|
|
2390
2460
|
/* ── Thumb ── */
|
|
2391
2461
|
|
|
2392
2462
|
:where(ui-range) > :where(.ui-range-thumb) {
|
|
@@ -2398,8 +2468,8 @@
|
|
|
2398
2468
|
width: var(--_thumb-size);
|
|
2399
2469
|
height: var(--_thumb-size);
|
|
2400
2470
|
border-radius: 50%;
|
|
2401
|
-
background: var(--
|
|
2402
|
-
border: 2px solid var(--
|
|
2471
|
+
background: var(--_surface-ink);
|
|
2472
|
+
border: 2px solid var(--_surface);
|
|
2403
2473
|
box-shadow: var(--ui-shadow-sm);
|
|
2404
2474
|
pointer-events: none;
|
|
2405
2475
|
|
|
@@ -2409,11 +2479,6 @@
|
|
|
2409
2479
|
border-color var(--_duration) var(--_easing);
|
|
2410
2480
|
}
|
|
2411
2481
|
|
|
2412
|
-
:where(ui-range)[intent] > :where(.ui-range-thumb) {
|
|
2413
|
-
background: var(--_surface-ink);
|
|
2414
|
-
border-color: var(--_surface);
|
|
2415
|
-
}
|
|
2416
|
-
|
|
2417
2482
|
/* ── Focus ── */
|
|
2418
2483
|
|
|
2419
2484
|
:where(ui-range):focus-visible > :where(.ui-range-thumb){
|
|
@@ -2424,19 +2489,10 @@
|
|
|
2424
2489
|
/* ── Hover ── */
|
|
2425
2490
|
|
|
2426
2491
|
:where(ui-range):hover::after{
|
|
2427
|
-
background: var(--accent-surface-hover);
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
:where(ui-range)[intent]:hover::after{
|
|
2431
2492
|
background: var(--_surface-hover);
|
|
2432
2493
|
}
|
|
2433
2494
|
|
|
2434
2495
|
:where(ui-range):hover > :where(.ui-range-thumb){
|
|
2435
|
-
border-color: var(--accent-surface-hover);
|
|
2436
|
-
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--accent-surface);
|
|
2437
|
-
}
|
|
2438
|
-
|
|
2439
|
-
:where(ui-range)[intent]:hover > :where(.ui-range-thumb){
|
|
2440
2496
|
border-color: var(--_surface-hover);
|
|
2441
2497
|
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--_surface);
|
|
2442
2498
|
}
|
|
@@ -2444,19 +2500,10 @@
|
|
|
2444
2500
|
/* ── Active (dragging) ── */
|
|
2445
2501
|
|
|
2446
2502
|
:where(ui-range)[pressed]::after {
|
|
2447
|
-
background: var(--accent-surface-active);
|
|
2448
|
-
}
|
|
2449
|
-
|
|
2450
|
-
:where(ui-range)[intent][pressed]::after {
|
|
2451
2503
|
background: var(--_surface-active);
|
|
2452
2504
|
}
|
|
2453
2505
|
|
|
2454
2506
|
:where(ui-range)[pressed] > :where(.ui-range-thumb) {
|
|
2455
|
-
border-color: var(--accent-surface-active);
|
|
2456
|
-
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--accent-surface);
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
:where(ui-range)[intent][pressed] > :where(.ui-range-thumb) {
|
|
2460
2507
|
border-color: var(--_surface-active);
|
|
2461
2508
|
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--_surface);
|
|
2462
2509
|
}
|
|
@@ -3003,22 +3050,13 @@
|
|
|
3003
3050
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
3004
3051
|
|
|
3005
3052
|
:where(ui-switch)[aria-checked="true"]::before {
|
|
3006
|
-
background: var(--
|
|
3007
|
-
border-color: var(--
|
|
3053
|
+
background: var(--_surface);
|
|
3054
|
+
border-color: var(--_surface);
|
|
3008
3055
|
}
|
|
3009
3056
|
|
|
3010
3057
|
:where(ui-switch)[aria-checked="true"]::after {
|
|
3011
3058
|
/* Slide thumb to the right via translateX — GPU composited */
|
|
3012
3059
|
transform: translateY(-50%) translateX(calc(var(--_track-width) - var(--_thumb-size) - var(--_thumb-offset) * 2));
|
|
3013
|
-
background: var(--accent-surface-ink);
|
|
3014
|
-
}
|
|
3015
|
-
|
|
3016
|
-
:where(ui-switch)[intent][aria-checked="true"]::before {
|
|
3017
|
-
background: var(--_surface);
|
|
3018
|
-
border-color: var(--_surface);
|
|
3019
|
-
}
|
|
3020
|
-
|
|
3021
|
-
:where(ui-switch)[intent][aria-checked="true"]::after {
|
|
3022
3060
|
background: var(--_surface-ink);
|
|
3023
3061
|
}
|
|
3024
3062
|
|
|
@@ -3034,11 +3072,6 @@
|
|
|
3034
3072
|
}
|
|
3035
3073
|
|
|
3036
3074
|
:where(ui-switch)[aria-checked="true"]:hover::before{
|
|
3037
|
-
background: var(--accent-surface-hover);
|
|
3038
|
-
border-color: var(--accent-surface-hover);
|
|
3039
|
-
}
|
|
3040
|
-
|
|
3041
|
-
:where(ui-switch)[intent][aria-checked="true"]:hover::before{
|
|
3042
3075
|
background: var(--_surface-hover);
|
|
3043
3076
|
border-color: var(--_surface-hover);
|
|
3044
3077
|
}
|
|
@@ -3051,11 +3084,6 @@
|
|
|
3051
3084
|
}
|
|
3052
3085
|
|
|
3053
3086
|
:where(ui-switch)[aria-checked="true"][pressed]::before {
|
|
3054
|
-
background: var(--accent-surface-active);
|
|
3055
|
-
border-color: var(--accent-surface-active);
|
|
3056
|
-
}
|
|
3057
|
-
|
|
3058
|
-
:where(ui-switch)[intent][aria-checked="true"][pressed]::before {
|
|
3059
3087
|
background: var(--_surface-active);
|
|
3060
3088
|
border-color: var(--_surface-active);
|
|
3061
3089
|
}
|
|
@@ -4494,7 +4522,7 @@
|
|
|
4494
4522
|
|
|
4495
4523
|
:where(ui-layout-chat) :where(.layout-resize-handle):hover,
|
|
4496
4524
|
:where(ui-layout-chat[resizing]) :where(.layout-resize-handle) {
|
|
4497
|
-
background: var(--
|
|
4525
|
+
background: var(--_border-muted);
|
|
4498
4526
|
}
|
|
4499
4527
|
|
|
4500
4528
|
}
|
|
@@ -4556,7 +4584,7 @@
|
|
|
4556
4584
|
|
|
4557
4585
|
:where(ui-layout-inspector) :where(.layout-resize-handle):hover,
|
|
4558
4586
|
:where(ui-layout-inspector[resizing]) :where(.layout-resize-handle) {
|
|
4559
|
-
background: var(--
|
|
4587
|
+
background: var(--_border-muted);
|
|
4560
4588
|
}
|
|
4561
4589
|
|
|
4562
4590
|
}
|
|
@@ -4583,16 +4611,16 @@
|
|
|
4583
4611
|
content: '';
|
|
4584
4612
|
width: var(--ui-layout-sidebar-width);
|
|
4585
4613
|
flex-shrink: 0;
|
|
4586
|
-
background: var(--
|
|
4587
|
-
border-right: 1px solid var(--
|
|
4614
|
+
background: var(--_body);
|
|
4615
|
+
border-right: 1px solid var(--_border-muted);
|
|
4588
4616
|
}
|
|
4589
4617
|
|
|
4590
4618
|
:where(ui-layout-sidebar):not([data-ready])[collapsed]::before {
|
|
4591
4619
|
content: '';
|
|
4592
4620
|
width: 48px;
|
|
4593
4621
|
flex-shrink: 0;
|
|
4594
|
-
background: var(--
|
|
4595
|
-
border-right: 1px solid var(--
|
|
4622
|
+
background: var(--_body);
|
|
4623
|
+
border-right: 1px solid var(--_border-muted);
|
|
4596
4624
|
}
|
|
4597
4625
|
|
|
4598
4626
|
/* ── Content Column ── */
|
|
@@ -4608,16 +4636,23 @@
|
|
|
4608
4636
|
}
|
|
4609
4637
|
|
|
4610
4638
|
/* ── Sidebar Aside ── */
|
|
4639
|
+
/* WHY: position: relative creates the containing block for absolute
|
|
4640
|
+
header/footer overlays. Content fills the full height and scrolls
|
|
4641
|
+
underneath the pinned header/footer. */
|
|
4611
4642
|
|
|
4612
4643
|
:where(ui-layout-sidebar) > :where([slot="sidebar"]) {
|
|
4644
|
+
--_sidebar-header-height: 0px;
|
|
4645
|
+
--_sidebar-footer-height: 0px;
|
|
4646
|
+
|
|
4647
|
+
container-name: sidebar;
|
|
4648
|
+
container-type: inline-size;
|
|
4649
|
+
position: sticky;
|
|
4650
|
+
top: 0;
|
|
4613
4651
|
width: var(--ui-layout-sidebar-width);
|
|
4614
4652
|
min-width: 160px;
|
|
4615
4653
|
max-width: 400px;
|
|
4616
4654
|
height: 100dvh;
|
|
4617
|
-
|
|
4618
|
-
top: 0;
|
|
4619
|
-
display: flex;
|
|
4620
|
-
flex-direction: column;
|
|
4655
|
+
display: block;
|
|
4621
4656
|
transition: width var(--_duration) var(--_easing), min-width var(--_duration) var(--_easing);
|
|
4622
4657
|
overflow: hidden;
|
|
4623
4658
|
z-index: 10;
|
|
@@ -4629,7 +4664,9 @@
|
|
|
4629
4664
|
}
|
|
4630
4665
|
|
|
4631
4666
|
/* ── Collapsed Icon Rail ── */
|
|
4632
|
-
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
4667
|
+
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
4668
|
+
[collapsed] drives the aside to 48px which triggers @container sidebar queries
|
|
4669
|
+
in this file and in child component CSS (ui-nav.css, etc.). */
|
|
4633
4670
|
|
|
4634
4671
|
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) {
|
|
4635
4672
|
width: 48px;
|
|
@@ -4650,11 +4687,7 @@
|
|
|
4650
4687
|
|
|
4651
4688
|
:where(ui-layout-sidebar) :where(.layout-resize-handle):hover,
|
|
4652
4689
|
:where(ui-layout-sidebar) > :where([slot="sidebar"][resizing]) :where(.layout-resize-handle) {
|
|
4653
|
-
background: var(--
|
|
4654
|
-
}
|
|
4655
|
-
|
|
4656
|
-
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) :where(.layout-resize-handle) {
|
|
4657
|
-
display: none;
|
|
4690
|
+
background: var(--_border-muted);
|
|
4658
4691
|
}
|
|
4659
4692
|
|
|
4660
4693
|
/* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
|
|
@@ -4667,101 +4700,89 @@
|
|
|
4667
4700
|
padding-left: 0;
|
|
4668
4701
|
}
|
|
4669
4702
|
|
|
4670
|
-
/* ── Collapsed Icon-Rail Content ── */
|
|
4671
|
-
/* WHY: When collapsed, sidebar slot becomes a narrow icon rail.
|
|
4672
|
-
Text and trailing slots are hidden; only icons remain visible.
|
|
4673
|
-
Nav items hide entirely — only group headers (with icons) stay. */
|
|
4674
|
-
|
|
4675
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-content) {
|
|
4676
|
-
align-items: center;
|
|
4677
|
-
padding: 0.5rem;
|
|
4678
|
-
}
|
|
4679
|
-
|
|
4680
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-header),
|
|
4681
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-footer) {
|
|
4682
|
-
justify-content: center;
|
|
4683
|
-
padding-inline: 0.5rem;
|
|
4684
|
-
}
|
|
4685
|
-
|
|
4686
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-trigger) :where([slot="label"]),
|
|
4687
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-layout-sidebar-trigger) :where([slot="trailing"]) {
|
|
4688
|
-
display: none;
|
|
4689
|
-
}
|
|
4690
|
-
|
|
4691
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-item) {
|
|
4692
|
-
display: none;
|
|
4693
|
-
}
|
|
4694
|
-
|
|
4695
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) > :where(details) > :where(summary) {
|
|
4696
|
-
justify-content: center;
|
|
4697
|
-
}
|
|
4698
|
-
|
|
4699
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
4700
|
-
display: none;
|
|
4701
|
-
}
|
|
4702
|
-
|
|
4703
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group)::after,
|
|
4704
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group)::before {
|
|
4705
|
-
display: none;
|
|
4706
|
-
}
|
|
4707
|
-
|
|
4708
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group-header) {
|
|
4709
|
-
justify-content: center;
|
|
4710
|
-
font-size: 0;
|
|
4711
|
-
gap: 0;
|
|
4712
|
-
}
|
|
4713
|
-
|
|
4714
|
-
/* WHY: Icon keeps its size even though parent font-size is 0. */
|
|
4715
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group-header) :where(ui-icon) {
|
|
4716
|
-
font-size: var(--_font-size, 1rem);
|
|
4717
|
-
}
|
|
4718
|
-
|
|
4719
|
-
:where(ui-layout-sidebar)[collapsed] :where([slot="sidebar"]) :where(ui-nav-group) + :where(ui-nav-group) {
|
|
4720
|
-
margin-block-start: 0;
|
|
4721
|
-
}
|
|
4722
|
-
|
|
4723
4703
|
/* ── Sidebar Header ── */
|
|
4704
|
+
/* WHY: Absolute-positioned overlay pinned to top of aside. Content scrolls
|
|
4705
|
+
underneath it. z-index: 2 sits above content (z-index: 0). */
|
|
4724
4706
|
|
|
4725
4707
|
:where(ui-layout-sidebar-header) {
|
|
4708
|
+
position: absolute;
|
|
4709
|
+
top: 0;
|
|
4710
|
+
left: 0;
|
|
4711
|
+
right: 0;
|
|
4712
|
+
z-index: 2;
|
|
4726
4713
|
display: flex;
|
|
4727
|
-
|
|
4728
|
-
min-height: var(--ui-layout-bar-height);
|
|
4729
|
-
gap: calc(var(--_space) * 2);
|
|
4730
|
-
padding-block: var(--_space);
|
|
4731
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4732
|
-
flex-shrink: 0;
|
|
4714
|
+
flex-direction: column;
|
|
4733
4715
|
}
|
|
4734
4716
|
|
|
4735
4717
|
/* ── Sidebar Content ── */
|
|
4718
|
+
/* WHY: Full height of the aside, scrollable. Padding-block offsets keep
|
|
4719
|
+
content from starting behind header / ending behind footer.
|
|
4720
|
+
Fade-out alpha mask dissolves content edges under the overlays. */
|
|
4736
4721
|
|
|
4737
4722
|
:where(ui-layout-sidebar-content) {
|
|
4738
4723
|
display: flex;
|
|
4739
4724
|
flex-direction: column;
|
|
4740
|
-
|
|
4741
|
-
padding-block: var(--
|
|
4742
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4743
|
-
flex: 1;
|
|
4744
|
-
min-height: 0;
|
|
4725
|
+
padding-block-start: var(--_sidebar-header-height);
|
|
4726
|
+
padding-block-end: var(--_sidebar-footer-height);
|
|
4745
4727
|
width: 100%;
|
|
4728
|
+
height: 100%;
|
|
4729
|
+
overflow-y: auto;
|
|
4730
|
+
scrollbar-width: none;
|
|
4731
|
+
}
|
|
4732
|
+
|
|
4733
|
+
/* WHY: When header is present, fade top edge. Content dissolves as it
|
|
4734
|
+
scrolls under the header — transparent at top, fully visible by 1.25×
|
|
4735
|
+
the header height. No opaque header background needed. */
|
|
4736
|
+
:where(ui-layout-sidebar-content)[data-has-header] {
|
|
4737
|
+
mask-image: linear-gradient(
|
|
4738
|
+
to bottom,
|
|
4739
|
+
transparent 0,
|
|
4740
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
4741
|
+
black 100%
|
|
4742
|
+
);
|
|
4743
|
+
}
|
|
4744
|
+
|
|
4745
|
+
/* WHY: When footer is present, fade bottom edge. */
|
|
4746
|
+
:where(ui-layout-sidebar-content)[data-has-footer] {
|
|
4747
|
+
mask-image: linear-gradient(
|
|
4748
|
+
to bottom,
|
|
4749
|
+
black 0,
|
|
4750
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
4751
|
+
transparent 100%
|
|
4752
|
+
);
|
|
4753
|
+
}
|
|
4754
|
+
|
|
4755
|
+
/* WHY: When both header AND footer are present, fade both edges. */
|
|
4756
|
+
:where(ui-layout-sidebar-content)[data-has-header][data-has-footer] {
|
|
4757
|
+
mask-image: linear-gradient(
|
|
4758
|
+
to bottom,
|
|
4759
|
+
transparent 0,
|
|
4760
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
4761
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
4762
|
+
transparent 100%
|
|
4763
|
+
);
|
|
4746
4764
|
}
|
|
4747
4765
|
|
|
4748
4766
|
/* ── Sidebar Footer ── */
|
|
4767
|
+
/* WHY: Absolute-positioned overlay pinned to bottom of aside. */
|
|
4749
4768
|
|
|
4750
4769
|
:where(ui-layout-sidebar-footer) {
|
|
4770
|
+
position: absolute;
|
|
4771
|
+
bottom: 0;
|
|
4772
|
+
left: 0;
|
|
4773
|
+
right: 0;
|
|
4774
|
+
z-index: 2;
|
|
4751
4775
|
display: flex;
|
|
4752
|
-
|
|
4753
|
-
min-height: var(--ui-layout-bar-height);
|
|
4754
|
-
gap: calc(var(--_space) * 2);
|
|
4755
|
-
padding-block: var(--_space);
|
|
4756
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4757
|
-
flex-shrink: 0;
|
|
4776
|
+
flex-direction: column;
|
|
4758
4777
|
}
|
|
4759
4778
|
|
|
4760
|
-
/* ── Sidebar
|
|
4761
|
-
/* WHY:
|
|
4762
|
-
|
|
4779
|
+
/* ── Sidebar Item ── */
|
|
4780
|
+
/* WHY: Universal sidebar row element. Provides inline padding for any content
|
|
4781
|
+
(buttons, links, icons). When a child ui-listbox[popover] is present, JS
|
|
4782
|
+
wires PopoverController for click-to-toggle menu behavior.
|
|
4783
|
+
Absorbs the old ui-layout-sidebar-trigger role — one element for all rows. */
|
|
4763
4784
|
|
|
4764
|
-
:where(ui-layout-sidebar-
|
|
4785
|
+
:where(ui-layout-sidebar-item) {
|
|
4765
4786
|
display: flex;
|
|
4766
4787
|
align-items: center;
|
|
4767
4788
|
flex: 1;
|
|
@@ -4777,29 +4798,59 @@
|
|
|
4777
4798
|
user-select: none;
|
|
4778
4799
|
border: none;
|
|
4779
4800
|
background: none;
|
|
4780
|
-
padding: var(--_space);
|
|
4801
|
+
padding-block: var(--_space);
|
|
4802
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4781
4803
|
border-radius: var(--_radius);
|
|
4782
4804
|
transition: color var(--_duration) var(--_easing);
|
|
4783
4805
|
}
|
|
4784
4806
|
|
|
4785
|
-
:
|
|
4807
|
+
/* WHY: Items in header/footer match the breadcrumb bar height so the
|
|
4808
|
+
first sidebar row aligns horizontally with the breadcrumb. */
|
|
4809
|
+
:where(ui-layout-sidebar-header) > :where(ui-layout-sidebar-item),
|
|
4810
|
+
:where(ui-layout-sidebar-footer) > :where(ui-layout-sidebar-item) {
|
|
4811
|
+
min-height: var(--ui-layout-bar-height);
|
|
4812
|
+
}
|
|
4813
|
+
|
|
4814
|
+
:where(ui-layout-sidebar-item):hover{
|
|
4786
4815
|
color: var(--_ink-strong);
|
|
4787
4816
|
}
|
|
4788
4817
|
|
|
4789
|
-
:where(ui-layout-sidebar-
|
|
4818
|
+
:where(ui-layout-sidebar-item):focus-visible{
|
|
4790
4819
|
outline: 2px solid var(--ui-focus-ring);
|
|
4791
4820
|
outline-offset: -2px;
|
|
4792
4821
|
}
|
|
4793
4822
|
|
|
4823
|
+
/* WHY: Fixed-size icon well so all sidebar icons (header logo, nav group icons,
|
|
4824
|
+
standalone icons) center-align on the same column width regardless of intrinsic
|
|
4825
|
+
icon size. 1.5rem matches the sidebar's visual rhythm at default density.
|
|
4826
|
+
Consumer wraps the icon: <span slot="icon"><ui-icon name="..."></ui-icon></span>
|
|
4827
|
+
The wrapper is the well; the icon keeps its own --ui-icon-size dimensions. */
|
|
4828
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
4829
|
+
display: inline-flex;
|
|
4830
|
+
align-items: center;
|
|
4831
|
+
justify-content: center;
|
|
4832
|
+
width: 1.5rem;
|
|
4833
|
+
height: 1.5rem;
|
|
4834
|
+
flex-shrink: 0;
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4794
4837
|
/* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
|
|
4795
|
-
:where(ui-layout-sidebar-
|
|
4838
|
+
:where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
|
|
4796
4839
|
margin-inline-start: auto;
|
|
4797
4840
|
flex-shrink: 0;
|
|
4798
4841
|
color: var(--_ink-muted);
|
|
4799
4842
|
}
|
|
4800
4843
|
|
|
4844
|
+
/* WHY: When the item wraps a sub-component (e.g. ui-button) that provides
|
|
4845
|
+
its own icon, hide [slot="icon"] in expanded mode — it only serves as the
|
|
4846
|
+
bare collapsed-rail representation. Items without sub-components (just
|
|
4847
|
+
icon + label + trailing) keep [slot="icon"] visible in both modes. */
|
|
4848
|
+
:where(ui-layout-sidebar-item:has(> ui-button)) > :where([slot="icon"]) {
|
|
4849
|
+
display: none;
|
|
4850
|
+
}
|
|
4851
|
+
|
|
4801
4852
|
/* WHY: Title text truncates when sidebar narrows during resize. */
|
|
4802
|
-
:where(ui-layout-sidebar-
|
|
4853
|
+
:where(ui-layout-sidebar-item) > :where([slot="label"]) {
|
|
4803
4854
|
flex: 1;
|
|
4804
4855
|
min-width: 0;
|
|
4805
4856
|
white-space: nowrap;
|
|
@@ -4807,25 +4858,67 @@
|
|
|
4807
4858
|
text-overflow: ellipsis;
|
|
4808
4859
|
}
|
|
4809
4860
|
|
|
4810
|
-
/* ──
|
|
4811
|
-
/* WHY: Popover opens to the right of the sidebar
|
|
4861
|
+
/* ── Item Popover ── */
|
|
4862
|
+
/* WHY: Popover opens to the right of the sidebar item.
|
|
4812
4863
|
Default: top-aligned, grows downward (span-block-end).
|
|
4813
4864
|
Flip: bottom-aligned, grows upward (span-block-start). */
|
|
4814
4865
|
|
|
4815
|
-
:where(ui-layout-sidebar-
|
|
4866
|
+
:where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
|
|
4816
4867
|
position: fixed;
|
|
4817
4868
|
position-area: inline-end span-block-end;
|
|
4818
|
-
position-try-fallbacks: --flip-up;
|
|
4869
|
+
position-try-fallbacks: --sidebar-item-flip-up;
|
|
4819
4870
|
margin: 0 0 0 var(--ui-popover-gap);
|
|
4820
4871
|
min-width: 200px;
|
|
4821
4872
|
max-height: var(--ui-popover-max-height);
|
|
4822
4873
|
overflow-y: auto;
|
|
4823
4874
|
}
|
|
4824
4875
|
|
|
4825
|
-
@position-try --flip-up {
|
|
4876
|
+
@position-try --sidebar-item-flip-up {
|
|
4826
4877
|
position-area: inline-end span-block-start;
|
|
4827
4878
|
}
|
|
4828
4879
|
|
|
4880
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
4881
|
+
/* WHY: Each component owns its own collapsed behavior via @container.
|
|
4882
|
+
The aside is the container (container-name: sidebar). When it shrinks
|
|
4883
|
+
to 48px (icon rail), components respond to the width, not to [collapsed].
|
|
4884
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
4885
|
+
|
|
4886
|
+
@container sidebar (max-width: 80px) {
|
|
4887
|
+
|
|
4888
|
+
/* Resize handle — no dragging in icon rail */
|
|
4889
|
+
:where(.layout-resize-handle) {
|
|
4890
|
+
display: none;
|
|
4891
|
+
}
|
|
4892
|
+
|
|
4893
|
+
/* Header/footer — center content horizontally */
|
|
4894
|
+
:where(ui-layout-sidebar-header),
|
|
4895
|
+
:where(ui-layout-sidebar-footer) {
|
|
4896
|
+
align-items: center;
|
|
4897
|
+
}
|
|
4898
|
+
|
|
4899
|
+
/* Content — center items in the 48px rail */
|
|
4900
|
+
:where(ui-layout-sidebar-content) {
|
|
4901
|
+
align-items: center;
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4904
|
+
/* Item — shrink to icon-only. Show [slot="icon"], hide everything else.
|
|
4905
|
+
WHY: Sidebar items can contain complex children (buttons with slots,
|
|
4906
|
+
links, etc.). Rather than overriding sub-component styles, the item
|
|
4907
|
+
provides its own bare icon via [slot="icon"] for the collapsed rail. */
|
|
4908
|
+
:where(ui-layout-sidebar-item) {
|
|
4909
|
+
flex: 0 0 auto;
|
|
4910
|
+
padding-inline: var(--_space);
|
|
4911
|
+
}
|
|
4912
|
+
|
|
4913
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
4914
|
+
display: inline-flex;
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4917
|
+
:where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
|
|
4918
|
+
display: none;
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
|
|
4829
4922
|
}
|
|
4830
4923
|
|
|
4831
4924
|
@layer ui {
|