@jungherz-de/glasskit 1.31.0 → 1.32.0
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/CHANGELOG.md +107 -1
- package/README.md +125 -20
- package/SKILL.md +496 -20
- package/glasskit-droplet.js +70 -32
- package/glasskit-styles.js +2 -2
- package/glasskit.css +783 -24
- package/glasskit.min.css +1 -1
- package/glasskit.min.css.map +1 -1
- package/package.json +2 -2
- package/theme-override.css +87 -0
package/glasskit.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ============================================================
|
|
2
2
|
GLASSKIT COMPONENT LIBRARY
|
|
3
|
-
Jungherz GmbH – v1.
|
|
3
|
+
Jungherz GmbH – v1.32.0
|
|
4
4
|
|
|
5
5
|
Features:
|
|
6
6
|
- Scoped Reset (box-sizing fix)
|
|
@@ -799,12 +799,15 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
|
|
|
799
799
|
stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
|
|
800
800
|
}
|
|
801
801
|
|
|
802
|
-
/* Primary
|
|
802
|
+
/* Primary. --gl-btn-primary-bg (since 1.32.0) replaces the whole
|
|
803
|
+
background, as the toggle and the radio have theirs: a product that keeps
|
|
804
|
+
white text starts the gradient darker without touching the brand colour,
|
|
805
|
+
which also draws focus rings, borders and the accent as text. */
|
|
803
806
|
.glass-btn--primary {
|
|
804
|
-
background: linear-gradient(135deg,
|
|
807
|
+
background: var(--gl-btn-primary-bg, linear-gradient(135deg,
|
|
805
808
|
var(--gl-color-primary) 0%, var(--gl-color-primary-mid) 50%,
|
|
806
809
|
var(--gl-color-primary-dark) 100%
|
|
807
|
-
);
|
|
810
|
+
));
|
|
808
811
|
color: var(--gl-color-on-primary, #ffffff);
|
|
809
812
|
border: 1px solid var(--gl-border-warm);
|
|
810
813
|
box-shadow: var(--gl-shadow-btn-primary), var(--gl-inset-strong);
|
|
@@ -1336,7 +1339,9 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
|
|
|
1336
1339
|
.glass-radio__dot {
|
|
1337
1340
|
width: var(--gl-radio-dot-size, 10px); height: var(--gl-radio-dot-size, 10px);
|
|
1338
1341
|
border-radius: var(--gl-radius-pill);
|
|
1339
|
-
|
|
1342
|
+
/* Unset, the ink on the primary (since 1.32.0), so the dot turns dark
|
|
1343
|
+
with the checkbox tick where a project switches the ink. */
|
|
1344
|
+
background: var(--gl-radio-dot-color, var(--gl-color-on-primary, white));
|
|
1340
1345
|
opacity: 0; transform: scale(0);
|
|
1341
1346
|
transition: var(--gl-transition-fast);
|
|
1342
1347
|
}
|
|
@@ -1984,7 +1989,16 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
1984
1989
|
on the item below it. Without the script a row keeps its usual look:
|
|
1985
1990
|
the tab bar its spotlight, the segmented row its raised option. GlassKit
|
|
1986
1991
|
Elements' <glk-tab-bar droplet> and <glk-segmented droplet> do all of
|
|
1987
|
-
this; for plain markup the docs have the script.
|
|
1992
|
+
this; for plain markup the docs have the script.
|
|
1993
|
+
|
|
1994
|
+
The motion is tokens (since 1.32.0), unset today's values, read by the
|
|
1995
|
+
stylesheet and the script alike: --gl-droplet-duration and -easing for
|
|
1996
|
+
the leading edge, -trail-duration, -trail-delay and -trail-easing for the
|
|
1997
|
+
trailing one, -lift (0.86; 1 squashes nothing), -lift-duration (280ms),
|
|
1998
|
+
-settle-duration and -settle-easing for the spring back, -lens-duration
|
|
1999
|
+
and -lens-easing for the item below the drop. In a column — a vertical
|
|
2000
|
+
tab bar, a sidebar — the script sets data-droplet-axis="y" and the
|
|
2001
|
+
directions "down" and "up", and the drop runs along y. */
|
|
1988
2002
|
.glass-tab-bar--floating.glass-tab-bar--droplet,
|
|
1989
2003
|
.glass-segmented.glass-segmented--droplet { position: relative; }
|
|
1990
2004
|
.glass-tab-bar.glass-tab-bar--droplet[data-droplet],
|
|
@@ -2012,9 +2026,11 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2012
2026
|
-webkit-backdrop-filter: blur(var(--gl-blur-light)) saturate(1.6);
|
|
2013
2027
|
pointer-events: none;
|
|
2014
2028
|
transition:
|
|
2015
|
-
transform 0.55s cubic-bezier(0.34, 1.8, 0.5, 1),
|
|
2029
|
+
transform var(--gl-droplet-settle-duration, 0.55s) var(--gl-droplet-settle-easing, cubic-bezier(0.34, 1.8, 0.5, 1)),
|
|
2016
2030
|
box-shadow 0.3s ease;
|
|
2017
2031
|
}
|
|
2032
|
+
/* A column hands sideways swipes to the page and keeps the vertical drag. */
|
|
2033
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-axis="y"] { touch-action: pan-x; }
|
|
2018
2034
|
/* The tab bar's drop is a capsule, in the active item's surface where a
|
|
2019
2035
|
project set one (--gl-tab-bar-active-bg, -shadow). */
|
|
2020
2036
|
.glass-tab-bar.glass-tab-bar--droplet[data-droplet]::before {
|
|
@@ -2042,18 +2058,35 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2042
2058
|
after it and overshoots, so the drop stretches and draws together. */
|
|
2043
2059
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir="right"]::before {
|
|
2044
2060
|
transition:
|
|
2045
|
-
right 0.3s cubic-bezier(0.3, 1.2, 0.5, 1),
|
|
2046
|
-
left 0.5s cubic-bezier(0.5, 1.5, 0.45, 0.92) 0.04s,
|
|
2047
|
-
top 0.3s ease, bottom 0.3s ease,
|
|
2048
|
-
transform 0.55s cubic-bezier(0.34, 1.8, 0.5, 1),
|
|
2061
|
+
right var(--gl-droplet-duration, 0.3s) var(--gl-droplet-easing, cubic-bezier(0.3, 1.2, 0.5, 1)),
|
|
2062
|
+
left var(--gl-droplet-trail-duration, 0.5s) var(--gl-droplet-trail-easing, cubic-bezier(0.5, 1.5, 0.45, 0.92)) var(--gl-droplet-trail-delay, 0.04s),
|
|
2063
|
+
top var(--gl-droplet-duration, 0.3s) ease, bottom var(--gl-droplet-duration, 0.3s) ease,
|
|
2064
|
+
transform var(--gl-droplet-settle-duration, 0.55s) var(--gl-droplet-settle-easing, cubic-bezier(0.34, 1.8, 0.5, 1)),
|
|
2049
2065
|
box-shadow 0.3s ease;
|
|
2050
2066
|
}
|
|
2051
2067
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir="left"]::before {
|
|
2052
2068
|
transition:
|
|
2053
|
-
left 0.3s cubic-bezier(0.3, 1.2, 0.5, 1),
|
|
2054
|
-
right 0.5s cubic-bezier(0.5, 1.5, 0.45, 0.92) 0.04s,
|
|
2055
|
-
top 0.3s ease, bottom 0.3s ease,
|
|
2056
|
-
transform 0.55s cubic-bezier(0.34, 1.8, 0.5, 1),
|
|
2069
|
+
left var(--gl-droplet-duration, 0.3s) var(--gl-droplet-easing, cubic-bezier(0.3, 1.2, 0.5, 1)),
|
|
2070
|
+
right var(--gl-droplet-trail-duration, 0.5s) var(--gl-droplet-trail-easing, cubic-bezier(0.5, 1.5, 0.45, 0.92)) var(--gl-droplet-trail-delay, 0.04s),
|
|
2071
|
+
top var(--gl-droplet-duration, 0.3s) ease, bottom var(--gl-droplet-duration, 0.3s) ease,
|
|
2072
|
+
transform var(--gl-droplet-settle-duration, 0.55s) var(--gl-droplet-settle-easing, cubic-bezier(0.34, 1.8, 0.5, 1)),
|
|
2073
|
+
box-shadow 0.3s ease;
|
|
2074
|
+
}
|
|
2075
|
+
/* In a column the same journey runs along y (since 1.32.0). */
|
|
2076
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir="down"]::before {
|
|
2077
|
+
transition:
|
|
2078
|
+
bottom var(--gl-droplet-duration, 0.3s) var(--gl-droplet-easing, cubic-bezier(0.3, 1.2, 0.5, 1)),
|
|
2079
|
+
top var(--gl-droplet-trail-duration, 0.5s) var(--gl-droplet-trail-easing, cubic-bezier(0.5, 1.5, 0.45, 0.92)) var(--gl-droplet-trail-delay, 0.04s),
|
|
2080
|
+
left var(--gl-droplet-duration, 0.3s) ease, right var(--gl-droplet-duration, 0.3s) ease,
|
|
2081
|
+
transform var(--gl-droplet-settle-duration, 0.55s) var(--gl-droplet-settle-easing, cubic-bezier(0.34, 1.8, 0.5, 1)),
|
|
2082
|
+
box-shadow 0.3s ease;
|
|
2083
|
+
}
|
|
2084
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir="up"]::before {
|
|
2085
|
+
transition:
|
|
2086
|
+
top var(--gl-droplet-duration, 0.3s) var(--gl-droplet-easing, cubic-bezier(0.3, 1.2, 0.5, 1)),
|
|
2087
|
+
bottom var(--gl-droplet-trail-duration, 0.5s) var(--gl-droplet-trail-easing, cubic-bezier(0.5, 1.5, 0.45, 0.92)) var(--gl-droplet-trail-delay, 0.04s),
|
|
2088
|
+
left var(--gl-droplet-duration, 0.3s) ease, right var(--gl-droplet-duration, 0.3s) ease,
|
|
2089
|
+
transform var(--gl-droplet-settle-duration, 0.55s) var(--gl-droplet-settle-easing, cubic-bezier(0.34, 1.8, 0.5, 1)),
|
|
2057
2090
|
box-shadow 0.3s ease;
|
|
2058
2091
|
}
|
|
2059
2092
|
/* While it travels the drop runs flatter and lifts off the row; it comes
|
|
@@ -2068,7 +2101,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2068
2101
|
var(--gl-inset-strong);
|
|
2069
2102
|
}
|
|
2070
2103
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-lift]::before {
|
|
2071
|
-
transform: scale(1, 0.86);
|
|
2104
|
+
transform: scale(1, var(--gl-droplet-lift, 0.86));
|
|
2072
2105
|
}
|
|
2073
2106
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-drag]::before {
|
|
2074
2107
|
transform: scale(1.1, 1.22);
|
|
@@ -2076,10 +2109,22 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2076
2109
|
left 0.1s ease-out, right 0.1s ease-out,
|
|
2077
2110
|
transform 0.25s ease-out, box-shadow 0.25s ease;
|
|
2078
2111
|
}
|
|
2112
|
+
/* Along y the drop runs narrower instead, and grows less across its long
|
|
2113
|
+
side when held: a sidebar's item is wide. */
|
|
2114
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-axis="y"][data-droplet-lift]::before {
|
|
2115
|
+
transform: scale(var(--gl-droplet-lift, 0.86), 1);
|
|
2116
|
+
}
|
|
2117
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-axis="y"][data-droplet-drag]::before {
|
|
2118
|
+
transform: scale(1.04, 1.18);
|
|
2119
|
+
transition:
|
|
2120
|
+
top 0.1s ease-out, bottom 0.1s ease-out,
|
|
2121
|
+
transform 0.25s ease-out, box-shadow 0.25s ease;
|
|
2122
|
+
}
|
|
2079
2123
|
|
|
2080
2124
|
/* The drop is the chosen item's surface, so the item draws none; on the
|
|
2081
2125
|
tab bar neither spotlight, dot nor glow. */
|
|
2082
2126
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-active { background: none; box-shadow: none; }
|
|
2127
|
+
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-active:focus-visible { box-shadow: var(--gl-shadow-focus); }
|
|
2083
2128
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-active::before { display: none; }
|
|
2084
2129
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-active .glass-tab-bar__icon::after { display: none; }
|
|
2085
2130
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-active .glass-tab-bar__icon > :where(:not(.glass-tab-bar__badge)),
|
|
@@ -2093,9 +2138,9 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2093
2138
|
a lens. While a finger drags the drop, the item below it takes the
|
|
2094
2139
|
chosen colour and the chosen item lets it go. The tab icon keeps the
|
|
2095
2140
|
fade of its colour next to the lens. */
|
|
2096
|
-
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition: var(--gl-transition), transform 0.4s cubic-bezier(0.34, 1.6, 0.5, 1); }
|
|
2141
|
+
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition: var(--gl-transition), transform var(--gl-droplet-lens-duration, 0.4s) var(--gl-droplet-lens-easing, cubic-bezier(0.34, 1.6, 0.5, 1)); }
|
|
2097
2142
|
.glass-segmented--droplet[data-droplet] .glass-segmented__dot,
|
|
2098
|
-
.glass-segmented--droplet[data-droplet] .glass-segmented__icon { transition: transform 0.4s cubic-bezier(0.34, 1.6, 0.5, 1); }
|
|
2143
|
+
.glass-segmented--droplet[data-droplet] .glass-segmented__icon { transition: transform var(--gl-droplet-lens-duration, 0.4s) var(--gl-droplet-lens-easing, cubic-bezier(0.34, 1.6, 0.5, 1)); }
|
|
2099
2144
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-under-droplet .glass-tab-bar__icon { transform: scale(1.15); }
|
|
2100
2145
|
.glass-segmented--droplet[data-droplet] .glass-segmented__item.is-under-droplet .glass-segmented__dot { transform: scale(1.3); }
|
|
2101
2146
|
.glass-segmented--droplet[data-droplet] .glass-segmented__item.is-under-droplet .glass-segmented__icon { transform: scale(1.15); }
|
|
@@ -2107,13 +2152,184 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2107
2152
|
@media (prefers-reduced-motion: reduce) {
|
|
2108
2153
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet]::before,
|
|
2109
2154
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir]::before,
|
|
2110
|
-
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-drag]::before
|
|
2155
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-drag]::before,
|
|
2156
|
+
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-axis="y"][data-droplet-drag]::before { transition: none; }
|
|
2111
2157
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition: var(--gl-transition), transform 0s; }
|
|
2112
2158
|
.glass-segmented--droplet[data-droplet] .glass-segmented__dot,
|
|
2113
2159
|
.glass-segmented--droplet[data-droplet] .glass-segmented__icon { transition: none; }
|
|
2114
2160
|
}
|
|
2115
2161
|
|
|
2116
2162
|
|
|
2163
|
+
/* ============================================================
|
|
2164
|
+
18d. TAB BAR – SIDEBAR, RAIL, TOP BAR, SIDE DOCK
|
|
2165
|
+
============================================================ */
|
|
2166
|
+
/* One navigation in more places than the bottom edge (since 1.32.0). The
|
|
2167
|
+
items stay the same — icon, label, badge, the active state, the drop —
|
|
2168
|
+
and only the bar's layout changes:
|
|
2169
|
+
|
|
2170
|
+
--vertical a column for a sidebar: placed by the page's layout (a grid
|
|
2171
|
+
column) and as high as its container, one item per row with
|
|
2172
|
+
the icon before the label at body size and the badge at the
|
|
2173
|
+
row's end. With --start or --end it is fixed to that edge of
|
|
2174
|
+
the viewport instead, full height and clear of the edge's
|
|
2175
|
+
safe area — the side a phone's thumb reaches when the system
|
|
2176
|
+
moves its own controls there. Start and end follow the
|
|
2177
|
+
writing direction.
|
|
2178
|
+
--rail with --vertical: icons alone, --gl-tab-bar-rail-width wide
|
|
2179
|
+
(72px). The label stays the item's name for assistive
|
|
2180
|
+
technology, hidden from view — show it in a tooltip — and the
|
|
2181
|
+
badge goes back to the icon's corner.
|
|
2182
|
+
--top a horizontal bar at the top: in the flow (put it in a sticky
|
|
2183
|
+
header), its border at the bottom, no room for the home
|
|
2184
|
+
indicator, and from 640px the icon beside the label.
|
|
2185
|
+
|
|
2186
|
+
The floating bar stands upright in a dock with --vertical and --start or
|
|
2187
|
+
--end: its items stacked as on the bottom edge, the accessory below them,
|
|
2188
|
+
above with --accessory-left. In a column the drop runs along y; the
|
|
2189
|
+
droplet script reads the flex direction. */
|
|
2190
|
+
|
|
2191
|
+
/* Every bar: a ring for the keyboard, which the items had none of. An
|
|
2192
|
+
item may be a link, to open a view in a new tab. */
|
|
2193
|
+
.glass-tab-bar__item:focus-visible { box-shadow: var(--gl-shadow-focus); }
|
|
2194
|
+
a.glass-tab-bar__item { text-decoration: none; color: inherit; }
|
|
2195
|
+
|
|
2196
|
+
/* ---- Sidebar ---- */
|
|
2197
|
+
.glass-tab-bar.glass-tab-bar--vertical {
|
|
2198
|
+
position: relative; inset: auto;
|
|
2199
|
+
height: 100%; width: auto;
|
|
2200
|
+
flex-direction: column; justify-content: flex-start; align-items: stretch;
|
|
2201
|
+
gap: var(--gl-space-2xs);
|
|
2202
|
+
padding: var(--gl-space-sm);
|
|
2203
|
+
border-top: none;
|
|
2204
|
+
border-inline-end: 1px solid var(--gl-border-subtle);
|
|
2205
|
+
overflow-y: auto; overscroll-behavior: contain;
|
|
2206
|
+
box-shadow: var(--gl-inset-subtle);
|
|
2207
|
+
}
|
|
2208
|
+
.glass-tab-bar--vertical .glass-tab-bar__item {
|
|
2209
|
+
position: relative;
|
|
2210
|
+
flex-direction: row; justify-content: flex-start;
|
|
2211
|
+
gap: var(--gl-space-sm);
|
|
2212
|
+
width: 100%; min-width: 0; min-height: 44px;
|
|
2213
|
+
padding: var(--gl-space-xs) var(--gl-space-md);
|
|
2214
|
+
text-align: start; text-decoration: none;
|
|
2215
|
+
}
|
|
2216
|
+
.glass-tab-bar--vertical .glass-tab-bar__label {
|
|
2217
|
+
flex: 1 1 auto; min-width: 0;
|
|
2218
|
+
font-size: var(--gl-font-size-base);
|
|
2219
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
2220
|
+
}
|
|
2221
|
+
.glass-tab-bar--vertical .glass-tab-bar__item:not(.is-active):hover { background: var(--gl-surface-1); }
|
|
2222
|
+
/* The active row stands on a surface of its own, unset --gl-surface-3,
|
|
2223
|
+
where the bottom bar has its dot. */
|
|
2224
|
+
.glass-tab-bar--vertical .glass-tab-bar__item.is-active { background: var(--gl-tab-bar-active-bg, var(--gl-surface-3)); }
|
|
2225
|
+
.glass-tab-bar--vertical .glass-tab-bar__item.is-active .glass-tab-bar__icon::after { display: none; }
|
|
2226
|
+
/* The badge at the row's end: positioned on the item, not the icon. */
|
|
2227
|
+
.glass-tab-bar--vertical:not(.glass-tab-bar--rail, .glass-tab-bar--floating) .glass-tab-bar__icon { position: static; }
|
|
2228
|
+
.glass-tab-bar--vertical:not(.glass-tab-bar--rail, .glass-tab-bar--floating) .glass-tab-bar__badge {
|
|
2229
|
+
top: 50%; inset-inline-end: var(--gl-space-md);
|
|
2230
|
+
transform: translateY(-50%);
|
|
2231
|
+
}
|
|
2232
|
+
/* A long label ends before the badge. */
|
|
2233
|
+
.glass-tab-bar--vertical:not(.glass-tab-bar--rail, .glass-tab-bar--floating) .glass-tab-bar__item:has(.glass-tab-bar__badge:not([hidden])) .glass-tab-bar__label {
|
|
2234
|
+
padding-inline-end: var(--gl-tab-bar-badge-room, 32px);
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
/* Fixed to an edge, full height, clear of that edge's safe area. */
|
|
2238
|
+
.glass-tab-bar.glass-tab-bar--vertical:is(.glass-tab-bar--start, .glass-tab-bar--end) {
|
|
2239
|
+
position: fixed; top: 0; bottom: 0; height: auto;
|
|
2240
|
+
padding-top: max(var(--gl-space-sm), env(safe-area-inset-top, 0px));
|
|
2241
|
+
padding-bottom: max(var(--gl-space-sm), env(safe-area-inset-bottom, 0px));
|
|
2242
|
+
z-index: var(--gl-tab-bar-z-index, 900);
|
|
2243
|
+
}
|
|
2244
|
+
.glass-tab-bar.glass-tab-bar--vertical.glass-tab-bar--start { inset-inline-start: 0; inset-inline-end: auto; }
|
|
2245
|
+
.glass-tab-bar.glass-tab-bar--vertical.glass-tab-bar--end {
|
|
2246
|
+
inset-inline-end: 0; inset-inline-start: auto;
|
|
2247
|
+
border-inline-end: none; border-inline-start: 1px solid var(--gl-border-subtle);
|
|
2248
|
+
}
|
|
2249
|
+
.glass-tab-bar.glass-tab-bar--vertical:is(.glass-tab-bar--start:dir(ltr), .glass-tab-bar--end:dir(rtl)) {
|
|
2250
|
+
padding-left: max(var(--gl-space-sm), env(safe-area-inset-left, 0px));
|
|
2251
|
+
}
|
|
2252
|
+
.glass-tab-bar.glass-tab-bar--vertical:is(.glass-tab-bar--end:dir(ltr), .glass-tab-bar--start:dir(rtl)) {
|
|
2253
|
+
padding-right: max(var(--gl-space-sm), env(safe-area-inset-right, 0px));
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/* ---- Rail ---- */
|
|
2257
|
+
.glass-tab-bar.glass-tab-bar--vertical.glass-tab-bar--rail {
|
|
2258
|
+
width: var(--gl-tab-bar-rail-width, 72px);
|
|
2259
|
+
align-items: center;
|
|
2260
|
+
padding-inline: var(--gl-space-xs);
|
|
2261
|
+
}
|
|
2262
|
+
.glass-tab-bar--rail .glass-tab-bar__item {
|
|
2263
|
+
justify-content: center;
|
|
2264
|
+
width: auto; min-width: 48px; min-height: 48px;
|
|
2265
|
+
padding: var(--gl-space-sm);
|
|
2266
|
+
}
|
|
2267
|
+
.glass-tab-bar--rail .glass-tab-bar__label {
|
|
2268
|
+
position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
|
|
2269
|
+
overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
/* ---- Floating, upright ---- */
|
|
2273
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical {
|
|
2274
|
+
flex-direction: column; align-items: center;
|
|
2275
|
+
width: auto; height: auto; max-height: 100%;
|
|
2276
|
+
padding: 10px 6px;
|
|
2277
|
+
border: 1px solid var(--gl-border-subtle);
|
|
2278
|
+
border-radius: var(--gl-tab-bar-floating-radius);
|
|
2279
|
+
}
|
|
2280
|
+
.glass-tab-bar--floating.glass-tab-bar--vertical .glass-tab-bar__item {
|
|
2281
|
+
flex-direction: column; gap: var(--gl-space-2xs);
|
|
2282
|
+
width: auto; min-height: 0;
|
|
2283
|
+
padding: var(--gl-space-2xs) var(--gl-space-sm);
|
|
2284
|
+
}
|
|
2285
|
+
.glass-tab-bar--floating.glass-tab-bar--vertical .glass-tab-bar__label {
|
|
2286
|
+
flex: none; font-size: var(--gl-tab-bar-label-size, 10px);
|
|
2287
|
+
}
|
|
2288
|
+
.glass-tab-bar--floating.glass-tab-bar--vertical .glass-tab-bar__item.is-active { background: var(--gl-tab-bar-active-bg, none); }
|
|
2289
|
+
|
|
2290
|
+
.glass-tab-bar-dock.glass-tab-bar-dock--vertical {
|
|
2291
|
+
flex-direction: column;
|
|
2292
|
+
top: 50%; bottom: auto;
|
|
2293
|
+
transform: translateY(-50%);
|
|
2294
|
+
max-width: none; max-height: calc(100dvh - 2 * var(--gl-space-md));
|
|
2295
|
+
/* The edge by the writing direction, for browsers without :dir(); the
|
|
2296
|
+
rules below add the safe area of the physical side. */
|
|
2297
|
+
left: auto; right: auto;
|
|
2298
|
+
inset-inline-end: calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-right, 0px));
|
|
2299
|
+
}
|
|
2300
|
+
.glass-tab-bar-dock.glass-tab-bar-dock--vertical.glass-tab-bar-dock--start {
|
|
2301
|
+
inset-inline-end: auto;
|
|
2302
|
+
inset-inline-start: calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-left, 0px));
|
|
2303
|
+
}
|
|
2304
|
+
.glass-tab-bar-dock.glass-tab-bar-dock--vertical.glass-tab-bar-dock--accessory-left { flex-direction: column-reverse; }
|
|
2305
|
+
/* Unset or --end, at the end edge; --start at the other. */
|
|
2306
|
+
.glass-tab-bar-dock.glass-tab-bar-dock--vertical:is(:not(.glass-tab-bar-dock--start):dir(ltr), .glass-tab-bar-dock--start:dir(rtl)) {
|
|
2307
|
+
left: auto; right: calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-right, 0px));
|
|
2308
|
+
}
|
|
2309
|
+
.glass-tab-bar-dock.glass-tab-bar-dock--vertical:is(.glass-tab-bar-dock--start:dir(ltr), :not(.glass-tab-bar-dock--start):dir(rtl)) {
|
|
2310
|
+
right: auto; left: calc(var(--gl-tab-bar-floating-bottom) + env(safe-area-inset-left, 0px));
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
/* ---- Top bar ---- */
|
|
2314
|
+
.glass-tab-bar.glass-tab-bar--top {
|
|
2315
|
+
position: relative; inset: auto;
|
|
2316
|
+
height: auto;
|
|
2317
|
+
align-items: center;
|
|
2318
|
+
padding-bottom: var(--gl-space-xs);
|
|
2319
|
+
border-top: none; border-bottom: 1px solid var(--gl-border-subtle);
|
|
2320
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.08), var(--gl-inset-subtle);
|
|
2321
|
+
}
|
|
2322
|
+
@media (min-width: 640px) {
|
|
2323
|
+
.glass-tab-bar--top .glass-tab-bar__item {
|
|
2324
|
+
flex-direction: row; gap: var(--gl-space-xs);
|
|
2325
|
+
padding-inline: var(--gl-space-md);
|
|
2326
|
+
}
|
|
2327
|
+
.glass-tab-bar--top .glass-tab-bar__label { font-size: var(--gl-font-size-sm); }
|
|
2328
|
+
/* Clear of the badge at the icon's corner. */
|
|
2329
|
+
.glass-tab-bar--top .glass-tab-bar__item:has(.glass-tab-bar__badge:not([hidden])) .glass-tab-bar__label { margin-inline-start: 8px; }
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
|
|
2117
2333
|
/* ============================================================
|
|
2118
2334
|
19. ACCORDION
|
|
2119
2335
|
============================================================ */
|
|
@@ -2440,6 +2656,171 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2440
2656
|
.glass-popover--end:dir(rtl) { transform-origin: top left; }
|
|
2441
2657
|
.glass-popover--end.is-open { transform: translateY(0) scale(1); }
|
|
2442
2658
|
|
|
2659
|
+
/* In the top layer (since 1.32.0): with the popover attribute the panel is
|
|
2660
|
+
shown with showPopover() and placed by script, fixed at the coordinates
|
|
2661
|
+
it writes. It is no longer cut off by a box with overflow: hidden around
|
|
2662
|
+
it, does not leave the screen at its edges, and closed it takes no room.
|
|
2663
|
+
GlassKit Elements' <glk-popover> does this. */
|
|
2664
|
+
/* It fades out with transitions that keep it in the top layer until they
|
|
2665
|
+
end (transition-behavior: allow-discrete), and in with an animation —
|
|
2666
|
+
written in longhands and keyframes, which the minifier keeps. */
|
|
2667
|
+
.glass-popover[popover] {
|
|
2668
|
+
position: fixed; inset: auto; margin: 0;
|
|
2669
|
+
transform: translateY(-4px) scale(0.96);
|
|
2670
|
+
transition-property: opacity, transform, overlay, display;
|
|
2671
|
+
transition-duration: .18s;
|
|
2672
|
+
transition-timing-function: ease;
|
|
2673
|
+
transition-behavior: allow-discrete;
|
|
2674
|
+
}
|
|
2675
|
+
.glass-popover[popover]:popover-open {
|
|
2676
|
+
opacity: 1; visibility: visible; pointer-events: auto;
|
|
2677
|
+
transform: none;
|
|
2678
|
+
animation: glass-popover-in .22s cubic-bezier(.2,.8,.2,1);
|
|
2679
|
+
}
|
|
2680
|
+
@keyframes glass-popover-in { from { opacity: 0; transform: translateY(-4px) scale(0.96); } }
|
|
2681
|
+
.glass-popover[popover][data-side="top"] { transform-origin: bottom center; }
|
|
2682
|
+
|
|
2683
|
+
|
|
2684
|
+
/* ============================================================
|
|
2685
|
+
24b. TOOLTIP
|
|
2686
|
+
============================================================ */
|
|
2687
|
+
/* A short name or hint for a control on hover and focus (since 1.32.0):
|
|
2688
|
+
an icon-only button, the items of a rail, a row action. Small text on an
|
|
2689
|
+
opaque surface of the theme, readable over any glass, at most
|
|
2690
|
+
--gl-tooltip-max-width (240px) wide; --gl-tooltip-bg and
|
|
2691
|
+
--gl-tooltip-color recolour it. role="tooltip"; the control points to it
|
|
2692
|
+
with aria-describedby, or aria-labelledby where it is the control's only
|
|
2693
|
+
name. Opened in the top layer (popover="hint") and placed by script next
|
|
2694
|
+
to its control, flipped and shifted to stay in the viewport; the pointer
|
|
2695
|
+
can move onto it without it closing (WCAG 1.4.13). GlassKit Elements'
|
|
2696
|
+
<glk-tooltip> does all of this. */
|
|
2697
|
+
.glass-tooltip {
|
|
2698
|
+
max-width: var(--gl-tooltip-max-width, 240px);
|
|
2699
|
+
padding: 6px 12px;
|
|
2700
|
+
border: 1px solid var(--gl-border-medium);
|
|
2701
|
+
border-radius: var(--gl-radius-sm);
|
|
2702
|
+
/* The popover's glass, tinted far enough to keep the text readable over
|
|
2703
|
+
whatever lies below it. */
|
|
2704
|
+
background: var(--gl-tooltip-bg, color-mix(in srgb, var(--gl-color-bg-mid) 80%, transparent));
|
|
2705
|
+
backdrop-filter: blur(var(--gl-blur));
|
|
2706
|
+
-webkit-backdrop-filter: blur(var(--gl-blur));
|
|
2707
|
+
box-shadow: var(--gl-shadow-card), var(--gl-inset-strong);
|
|
2708
|
+
color: var(--gl-tooltip-color, var(--gl-color-text));
|
|
2709
|
+
font-family: var(--gl-font-family);
|
|
2710
|
+
font-size: var(--gl-font-size-xs); font-weight: var(--gl-font-weight-medium);
|
|
2711
|
+
line-height: 1.4;
|
|
2712
|
+
overflow-wrap: anywhere;
|
|
2713
|
+
}
|
|
2714
|
+
.glass-tooltip[popover] {
|
|
2715
|
+
inset: auto; margin: 0; overflow: visible;
|
|
2716
|
+
opacity: 0;
|
|
2717
|
+
transition-property: opacity, overlay, display;
|
|
2718
|
+
transition-duration: .12s;
|
|
2719
|
+
transition-behavior: allow-discrete;
|
|
2720
|
+
}
|
|
2721
|
+
.glass-tooltip[popover]:popover-open { opacity: 1; animation: glass-fade-in .12s ease; }
|
|
2722
|
+
@keyframes glass-fade-in { from { opacity: 0; } }
|
|
2723
|
+
|
|
2724
|
+
|
|
2725
|
+
/* ============================================================
|
|
2726
|
+
24c. MENU
|
|
2727
|
+
============================================================ */
|
|
2728
|
+
/* A list of actions behind a button (since 1.32.0): the overflow menu of a
|
|
2729
|
+
header, the actions of a table row. On the popover's surface, in the top
|
|
2730
|
+
layer and placed like the tooltip. Items are buttons with
|
|
2731
|
+
role="menuitem" — or menuitemcheckbox and menuitemradio with aria-checked
|
|
2732
|
+
(or .is-checked), which shows the check mark — with an icon before the
|
|
2733
|
+
label and a hint at the end, such as a shortcut. --danger takes the error
|
|
2734
|
+
colour for something destructive, aria-disabled="true" leaves an item
|
|
2735
|
+
announced but inert; __separator and __group-label part the list. The
|
|
2736
|
+
keyboard — arrows, Home and End, typing to jump, Escape back to the
|
|
2737
|
+
button — is GlassKit Elements' <glk-menu>. */
|
|
2738
|
+
.glass-menu {
|
|
2739
|
+
min-width: 180px; max-width: min(320px, calc(100vw - 16px));
|
|
2740
|
+
max-height: min(70vh, 480px);
|
|
2741
|
+
overflow-y: auto; overscroll-behavior: contain;
|
|
2742
|
+
padding: 6px;
|
|
2743
|
+
background: var(--gl-surface-3);
|
|
2744
|
+
backdrop-filter: blur(var(--gl-blur));
|
|
2745
|
+
-webkit-backdrop-filter: blur(var(--gl-blur));
|
|
2746
|
+
border: 1px solid var(--gl-border-medium);
|
|
2747
|
+
border-radius: var(--gl-radius-card);
|
|
2748
|
+
box-shadow: var(--gl-shadow-card), var(--gl-inset-strong);
|
|
2749
|
+
color: var(--gl-color-text);
|
|
2750
|
+
font-family: var(--gl-font-family);
|
|
2751
|
+
}
|
|
2752
|
+
.glass-menu[popover] {
|
|
2753
|
+
inset: auto; margin: 0;
|
|
2754
|
+
opacity: 0; transform: scale(0.97);
|
|
2755
|
+
transition-property: opacity, transform, overlay, display;
|
|
2756
|
+
transition-duration: .14s;
|
|
2757
|
+
transition-behavior: allow-discrete;
|
|
2758
|
+
}
|
|
2759
|
+
.glass-menu[popover]:popover-open { opacity: 1; transform: none; animation: glass-menu-in .14s ease; }
|
|
2760
|
+
@keyframes glass-menu-in { from { opacity: 0; transform: scale(0.97); } }
|
|
2761
|
+
.glass-menu__item {
|
|
2762
|
+
display: flex; align-items: center; gap: 10px;
|
|
2763
|
+
width: 100%; min-height: 40px;
|
|
2764
|
+
padding: 8px 12px;
|
|
2765
|
+
/* Concentric with the panel's corners. */
|
|
2766
|
+
border: 0; border-radius: calc(var(--gl-radius-card) - 6px);
|
|
2767
|
+
background: none;
|
|
2768
|
+
color: var(--gl-color-text);
|
|
2769
|
+
font: inherit; font-size: var(--gl-font-size-sm); text-align: start;
|
|
2770
|
+
cursor: pointer; outline: none; user-select: none;
|
|
2771
|
+
-webkit-tap-highlight-color: transparent;
|
|
2772
|
+
}
|
|
2773
|
+
.glass-menu__item:hover,
|
|
2774
|
+
.glass-menu__item:focus,
|
|
2775
|
+
.glass-menu__item.is-focused { background: var(--gl-surface-2); }
|
|
2776
|
+
.glass-menu__item:focus-visible,
|
|
2777
|
+
.glass-menu__item.is-focus-visible { box-shadow: inset 0 0 0 2px var(--gl-border-focus); }
|
|
2778
|
+
.glass-menu__item--danger { color: var(--gl-color-error-on-surface, var(--gl-color-error)); }
|
|
2779
|
+
.glass-menu__item[aria-disabled="true"],
|
|
2780
|
+
.glass-menu__item.is-disabled { opacity: 0.45; cursor: not-allowed; }
|
|
2781
|
+
.glass-menu__icon {
|
|
2782
|
+
flex: none; width: 18px; height: 18px;
|
|
2783
|
+
display: flex; align-items: center; justify-content: center;
|
|
2784
|
+
color: var(--gl-icon-default);
|
|
2785
|
+
}
|
|
2786
|
+
.glass-menu__item--danger .glass-menu__icon { color: inherit; }
|
|
2787
|
+
.glass-menu__icon:empty, .glass-menu__icon[hidden] { display: none; }
|
|
2788
|
+
.glass-menu__icon svg,
|
|
2789
|
+
.glass-menu__icon ::slotted(svg) {
|
|
2790
|
+
width: 18px; height: 18px; fill: none;
|
|
2791
|
+
stroke: currentColor; stroke-width: 1.8;
|
|
2792
|
+
stroke-linecap: round; stroke-linejoin: round;
|
|
2793
|
+
}
|
|
2794
|
+
.glass-menu__check {
|
|
2795
|
+
flex: none; width: 16px; height: 16px;
|
|
2796
|
+
color: var(--gl-color-primary-text);
|
|
2797
|
+
visibility: hidden;
|
|
2798
|
+
}
|
|
2799
|
+
.glass-menu__check svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
|
|
2800
|
+
.glass-menu__item:is([aria-checked="true"], .is-checked) .glass-menu__check { visibility: visible; }
|
|
2801
|
+
.glass-menu__label {
|
|
2802
|
+
flex: 1 1 auto; min-width: 0;
|
|
2803
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
2804
|
+
}
|
|
2805
|
+
.glass-menu__trailing {
|
|
2806
|
+
flex: none; margin-inline-start: auto; padding-inline-start: var(--gl-space-sm);
|
|
2807
|
+
color: var(--gl-color-text-muted); font-size: var(--gl-font-size-xs);
|
|
2808
|
+
}
|
|
2809
|
+
.glass-menu__separator {
|
|
2810
|
+
height: 1px; margin: var(--gl-space-2xs) var(--gl-space-xs);
|
|
2811
|
+
border: 0; background: var(--gl-border-subtle);
|
|
2812
|
+
}
|
|
2813
|
+
.glass-menu__group-label {
|
|
2814
|
+
padding: 6px 12px 2px;
|
|
2815
|
+
color: var(--gl-color-text-muted);
|
|
2816
|
+
font-size: var(--gl-font-size-xs); font-weight: var(--gl-font-weight-semibold);
|
|
2817
|
+
}
|
|
2818
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2819
|
+
.glass-popover[popover], .glass-popover[popover]:popover-open,
|
|
2820
|
+
.glass-tooltip[popover], .glass-tooltip[popover]:popover-open,
|
|
2821
|
+
.glass-menu[popover], .glass-menu[popover]:popover-open { transition: none; animation: none; }
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2443
2824
|
|
|
2444
2825
|
/* ============================================================
|
|
2445
2826
|
25. LIST
|
|
@@ -2558,6 +2939,9 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2558
2939
|
background: var(--gl-surface-2);
|
|
2559
2940
|
outline: none;
|
|
2560
2941
|
}
|
|
2942
|
+
/* A ring for the keyboard (since 1.32.0), inside the row: the list clips
|
|
2943
|
+
what lies outside it. The tint alone was too faint to find the focus. */
|
|
2944
|
+
.glass-list__item--interactive:focus-visible { box-shadow: inset 0 0 0 2px var(--gl-border-focus); }
|
|
2561
2945
|
.glass-list__item--interactive:active {
|
|
2562
2946
|
background: var(--gl-surface-3);
|
|
2563
2947
|
}
|
|
@@ -2689,6 +3073,249 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2689
3073
|
}
|
|
2690
3074
|
|
|
2691
3075
|
|
|
3076
|
+
/* ============================================================
|
|
3077
|
+
25b. TREE
|
|
3078
|
+
============================================================ */
|
|
3079
|
+
/* Levels that open and close (since 1.32.0): the structure of an app, menus
|
|
3080
|
+
with submenus. A row per item — a twisty that turns when the item opens,
|
|
3081
|
+
an icon, the label, something at the end (a badge, a status, an action) —
|
|
3082
|
+
indented by --gl-tree-indent (20px) per level, with the item's children
|
|
3083
|
+
in a __group below it. role="tree" on the container, "treeitem" on each
|
|
3084
|
+
item with aria-level, aria-expanded on the ones with children and
|
|
3085
|
+
aria-selected; one tab stop and the arrow keys of the WAI-ARIA tree view,
|
|
3086
|
+
which GlassKit Elements' <glk-tree> brings. No surface of its own: put it
|
|
3087
|
+
in a card or a sidebar. */
|
|
3088
|
+
.glass-tree {
|
|
3089
|
+
display: flex; flex-direction: column; gap: 1px;
|
|
3090
|
+
margin: 0; padding: 0; list-style: none;
|
|
3091
|
+
font-family: var(--gl-font-family);
|
|
3092
|
+
font-size: var(--gl-font-size-sm);
|
|
3093
|
+
color: var(--gl-color-text);
|
|
3094
|
+
}
|
|
3095
|
+
.glass-tree__row {
|
|
3096
|
+
position: relative;
|
|
3097
|
+
display: flex; align-items: center; gap: var(--gl-space-xs);
|
|
3098
|
+
min-height: var(--gl-tree-row-height, 36px);
|
|
3099
|
+
padding-block: 4px;
|
|
3100
|
+
padding-inline: calc(var(--gl-space-xs) + (var(--gl-tree-level, 1) - 1) * var(--gl-tree-indent, 20px)) var(--gl-space-sm);
|
|
3101
|
+
border-radius: var(--gl-radius-sm);
|
|
3102
|
+
cursor: pointer; user-select: none;
|
|
3103
|
+
transition: background .15s ease;
|
|
3104
|
+
}
|
|
3105
|
+
.glass-tree__row:hover { background: var(--gl-surface-1); }
|
|
3106
|
+
/* The chosen row stands on raised glass, as the active row of a sidebar
|
|
3107
|
+
does, its icon in the accent. */
|
|
3108
|
+
.glass-tree__row.is-selected {
|
|
3109
|
+
background: var(--gl-tree-selected-bg, var(--gl-surface-4));
|
|
3110
|
+
box-shadow: var(--gl-inset-strong), var(--gl-shadow-btn);
|
|
3111
|
+
color: var(--gl-color-text-heading);
|
|
3112
|
+
font-weight: var(--gl-font-weight-semibold);
|
|
3113
|
+
}
|
|
3114
|
+
.glass-tree__row.is-selected .glass-tree__icon { color: var(--gl-color-primary-text); }
|
|
3115
|
+
.glass-tree__row.is-focus-visible,
|
|
3116
|
+
.glass-tree__row:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--gl-border-focus); }
|
|
3117
|
+
/* In plain markup the treeitem takes the focus, its row shows it. */
|
|
3118
|
+
.glass-tree [role="treeitem"]:focus-visible { outline: none; }
|
|
3119
|
+
.glass-tree [role="treeitem"]:focus-visible > .glass-tree__row { box-shadow: inset 0 0 0 2px var(--gl-border-focus); }
|
|
3120
|
+
.glass-tree__row.is-disabled { opacity: 0.45; cursor: not-allowed; }
|
|
3121
|
+
.glass-tree__twisty {
|
|
3122
|
+
flex: none; width: 20px; height: 20px;
|
|
3123
|
+
display: flex; align-items: center; justify-content: center;
|
|
3124
|
+
color: var(--gl-icon-default);
|
|
3125
|
+
border-radius: var(--gl-radius-xs);
|
|
3126
|
+
transition: transform .15s ease;
|
|
3127
|
+
}
|
|
3128
|
+
.glass-tree__twisty svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
3129
|
+
.glass-tree__twisty:dir(rtl) { transform: scaleX(-1); }
|
|
3130
|
+
.glass-tree__row.is-expanded .glass-tree__twisty { transform: rotate(90deg); }
|
|
3131
|
+
.glass-tree__row.is-leaf .glass-tree__twisty { visibility: hidden; }
|
|
3132
|
+
/* Children on their way: the twisty turns into a small spinner. */
|
|
3133
|
+
.glass-tree__row.is-loading .glass-tree__twisty svg { display: none; }
|
|
3134
|
+
.glass-tree__row.is-loading .glass-tree__twisty::after {
|
|
3135
|
+
content: ''; width: 12px; height: 12px;
|
|
3136
|
+
border: 2px solid var(--gl-border-medium); border-top-color: var(--gl-color-primary);
|
|
3137
|
+
border-radius: 50%;
|
|
3138
|
+
animation: glass-tree-spin .8s linear infinite;
|
|
3139
|
+
}
|
|
3140
|
+
@keyframes glass-tree-spin { to { transform: rotate(360deg); } }
|
|
3141
|
+
.glass-tree__icon {
|
|
3142
|
+
flex: none; width: 18px; height: 18px;
|
|
3143
|
+
display: flex; align-items: center; justify-content: center;
|
|
3144
|
+
color: var(--gl-icon-default);
|
|
3145
|
+
}
|
|
3146
|
+
.glass-tree__icon:empty, .glass-tree__icon[hidden] { display: none; }
|
|
3147
|
+
.glass-tree__icon svg,
|
|
3148
|
+
.glass-tree__icon ::slotted(svg) {
|
|
3149
|
+
width: 18px; height: 18px; fill: none;
|
|
3150
|
+
stroke: currentColor; stroke-width: 1.8;
|
|
3151
|
+
stroke-linecap: round; stroke-linejoin: round;
|
|
3152
|
+
}
|
|
3153
|
+
.glass-tree__label {
|
|
3154
|
+
flex: 1 1 auto; min-width: 0;
|
|
3155
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
3156
|
+
}
|
|
3157
|
+
.glass-tree__trailing {
|
|
3158
|
+
flex: none; display: flex; align-items: center; gap: var(--gl-space-2xs);
|
|
3159
|
+
margin-inline-start: auto;
|
|
3160
|
+
color: var(--gl-color-text-muted); font-size: var(--gl-font-size-xs);
|
|
3161
|
+
}
|
|
3162
|
+
.glass-tree__trailing[hidden] { display: none; }
|
|
3163
|
+
.glass-tree__group { display: flex; flex-direction: column; gap: 1px; margin: 0; padding: 0; list-style: none; }
|
|
3164
|
+
.glass-tree__group[hidden] { display: none; }
|
|
3165
|
+
/* Children that could not load: the twisty turns into a mark in the error
|
|
3166
|
+
colour, and opening the item again tries once more. */
|
|
3167
|
+
.glass-tree__row.is-error .glass-tree__twisty { color: var(--gl-color-error-on-surface, var(--gl-color-error)); }
|
|
3168
|
+
.glass-tree__row.is-error .glass-tree__twisty svg { display: none; }
|
|
3169
|
+
.glass-tree__row.is-error .glass-tree__twisty::after {
|
|
3170
|
+
content: '!';
|
|
3171
|
+
display: flex; align-items: center; justify-content: center;
|
|
3172
|
+
width: 14px; height: 14px; box-sizing: border-box;
|
|
3173
|
+
border: 1.5px solid currentColor; border-radius: 50%;
|
|
3174
|
+
font-size: 10px; font-weight: var(--gl-font-weight-semibold); line-height: 1;
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
/* A short flash on an item that changed elsewhere — on another device, by
|
|
3178
|
+
an undo — so the eye finds it among the others (since 1.32.0), on a tree
|
|
3179
|
+
row or a list item; --gl-flash-color tints it. */
|
|
3180
|
+
.glass-tree__row.is-flash,
|
|
3181
|
+
.glass-list__item.is-flash { animation: glass-flash 1.2s ease-out; }
|
|
3182
|
+
@keyframes glass-flash { from { background-color: var(--gl-flash-color, color-mix(in srgb, var(--gl-color-primary) 30%, transparent)); } }
|
|
3183
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3184
|
+
.glass-tree__twisty, .glass-tree__row { transition: none; }
|
|
3185
|
+
.glass-tree__row.is-loading .glass-tree__twisty::after { animation-duration: 2.4s; }
|
|
3186
|
+
.glass-tree__row.is-flash, .glass-list__item.is-flash { animation: none; }
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
|
|
3190
|
+
/* ============================================================
|
|
3191
|
+
25c. BREADCRUMBS
|
|
3192
|
+
============================================================ */
|
|
3193
|
+
/* The path through nested levels (since 1.32.0): My app › Main menu ›
|
|
3194
|
+
Services › Online booking. A <nav aria-label="Breadcrumb"> around an
|
|
3195
|
+
<ol>; each crumb a link (or a button), the current level plain text with
|
|
3196
|
+
aria-current="page". The separators are drawn by CSS, hidden from
|
|
3197
|
+
assistive technology and mirrored right to left. A crumb longer than
|
|
3198
|
+
--gl-breadcrumbs-crumb-width (200px) is cut with an ellipsis. Where the
|
|
3199
|
+
path does not fit, __overflow stands for the middle levels — a button
|
|
3200
|
+
that opens them as a menu; GlassKit Elements' <glk-breadcrumbs> folds
|
|
3201
|
+
them by itself and makes the crumbs drop targets for a sortable list. */
|
|
3202
|
+
.glass-breadcrumbs { min-width: 0; font-family: var(--gl-font-family); }
|
|
3203
|
+
.glass-breadcrumbs__list {
|
|
3204
|
+
display: flex; align-items: center; flex-wrap: nowrap;
|
|
3205
|
+
min-width: 0; margin: 0; padding: 0; list-style: none;
|
|
3206
|
+
font-size: var(--gl-font-size-sm);
|
|
3207
|
+
}
|
|
3208
|
+
.glass-breadcrumbs__item { display: flex; align-items: center; min-width: 0; }
|
|
3209
|
+
.glass-breadcrumbs__item[hidden] { display: none; }
|
|
3210
|
+
.glass-breadcrumbs__item + .glass-breadcrumbs__item::before {
|
|
3211
|
+
content: ''; flex: none;
|
|
3212
|
+
width: 6px; height: 6px; margin-inline: 4px 8px;
|
|
3213
|
+
border-top: 1.5px solid var(--gl-icon-muted);
|
|
3214
|
+
border-right: 1.5px solid var(--gl-icon-muted);
|
|
3215
|
+
transform: rotate(45deg);
|
|
3216
|
+
}
|
|
3217
|
+
.glass-breadcrumbs__item + .glass-breadcrumbs__item:dir(rtl)::before { transform: rotate(-135deg); }
|
|
3218
|
+
.glass-breadcrumbs__crumb,
|
|
3219
|
+
.glass-breadcrumbs__current {
|
|
3220
|
+
display: block; min-width: 0;
|
|
3221
|
+
max-width: var(--gl-breadcrumbs-crumb-width, 200px);
|
|
3222
|
+
padding: 4px 8px;
|
|
3223
|
+
border-radius: var(--gl-radius-full);
|
|
3224
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
3225
|
+
}
|
|
3226
|
+
.glass-breadcrumbs__crumb {
|
|
3227
|
+
border: 0; background: none;
|
|
3228
|
+
color: var(--gl-color-text-muted);
|
|
3229
|
+
font: inherit; text-decoration: none;
|
|
3230
|
+
cursor: pointer;
|
|
3231
|
+
transition: background .15s ease, color .15s ease;
|
|
3232
|
+
}
|
|
3233
|
+
.glass-breadcrumbs__crumb:hover { color: var(--gl-color-text); background: var(--gl-surface-1); }
|
|
3234
|
+
.glass-breadcrumbs__crumb:focus-visible { outline: none; box-shadow: var(--gl-shadow-focus); }
|
|
3235
|
+
.glass-breadcrumbs__current { color: var(--gl-color-text-heading); font-weight: var(--gl-font-weight-semibold); }
|
|
3236
|
+
.glass-breadcrumbs__overflow { min-width: 32px; text-align: center; letter-spacing: 1px; }
|
|
3237
|
+
/* The "…" crumb keeps its width where the path still does not fit. */
|
|
3238
|
+
.glass-breadcrumbs__item--overflow { flex: none; }
|
|
3239
|
+
/* A crumb as the target of a dragged item: it stands for its level. */
|
|
3240
|
+
.glass-breadcrumbs__crumb.is-drop-target,
|
|
3241
|
+
.glass-breadcrumbs__current.is-drop-target {
|
|
3242
|
+
color: var(--gl-color-text);
|
|
3243
|
+
background: color-mix(in srgb, var(--gl-color-primary) 18%, transparent);
|
|
3244
|
+
box-shadow: inset 0 0 0 1.5px var(--gl-border-focus);
|
|
3245
|
+
}
|
|
3246
|
+
.glass-breadcrumbs__crumb.is-drop-refused { box-shadow: inset 0 0 0 1.5px var(--gl-color-error-border); background: var(--gl-color-error-surface); }
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
/* ============================================================
|
|
3250
|
+
25d. SORTING
|
|
3251
|
+
============================================================ */
|
|
3252
|
+
/* The states of a drag that reorders a list or a tree (since 1.32.0). The
|
|
3253
|
+
dragged item stays where it was, faded (.is-sort-source); a raised copy,
|
|
3254
|
+
__ghost, follows the pointer in the top layer. A line shows where it
|
|
3255
|
+
lands before or after an item — .is-sort-before / .is-sort-after on the
|
|
3256
|
+
target, indented to the level it lands on (--gl-tree-level) — and an
|
|
3257
|
+
item that takes it inside lights up (.is-sort-inside); one that refuses
|
|
3258
|
+
it shows the error colour (.is-sort-refused). The motion of the items
|
|
3259
|
+
that make room and of the drop gliding into place is GlassKit
|
|
3260
|
+
Elements'; --gl-sort-duration (180ms) and --gl-sort-easing (ease-out)
|
|
3261
|
+
time it. None of it moves under prefers-reduced-motion. */
|
|
3262
|
+
.is-sort-source { opacity: 0.4; }
|
|
3263
|
+
.is-sort-before, .is-sort-after { position: relative; }
|
|
3264
|
+
.is-sort-before::before,
|
|
3265
|
+
.is-sort-after::before {
|
|
3266
|
+
content: ''; position: absolute; z-index: 2;
|
|
3267
|
+
inset-inline-start: calc(var(--gl-space-xs) + (var(--gl-tree-level, 1) - 1) * var(--gl-tree-indent, 20px));
|
|
3268
|
+
inset-inline-end: var(--gl-space-xs);
|
|
3269
|
+
height: 2px; border-radius: 1px;
|
|
3270
|
+
background: var(--gl-color-primary);
|
|
3271
|
+
box-shadow: 0 0 6px color-mix(in srgb, var(--gl-color-primary) 50%, transparent);
|
|
3272
|
+
pointer-events: none;
|
|
3273
|
+
}
|
|
3274
|
+
.is-sort-before::before { top: -1px; }
|
|
3275
|
+
.is-sort-after::before { bottom: -1px; }
|
|
3276
|
+
.is-sort-inside {
|
|
3277
|
+
background: color-mix(in srgb, var(--gl-color-primary) 16%, transparent);
|
|
3278
|
+
box-shadow: inset 0 0 0 1.5px var(--gl-border-focus);
|
|
3279
|
+
}
|
|
3280
|
+
.is-sort-refused {
|
|
3281
|
+
background: var(--gl-color-error-surface);
|
|
3282
|
+
box-shadow: inset 0 0 0 1.5px var(--gl-color-error-border);
|
|
3283
|
+
}
|
|
3284
|
+
.is-sort-refused::before { background: var(--gl-color-error); box-shadow: none; }
|
|
3285
|
+
.glass-sort__ghost {
|
|
3286
|
+
display: flex; align-items: center; gap: var(--gl-space-xs);
|
|
3287
|
+
max-width: min(360px, calc(100vw - 16px));
|
|
3288
|
+
padding: 10px 14px;
|
|
3289
|
+
border: 1px solid var(--gl-border-medium);
|
|
3290
|
+
border-radius: var(--gl-radius-sm);
|
|
3291
|
+
background: var(--gl-surface-4);
|
|
3292
|
+
backdrop-filter: blur(var(--gl-blur));
|
|
3293
|
+
-webkit-backdrop-filter: blur(var(--gl-blur));
|
|
3294
|
+
box-shadow: 0 12px 32px rgba(0,0,0,0.28), 0 2px 8px rgba(0,0,0,0.14), var(--gl-inset-strong);
|
|
3295
|
+
color: var(--gl-color-text);
|
|
3296
|
+
font-family: var(--gl-font-family); font-size: var(--gl-font-size-sm);
|
|
3297
|
+
font-weight: var(--gl-font-weight-medium);
|
|
3298
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
3299
|
+
pointer-events: none;
|
|
3300
|
+
}
|
|
3301
|
+
.glass-sort__ghost[popover] { inset: auto; margin: 0; overflow: hidden; }
|
|
3302
|
+
/* Closed, out of the page: its own display would keep it on screen. */
|
|
3303
|
+
.glass-sort__ghost[popover]:not(:popover-open) { display: none; }
|
|
3304
|
+
/* A handle: with one, only the handle starts a drag, so a tap on the item
|
|
3305
|
+
still chooses it; a finger on it drags at once, without the long press. */
|
|
3306
|
+
.glass-sort__handle {
|
|
3307
|
+
flex: none; display: flex; align-items: center; justify-content: center;
|
|
3308
|
+
color: var(--gl-icon-muted);
|
|
3309
|
+
cursor: grab; touch-action: none;
|
|
3310
|
+
}
|
|
3311
|
+
.glass-sort__handle[hidden] { display: none; }
|
|
3312
|
+
.glass-sort__handle svg,
|
|
3313
|
+
.glass-sort__handle ::slotted(svg) {
|
|
3314
|
+
width: 18px; height: 18px; fill: none;
|
|
3315
|
+
stroke: currentColor; stroke-width: 1.8; stroke-linecap: round;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
|
|
2692
3319
|
/* ============================================================
|
|
2693
3320
|
26. SKELETON
|
|
2694
3321
|
============================================================ */
|
|
@@ -2728,12 +3355,12 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2728
3355
|
font-size: var(--gl-font-size-sm); color: var(--gl-color-text);
|
|
2729
3356
|
}
|
|
2730
3357
|
.glass-table th {
|
|
2731
|
-
text-align: start; padding: 8px 10px; white-space: nowrap;
|
|
3358
|
+
text-align: start; padding: var(--gl-table-header-padding, 8px 10px); white-space: nowrap;
|
|
2732
3359
|
font-weight: var(--gl-font-weight-medium); color: var(--gl-color-text-muted);
|
|
2733
3360
|
border-bottom: 1px solid var(--gl-border-medium);
|
|
2734
3361
|
}
|
|
2735
3362
|
.glass-table td {
|
|
2736
|
-
padding: 9px 10px; vertical-align: top;
|
|
3363
|
+
padding: var(--gl-table-cell-padding, 9px 10px); vertical-align: top;
|
|
2737
3364
|
border-bottom: 1px solid var(--gl-border-subtle);
|
|
2738
3365
|
}
|
|
2739
3366
|
.glass-table tbody tr:last-child td { border-bottom: 0; }
|
|
@@ -2741,6 +3368,131 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2741
3368
|
.glass-table__num { text-align: end; font-variant-numeric: tabular-nums; }
|
|
2742
3369
|
.glass-table__muted { color: var(--gl-color-text-muted); }
|
|
2743
3370
|
|
|
3371
|
+
/* More since 1.32.0, mostly brought by GlassKit Elements' <glk-table>
|
|
3372
|
+
around the table, which keeps it a native table in the page:
|
|
3373
|
+
|
|
3374
|
+
__sort a button filling a header cell that sorts by its column;
|
|
3375
|
+
the th carries aria-sort and the arrow shows it.
|
|
3376
|
+
--sticky the header cells stick to the top of a wrap that scrolls
|
|
3377
|
+
both ways (.glass-table-wrap--sticky, as high as
|
|
3378
|
+
--gl-table-max-height, 60vh), on --gl-table-header-bg.
|
|
3379
|
+
__actions a cell for row actions — a menu, icon buttons — at the
|
|
3380
|
+
row's end, kept there while the table scrolls sideways
|
|
3381
|
+
(on a surface of its own once it does: --scrolls).
|
|
3382
|
+
--list each row a card with the column's name before each value
|
|
3383
|
+
(data-label on the cells), the actions at its top end —
|
|
3384
|
+
for narrow places.
|
|
3385
|
+
|
|
3386
|
+
--gl-table-cell-padding and --gl-table-header-padding set the cells'
|
|
3387
|
+
room. */
|
|
3388
|
+
.glass-table__sort {
|
|
3389
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
3390
|
+
margin: -4px -6px; padding: 4px 6px;
|
|
3391
|
+
border: 0; border-radius: var(--gl-radius-xs);
|
|
3392
|
+
background: none; color: inherit;
|
|
3393
|
+
font: inherit; font-weight: inherit; white-space: nowrap;
|
|
3394
|
+
cursor: pointer;
|
|
3395
|
+
transition: background .15s ease, color .15s ease;
|
|
3396
|
+
}
|
|
3397
|
+
.glass-table__sort:hover { color: var(--gl-color-text); background: var(--gl-surface-1); }
|
|
3398
|
+
.glass-table__sort:focus-visible { outline: none; box-shadow: var(--gl-shadow-focus); }
|
|
3399
|
+
.glass-table__sort-icon {
|
|
3400
|
+
flex: none; width: 12px; height: 12px;
|
|
3401
|
+
fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
|
|
3402
|
+
opacity: 0.35;
|
|
3403
|
+
transition: transform .15s ease, opacity .15s ease;
|
|
3404
|
+
}
|
|
3405
|
+
.glass-table th:is([aria-sort="ascending"], [aria-sort="descending"]) .glass-table__sort { color: var(--gl-color-text); }
|
|
3406
|
+
.glass-table th:is([aria-sort="ascending"], [aria-sort="descending"]) .glass-table__sort-icon { opacity: 1; }
|
|
3407
|
+
.glass-table th[aria-sort="descending"] .glass-table__sort-icon { transform: rotate(180deg); }
|
|
3408
|
+
|
|
3409
|
+
.glass-table-wrap--sticky { overflow: auto; max-height: var(--gl-table-max-height, 60vh); overscroll-behavior: contain; }
|
|
3410
|
+
.glass-table--sticky thead th {
|
|
3411
|
+
position: sticky; top: 0; z-index: 2;
|
|
3412
|
+
/* The line goes with the cell: a collapsed border stays with the table. */
|
|
3413
|
+
border-bottom: 0;
|
|
3414
|
+
box-shadow: inset 0 -1px 0 var(--gl-border-medium);
|
|
3415
|
+
background: var(--gl-table-header-bg, color-mix(in srgb, var(--gl-color-bg-mid) 94%, transparent));
|
|
3416
|
+
backdrop-filter: blur(var(--gl-blur-light));
|
|
3417
|
+
-webkit-backdrop-filter: blur(var(--gl-blur-light));
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
.glass-table__actions {
|
|
3421
|
+
position: sticky; inset-inline-end: 0; z-index: 1;
|
|
3422
|
+
width: 1%; text-align: end; white-space: nowrap;
|
|
3423
|
+
}
|
|
3424
|
+
.glass-table--sticky thead th.glass-table__actions { z-index: 3; }
|
|
3425
|
+
.glass-table--scrolls .glass-table__actions {
|
|
3426
|
+
background: var(--gl-table-header-bg, color-mix(in srgb, var(--gl-color-bg-mid) 94%, transparent));
|
|
3427
|
+
box-shadow: -8px 0 8px -8px rgba(0,0,0,0.3);
|
|
3428
|
+
}
|
|
3429
|
+
.glass-table--scrolls .glass-table__actions:dir(rtl) { box-shadow: 8px 0 8px -8px rgba(0,0,0,0.3); }
|
|
3430
|
+
|
|
3431
|
+
/* The edges of a wrap that scrolls sideways shade where more columns wait
|
|
3432
|
+
(data-more-start, data-more-end on the frame, set by <glk-table>). */
|
|
3433
|
+
.glass-table-frame { position: relative; min-width: 0; }
|
|
3434
|
+
.glass-table-frame::before,
|
|
3435
|
+
.glass-table-frame::after {
|
|
3436
|
+
content: ''; position: absolute; top: 0; bottom: 0; z-index: 4;
|
|
3437
|
+
width: 16px; pointer-events: none;
|
|
3438
|
+
opacity: 0; transition: opacity .15s ease;
|
|
3439
|
+
}
|
|
3440
|
+
.glass-table-frame::before { inset-inline-start: 0; background: linear-gradient(to right, rgba(0,0,0,0.22), transparent); }
|
|
3441
|
+
.glass-table-frame::after { inset-inline-end: 0; background: linear-gradient(to left, rgba(0,0,0,0.22), transparent); }
|
|
3442
|
+
.glass-table-frame:dir(rtl)::before { background: linear-gradient(to left, rgba(0,0,0,0.22), transparent); }
|
|
3443
|
+
.glass-table-frame:dir(rtl)::after { background: linear-gradient(to right, rgba(0,0,0,0.22), transparent); }
|
|
3444
|
+
.glass-table-frame[data-more-start]::before,
|
|
3445
|
+
.glass-table-frame[data-more-end]::after { opacity: 1; }
|
|
3446
|
+
.glass-table__empty { padding: var(--gl-space-lg) var(--gl-space-md); }
|
|
3447
|
+
.glass-table__empty[hidden] { display: none; }
|
|
3448
|
+
|
|
3449
|
+
/* As cards. The header stays for assistive technology, hidden from view;
|
|
3450
|
+
the labels are generated content without a text of their own, so a
|
|
3451
|
+
screen reader does not hear the column twice. */
|
|
3452
|
+
.glass-table--list thead {
|
|
3453
|
+
position: absolute; width: 1px; height: 1px; margin: -1px;
|
|
3454
|
+
overflow: hidden; clip-path: inset(50%); white-space: nowrap;
|
|
3455
|
+
}
|
|
3456
|
+
.glass-table--list,
|
|
3457
|
+
.glass-table--list tbody,
|
|
3458
|
+
.glass-table--list tr,
|
|
3459
|
+
.glass-table--list td { display: block; width: 100%; box-sizing: border-box; }
|
|
3460
|
+
.glass-table--list tbody { display: flex; flex-direction: column; gap: var(--gl-space-sm); }
|
|
3461
|
+
.glass-table--list tr {
|
|
3462
|
+
position: relative;
|
|
3463
|
+
display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--gl-space-sm);
|
|
3464
|
+
padding: var(--gl-space-sm) var(--gl-space-md);
|
|
3465
|
+
border: 1px solid var(--gl-border-subtle);
|
|
3466
|
+
/* Glass like the list's and the accordion's items. */
|
|
3467
|
+
border-radius: var(--gl-radius-btn);
|
|
3468
|
+
background: var(--gl-surface-1);
|
|
3469
|
+
box-shadow: var(--gl-inset-subtle);
|
|
3470
|
+
}
|
|
3471
|
+
.glass-table--list td {
|
|
3472
|
+
display: flex; justify-content: space-between; align-items: baseline; gap: var(--gl-space-md);
|
|
3473
|
+
grid-column: 1 / -1;
|
|
3474
|
+
padding: 4px 0; border: 0;
|
|
3475
|
+
text-align: end; overflow-wrap: anywhere;
|
|
3476
|
+
}
|
|
3477
|
+
/* The actions at the card's top end, beside its first two values. */
|
|
3478
|
+
.glass-table--list tr:has(> .glass-table__actions) > td:nth-child(-n+2):not(.glass-table__actions) { grid-column: 1; }
|
|
3479
|
+
.glass-table--list td::before {
|
|
3480
|
+
content: attr(data-label);
|
|
3481
|
+
content: attr(data-label) / "";
|
|
3482
|
+
flex: none; max-width: 50%;
|
|
3483
|
+
color: var(--gl-color-text-muted); font-weight: var(--gl-font-weight-medium);
|
|
3484
|
+
text-align: start;
|
|
3485
|
+
}
|
|
3486
|
+
.glass-table--list td:is(:not([data-label]), [data-label=""])::before { content: none; }
|
|
3487
|
+
.glass-table--list tbody tr:hover td { background: none; }
|
|
3488
|
+
.glass-table--list .glass-table__actions {
|
|
3489
|
+
position: static; grid-column: 2; grid-row: 1 / span 2; align-self: start;
|
|
3490
|
+
width: auto; padding: 0; background: none; box-shadow: none;
|
|
3491
|
+
}
|
|
3492
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3493
|
+
.glass-table__sort, .glass-table__sort-icon, .glass-table-frame::before, .glass-table-frame::after { transition: none; }
|
|
3494
|
+
}
|
|
3495
|
+
|
|
2744
3496
|
|
|
2745
3497
|
/* ============================================================
|
|
2746
3498
|
28. PROSE
|
|
@@ -3010,8 +3762,11 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
3010
3762
|
color: var(--gl-color-success-on-surface);
|
|
3011
3763
|
}
|
|
3012
3764
|
.glass-steps__item--current { color: var(--gl-color-text-heading); }
|
|
3765
|
+
/* The flat accent fills that carry text — this number, the chosen day of
|
|
3766
|
+
the date strip and of the calendar — take --gl-color-primary-fill where
|
|
3767
|
+
it is set (since 1.32.0), else the primary. */
|
|
3013
3768
|
.glass-steps__item--current .glass-steps__num {
|
|
3014
|
-
background: var(--gl-color-primary); border-color: transparent;
|
|
3769
|
+
background: var(--gl-color-primary-fill, var(--gl-color-primary)); border-color: transparent;
|
|
3015
3770
|
color: var(--gl-color-on-primary);
|
|
3016
3771
|
}
|
|
3017
3772
|
.glass-steps__line { flex: 1 1 8px; min-width: 8px; height: 1px; background: var(--gl-border-subtle); }
|
|
@@ -3184,7 +3939,7 @@ dialog.glass-sheet-overlay::backdrop { background: transparent; }
|
|
|
3184
3939
|
.glass-date-strip__day:hover { background: var(--gl-surface-3); }
|
|
3185
3940
|
.glass-date-strip__day[aria-pressed="true"] {
|
|
3186
3941
|
--gl-date-strip-ink: var(--gl-color-on-primary);
|
|
3187
|
-
background: var(--gl-color-primary);
|
|
3942
|
+
background: var(--gl-color-primary-fill, var(--gl-color-primary));
|
|
3188
3943
|
color: var(--gl-color-on-primary);
|
|
3189
3944
|
border-color: transparent;
|
|
3190
3945
|
box-shadow: var(--gl-shadow-btn-primary);
|
|
@@ -3201,6 +3956,10 @@ dialog.glass-sheet-overlay::backdrop { background: transparent; }
|
|
|
3201
3956
|
font-size: var(--gl-font-size-xs); opacity: 0.75;
|
|
3202
3957
|
text-transform: uppercase; letter-spacing: 0.04em;
|
|
3203
3958
|
}
|
|
3959
|
+
/* On the chosen chip the weekday is as strong as the number (since
|
|
3960
|
+
1.32.0): faded, it stayed below 4.5:1 even on a fill that the number
|
|
3961
|
+
reaches it on. */
|
|
3962
|
+
.glass-date-strip__day[aria-pressed="true"] .glass-date-strip__wd { opacity: 1; }
|
|
3204
3963
|
.glass-date-strip__num {
|
|
3205
3964
|
font-size: var(--gl-font-size-lg); font-weight: var(--gl-font-weight-semibold);
|
|
3206
3965
|
line-height: 1.1;
|
|
@@ -3290,7 +4049,7 @@ dialog.glass-sheet-overlay::backdrop { background: transparent; }
|
|
|
3290
4049
|
.glass-calendar__day--today { border-color: var(--gl-border-warm); }
|
|
3291
4050
|
.glass-calendar__day[aria-pressed="true"] {
|
|
3292
4051
|
--gl-calendar-ink: var(--gl-color-on-primary);
|
|
3293
|
-
background: var(--gl-color-primary);
|
|
4052
|
+
background: var(--gl-color-primary-fill, var(--gl-color-primary));
|
|
3294
4053
|
color: var(--gl-color-on-primary);
|
|
3295
4054
|
}
|
|
3296
4055
|
.glass-calendar__day:focus-visible { box-shadow: var(--gl-shadow-focus); }
|