@jungherz-de/glasskit 1.23.0 → 1.25.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.23.0
3
+ Jungherz GmbH – v1.25.0
4
4
 
5
5
  Features:
6
6
  - Scoped Reset (box-sizing fix)
@@ -179,6 +179,18 @@
179
179
  --gl-inset-strong: inset 0 1px 2px rgba(255, 255, 255, 0.25);
180
180
  --gl-inset-milk: inset 0 1px 2px rgba(255, 255, 255, 0.40);
181
181
 
182
+ /* ---- Gloss ----
183
+ The light that glass catches: the highlight along the top edge of the
184
+ glow card and of the modal, the sheen on the progress fill and the rim
185
+ of the range thumb. The same in both themes, so only declared here.
186
+ Literals until 1.23.0; [data-surface="solid"] (1d) turns them off. */
187
+ --gl-gloss-card: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.5) 30%,
188
+ rgba(255,255,255,0.6) 50%, rgba(255,255,255,0.5) 70%, transparent 100%);
189
+ --gl-gloss-modal: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.4) 30%,
190
+ rgba(255,255,255,0.5) 50%, rgba(255,255,255,0.4) 70%, transparent 100%);
191
+ --gl-gloss-progress: linear-gradient(to bottom, rgba(255,255,255,0.3) 0%, transparent 100%);
192
+ --gl-range-thumb-border: 2px solid rgba(255,255,255,0.5);
193
+
182
194
  /* ---- Background Effects ----
183
195
  Deliberately *not* derived from --gl-color-primary: the aurora is the scene
184
196
  behind the glass, a fixed cool/warm mix, not the action color. Deriving it
@@ -407,6 +419,155 @@
407
419
  }
408
420
 
409
421
 
422
+ /* ============================================================
423
+ 1d. SURFACE PRESETS – SOLID AND TINT
424
+ ============================================================ */
425
+ /* Opt-in, next to the theme and the density, on <html>.
426
+
427
+ data-surface="solid" (since 1.24.0): opaque surfaces without blur and
428
+ gloss, for admin screens, forms on a plain background, designs without
429
+ glass. Each surface takes the colour the glass shows over the theme's
430
+ middle background, --gl-color-bg-mid: one surface above another keeps
431
+ its place in the order, and a re-branded background carries over.
432
+
433
+ data-surface="tint" (since 1.25.0): for a page with a background of its
434
+ own — a brand colour, a photo, a pattern — where a surface mixed over
435
+ --gl-color-bg-mid would stand out as a foreign block. The surfaces in the
436
+ flow of the page become see-through tints of the text colour, nothing
437
+ blurred: a field on a card stays as see-through as the card, and its
438
+ contrast follows the text. What lies over other content keeps the solid
439
+ values: modal, sheet, popover, toast and the tab bars (1e). So do the
440
+ milk surfaces, light plates for dark ink: a see-through secondary button
441
+ would lose its text on a dark page.
442
+
443
+ Both turn off the blur, the inner shine (--gl-inset-*) and the gloss.
444
+ Borders, drop shadows, the tints of badges and chips and the dimming
445
+ overlay stay as they are; a blur behind dialogs stays where a project
446
+ sets --gl-blur-overlay.
447
+
448
+ The bare selectors match <html>, like the density preset. A theme scope
449
+ inside the page — an element with its own data-theme — re-declares its
450
+ theme's glass tokens, so the presets name it too. build-styles-js.mjs
451
+ moves the three blocks into tokensCss, after the density block. */
452
+
453
+ /* Solid, dark theme — and the ground of the tint preset. The solid
454
+ surfaces are kept under names of their own as well, --gl-solid-*: the
455
+ panels of the tint preset take them from there (1e). */
456
+ [data-surface="solid"],
457
+ [data-surface="tint"],
458
+ [data-surface="solid"] [data-theme="dark"],
459
+ [data-surface="tint"] [data-theme="dark"] {
460
+ --gl-solid-surface-1: color-mix(in srgb, #ffffff 8%, var(--gl-color-bg-mid));
461
+ --gl-solid-surface-2: color-mix(in srgb, #ffffff 10%, var(--gl-color-bg-mid));
462
+ --gl-solid-surface-3: color-mix(in srgb, #ffffff 14%, var(--gl-color-bg-mid));
463
+ --gl-solid-surface-4: color-mix(in srgb, #ffffff 16%, var(--gl-color-bg-mid));
464
+ --gl-solid-surface-5: color-mix(in srgb, #ffffff 22%, var(--gl-color-bg-mid));
465
+ --gl-solid-card-glow-top: color-mix(in srgb, #ffffff 32%, var(--gl-color-bg-mid));
466
+ --gl-solid-card-glow-mid: color-mix(in srgb, #ffffff 22%, var(--gl-color-bg-mid));
467
+ --gl-solid-card-glow-low: color-mix(in srgb, #ffffff 14%, var(--gl-color-bg-mid));
468
+ --gl-solid-card-glow-bottom: color-mix(in srgb, #ffffff 8%, var(--gl-color-bg-mid));
469
+ --gl-surface-1: var(--gl-solid-surface-1);
470
+ --gl-surface-2: var(--gl-solid-surface-2);
471
+ --gl-surface-3: var(--gl-solid-surface-3);
472
+ --gl-surface-4: var(--gl-solid-surface-4);
473
+ --gl-surface-5: var(--gl-solid-surface-5);
474
+ --gl-surface-milk: color-mix(in srgb, #ffffff 55%, var(--gl-color-bg-mid));
475
+ --gl-surface-milk-strong: color-mix(in srgb, #ffffff 75%, var(--gl-color-bg-mid));
476
+ --gl-card-glow-top: var(--gl-solid-card-glow-top);
477
+ --gl-card-glow-mid: var(--gl-solid-card-glow-mid);
478
+ --gl-card-glow-low: var(--gl-solid-card-glow-low);
479
+ --gl-card-glow-bottom: var(--gl-solid-card-glow-bottom);
480
+ --gl-toggle-thumb-bg: linear-gradient(to bottom, #ffffff 0%, #f0f0f0 100%);
481
+ --gl-shadow-glow: 0 4px 16px rgba(0, 0, 0, 0.15);
482
+ --gl-blur: 0px;
483
+ --gl-blur-light: 0px;
484
+ --gl-blur-soft: 0px;
485
+ --gl-blur-heavy: 0px;
486
+ /* No inner shine. A zero shadow, not none: the insets sit in shadow lists. */
487
+ --gl-inset-subtle: inset 0 0 0 transparent;
488
+ --gl-inset-medium: inset 0 0 0 transparent;
489
+ --gl-inset-strong: inset 0 0 0 transparent;
490
+ --gl-inset-milk: inset 0 0 0 transparent;
491
+ --gl-gloss-card: none;
492
+ --gl-gloss-modal: none;
493
+ --gl-gloss-progress: none;
494
+ --gl-range-thumb-border: 2px solid transparent;
495
+ }
496
+ /* Solid, light theme — and the tint preset's ground in it. */
497
+ [data-surface="solid"][data-theme="light"],
498
+ [data-surface="solid"] [data-theme="light"],
499
+ [data-theme="light"] [data-surface="solid"],
500
+ [data-surface="tint"][data-theme="light"],
501
+ [data-surface="tint"] [data-theme="light"],
502
+ [data-theme="light"] [data-surface="tint"] {
503
+ --gl-solid-surface-1: color-mix(in srgb, #ffffff 50%, var(--gl-color-bg-mid));
504
+ --gl-solid-surface-2: color-mix(in srgb, #ffffff 60%, var(--gl-color-bg-mid));
505
+ --gl-solid-surface-3: color-mix(in srgb, #ffffff 70%, var(--gl-color-bg-mid));
506
+ --gl-solid-surface-4: color-mix(in srgb, #ffffff 75%, var(--gl-color-bg-mid));
507
+ --gl-solid-surface-5: color-mix(in srgb, #ffffff 85%, var(--gl-color-bg-mid));
508
+ --gl-solid-card-glow-top: color-mix(in srgb, #ffffff 90%, var(--gl-color-bg-mid));
509
+ --gl-solid-card-glow-mid: color-mix(in srgb, #ffffff 78%, var(--gl-color-bg-mid));
510
+ --gl-solid-card-glow-low: color-mix(in srgb, #ffffff 65%, var(--gl-color-bg-mid));
511
+ --gl-solid-card-glow-bottom: color-mix(in srgb, #ffffff 50%, var(--gl-color-bg-mid));
512
+ --gl-surface-1: var(--gl-solid-surface-1);
513
+ --gl-surface-2: var(--gl-solid-surface-2);
514
+ --gl-surface-3: var(--gl-solid-surface-3);
515
+ --gl-surface-4: var(--gl-solid-surface-4);
516
+ --gl-surface-5: var(--gl-solid-surface-5);
517
+ --gl-surface-milk: color-mix(in srgb, #ffffff 85%, var(--gl-color-bg-mid));
518
+ --gl-surface-milk-strong: color-mix(in srgb, #ffffff 92%, var(--gl-color-bg-mid));
519
+ --gl-card-glow-top: var(--gl-solid-card-glow-top);
520
+ --gl-card-glow-mid: var(--gl-solid-card-glow-mid);
521
+ --gl-card-glow-low: var(--gl-solid-card-glow-low);
522
+ --gl-card-glow-bottom: var(--gl-solid-card-glow-bottom);
523
+ --gl-shadow-glow: 0 2px 8px rgba(0, 0, 0, 0.05),
524
+ 0 4px 12px rgba(0, 0, 0, 0.04);
525
+ --gl-inset-subtle: inset 0 0 0 transparent;
526
+ --gl-inset-medium: inset 0 0 0 transparent;
527
+ --gl-inset-strong: inset 0 0 0 transparent;
528
+ --gl-inset-milk: inset 0 0 0 transparent;
529
+ }
530
+ /* Tint: the surfaces in the flow of the page become see-through tints of
531
+ the text colour. One block for both themes: the text colour is the
532
+ theme's. It comes after the solid blocks and outranks the light one. */
533
+ :root[data-surface="tint"],
534
+ [data-surface="tint"][data-theme],
535
+ [data-surface="tint"] [data-theme],
536
+ [data-theme] [data-surface="tint"] {
537
+ --gl-surface-1: color-mix(in srgb, var(--gl-color-text) 4%, transparent);
538
+ --gl-surface-2: color-mix(in srgb, var(--gl-color-text) 6%, transparent);
539
+ --gl-surface-3: color-mix(in srgb, var(--gl-color-text) 9%, transparent);
540
+ --gl-surface-4: color-mix(in srgb, var(--gl-color-text) 12%, transparent);
541
+ --gl-surface-5: color-mix(in srgb, var(--gl-color-text) 16%, transparent);
542
+ --gl-card-glow-top: color-mix(in srgb, var(--gl-color-text) 16%, transparent);
543
+ --gl-card-glow-mid: color-mix(in srgb, var(--gl-color-text) 12%, transparent);
544
+ --gl-card-glow-low: color-mix(in srgb, var(--gl-color-text) 9%, transparent);
545
+ --gl-card-glow-bottom: color-mix(in srgb, var(--gl-color-text) 6%, transparent);
546
+ }
547
+
548
+
549
+ /* ============================================================
550
+ 1e. TINT PRESET – PANELS
551
+ ============================================================ */
552
+ /* What lies over other content stays opaque under data-surface="tint":
553
+ it takes the solid surfaces the preset keeps under --gl-solid-*, and so
554
+ does what sits inside it — a field in a modal, a row in a popover. A
555
+ component rule, not a token block, so that it also matches inside the
556
+ shadow roots of GlassKit Elements, on the theme wrapper that mirrors
557
+ data-surface. */
558
+ [data-surface="tint"] :is(.glass-modal, .glass-sheet, .glass-popover, .glass-toast, .glass-tab-bar, .glass-tab-bar__accessory) {
559
+ --gl-surface-1: var(--gl-solid-surface-1);
560
+ --gl-surface-2: var(--gl-solid-surface-2);
561
+ --gl-surface-3: var(--gl-solid-surface-3);
562
+ --gl-surface-4: var(--gl-solid-surface-4);
563
+ --gl-surface-5: var(--gl-solid-surface-5);
564
+ --gl-card-glow-top: var(--gl-solid-card-glow-top);
565
+ --gl-card-glow-mid: var(--gl-solid-card-glow-mid);
566
+ --gl-card-glow-low: var(--gl-solid-card-glow-low);
567
+ --gl-card-glow-bottom: var(--gl-solid-card-glow-bottom);
568
+ }
569
+
570
+
410
571
  /* ============================================================
411
572
  2. HINTERGRUND
412
573
  ============================================================ */
@@ -554,10 +715,7 @@
554
715
  .glass-card--glow::before {
555
716
  content: '';
556
717
  position: absolute; top: 0; left: 10%; right: 10%; height: 1px;
557
- background: linear-gradient(90deg,
558
- transparent 0%, rgba(255,255,255,0.5) 30%,
559
- rgba(255,255,255,0.6) 50%, rgba(255,255,255,0.5) 70%, transparent 100%
560
- );
718
+ background: var(--gl-gloss-card);
561
719
  z-index: 1;
562
720
  }
563
721
 
@@ -725,6 +883,9 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
725
883
  color: var(--gl-icon-strong);
726
884
  padding-inline-start: var(--gl-space-2xs);
727
885
  }
886
+ /* Without text a label takes no room: an empty one kept the group's gap
887
+ above its field (until 1.24.0). */
888
+ .glass-label:empty { display: none; }
728
889
 
729
890
  .glass-input {
730
891
  width: 100%; height: var(--gl-control-height, 52px);
@@ -741,7 +902,15 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
741
902
  outline: none;
742
903
  box-shadow: var(--gl-inset-subtle);
743
904
  -webkit-tap-highlight-color: transparent;
905
+ /* A value or placeholder too long for the field ends in an ellipsis
906
+ while the field is not being edited (since 1.25.0). */
907
+ text-overflow: ellipsis;
744
908
  }
909
+ /* The browser's own picker button of a date or time field, and the arrow
910
+ of a datalist, unless --gl-input-picker-icon is none (since 1.25.0) —
911
+ when the field's prefix is the picker, for instance; call showPicker()
912
+ from it then. Unset, revert keeps each browser's own. */
913
+ .glass-input::-webkit-calendar-picker-indicator { display: var(--gl-input-picker-icon, revert); }
745
914
 
746
915
  .glass-input::placeholder { color: var(--gl-placeholder); }
747
916
 
@@ -854,7 +1023,13 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
854
1023
  transition: var(--gl-transition);
855
1024
  outline: none;
856
1025
  box-shadow: var(--gl-inset-subtle);
1026
+ /* --gl-textarea-field-sizing: content lets text areas grow with their
1027
+ text (since 1.25.0); off by default, because it ignores rows. Browsers
1028
+ without field-sizing keep the fixed height. */
1029
+ field-sizing: var(--gl-textarea-field-sizing, fixed);
857
1030
  }
1031
+ /* Nothing to resize in a text area that cannot be edited (since 1.25.0). */
1032
+ .glass-textarea:read-only { resize: none; }
858
1033
  .glass-textarea::placeholder { color: var(--gl-placeholder); }
859
1034
  .glass-textarea:focus {
860
1035
  border-color: var(--gl-border-focus);
@@ -954,7 +1129,9 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
954
1129
 
955
1130
  .glass-toggle__track {
956
1131
  position: relative; width: var(--gl-toggle-width, 52px); height: var(--gl-toggle-height, 30px);
957
- background: var(--gl-surface-2);
1132
+ /* --gl-toggle-track-bg and -checked (since 1.25.0): a stronger track for
1133
+ a page without glass, where the surface can be hard to see. */
1134
+ background: var(--gl-toggle-track-bg, var(--gl-surface-2));
958
1135
  backdrop-filter: blur(var(--gl-blur-soft));
959
1136
  -webkit-backdrop-filter: blur(var(--gl-blur-soft));
960
1137
  border: 1.5px solid var(--gl-border-medium);
@@ -982,9 +1159,9 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
982
1159
  }
983
1160
 
984
1161
  .glass-toggle__input:checked + .glass-toggle__track {
985
- background: linear-gradient(135deg,
1162
+ background: var(--gl-toggle-track-bg-checked, linear-gradient(135deg,
986
1163
  var(--gl-color-primary) 0%, var(--gl-color-primary-dark) 100%
987
- );
1164
+ ));
988
1165
  border-color: var(--gl-border-warm);
989
1166
  }
990
1167
 
@@ -1103,12 +1280,15 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1103
1280
  margin-top: max(0px, calc((1lh - var(--gl-check-size, 24px)) / 2));
1104
1281
  }
1105
1282
 
1283
+ /* --gl-radio-* (since 1.25.0): fill, rim and dot, for a look without glass —
1284
+ a ring in the text colour that turns the accent colour when checked, say.
1285
+ The two rims are whole border values, so give both the same width. */
1106
1286
  .glass-radio__circle {
1107
1287
  width: var(--gl-check-size, 24px); height: var(--gl-check-size, 24px);
1108
1288
  border-radius: var(--gl-radius-pill);
1109
- background: var(--gl-surface-2);
1289
+ background: var(--gl-radio-bg, var(--gl-surface-2));
1110
1290
  backdrop-filter: blur(var(--gl-blur-soft));
1111
- border: 1.5px solid var(--gl-border-medium);
1291
+ border: var(--gl-radio-border, 1.5px solid var(--gl-border-medium));
1112
1292
  display: flex; align-items: center; justify-content: center;
1113
1293
  transition: var(--gl-transition);
1114
1294
  box-shadow: var(--gl-inset-subtle);
@@ -1117,18 +1297,18 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1117
1297
  }
1118
1298
 
1119
1299
  .glass-radio__dot {
1120
- width: 10px; height: 10px;
1300
+ width: var(--gl-radio-dot-size, 10px); height: var(--gl-radio-dot-size, 10px);
1121
1301
  border-radius: var(--gl-radius-pill);
1122
- background: white;
1302
+ background: var(--gl-radio-dot-color, white);
1123
1303
  opacity: 0; transform: scale(0);
1124
1304
  transition: var(--gl-transition-fast);
1125
1305
  }
1126
1306
 
1127
1307
  .glass-radio__input:checked + .glass-radio__circle {
1128
- background: linear-gradient(135deg,
1308
+ background: var(--gl-radio-bg-checked, linear-gradient(135deg,
1129
1309
  var(--gl-color-primary) 0%, var(--gl-color-primary-dark) 100%
1130
- );
1131
- border-color: var(--gl-border-warm);
1310
+ ));
1311
+ border: var(--gl-radio-border-checked, 1.5px solid var(--gl-border-warm));
1132
1312
  }
1133
1313
  .glass-radio__input:checked + .glass-radio__circle .glass-radio__dot { opacity: 1; transform: scale(1); }
1134
1314
  .glass-radio__input:focus-visible + .glass-radio__circle { box-shadow: var(--gl-shadow-focus); }
@@ -1175,7 +1355,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1175
1355
  background: linear-gradient(135deg,
1176
1356
  var(--gl-color-primary) 0%, var(--gl-color-primary-dark) 100%
1177
1357
  );
1178
- border: 2px solid rgba(255,255,255,0.5);
1358
+ border: var(--gl-range-thumb-border);
1179
1359
  box-shadow: 0 2px 8px color-mix(in srgb, var(--gl-color-primary-mid) 35%, transparent), var(--gl-inset-strong);
1180
1360
  margin-top: -2px; cursor: pointer;
1181
1361
  transition: var(--gl-transition);
@@ -1189,7 +1369,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1189
1369
  background: linear-gradient(135deg,
1190
1370
  var(--gl-color-primary) 0%, var(--gl-color-primary-dark) 100%
1191
1371
  );
1192
- border: 2px solid rgba(255,255,255,0.5);
1372
+ border: var(--gl-range-thumb-border);
1193
1373
  box-shadow: 0 2px 8px color-mix(in srgb, var(--gl-color-primary-mid) 35%, transparent);
1194
1374
  cursor: pointer;
1195
1375
  }
@@ -1250,7 +1430,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1250
1430
  content: '';
1251
1431
  position: absolute; top: 0; left: 0; right: 0; height: 50%;
1252
1432
  border-radius: var(--gl-radius-full);
1253
- background: linear-gradient(to bottom, rgba(255,255,255,0.3) 0%, transparent 100%);
1433
+ background: var(--gl-gloss-progress);
1254
1434
  }
1255
1435
 
1256
1436
  .glass-progress--sm .glass-progress__track { height: 4px; }
@@ -1276,11 +1456,15 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1276
1456
  /* ============================================================
1277
1457
  16. MODAL
1278
1458
  ============================================================ */
1459
+ /* The dimmer behind a dialog blurs with --gl-blur-overlay where a project
1460
+ sets it, else with --gl-blur-soft (since 1.25.0). The surface presets set
1461
+ the blur tokens to 0 but leave this one alone: a blurred dimmer suits a
1462
+ page without glass as well. */
1279
1463
  .glass-modal-overlay {
1280
1464
  position: fixed; inset: 0;
1281
1465
  background: var(--gl-surface-overlay);
1282
- backdrop-filter: blur(var(--gl-blur-soft));
1283
- -webkit-backdrop-filter: blur(var(--gl-blur-soft));
1466
+ backdrop-filter: blur(var(--gl-blur-overlay, var(--gl-blur-soft)));
1467
+ -webkit-backdrop-filter: blur(var(--gl-blur-overlay, var(--gl-blur-soft)));
1284
1468
  display: flex; align-items: center; justify-content: center;
1285
1469
  padding: var(--gl-space-lg); z-index: 1000;
1286
1470
  opacity: 0; pointer-events: none;
@@ -1321,10 +1505,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
1321
1505
  .glass-modal::before {
1322
1506
  content: '';
1323
1507
  position: absolute; top: 0; left: 10%; right: 10%; height: 1px;
1324
- background: linear-gradient(90deg,
1325
- transparent 0%, rgba(255,255,255,0.4) 30%,
1326
- rgba(255,255,255,0.5) 50%, rgba(255,255,255,0.4) 70%, transparent 100%
1327
- );
1508
+ background: var(--gl-gloss-modal);
1328
1509
  }
1329
1510
 
1330
1511
  .glass-modal__header { padding: var(--gl-space-xl) var(--gl-space-xl) var(--gl-space-sm); text-align: center; }
@@ -2492,8 +2673,9 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2492
2673
  position: fixed; inset: 0; z-index: 1000;
2493
2674
  display: flex; align-items: flex-end; justify-content: center;
2494
2675
  background: var(--gl-surface-overlay);
2495
- backdrop-filter: blur(var(--gl-blur-soft));
2496
- -webkit-backdrop-filter: blur(var(--gl-blur-soft));
2676
+ /* Like the modal's dimmer: --gl-blur-overlay where set (1.25.0). */
2677
+ backdrop-filter: blur(var(--gl-blur-overlay, var(--gl-blur-soft)));
2678
+ -webkit-backdrop-filter: blur(var(--gl-blur-overlay, var(--gl-blur-soft)));
2497
2679
  font-family: var(--gl-font-family);
2498
2680
  -webkit-font-smoothing: antialiased;
2499
2681
  opacity: 0;