@jungherz-de/glasskit 1.32.0 → 1.33.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 +35 -1
- package/README.md +47 -13
- package/SKILL.md +81 -4
- package/glasskit-styles.js +2 -2
- package/glasskit.css +153 -13
- package/glasskit.min.css +1 -1
- package/glasskit.min.css.map +1 -1
- package/package.json +1 -1
- package/theme-override.css +32 -0
package/glasskit.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ============================================================
|
|
2
2
|
GLASSKIT COMPONENT LIBRARY
|
|
3
|
-
Jungherz GmbH – v1.
|
|
3
|
+
Jungherz GmbH – v1.33.0
|
|
4
4
|
|
|
5
5
|
Features:
|
|
6
6
|
- Scoped Reset (box-sizing fix)
|
|
@@ -927,6 +927,21 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
|
|
|
927
927
|
above its field (until 1.24.0). */
|
|
928
928
|
.glass-label:empty { display: none; }
|
|
929
929
|
|
|
930
|
+
/* A place at the end of the label row (since 1.33.0): "Forgot password?"
|
|
931
|
+
on the line of the label "Password". The __label-end element comes
|
|
932
|
+
after the field in the markup, so the keyboard reaches it after the
|
|
933
|
+
field, which reads best in a sign-in form; --label-end draws it on the
|
|
934
|
+
label's line, at its end. */
|
|
935
|
+
.glass-input-group.glass-input-group--label-end {
|
|
936
|
+
display: grid; grid-template-columns: minmax(0, 1fr) auto;
|
|
937
|
+
align-items: center; column-gap: var(--gl-space-sm);
|
|
938
|
+
}
|
|
939
|
+
.glass-input-group--label-end > * { grid-column: 1 / -1; }
|
|
940
|
+
.glass-input-group--label-end > .glass-label { grid-column: 1; grid-row: 1; }
|
|
941
|
+
.glass-input-group--label-end > .glass-input-group__label-end { grid-column: 2; grid-row: 1; justify-self: end; }
|
|
942
|
+
.glass-input-group__label-end { font-size: var(--gl-font-size-sm); }
|
|
943
|
+
.glass-input-group__label-end[hidden] { display: none; }
|
|
944
|
+
|
|
930
945
|
.glass-input {
|
|
931
946
|
width: 100%; height: var(--gl-control-height, 52px);
|
|
932
947
|
padding: 0 var(--gl-control-padding-x, var(--gl-space-md));
|
|
@@ -1731,7 +1746,12 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
1731
1746
|
padding: var(--gl-space-2xs) var(--gl-space-sm);
|
|
1732
1747
|
background: none; border: none; cursor: pointer;
|
|
1733
1748
|
border-radius: var(--gl-radius-sm);
|
|
1734
|
-
|
|
1749
|
+
/* Colours and the press move; the box does not (since 1.33.0): a bar that
|
|
1750
|
+
changes its layout — upright, floating, a rail — took 250ms to settle
|
|
1751
|
+
with `all`, and an item measured then was not yet its size. */
|
|
1752
|
+
transition-property: color, background-color, box-shadow, opacity, transform;
|
|
1753
|
+
transition-duration: 0.25s; transition-timing-function: ease;
|
|
1754
|
+
outline: none;
|
|
1735
1755
|
-webkit-tap-highlight-color: transparent;
|
|
1736
1756
|
min-width: 60px;
|
|
1737
1757
|
}
|
|
@@ -1743,26 +1763,28 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
1743
1763
|
inactive colour is --gl-icon-muted and the hovered one --gl-icon-default;
|
|
1744
1764
|
--gl-tab-bar-color and --gl-tab-bar-hover-color set them, for icon and
|
|
1745
1765
|
label alike. */
|
|
1766
|
+
/* --gl-tab-bar-icon-size (24px, since 1.33.0) sizes the box and the SVG:
|
|
1767
|
+
a compact top bar takes the 18px of the segmented control's icons. */
|
|
1746
1768
|
.glass-tab-bar__icon {
|
|
1747
|
-
width: 24px; height: 24px;
|
|
1769
|
+
width: var(--gl-tab-bar-icon-size, 24px); height: var(--gl-tab-bar-icon-size, 24px);
|
|
1748
1770
|
display: flex; align-items: center; justify-content: center;
|
|
1749
1771
|
position: relative;
|
|
1750
1772
|
color: var(--gl-tab-bar-color, var(--gl-icon-muted));
|
|
1751
|
-
font-size: 24px;
|
|
1752
|
-
transition:
|
|
1773
|
+
font-size: var(--gl-tab-bar-icon-size, 24px);
|
|
1774
|
+
transition: color 0.25s ease;
|
|
1753
1775
|
}
|
|
1754
1776
|
|
|
1755
1777
|
.glass-tab-bar__icon svg,
|
|
1756
1778
|
.glass-tab-bar__icon ::slotted(svg) {
|
|
1757
|
-
width: 24px; height: 24px; fill: none;
|
|
1779
|
+
width: var(--gl-tab-bar-icon-size, 24px); height: var(--gl-tab-bar-icon-size, 24px); fill: none;
|
|
1758
1780
|
stroke: currentColor; stroke-width: 1.8;
|
|
1759
1781
|
stroke-linecap: round; stroke-linejoin: round;
|
|
1760
|
-
transition:
|
|
1782
|
+
transition: color 0.25s ease;
|
|
1761
1783
|
}
|
|
1762
1784
|
|
|
1763
1785
|
.glass-tab-bar__label {
|
|
1764
1786
|
font-size: var(--gl-tab-bar-label-size, 10px); font-weight: var(--gl-font-weight-medium);
|
|
1765
|
-
color: var(--gl-tab-bar-color, var(--gl-icon-muted)); transition:
|
|
1787
|
+
color: var(--gl-tab-bar-color, var(--gl-icon-muted)); transition: color 0.25s ease;
|
|
1766
1788
|
letter-spacing: 0.2px;
|
|
1767
1789
|
}
|
|
1768
1790
|
|
|
@@ -1776,7 +1798,12 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
1776
1798
|
.glass-tab-bar__item.is-active .glass-tab-bar__icon ::slotted(*) {
|
|
1777
1799
|
filter: var(--gl-tab-bar-active-glow, drop-shadow(0 0 6px color-mix(in srgb, var(--gl-color-primary) 35%, transparent)));
|
|
1778
1800
|
}
|
|
1779
|
-
|
|
1801
|
+
/* --gl-tab-bar-active-weight (since 1.33.0) sets the active label's weight,
|
|
1802
|
+
unset the medium of every label. */
|
|
1803
|
+
.glass-tab-bar__item.is-active .glass-tab-bar__label {
|
|
1804
|
+
color: var(--gl-tab-bar-active-color, var(--gl-color-primary-text));
|
|
1805
|
+
font-weight: var(--gl-tab-bar-active-weight, var(--gl-font-weight-medium));
|
|
1806
|
+
}
|
|
1780
1807
|
|
|
1781
1808
|
/* The active item's own surface; unset, it has none. A capsule like the
|
|
1782
1809
|
selected tab of iOS 26 takes --gl-tab-bar-active-bg and -shadow; on the
|
|
@@ -1846,9 +1873,12 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
1846
1873
|
gap: var(--gl-space-2xs);
|
|
1847
1874
|
}
|
|
1848
1875
|
|
|
1876
|
+
/* --gl-tab-bar-item-radius (since 1.33.0) rounds the floating items and the
|
|
1877
|
+
drop, unset a capsule: rounded squares in a rail, the 12px of the
|
|
1878
|
+
segmented control in a compact top bar. */
|
|
1849
1879
|
.glass-tab-bar--floating .glass-tab-bar__item {
|
|
1850
1880
|
position: relative;
|
|
1851
|
-
border-radius: var(--gl-radius-full);
|
|
1881
|
+
border-radius: var(--gl-tab-bar-item-radius, var(--gl-radius-full));
|
|
1852
1882
|
padding: var(--gl-space-2xs) var(--gl-space-sm);
|
|
1853
1883
|
min-width: auto;
|
|
1854
1884
|
align-items: center;
|
|
@@ -2034,7 +2064,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2034
2064
|
/* The tab bar's drop is a capsule, in the active item's surface where a
|
|
2035
2065
|
project set one (--gl-tab-bar-active-bg, -shadow). */
|
|
2036
2066
|
.glass-tab-bar.glass-tab-bar--droplet[data-droplet]::before {
|
|
2037
|
-
border-radius: var(--gl-radius-full);
|
|
2067
|
+
border-radius: var(--gl-tab-bar-item-radius, var(--gl-radius-full));
|
|
2038
2068
|
background:
|
|
2039
2069
|
var(--gl-gloss-droplet, none),
|
|
2040
2070
|
var(--gl-tab-bar-active-bg, linear-gradient(to bottom, var(--gl-surface-5) 0%, var(--gl-surface-3) 100%));
|
|
@@ -2138,7 +2168,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2138
2168
|
a lens. While a finger drags the drop, the item below it takes the
|
|
2139
2169
|
chosen colour and the chosen item lets it go. The tab icon keeps the
|
|
2140
2170
|
fade of its colour next to the lens. */
|
|
2141
|
-
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition:
|
|
2171
|
+
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition: color 0.25s ease, transform var(--gl-droplet-lens-duration, 0.4s) var(--gl-droplet-lens-easing, cubic-bezier(0.34, 1.6, 0.5, 1)); }
|
|
2142
2172
|
.glass-segmented--droplet[data-droplet] .glass-segmented__dot,
|
|
2143
2173
|
.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)); }
|
|
2144
2174
|
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__item.is-under-droplet .glass-tab-bar__icon { transform: scale(1.15); }
|
|
@@ -2154,7 +2184,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
|
|
|
2154
2184
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-dir]::before,
|
|
2155
2185
|
:is(.glass-tab-bar.glass-tab-bar--droplet, .glass-segmented.glass-segmented--droplet)[data-droplet][data-droplet-drag]::before,
|
|
2156
2186
|
: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; }
|
|
2157
|
-
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition:
|
|
2187
|
+
.glass-tab-bar--droplet[data-droplet] .glass-tab-bar__icon { transition: color 0.25s ease, transform 0s; }
|
|
2158
2188
|
.glass-segmented--droplet[data-droplet] .glass-segmented__dot,
|
|
2159
2189
|
.glass-segmented--droplet[data-droplet] .glass-segmented__icon { transition: none; }
|
|
2160
2190
|
}
|
|
@@ -2287,6 +2317,99 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
|
|
|
2287
2317
|
}
|
|
2288
2318
|
.glass-tab-bar--floating.glass-tab-bar--vertical .glass-tab-bar__item.is-active { background: var(--gl-tab-bar-active-bg, none); }
|
|
2289
2319
|
|
|
2320
|
+
/* ---- Rail with labels (since 1.33.0) ---- */
|
|
2321
|
+
/* --labels with --rail: the label under the icon, as on the floating bar —
|
|
2322
|
+
a desktop rail that names its items. The items fill the rail's width
|
|
2323
|
+
(--gl-tab-bar-rail-width) and are at least --gl-tab-bar-rail-item-height
|
|
2324
|
+
(62px) high; --gl-tab-bar-item-radius rounds them and the drop, unset
|
|
2325
|
+
16px, the corners of a button. */
|
|
2326
|
+
/* A floating rail is a pane, not a pill, docked or in the flow: as high as
|
|
2327
|
+
its container, with the card's corners (--gl-tab-bar-rail-radius) and
|
|
2328
|
+
room around its items. */
|
|
2329
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical.glass-tab-bar--rail {
|
|
2330
|
+
width: var(--gl-tab-bar-rail-width, 72px); height: 100%;
|
|
2331
|
+
padding: var(--gl-space-sm) var(--gl-space-xs);
|
|
2332
|
+
border-radius: var(--gl-tab-bar-rail-radius, var(--gl-radius-card));
|
|
2333
|
+
}
|
|
2334
|
+
.glass-tab-bar.glass-tab-bar--vertical.glass-tab-bar--rail.glass-tab-bar--labels { align-items: stretch; }
|
|
2335
|
+
.glass-tab-bar--rail.glass-tab-bar--labels .glass-tab-bar__item {
|
|
2336
|
+
flex-direction: column; justify-content: center;
|
|
2337
|
+
gap: var(--gl-space-2xs);
|
|
2338
|
+
width: 100%; min-height: var(--gl-tab-bar-rail-item-height, 62px);
|
|
2339
|
+
padding: var(--gl-space-xs) var(--gl-space-2xs);
|
|
2340
|
+
border-radius: var(--gl-tab-bar-item-radius, var(--gl-radius-btn));
|
|
2341
|
+
}
|
|
2342
|
+
.glass-tab-bar--rail.glass-tab-bar--labels .glass-tab-bar__label {
|
|
2343
|
+
position: static; width: auto; height: auto; margin: 0; padding: 0; clip-path: none;
|
|
2344
|
+
flex: none; max-width: 100%;
|
|
2345
|
+
font-size: var(--gl-tab-bar-label-size, 10px); text-align: center;
|
|
2346
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
2347
|
+
}
|
|
2348
|
+
.glass-tab-bar.glass-tab-bar--rail.glass-tab-bar--labels.glass-tab-bar--droplet[data-droplet]::before {
|
|
2349
|
+
border-radius: var(--gl-tab-bar-item-radius, var(--gl-radius-btn));
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
/* ---- Floating rail at an edge (since 1.33.0) ---- */
|
|
2353
|
+
/* --floating with --vertical and --start or --end: a rail of its own
|
|
2354
|
+
glass, as high as the viewport less --gl-tab-bar-floating-inset (16px)
|
|
2355
|
+
at both ends and that much from its edge, clear of the safe areas, with
|
|
2356
|
+
the corners of a card (--gl-tab-bar-rail-radius). */
|
|
2357
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical:is(.glass-tab-bar--start, .glass-tab-bar--end) {
|
|
2358
|
+
top: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-top, 0px));
|
|
2359
|
+
bottom: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-bottom, 0px));
|
|
2360
|
+
height: auto; max-height: none;
|
|
2361
|
+
padding: var(--gl-space-sm) var(--gl-space-xs);
|
|
2362
|
+
border: 1px solid var(--gl-border-subtle);
|
|
2363
|
+
border-radius: var(--gl-tab-bar-rail-radius, var(--gl-radius-card));
|
|
2364
|
+
overflow-y: auto;
|
|
2365
|
+
}
|
|
2366
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical.glass-tab-bar--start {
|
|
2367
|
+
inset-inline-start: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-left, 0px));
|
|
2368
|
+
}
|
|
2369
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical.glass-tab-bar--end {
|
|
2370
|
+
inset-inline-end: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-right, 0px));
|
|
2371
|
+
}
|
|
2372
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical.glass-tab-bar--start:dir(rtl) {
|
|
2373
|
+
inset-inline-start: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-right, 0px));
|
|
2374
|
+
}
|
|
2375
|
+
.glass-tab-bar.glass-tab-bar--floating.glass-tab-bar--vertical.glass-tab-bar--end:dir(rtl) {
|
|
2376
|
+
inset-inline-end: calc(var(--gl-tab-bar-floating-inset, 16px) + env(safe-area-inset-left, 0px));
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
/* ---- A place before and after the items (since 1.33.0) ---- */
|
|
2380
|
+
/* __leading holds a mark or the accessory, __trailing a foot such as the
|
|
2381
|
+
account: above and below the items in a column, the trailing part at
|
|
2382
|
+
the far end; before and after them in a row. */
|
|
2383
|
+
.glass-tab-bar__leading,
|
|
2384
|
+
.glass-tab-bar__trailing {
|
|
2385
|
+
display: flex; align-items: center; justify-content: center;
|
|
2386
|
+
gap: var(--gl-space-sm);
|
|
2387
|
+
flex: none;
|
|
2388
|
+
}
|
|
2389
|
+
.glass-tab-bar__leading[hidden],
|
|
2390
|
+
.glass-tab-bar__trailing[hidden] { display: none; }
|
|
2391
|
+
.glass-tab-bar--vertical .glass-tab-bar__leading,
|
|
2392
|
+
.glass-tab-bar--vertical .glass-tab-bar__trailing {
|
|
2393
|
+
flex-direction: column;
|
|
2394
|
+
width: 100%;
|
|
2395
|
+
padding-block: var(--gl-space-2xs);
|
|
2396
|
+
}
|
|
2397
|
+
.glass-tab-bar--vertical .glass-tab-bar__leading { margin-block-end: var(--gl-space-sm); }
|
|
2398
|
+
.glass-tab-bar--vertical .glass-tab-bar__trailing { margin-block-start: auto; padding-block-start: var(--gl-space-sm); }
|
|
2399
|
+
|
|
2400
|
+
/* The accessory with its name under it (since 1.33.0), for a rail's
|
|
2401
|
+
leading place; the name is the button's too. */
|
|
2402
|
+
.glass-tab-bar__accessory-item {
|
|
2403
|
+
display: flex; flex-direction: column; align-items: center;
|
|
2404
|
+
gap: var(--gl-space-2xs);
|
|
2405
|
+
}
|
|
2406
|
+
.glass-tab-bar__accessory-label {
|
|
2407
|
+
font-size: var(--gl-tab-bar-label-size, 10px); font-weight: var(--gl-font-weight-medium);
|
|
2408
|
+
letter-spacing: 0.2px; text-align: center;
|
|
2409
|
+
color: var(--gl-tab-bar-color, var(--gl-icon-muted));
|
|
2410
|
+
cursor: pointer;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2290
2413
|
.glass-tab-bar-dock.glass-tab-bar-dock--vertical {
|
|
2291
2414
|
flex-direction: column;
|
|
2292
2415
|
top: 50%; bottom: auto;
|
|
@@ -2526,6 +2649,23 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
|
|
|
2526
2649
|
inset 0 0 0 100px color-mix(in srgb, var(--gl-badge-accent) 22%, transparent);
|
|
2527
2650
|
}
|
|
2528
2651
|
|
|
2652
|
+
/* A chip to choose with (since 1.33.0): --gl-badge-md-height (36px) high,
|
|
2653
|
+
in the small text of a form. Interactive, it takes taps on 44px above
|
|
2654
|
+
and below its edges, the target every control keeps. */
|
|
2655
|
+
.glass-badge--md {
|
|
2656
|
+
box-sizing: border-box;
|
|
2657
|
+
min-height: var(--gl-badge-md-height, 36px);
|
|
2658
|
+
padding: 0 var(--gl-space-md);
|
|
2659
|
+
justify-content: center;
|
|
2660
|
+
font-size: var(--gl-font-size-sm);
|
|
2661
|
+
}
|
|
2662
|
+
.glass-badge--interactive.glass-badge--md { position: relative; }
|
|
2663
|
+
.glass-badge--interactive.glass-badge--md::after {
|
|
2664
|
+
content: ''; position: absolute;
|
|
2665
|
+
/* From the padding box, so the 1px border counts as well. */
|
|
2666
|
+
inset: min(0px, calc((var(--gl-badge-md-height, 36px) - 44px) / 2 - 1px)) 0;
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2529
2669
|
|
|
2530
2670
|
/* ============================================================
|
|
2531
2671
|
21. DIVIDER
|