@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/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.25rem;
|
|
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;
|
|
@@ -2036,8 +2049,11 @@
|
|
|
2036
2049
|
/* WHY: Connector draws from below the header to the bottom of the group.
|
|
2037
2050
|
Only shown when header contains an icon. Scoped via :has(). */
|
|
2038
2051
|
|
|
2052
|
+
/* WHY: Insets account for the summary's padding-inline so the connector
|
|
2053
|
+
line passes through the icon center and child text aligns with header text. */
|
|
2039
2054
|
:where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)) {
|
|
2040
|
-
--_group-
|
|
2055
|
+
--_group-pad: calc(var(--_space-k) * var(--_space));
|
|
2056
|
+
--_group-line-inset: calc(var(--_group-pad) + var(--_icon-size) / 2);
|
|
2041
2057
|
--_group-child-inset: calc(var(--_icon-size) + var(--_space) * 2);
|
|
2042
2058
|
}
|
|
2043
2059
|
|
|
@@ -2083,6 +2099,73 @@
|
|
|
2083
2099
|
margin-inline-start: var(--_group-child-inset, 0);
|
|
2084
2100
|
}
|
|
2085
2101
|
|
|
2102
|
+
/* ── Nav Group Flyout (collapsed sidebar) ── */
|
|
2103
|
+
/* WHY: In collapsed mode, summary click opens a ui-listbox popover to the right
|
|
2104
|
+
instead of expanding the <details>. Same pattern as sidebar-trigger menus. */
|
|
2105
|
+
|
|
2106
|
+
:where(ui-nav-group) > :where(ui-listbox.nav-group-flyout[popover]) {
|
|
2107
|
+
position: fixed;
|
|
2108
|
+
position-area: inline-end span-block-end;
|
|
2109
|
+
position-try-fallbacks: --nav-flyout-flip-up;
|
|
2110
|
+
margin: 0 0 0 var(--ui-popover-gap);
|
|
2111
|
+
min-width: 200px;
|
|
2112
|
+
max-height: var(--ui-popover-max-height);
|
|
2113
|
+
overflow-y: auto;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
@position-try --nav-flyout-flip-up {
|
|
2117
|
+
position-area: inline-end span-block-start;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
2121
|
+
/* WHY: Nav components own their own collapsed behavior via @container.
|
|
2122
|
+
The sidebar aside declares container-name: sidebar. When it shrinks
|
|
2123
|
+
to 48px (icon rail), nav responds to the width — not to [collapsed].
|
|
2124
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
2125
|
+
|
|
2126
|
+
@container sidebar (max-width: 80px) {
|
|
2127
|
+
|
|
2128
|
+
/* Nav items hide entirely — only group headers (with icons) remain. */
|
|
2129
|
+
:where(ui-nav-item) {
|
|
2130
|
+
display: none;
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
/* Summary shrinks to icon-only. Reduced inline padding wraps tightly
|
|
2134
|
+
around the icon; parent align-items: center handles horizontal centering. */
|
|
2135
|
+
:where(ui-nav-group) > :where(details) > :where(summary) {
|
|
2136
|
+
padding-inline: var(--_space);
|
|
2137
|
+
border-radius: var(--_radius);
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
/* Hide chevron — no expand/collapse in icon rail (flyout instead). */
|
|
2141
|
+
:where(ui-nav-group) > :where(details) > :where(summary)::after {
|
|
2142
|
+
display: none;
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
/* Hide vertical connector line and sliding indicator. */
|
|
2146
|
+
:where(ui-nav-group)::after,
|
|
2147
|
+
:where(ui-nav-group)::before {
|
|
2148
|
+
display: none;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
/* Header collapses to icon-only. font-size: 0 hides text nodes
|
|
2152
|
+
(can't be targeted by CSS). Icon overrides back to normal below. */
|
|
2153
|
+
:where(ui-nav-group-header) {
|
|
2154
|
+
flex: 0 0 auto;
|
|
2155
|
+
font-size: 0;
|
|
2156
|
+
gap: 0;
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
:where(ui-nav-group-header) :where(ui-icon) {
|
|
2160
|
+
font-size: var(--_font-size, 1rem);
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
/* Collapse inter-group spacing in icon rail. */
|
|
2164
|
+
:where(ui-nav-group) + :where(ui-nav-group) {
|
|
2165
|
+
margin-block-start: 0;
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2086
2169
|
}
|
|
2087
2170
|
|
|
2088
2171
|
@layer ui {
|
|
@@ -2223,27 +2306,15 @@
|
|
|
2223
2306
|
}
|
|
2224
2307
|
|
|
2225
2308
|
/* ── 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
2309
|
|
|
2230
2310
|
: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
2311
|
background: var(--_surface);
|
|
2242
2312
|
border-color: var(--_surface);
|
|
2243
2313
|
}
|
|
2244
2314
|
|
|
2245
|
-
:where(ui-radio
|
|
2315
|
+
:where(ui-radio)[aria-checked="true"]::after {
|
|
2246
2316
|
background: var(--_surface-ink);
|
|
2317
|
+
transform: translateY(-50%) scale(1);
|
|
2247
2318
|
}
|
|
2248
2319
|
|
|
2249
2320
|
/* ── Hover ── */
|
|
@@ -2258,11 +2329,6 @@
|
|
|
2258
2329
|
}
|
|
2259
2330
|
|
|
2260
2331
|
: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
2332
|
background: var(--_surface-hover);
|
|
2267
2333
|
border-color: var(--_surface-hover);
|
|
2268
2334
|
}
|
|
@@ -2275,11 +2341,6 @@
|
|
|
2275
2341
|
}
|
|
2276
2342
|
|
|
2277
2343
|
: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
2344
|
background: var(--_surface-active);
|
|
2284
2345
|
border-color: var(--_surface-active);
|
|
2285
2346
|
}
|
|
@@ -2377,16 +2438,12 @@
|
|
|
2377
2438
|
/* 0% = track-height (circle), 100% = full width */
|
|
2378
2439
|
width: calc(var(--_track-height) + (100% - var(--_track-height)) * var(--_progress));
|
|
2379
2440
|
border-radius: calc(var(--_track-height) / 2);
|
|
2380
|
-
background: var(--
|
|
2441
|
+
background: var(--_surface);
|
|
2381
2442
|
|
|
2382
2443
|
transition:
|
|
2383
2444
|
background var(--_duration) var(--_easing);
|
|
2384
2445
|
}
|
|
2385
2446
|
|
|
2386
|
-
:where(ui-range)[intent]::after {
|
|
2387
|
-
background: var(--_surface);
|
|
2388
|
-
}
|
|
2389
|
-
|
|
2390
2447
|
/* ── Thumb ── */
|
|
2391
2448
|
|
|
2392
2449
|
:where(ui-range) > :where(.ui-range-thumb) {
|
|
@@ -2398,8 +2455,8 @@
|
|
|
2398
2455
|
width: var(--_thumb-size);
|
|
2399
2456
|
height: var(--_thumb-size);
|
|
2400
2457
|
border-radius: 50%;
|
|
2401
|
-
background: var(--
|
|
2402
|
-
border: 2px solid var(--
|
|
2458
|
+
background: var(--_surface-ink);
|
|
2459
|
+
border: 2px solid var(--_surface);
|
|
2403
2460
|
box-shadow: var(--ui-shadow-sm);
|
|
2404
2461
|
pointer-events: none;
|
|
2405
2462
|
|
|
@@ -2409,11 +2466,6 @@
|
|
|
2409
2466
|
border-color var(--_duration) var(--_easing);
|
|
2410
2467
|
}
|
|
2411
2468
|
|
|
2412
|
-
:where(ui-range)[intent] > :where(.ui-range-thumb) {
|
|
2413
|
-
background: var(--_surface-ink);
|
|
2414
|
-
border-color: var(--_surface);
|
|
2415
|
-
}
|
|
2416
|
-
|
|
2417
2469
|
/* ── Focus ── */
|
|
2418
2470
|
|
|
2419
2471
|
:where(ui-range):focus-visible > :where(.ui-range-thumb){
|
|
@@ -2424,19 +2476,10 @@
|
|
|
2424
2476
|
/* ── Hover ── */
|
|
2425
2477
|
|
|
2426
2478
|
:where(ui-range):hover::after{
|
|
2427
|
-
background: var(--accent-surface-hover);
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
:where(ui-range)[intent]:hover::after{
|
|
2431
2479
|
background: var(--_surface-hover);
|
|
2432
2480
|
}
|
|
2433
2481
|
|
|
2434
2482
|
: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
2483
|
border-color: var(--_surface-hover);
|
|
2441
2484
|
box-shadow: var(--ui-shadow-sm), 0 0 0 4px var(--_surface);
|
|
2442
2485
|
}
|
|
@@ -2444,19 +2487,10 @@
|
|
|
2444
2487
|
/* ── Active (dragging) ── */
|
|
2445
2488
|
|
|
2446
2489
|
:where(ui-range)[pressed]::after {
|
|
2447
|
-
background: var(--accent-surface-active);
|
|
2448
|
-
}
|
|
2449
|
-
|
|
2450
|
-
:where(ui-range)[intent][pressed]::after {
|
|
2451
2490
|
background: var(--_surface-active);
|
|
2452
2491
|
}
|
|
2453
2492
|
|
|
2454
2493
|
: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
2494
|
border-color: var(--_surface-active);
|
|
2461
2495
|
box-shadow: var(--ui-shadow-sm), 0 0 0 6px var(--_surface);
|
|
2462
2496
|
}
|
|
@@ -3003,22 +3037,13 @@
|
|
|
3003
3037
|
When an explicit [intent] is set, the intent selector's --_surface wins. */
|
|
3004
3038
|
|
|
3005
3039
|
:where(ui-switch)[aria-checked="true"]::before {
|
|
3006
|
-
background: var(--
|
|
3007
|
-
border-color: var(--
|
|
3040
|
+
background: var(--_surface);
|
|
3041
|
+
border-color: var(--_surface);
|
|
3008
3042
|
}
|
|
3009
3043
|
|
|
3010
3044
|
:where(ui-switch)[aria-checked="true"]::after {
|
|
3011
3045
|
/* Slide thumb to the right via translateX — GPU composited */
|
|
3012
3046
|
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
3047
|
background: var(--_surface-ink);
|
|
3023
3048
|
}
|
|
3024
3049
|
|
|
@@ -3034,11 +3059,6 @@
|
|
|
3034
3059
|
}
|
|
3035
3060
|
|
|
3036
3061
|
: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
3062
|
background: var(--_surface-hover);
|
|
3043
3063
|
border-color: var(--_surface-hover);
|
|
3044
3064
|
}
|
|
@@ -3051,11 +3071,6 @@
|
|
|
3051
3071
|
}
|
|
3052
3072
|
|
|
3053
3073
|
: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
3074
|
background: var(--_surface-active);
|
|
3060
3075
|
border-color: var(--_surface-active);
|
|
3061
3076
|
}
|
|
@@ -4494,7 +4509,7 @@
|
|
|
4494
4509
|
|
|
4495
4510
|
:where(ui-layout-chat) :where(.layout-resize-handle):hover,
|
|
4496
4511
|
:where(ui-layout-chat[resizing]) :where(.layout-resize-handle) {
|
|
4497
|
-
background: var(--
|
|
4512
|
+
background: var(--_border-muted);
|
|
4498
4513
|
}
|
|
4499
4514
|
|
|
4500
4515
|
}
|
|
@@ -4556,7 +4571,7 @@
|
|
|
4556
4571
|
|
|
4557
4572
|
:where(ui-layout-inspector) :where(.layout-resize-handle):hover,
|
|
4558
4573
|
:where(ui-layout-inspector[resizing]) :where(.layout-resize-handle) {
|
|
4559
|
-
background: var(--
|
|
4574
|
+
background: var(--_border-muted);
|
|
4560
4575
|
}
|
|
4561
4576
|
|
|
4562
4577
|
}
|
|
@@ -4583,16 +4598,16 @@
|
|
|
4583
4598
|
content: '';
|
|
4584
4599
|
width: var(--ui-layout-sidebar-width);
|
|
4585
4600
|
flex-shrink: 0;
|
|
4586
|
-
background: var(--
|
|
4587
|
-
border-right: 1px solid var(--
|
|
4601
|
+
background: var(--_body);
|
|
4602
|
+
border-right: 1px solid var(--_border-muted);
|
|
4588
4603
|
}
|
|
4589
4604
|
|
|
4590
4605
|
:where(ui-layout-sidebar):not([data-ready])[collapsed]::before {
|
|
4591
4606
|
content: '';
|
|
4592
4607
|
width: 48px;
|
|
4593
4608
|
flex-shrink: 0;
|
|
4594
|
-
background: var(--
|
|
4595
|
-
border-right: 1px solid var(--
|
|
4609
|
+
background: var(--_body);
|
|
4610
|
+
border-right: 1px solid var(--_border-muted);
|
|
4596
4611
|
}
|
|
4597
4612
|
|
|
4598
4613
|
/* ── Content Column ── */
|
|
@@ -4608,16 +4623,23 @@
|
|
|
4608
4623
|
}
|
|
4609
4624
|
|
|
4610
4625
|
/* ── Sidebar Aside ── */
|
|
4626
|
+
/* WHY: position: relative creates the containing block for absolute
|
|
4627
|
+
header/footer overlays. Content fills the full height and scrolls
|
|
4628
|
+
underneath the pinned header/footer. */
|
|
4611
4629
|
|
|
4612
4630
|
:where(ui-layout-sidebar) > :where([slot="sidebar"]) {
|
|
4631
|
+
--_sidebar-header-height: 0px;
|
|
4632
|
+
--_sidebar-footer-height: 0px;
|
|
4633
|
+
|
|
4634
|
+
container-name: sidebar;
|
|
4635
|
+
container-type: inline-size;
|
|
4636
|
+
position: sticky;
|
|
4637
|
+
top: 0;
|
|
4613
4638
|
width: var(--ui-layout-sidebar-width);
|
|
4614
4639
|
min-width: 160px;
|
|
4615
4640
|
max-width: 400px;
|
|
4616
4641
|
height: 100dvh;
|
|
4617
|
-
|
|
4618
|
-
top: 0;
|
|
4619
|
-
display: flex;
|
|
4620
|
-
flex-direction: column;
|
|
4642
|
+
display: block;
|
|
4621
4643
|
transition: width var(--_duration) var(--_easing), min-width var(--_duration) var(--_easing);
|
|
4622
4644
|
overflow: hidden;
|
|
4623
4645
|
z-index: 10;
|
|
@@ -4629,7 +4651,9 @@
|
|
|
4629
4651
|
}
|
|
4630
4652
|
|
|
4631
4653
|
/* ── Collapsed Icon Rail ── */
|
|
4632
|
-
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
4654
|
+
/* WHY: Collapsed = icon rail, not fully hidden. 48px fits icons (1rem) + padding.
|
|
4655
|
+
[collapsed] drives the aside to 48px which triggers @container sidebar queries
|
|
4656
|
+
in this file and in child component CSS (ui-nav.css, etc.). */
|
|
4633
4657
|
|
|
4634
4658
|
:where(ui-layout-sidebar)[collapsed] > :where([slot="sidebar"]) {
|
|
4635
4659
|
width: 48px;
|
|
@@ -4650,11 +4674,7 @@
|
|
|
4650
4674
|
|
|
4651
4675
|
:where(ui-layout-sidebar) :where(.layout-resize-handle):hover,
|
|
4652
4676
|
: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;
|
|
4677
|
+
background: var(--_border-muted);
|
|
4658
4678
|
}
|
|
4659
4679
|
|
|
4660
4680
|
/* WHY: When collapsed to icon rail, the sidebar edge meets content — drop left padding. */
|
|
@@ -4668,47 +4688,88 @@
|
|
|
4668
4688
|
}
|
|
4669
4689
|
|
|
4670
4690
|
/* ── Sidebar Header ── */
|
|
4691
|
+
/* WHY: Absolute-positioned overlay pinned to top of aside. Content scrolls
|
|
4692
|
+
underneath it. z-index: 2 sits above content (z-index: 0). */
|
|
4671
4693
|
|
|
4672
4694
|
:where(ui-layout-sidebar-header) {
|
|
4695
|
+
position: absolute;
|
|
4696
|
+
top: 0;
|
|
4697
|
+
left: 0;
|
|
4698
|
+
right: 0;
|
|
4699
|
+
z-index: 2;
|
|
4673
4700
|
display: flex;
|
|
4674
|
-
|
|
4675
|
-
min-height: var(--ui-layout-bar-height);
|
|
4676
|
-
gap: calc(var(--_space) * 2);
|
|
4677
|
-
padding-block: var(--_space);
|
|
4678
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4679
|
-
flex-shrink: 0;
|
|
4701
|
+
flex-direction: column;
|
|
4680
4702
|
}
|
|
4681
4703
|
|
|
4682
4704
|
/* ── Sidebar Content ── */
|
|
4705
|
+
/* WHY: Full height of the aside, scrollable. Padding-block offsets keep
|
|
4706
|
+
content from starting behind header / ending behind footer.
|
|
4707
|
+
Fade-out alpha mask dissolves content edges under the overlays. */
|
|
4683
4708
|
|
|
4684
4709
|
:where(ui-layout-sidebar-content) {
|
|
4685
4710
|
display: flex;
|
|
4686
4711
|
flex-direction: column;
|
|
4687
|
-
|
|
4688
|
-
padding-block: var(--
|
|
4689
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4690
|
-
flex: 1;
|
|
4691
|
-
min-height: 0;
|
|
4712
|
+
padding-block-start: var(--_sidebar-header-height);
|
|
4713
|
+
padding-block-end: var(--_sidebar-footer-height);
|
|
4692
4714
|
width: 100%;
|
|
4715
|
+
height: 100%;
|
|
4716
|
+
overflow-y: auto;
|
|
4717
|
+
scrollbar-width: none;
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
/* WHY: When header is present, fade top edge. Content dissolves as it
|
|
4721
|
+
scrolls under the header — transparent at top, fully visible by 1.25×
|
|
4722
|
+
the header height. No opaque header background needed. */
|
|
4723
|
+
:where(ui-layout-sidebar-content)[data-has-header] {
|
|
4724
|
+
mask-image: linear-gradient(
|
|
4725
|
+
to bottom,
|
|
4726
|
+
transparent 0,
|
|
4727
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
4728
|
+
black 100%
|
|
4729
|
+
);
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
/* WHY: When footer is present, fade bottom edge. */
|
|
4733
|
+
:where(ui-layout-sidebar-content)[data-has-footer] {
|
|
4734
|
+
mask-image: linear-gradient(
|
|
4735
|
+
to bottom,
|
|
4736
|
+
black 0,
|
|
4737
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
4738
|
+
transparent 100%
|
|
4739
|
+
);
|
|
4740
|
+
}
|
|
4741
|
+
|
|
4742
|
+
/* WHY: When both header AND footer are present, fade both edges. */
|
|
4743
|
+
:where(ui-layout-sidebar-content)[data-has-header][data-has-footer] {
|
|
4744
|
+
mask-image: linear-gradient(
|
|
4745
|
+
to bottom,
|
|
4746
|
+
transparent 0,
|
|
4747
|
+
black calc(var(--_sidebar-header-height) * 1.25),
|
|
4748
|
+
black calc(100% - var(--_sidebar-footer-height) * 1.25),
|
|
4749
|
+
transparent 100%
|
|
4750
|
+
);
|
|
4693
4751
|
}
|
|
4694
4752
|
|
|
4695
4753
|
/* ── Sidebar Footer ── */
|
|
4754
|
+
/* WHY: Absolute-positioned overlay pinned to bottom of aside. */
|
|
4696
4755
|
|
|
4697
4756
|
:where(ui-layout-sidebar-footer) {
|
|
4757
|
+
position: absolute;
|
|
4758
|
+
bottom: 0;
|
|
4759
|
+
left: 0;
|
|
4760
|
+
right: 0;
|
|
4761
|
+
z-index: 2;
|
|
4698
4762
|
display: flex;
|
|
4699
|
-
|
|
4700
|
-
min-height: var(--ui-layout-bar-height);
|
|
4701
|
-
gap: calc(var(--_space) * 2);
|
|
4702
|
-
padding-block: var(--_space);
|
|
4703
|
-
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4704
|
-
flex-shrink: 0;
|
|
4763
|
+
flex-direction: column;
|
|
4705
4764
|
}
|
|
4706
4765
|
|
|
4707
|
-
/* ── Sidebar
|
|
4708
|
-
/* WHY:
|
|
4709
|
-
|
|
4766
|
+
/* ── Sidebar Item ── */
|
|
4767
|
+
/* WHY: Universal sidebar row element. Provides inline padding for any content
|
|
4768
|
+
(buttons, links, icons). When a child ui-listbox[popover] is present, JS
|
|
4769
|
+
wires PopoverController for click-to-toggle menu behavior.
|
|
4770
|
+
Absorbs the old ui-layout-sidebar-trigger role — one element for all rows. */
|
|
4710
4771
|
|
|
4711
|
-
:where(ui-layout-sidebar-
|
|
4772
|
+
:where(ui-layout-sidebar-item) {
|
|
4712
4773
|
display: flex;
|
|
4713
4774
|
align-items: center;
|
|
4714
4775
|
flex: 1;
|
|
@@ -4724,29 +4785,45 @@
|
|
|
4724
4785
|
user-select: none;
|
|
4725
4786
|
border: none;
|
|
4726
4787
|
background: none;
|
|
4727
|
-
padding: var(--_space);
|
|
4788
|
+
padding-block: var(--_space);
|
|
4789
|
+
padding-inline: calc(var(--_space-k) * var(--_space));
|
|
4728
4790
|
border-radius: var(--_radius);
|
|
4729
4791
|
transition: color var(--_duration) var(--_easing);
|
|
4730
4792
|
}
|
|
4731
4793
|
|
|
4732
|
-
:
|
|
4794
|
+
/* WHY: Items in header/footer match the breadcrumb bar height so the
|
|
4795
|
+
first sidebar row aligns horizontally with the breadcrumb. */
|
|
4796
|
+
:where(ui-layout-sidebar-header) > :where(ui-layout-sidebar-item),
|
|
4797
|
+
:where(ui-layout-sidebar-footer) > :where(ui-layout-sidebar-item) {
|
|
4798
|
+
min-height: var(--ui-layout-bar-height);
|
|
4799
|
+
}
|
|
4800
|
+
|
|
4801
|
+
:where(ui-layout-sidebar-item):hover{
|
|
4733
4802
|
color: var(--_ink-strong);
|
|
4734
4803
|
}
|
|
4735
4804
|
|
|
4736
|
-
:where(ui-layout-sidebar-
|
|
4805
|
+
:where(ui-layout-sidebar-item):focus-visible{
|
|
4737
4806
|
outline: 2px solid var(--ui-focus-ring);
|
|
4738
4807
|
outline-offset: -2px;
|
|
4739
4808
|
}
|
|
4740
4809
|
|
|
4741
4810
|
/* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
|
|
4742
|
-
:where(ui-layout-sidebar-
|
|
4811
|
+
:where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
|
|
4743
4812
|
margin-inline-start: auto;
|
|
4744
4813
|
flex-shrink: 0;
|
|
4745
4814
|
color: var(--_ink-muted);
|
|
4746
4815
|
}
|
|
4747
4816
|
|
|
4817
|
+
/* WHY: When the item wraps a sub-component (e.g. ui-button) that provides
|
|
4818
|
+
its own icon, hide [slot="icon"] in expanded mode — it only serves as the
|
|
4819
|
+
bare collapsed-rail representation. Items without sub-components (just
|
|
4820
|
+
icon + label + trailing) keep [slot="icon"] visible in both modes. */
|
|
4821
|
+
:where(ui-layout-sidebar-item:has(> ui-button)) > :where([slot="icon"]) {
|
|
4822
|
+
display: none;
|
|
4823
|
+
}
|
|
4824
|
+
|
|
4748
4825
|
/* WHY: Title text truncates when sidebar narrows during resize. */
|
|
4749
|
-
:where(ui-layout-sidebar-
|
|
4826
|
+
:where(ui-layout-sidebar-item) > :where([slot="label"]) {
|
|
4750
4827
|
flex: 1;
|
|
4751
4828
|
min-width: 0;
|
|
4752
4829
|
white-space: nowrap;
|
|
@@ -4754,25 +4831,67 @@
|
|
|
4754
4831
|
text-overflow: ellipsis;
|
|
4755
4832
|
}
|
|
4756
4833
|
|
|
4757
|
-
/* ──
|
|
4758
|
-
/* WHY: Popover opens to the right of the sidebar
|
|
4834
|
+
/* ── Item Popover ── */
|
|
4835
|
+
/* WHY: Popover opens to the right of the sidebar item.
|
|
4759
4836
|
Default: top-aligned, grows downward (span-block-end).
|
|
4760
4837
|
Flip: bottom-aligned, grows upward (span-block-start). */
|
|
4761
4838
|
|
|
4762
|
-
:where(ui-layout-sidebar-
|
|
4839
|
+
:where(ui-layout-sidebar-item) > :where(ui-listbox[popover]) {
|
|
4763
4840
|
position: fixed;
|
|
4764
4841
|
position-area: inline-end span-block-end;
|
|
4765
|
-
position-try-fallbacks: --flip-up;
|
|
4842
|
+
position-try-fallbacks: --sidebar-item-flip-up;
|
|
4766
4843
|
margin: 0 0 0 var(--ui-popover-gap);
|
|
4767
4844
|
min-width: 200px;
|
|
4768
4845
|
max-height: var(--ui-popover-max-height);
|
|
4769
4846
|
overflow-y: auto;
|
|
4770
4847
|
}
|
|
4771
4848
|
|
|
4772
|
-
@position-try --flip-up {
|
|
4849
|
+
@position-try --sidebar-item-flip-up {
|
|
4773
4850
|
position-area: inline-end span-block-start;
|
|
4774
4851
|
}
|
|
4775
4852
|
|
|
4853
|
+
/* ── Container Query: Collapsed Sidebar ── */
|
|
4854
|
+
/* WHY: Each component owns its own collapsed behavior via @container.
|
|
4855
|
+
The aside is the container (container-name: sidebar). When it shrinks
|
|
4856
|
+
to 48px (icon rail), components respond to the width, not to [collapsed].
|
|
4857
|
+
Threshold 80px: collapsed = 48px, min expanded = 160px. */
|
|
4858
|
+
|
|
4859
|
+
@container sidebar (max-width: 80px) {
|
|
4860
|
+
|
|
4861
|
+
/* Resize handle — no dragging in icon rail */
|
|
4862
|
+
:where(.layout-resize-handle) {
|
|
4863
|
+
display: none;
|
|
4864
|
+
}
|
|
4865
|
+
|
|
4866
|
+
/* Header/footer — center content horizontally */
|
|
4867
|
+
:where(ui-layout-sidebar-header),
|
|
4868
|
+
:where(ui-layout-sidebar-footer) {
|
|
4869
|
+
align-items: center;
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4872
|
+
/* Content — center items in the 48px rail */
|
|
4873
|
+
:where(ui-layout-sidebar-content) {
|
|
4874
|
+
align-items: center;
|
|
4875
|
+
}
|
|
4876
|
+
|
|
4877
|
+
/* Item — shrink to icon-only. Show [slot="icon"], hide everything else.
|
|
4878
|
+
WHY: Sidebar items can contain complex children (buttons with slots,
|
|
4879
|
+
links, etc.). Rather than overriding sub-component styles, the item
|
|
4880
|
+
provides its own bare icon via [slot="icon"] for the collapsed rail. */
|
|
4881
|
+
:where(ui-layout-sidebar-item) {
|
|
4882
|
+
flex: 0 0 auto;
|
|
4883
|
+
padding-inline: var(--_space);
|
|
4884
|
+
}
|
|
4885
|
+
|
|
4886
|
+
:where(ui-layout-sidebar-item) > :where([slot="icon"]) {
|
|
4887
|
+
display: block;
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4890
|
+
:where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
|
|
4891
|
+
display: none;
|
|
4892
|
+
}
|
|
4893
|
+
}
|
|
4894
|
+
|
|
4776
4895
|
}
|
|
4777
4896
|
|
|
4778
4897
|
@layer ui {
|