@jungherz-de/glasskit 1.29.1 → 1.31.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/glasskit.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /* ============================================================
2
2
  GLASSKIT COMPONENT LIBRARY
3
- Jungherz GmbH – v1.29.1
3
+ Jungherz GmbH – v1.31.0
4
4
 
5
5
  Features:
6
6
  - Scoped Reset (box-sizing fix)
@@ -66,11 +66,13 @@
66
66
  --gl-color-bg-mid: #1a3d4e;
67
67
  --gl-color-bg-light: #1b3e50;
68
68
  --gl-color-text: #ffffff;
69
- --gl-color-text-muted: rgba(255, 255, 255, 0.60);
69
+ /* Muted text keeps 4.5:1 on the page and on glass: 65 % since 1.31.0,
70
+ before 60 % (4.45:1 on glass). The select's chevron below follows. */
71
+ --gl-color-text-muted: rgba(255, 255, 255, 0.65);
70
72
  --gl-color-text-on-light: #1a3a4a;
71
73
  --gl-color-text-heading: #ffffff;
72
74
  /* The select's chevron, drawn in the muted text colour of each theme. */
73
- --gl-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.6)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
75
+ --gl-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.65)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
74
76
  --gl-color-success: #34c759;
75
77
  --gl-color-error: #ff3b30;
76
78
  --gl-color-warning: #ffcc00;
@@ -311,10 +313,14 @@
311
313
  --gl-color-bg-mid: #f0f4f8;
312
314
  --gl-color-bg-light: #f5f7fa;
313
315
  --gl-color-text: #1a2a36;
314
- --gl-color-text-muted: rgba(26, 42, 54, 0.55);
316
+ /* Muted text, card text and the icons reach WCAG AA on the page and on
317
+ glass since 1.31.0: text 4.5:1 (before 3.4:1, card text 4.0:1), icons
318
+ that carry a meaning 3:1 (before 2.0:1). The icon steps, muted, default
319
+ and strong, stay in their order. */
320
+ --gl-color-text-muted: rgba(26, 42, 54, 0.68);
315
321
  --gl-color-text-on-light: #1a3a4a;
316
322
  --gl-color-text-heading: #0f1f2a;
317
- --gl-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(26,42,54,0.55)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
323
+ --gl-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(26,42,54,0.68)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
318
324
  --gl-color-success: #28a745;
319
325
  --gl-color-error: #dc3545;
320
326
  --gl-color-warning: #e6a800;
@@ -354,8 +360,8 @@
354
360
  --gl-card-glow-low: rgba(255, 255, 255, 0.65);
355
361
  --gl-card-glow-bottom: rgba(255, 255, 255, 0.50);
356
362
 
357
- --gl-card-icon-color: rgba(26, 42, 54, 0.5);
358
- --gl-card-text-color: rgba(26, 42, 54, 0.6);
363
+ --gl-card-icon-color: rgba(26, 42, 54, 0.65);
364
+ --gl-card-text-color: rgba(26, 42, 54, 0.68);
359
365
 
360
366
  --gl-border-subtle: rgba(0, 0, 0, 0.08);
361
367
  --gl-border-medium: rgba(0, 0, 0, 0.12);
@@ -364,12 +370,12 @@
364
370
  --gl-border-warm: color-mix(in srgb, var(--gl-color-primary) 30%, transparent);
365
371
  --gl-border-focus: color-mix(in srgb, var(--gl-color-primary) 50%, transparent);
366
372
 
367
- --gl-icon-default: rgba(26, 42, 54, 0.50);
368
- --gl-icon-muted: rgba(26, 42, 54, 0.35);
369
- --gl-icon-strong: rgba(26, 42, 54, 0.70);
373
+ --gl-icon-default: rgba(26, 42, 54, 0.65);
374
+ --gl-icon-muted: rgba(26, 42, 54, 0.55);
375
+ --gl-icon-strong: rgba(26, 42, 54, 0.80);
370
376
  --gl-icon-on-primary: var(--gl-color-on-primary, #ffffff);
371
377
  --gl-icon-on-secondary: #1a3a4a;
372
- --gl-icon-on-tertiary: rgba(26, 42, 54, 0.50);
378
+ --gl-icon-on-tertiary: rgba(26, 42, 54, 0.65);
373
379
 
374
380
  --gl-shadow-card: 0 4px 20px rgba(0, 0, 0, 0.06);
375
381
  --gl-shadow-btn: 0 2px 10px rgba(0, 0, 0, 0.06);
@@ -757,10 +763,20 @@
757
763
  /* ============================================================
758
764
  6. BUTTONS
759
765
  ============================================================ */
766
+ /* Hooks of their own (since 1.31.0), as the height has --gl-btn-height:
767
+ --gl-btn-radius, unset --gl-radius-btn, which lists, the status card,
768
+ toasts, the accordion and the segmented control share, so pill-shaped
769
+ buttons no longer turn those into capsules; and --gl-btn-padding-x, the
770
+ room beside the label, unset 24px. That was the padding of --auto alone;
771
+ any other button had the browser's 6px, so a small one in a row of
772
+ actions, its width taken from its text, touched the text with its edges.
773
+ A full-width button keeps its label where it was. --sm takes
774
+ --gl-btn-radius-sm and --gl-btn-padding-x-sm, each unset the one above. */
760
775
  .glass-btn {
761
776
  display: flex; align-items: center; justify-content: center;
762
777
  gap: 10px; width: 100%; height: var(--gl-btn-height, 56px);
763
- border: none; border-radius: var(--gl-radius-btn);
778
+ padding-inline: var(--gl-btn-padding-x, var(--gl-space-xl));
779
+ border: none; border-radius: var(--gl-btn-radius, var(--gl-radius-btn));
764
780
  font-family: var(--gl-font-family);
765
781
  font-size: var(--gl-font-size-btn);
766
782
  font-weight: var(--gl-font-weight-semibold);
@@ -853,9 +869,13 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
853
869
  }
854
870
 
855
871
  /* Sizes */
856
- .glass-btn--sm { height: var(--gl-btn-height-sm, 44px); font-size: var(--gl-font-size-sm); border-radius: var(--gl-radius-sm); }
872
+ .glass-btn--sm {
873
+ height: var(--gl-btn-height-sm, 44px); font-size: var(--gl-font-size-sm);
874
+ padding-inline: var(--gl-btn-padding-x-sm, var(--gl-btn-padding-x, var(--gl-space-xl)));
875
+ border-radius: var(--gl-btn-radius-sm, var(--gl-btn-radius, var(--gl-radius-sm)));
876
+ }
857
877
  .glass-btn--lg { height: var(--gl-btn-height-lg, 64px); font-size: var(--gl-font-size-lg); }
858
- .glass-btn--auto { width: auto; padding: 0 var(--gl-space-xl); }
878
+ .glass-btn--auto { width: auto; padding-block: 0; }
859
879
 
860
880
 
861
881
  /* ============================================================
@@ -1074,7 +1094,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1074
1094
  box-shadow: var(--gl-inset-subtle);
1075
1095
  cursor: pointer;
1076
1096
  appearance: none; -webkit-appearance: none;
1077
- background-image: var(--gl-select-chevron, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.6)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"));
1097
+ background-image: var(--gl-select-chevron, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.65)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"));
1078
1098
  background-repeat: no-repeat;
1079
1099
  background-position: right 16px center;
1080
1100
  }
@@ -1494,10 +1514,12 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1494
1514
  the top layer, the page behind it is inert, focus moves in and Escape
1495
1515
  closes it. These rules undo the dialog's own box and backdrop; the
1496
1516
  overlay above paints the dimmed, blurred layer. GlassKit Elements'
1497
- <glk-modal> uses exactly this. */
1517
+ <glk-modal> uses exactly this. With nothing to focus inside, showModal()
1518
+ focuses the dialog itself, and its focus ring traced the edges of the
1519
+ screen; no outline since 1.30.0, Tab still goes to the first control. */
1498
1520
  dialog.glass-modal-overlay {
1499
1521
  width: auto; height: auto; max-width: none; max-height: none;
1500
- margin: 0; border: 0; color: inherit;
1522
+ margin: 0; border: 0; color: inherit; outline: none;
1501
1523
  }
1502
1524
  dialog.glass-modal-overlay:not([open]) { display: none; }
1503
1525
  dialog.glass-modal-overlay::backdrop { background: transparent; }
@@ -2143,11 +2165,23 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2143
2165
  stroke: var(--gl-color-primary-text);
2144
2166
  }
2145
2167
 
2168
+ /* Open, the content takes its own height, however long (since 1.30.0): a
2169
+ grid of one row that slides from 0fr to 1fr, clipped while it does.
2170
+ Until then max-height capped an open item at 500px and cut off the
2171
+ rest. Both tracks start at 0: the row, so the body's padding cannot hold
2172
+ a closed item open; the column, so a long word or a URL cannot make the
2173
+ body wider than the item, as it could not in a block. */
2146
2174
  .glass-accordion__content {
2147
- max-height: 0; overflow: hidden;
2148
- transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1);
2175
+ display: grid;
2176
+ grid-template-rows: minmax(0, 0fr);
2177
+ grid-template-columns: minmax(0, 1fr);
2178
+ overflow: hidden;
2179
+ transition: grid-template-rows 0.35s cubic-bezier(0.4, 0, 0.2, 1);
2180
+ }
2181
+ .glass-accordion__item.is-open .glass-accordion__content { grid-template-rows: minmax(0, 1fr); }
2182
+ @media (prefers-reduced-motion: reduce) {
2183
+ .glass-accordion__content { transition: none; }
2149
2184
  }
2150
- .glass-accordion__item.is-open .glass-accordion__content { max-height: 500px; }
2151
2185
 
2152
2186
  .glass-accordion__body {
2153
2187
  padding: 0 var(--gl-space-lg) var(--gl-space-lg);
@@ -2864,17 +2898,22 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2864
2898
  the place for an --icons row. There it covers the icon, so the theme's
2865
2899
  middle background goes underneath (--gl-segmented-badge-base, the
2866
2900
  badge's background colour). Its number is no name: give the option an
2867
- aria-label such as "Tickets, 1 open". */
2901
+ aria-label such as "Tickets, 1 open". Since 1.31.0 its size and the
2902
+ hairline of the neutral count are tokens: --gl-segmented-badge-height
2903
+ (unset 16px, also the least width), --gl-segmented-badge-font-size
2904
+ (unset 11px) and --gl-segmented-badge-border (a colour, unset none,
2905
+ drawn inside, so the count keeps its size). */
2868
2906
  .glass-segmented__badge {
2869
2907
  flex: none;
2870
2908
  display: inline-flex; align-items: center; justify-content: center;
2871
- min-width: 16px; height: 16px; padding: 0 5px;
2909
+ min-width: var(--gl-segmented-badge-height, 16px); height: var(--gl-segmented-badge-height, 16px); padding: 0 5px;
2872
2910
  border-radius: var(--gl-radius-full);
2873
2911
  background-color: var(--gl-segmented-badge-base, var(--gl-state-scrim, transparent));
2874
2912
  background-image: linear-gradient(var(--gl-segmented-badge-bg, color-mix(in srgb, var(--gl-color-text) 12%, transparent)),
2875
2913
  var(--gl-segmented-badge-bg, color-mix(in srgb, var(--gl-color-text) 12%, transparent)));
2914
+ box-shadow: inset 0 0 0 1px var(--gl-segmented-badge-border, transparent);
2876
2915
  color: var(--gl-segmented-badge-color, var(--gl-color-text));
2877
- font-size: 11px; font-weight: var(--gl-font-weight-semibold);
2916
+ font-size: var(--gl-segmented-badge-font-size, 11px); font-weight: var(--gl-font-weight-semibold);
2878
2917
  font-variant-numeric: tabular-nums;
2879
2918
  line-height: 1;
2880
2919
  }
@@ -2896,6 +2935,36 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2896
2935
  box-shadow: inset 0 0 0 1px var(--gl-color-error-border);
2897
2936
  color: var(--gl-color-error-on-surface, var(--gl-color-error));
2898
2937
  }
2938
+ /* A colour of the count's own (since 1.31.0), whatever the option's tone:
2939
+ --primary, --success, --warning and --error give it the look of
2940
+ .glass-badge's variants (the state tint over a doubled scrim, a hairline,
2941
+ the readable text colour), without the dot a tone puts before the label.
2942
+ After the tones of the option, so the count's own colour wins where both
2943
+ are set. */
2944
+ .glass-segmented__badge.glass-segmented__badge--primary {
2945
+ background-image: linear-gradient(var(--gl-color-primary-surface), var(--gl-color-primary-surface)),
2946
+ linear-gradient(var(--gl-state-scrim), var(--gl-state-scrim));
2947
+ box-shadow: inset 0 0 0 1px var(--gl-color-primary-border);
2948
+ color: var(--gl-color-primary-on-surface, var(--gl-color-primary));
2949
+ }
2950
+ .glass-segmented__badge.glass-segmented__badge--success {
2951
+ background-image: linear-gradient(var(--gl-color-success-surface), var(--gl-color-success-surface)),
2952
+ linear-gradient(var(--gl-state-scrim), var(--gl-state-scrim));
2953
+ box-shadow: inset 0 0 0 1px var(--gl-color-success-border);
2954
+ color: var(--gl-color-success-on-surface, var(--gl-color-success));
2955
+ }
2956
+ .glass-segmented__badge.glass-segmented__badge--warning {
2957
+ background-image: linear-gradient(var(--gl-color-warning-surface), var(--gl-color-warning-surface)),
2958
+ linear-gradient(var(--gl-state-scrim), var(--gl-state-scrim));
2959
+ box-shadow: inset 0 0 0 1px var(--gl-color-warning-border);
2960
+ color: var(--gl-color-warning-on-surface, var(--gl-color-warning));
2961
+ }
2962
+ .glass-segmented__badge.glass-segmented__badge--error {
2963
+ background-image: linear-gradient(var(--gl-color-error-surface), var(--gl-color-error-surface)),
2964
+ linear-gradient(var(--gl-state-scrim), var(--gl-state-scrim));
2965
+ box-shadow: inset 0 0 0 1px var(--gl-color-error-border);
2966
+ color: var(--gl-color-error-on-surface, var(--gl-color-error));
2967
+ }
2899
2968
  .glass-segmented__icon > .glass-segmented__badge {
2900
2969
  --gl-segmented-badge-base: var(--gl-color-bg-mid);
2901
2970
  position: absolute; top: -4px; inset-inline-end: -8px;
@@ -2987,6 +3056,22 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2987
3056
  }
2988
3057
  .glass-sheet-overlay[hidden] { display: none; }
2989
3058
  .glass-sheet-overlay.is-active { opacity: 1; }
3059
+ /* The overlay may be a native <dialog>, as the modal's (since 1.30.0):
3060
+ opened with showModal() it lies in the top layer, above every fixed or
3061
+ transformed element of the page whatever its z-index, and the page
3062
+ behind it is inert. These rules undo the dialog's own box and backdrop;
3063
+ overflow stays hidden, so the panel rising from below the edge does not
3064
+ make the overlay scroll. Show with showModal(), then .is-active; hide by
3065
+ removing .is-active, then close() after transitionend. GlassKit
3066
+ Elements' <glk-sheet> does this. No outline, as on the modal's: with
3067
+ nothing to focus inside, the dialog itself takes the focus. */
3068
+ dialog.glass-sheet-overlay {
3069
+ width: auto; height: auto; max-width: none; max-height: none;
3070
+ margin: 0; padding: 0; border: 0; color: inherit; outline: none;
3071
+ overflow: hidden;
3072
+ }
3073
+ dialog.glass-sheet-overlay:not([open]) { display: none; }
3074
+ dialog.glass-sheet-overlay::backdrop { background: transparent; }
2990
3075
 
2991
3076
  .glass-sheet {
2992
3077
  width: min(100%, 560px); max-height: 88dvh; overflow: auto;