@jungherz-de/glasskit 1.33.0 → 1.35.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.33.0
3
+ Jungherz GmbH – v1.35.0
4
4
 
5
5
  Features:
6
6
  - Scoped Reset (box-sizing fix)
@@ -133,6 +133,21 @@
133
133
  --gl-card-glow-mid: rgba(255, 255, 255, 0.22);
134
134
  --gl-card-glow-low: rgba(255, 255, 255, 0.14);
135
135
  --gl-card-glow-bottom: rgba(255, 255, 255, 0.08);
136
+ /* Dark glass of a modal or a sheet is brighter than the page (since
137
+ 1.35.0): its glow starts at the middle one, a segmented control on it
138
+ lies in a well with its chosen option one step darker, a tertiary
139
+ button too is one step darker, and a chosen badge says its label in
140
+ the text colour. Unset in light mode. */
141
+ --gl-dialog-glow-top: var(--gl-card-glow-mid);
142
+ --gl-dialog-well: rgba(0, 0, 0, 0.10);
143
+ --gl-dialog-raised: var(--gl-surface-3);
144
+ --gl-dialog-control: var(--gl-surface-1);
145
+ --gl-badge-selected-color: var(--gl-color-text);
146
+ /* The accent as text on the glass of a card, a modal or a sheet (since
147
+ 1.35.0): the primary text lightened by 40 % white. A card is brighter
148
+ than the page, and the primary as a link, a range value or an accent
149
+ row fell to 4.2:1 on it. Light mode keeps the primary text. */
150
+ --gl-color-primary-on-glass: color-mix(in srgb, var(--gl-color-primary-text) 60%, #ffffff);
136
151
 
137
152
  /* Card Text & Icons */
138
153
  --gl-card-icon-color: rgba(255, 255, 255, 0.8);
@@ -359,6 +374,12 @@
359
374
  --gl-card-glow-mid: rgba(255, 255, 255, 0.78);
360
375
  --gl-card-glow-low: rgba(255, 255, 255, 0.65);
361
376
  --gl-card-glow-bottom: rgba(255, 255, 255, 0.50);
377
+ --gl-dialog-glow-top: initial;
378
+ --gl-dialog-well: initial;
379
+ --gl-dialog-raised: initial;
380
+ --gl-dialog-control: initial;
381
+ --gl-badge-selected-color: initial;
382
+ --gl-color-primary-on-glass: var(--gl-color-primary-text);
362
383
 
363
384
  --gl-card-icon-color: rgba(26, 42, 54, 0.65);
364
385
  --gl-card-text-color: rgba(26, 42, 54, 0.68);
@@ -723,6 +744,8 @@
723
744
  box-shadow: var(--gl-shadow-card), var(--gl-inset-strong);
724
745
  /* A .glass-list--flush inside reaches the card's edges (since 1.29.1). */
725
746
  --gl-list-flush-inset: var(--gl-space-xl);
747
+ /* Accent text on it takes --gl-color-primary-on-glass (since 1.35.0). */
748
+ --gl-ctx-primary-text: var(--gl-color-primary-on-glass);
726
749
  }
727
750
 
728
751
  .glass-card--glow {
@@ -837,10 +860,13 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
837
860
  .glass-btn--secondary:active { transform: translateY(1px); }
838
861
 
839
862
  /* Tertiary */
863
+ /* On the glass of a modal or a sheet (since 1.35.0) one step darker in dark
864
+ mode, --gl-dialog-control, and without a blur of its own: its muted
865
+ label read 3 to 4:1 there. */
840
866
  .glass-btn--tertiary {
841
- background: var(--gl-surface-2);
842
- backdrop-filter: blur(var(--gl-blur-light));
843
- -webkit-backdrop-filter: blur(var(--gl-blur-light));
867
+ background: var(--gl-ctx-btn-tertiary-bg, var(--gl-surface-2));
868
+ backdrop-filter: var(--gl-ctx-control-backdrop, blur(var(--gl-blur-light)));
869
+ -webkit-backdrop-filter: var(--gl-ctx-control-backdrop, blur(var(--gl-blur-light)));
844
870
  border: 1px solid var(--gl-border-subtle);
845
871
  color: var(--gl-color-text-muted);
846
872
  box-shadow: 0 4px 12px rgba(0,0,0,0.10), var(--gl-inset-subtle);
@@ -868,7 +894,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
868
894
  .glass-btn[aria-disabled="true"]:is(:hover, :active) { transform: none; }
869
895
  .glass-btn--tertiary:disabled:hover,
870
896
  .glass-btn--tertiary[aria-disabled="true"]:hover {
871
- background: var(--gl-surface-2); color: var(--gl-color-text-muted);
897
+ background: var(--gl-ctx-btn-tertiary-bg, var(--gl-surface-2)); color: var(--gl-color-text-muted);
872
898
  }
873
899
 
874
900
  /* Sizes */
@@ -903,7 +929,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
903
929
  }
904
930
 
905
931
  .glass-status p {
906
- color: var(--gl-color-text-muted);
932
+ color: var(--gl-status-color, var(--gl-color-text-muted));
907
933
  font-size: var(--gl-font-size-sm);
908
934
  font-weight: var(--gl-font-weight-normal);
909
935
  line-height: 1.45;
@@ -1391,7 +1417,7 @@ a.glass-btn { display: inline-flex; text-decoration: none; }
1391
1417
  .glass-range-value {
1392
1418
  font-size: var(--gl-font-size-sm);
1393
1419
  font-weight: var(--gl-font-weight-semibold);
1394
- color: var(--gl-color-primary-text);
1420
+ color: var(--gl-ctx-primary-text, var(--gl-color-primary-text));
1395
1421
  font-variant-numeric: tabular-nums;
1396
1422
  }
1397
1423
 
@@ -1546,9 +1572,11 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
1546
1572
 
1547
1573
  .glass-modal {
1548
1574
  width: 100%; max-width: var(--gl-modal-max-width, 340px);
1549
- background: linear-gradient(to bottom,
1550
- var(--gl-card-glow-top) 0%, var(--gl-card-glow-bottom) 100%
1551
- );
1575
+ /* --gl-modal-bg replaces the surface (since 1.35.0); in dark mode the
1576
+ glow starts at --gl-dialog-glow-top, the card's middle one. */
1577
+ background: var(--gl-modal-bg, linear-gradient(to bottom,
1578
+ var(--gl-dialog-glow-top, var(--gl-card-glow-top)) 0%, var(--gl-card-glow-bottom) 100%
1579
+ ));
1552
1580
  backdrop-filter: blur(var(--gl-blur-heavy));
1553
1581
  -webkit-backdrop-filter: blur(var(--gl-blur-heavy));
1554
1582
  border: 1.5px solid var(--gl-border-medium);
@@ -1586,7 +1614,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
1586
1614
  .glass-modal__action:disabled { opacity: 0.45; cursor: not-allowed; }
1587
1615
  .glass-modal__action:disabled:hover { background: transparent; }
1588
1616
  .glass-modal__action + .glass-modal__action { border-inline-start: 1px solid var(--gl-border-subtle); }
1589
- .glass-modal__action--primary { color: var(--gl-color-primary-text); font-weight: var(--gl-font-weight-semibold); }
1617
+ .glass-modal__action--primary { color: var(--gl-ctx-primary-text, var(--gl-color-primary-text)); font-weight: var(--gl-font-weight-semibold); }
1590
1618
  .glass-modal__action--danger { color: var(--gl-color-error); font-weight: var(--gl-font-weight-semibold); }
1591
1619
 
1592
1620
 
@@ -2078,7 +2106,7 @@ dialog.glass-modal-overlay::backdrop { background: transparent; }
2078
2106
  .glass-segmented.glass-segmented--droplet[data-droplet]::before {
2079
2107
  background:
2080
2108
  var(--gl-gloss-droplet, none),
2081
- var(--gl-segmented-active-bg, linear-gradient(to bottom, var(--gl-surface-5) 0%, var(--gl-surface-3) 100%));
2109
+ var(--gl-segmented-active-bg, var(--gl-ctx-segmented-active-bg, linear-gradient(to bottom, var(--gl-surface-5) 0%, var(--gl-surface-3) 100%)));
2082
2110
  box-shadow:
2083
2111
  var(--gl-segmented-active-shadow, 0 4px 14px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.12)),
2084
2112
  inset 0 0 0 1px var(--gl-border-subtle),
@@ -2488,7 +2516,7 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
2488
2516
  -webkit-tap-highlight-color: transparent;
2489
2517
  }
2490
2518
 
2491
- .glass-accordion__trigger:hover { color: var(--gl-color-primary-text); }
2519
+ .glass-accordion__trigger:hover { color: var(--gl-ctx-primary-text, var(--gl-color-primary-text)); }
2492
2520
 
2493
2521
  .glass-accordion__trigger-icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
2494
2522
 
@@ -2543,8 +2571,11 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
2543
2571
  display: inline-flex; align-items: center; gap: var(--gl-space-2xs);
2544
2572
  padding: var(--gl-space-2xs) var(--gl-space-sm);
2545
2573
  background: var(--gl-surface-3);
2546
- backdrop-filter: blur(var(--gl-blur-soft));
2547
- -webkit-backdrop-filter: blur(var(--gl-blur-soft));
2574
+ /* No blur of its own on the glass of a modal or a sheet (since 1.35.0):
2575
+ the dialog blurs already, and Chromium counted its glow twice beneath
2576
+ a nested backdrop filter — a chip there came out 2.9:1 for white. */
2577
+ backdrop-filter: var(--gl-ctx-control-backdrop, blur(var(--gl-blur-soft)));
2578
+ -webkit-backdrop-filter: var(--gl-ctx-control-backdrop, blur(var(--gl-blur-soft)));
2548
2579
  border: 1px solid var(--gl-border-subtle);
2549
2580
  border-radius: var(--gl-radius-full);
2550
2581
  font-size: var(--gl-font-size-xs);
@@ -2632,9 +2663,12 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
2632
2663
  box-shadow: var(--gl-shadow-focus), var(--gl-inset-subtle);
2633
2664
  }
2634
2665
 
2666
+ /* In dark mode the label takes the text colour (since 1.35.0): the accent
2667
+ lightened for dark surfaces read 2.2 to 3:1 on a chip over glass. The
2668
+ selection shows in the border and the tint. */
2635
2669
  .glass-badge--selected {
2636
2670
  border-color: color-mix(in srgb, var(--gl-badge-accent) 55%, transparent);
2637
- color: var(--gl-badge-accent-text);
2671
+ color: var(--gl-badge-selected-color, var(--gl-badge-accent-text));
2638
2672
  box-shadow: var(--gl-inset-subtle),
2639
2673
  inset 0 0 0 100px color-mix(in srgb, var(--gl-badge-accent) 22%, transparent);
2640
2674
  }
@@ -3037,10 +3071,14 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3037
3071
  list-style: none;
3038
3072
  }
3039
3073
 
3074
+ /* The divider starts under the text: after the leading icon, or at the
3075
+ row's padding without one. --gl-list-item-divider-inset (since 1.34.0)
3076
+ sets the start for rows laid out otherwise — a drag handle before the
3077
+ icon, a wider leading element. */
3040
3078
  .glass-list__item:not(:last-child)::after {
3041
3079
  content: '';
3042
3080
  position: absolute;
3043
- inset-inline-start: calc(var(--gl-space-lg) + 28px + var(--gl-space-sm));
3081
+ inset-inline-start: var(--gl-list-item-divider-inset, calc(var(--gl-space-lg) + 28px + var(--gl-space-sm)));
3044
3082
  inset-inline-end: var(--gl-space-lg);
3045
3083
  bottom: 0;
3046
3084
  height: 1px;
@@ -3050,10 +3088,16 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3050
3088
  /* Items without a leading icon — no slot, or a hidden one: divider follows
3051
3089
  the standard horizontal padding instead of the icon slot. */
3052
3090
  .glass-list__item:not(:has(.glass-list__leading:not([hidden]))):not(:last-child)::after {
3053
- inset-inline-start: var(--gl-space-lg);
3091
+ inset-inline-start: var(--gl-list-item-divider-inset, var(--gl-space-lg));
3054
3092
  }
3055
3093
  .glass-list__item:has(.glass-list__leading--lg:not([hidden])):not(:last-child)::after {
3056
- inset-inline-start: calc(var(--gl-space-lg) + 40px + var(--gl-space-sm));
3094
+ inset-inline-start: var(--gl-list-item-divider-inset, calc(var(--gl-space-lg) + 40px + var(--gl-space-sm)));
3095
+ }
3096
+ /* A drag handle at the start of the row (since 1.34.0): its width is the
3097
+ page's, so the line runs from the row's padding, as in a row without an
3098
+ icon, until --gl-list-item-divider-inset says where the text begins. */
3099
+ .glass-list__item:has(> .glass-sort__handle:first-child:not([hidden])):not(:last-child)::after {
3100
+ inset-inline-start: var(--gl-list-item-divider-inset, var(--gl-space-lg));
3057
3101
  }
3058
3102
 
3059
3103
  .glass-list__item--center {
@@ -3091,11 +3135,36 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3091
3135
  .glass-list__item--interactive:disabled:is(:hover, :active),
3092
3136
  .glass-list__item--interactive[aria-disabled="true"]:is(:hover, :active) { background: transparent; }
3093
3137
 
3138
+ /* The chosen row of a list beside its detail (since 1.34.0) — the entry an
3139
+ editor next to it shows: a pill of raised glass inside the row, as the
3140
+ chosen tree row and the active row of a sidebar, with the title in the
3141
+ heading colour and the icon in the accent. The state is .is-selected;
3142
+ aria-current="true" (or aria-selected in a listbox) tells assistive
3143
+ technology. Hover and press leave it as it is; the keyboard ring stays
3144
+ around the row. While the row is a drop target of a drag, the pill makes
3145
+ way for the line or the tint. */
3146
+ /* Tokens since 1.35.0 shape it otherwise: --gl-list-item-selected-inset
3147
+ (3px --gl-space-xs), -radius (--gl-radius-sm), -shadow (edge light and a
3148
+ button's shadow), -color (the heading colour) and -weight (semibold).
3149
+ Inset 0, radius 0 and shadow none make a flat tint over the whole row. */
3150
+ .glass-list__item.is-selected { color: var(--gl-list-item-selected-color, var(--gl-color-text-heading)); isolation: isolate; }
3151
+ .glass-list__item.is-selected:not(.is-sort-before, .is-sort-after, .is-sort-inside, .is-sort-refused)::before {
3152
+ content: ''; position: absolute; z-index: -1;
3153
+ inset: var(--gl-list-item-selected-inset, 3px var(--gl-space-xs));
3154
+ border-radius: var(--gl-list-item-selected-radius, var(--gl-radius-sm));
3155
+ background: var(--gl-list-item-selected-bg, var(--gl-surface-4));
3156
+ box-shadow: var(--gl-list-item-selected-shadow, var(--gl-inset-strong), var(--gl-shadow-btn));
3157
+ pointer-events: none;
3158
+ }
3159
+ .glass-list__item--interactive.is-selected:is(:hover, :active, :focus-visible) { background: transparent; }
3160
+ .glass-list__item.is-selected .glass-list__title { font-weight: var(--gl-list-item-selected-weight, var(--gl-font-weight-semibold)); }
3161
+ .glass-list__item.is-selected .glass-list__leading { color: var(--gl-color-primary-text); }
3162
+
3094
3163
  .glass-list__item--danger { color: var(--gl-color-error); }
3095
3164
  .glass-list__item--danger .glass-list__title,
3096
3165
  .glass-list__item--danger .glass-list__leading { color: inherit; }
3097
3166
 
3098
- .glass-list__item--accent { color: var(--gl-color-primary-text); }
3167
+ .glass-list__item--accent { color: var(--gl-ctx-primary-text, var(--gl-color-primary-text)); }
3099
3168
  .glass-list__item--accent .glass-list__title,
3100
3169
  .glass-list__item--accent .glass-list__leading { color: inherit; }
3101
3170
 
@@ -3160,9 +3229,11 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3160
3229
  out of it — an e-mail address in a --wrap subtitle used to — while text
3161
3230
  still breaks at spaces. hyphens is left to inheritance: set it on the
3162
3231
  list or the page for breaks at syllables. */
3232
+ /* --gl-list-title-size, --gl-list-title-weight and --gl-list-subtitle-size
3233
+ (since 1.35.0) set the type of a row, on the list or one row. */
3163
3234
  .glass-list__title {
3164
- font-size: var(--gl-font-size-base);
3165
- font-weight: var(--gl-font-weight-medium);
3235
+ font-size: var(--gl-list-title-size, var(--gl-font-size-base));
3236
+ font-weight: var(--gl-list-title-weight, var(--gl-font-weight-medium));
3166
3237
  color: var(--gl-color-text);
3167
3238
  white-space: var(--gl-list-title-white-space, nowrap);
3168
3239
  overflow: hidden;
@@ -3170,7 +3241,7 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3170
3241
  overflow-wrap: anywhere;
3171
3242
  }
3172
3243
  .glass-list__subtitle {
3173
- font-size: var(--gl-font-size-sm);
3244
+ font-size: var(--gl-list-subtitle-size, var(--gl-font-size-sm));
3174
3245
  color: var(--gl-color-text-muted);
3175
3246
  white-space: var(--gl-list-subtitle-white-space, nowrap);
3176
3247
  overflow: hidden;
@@ -3187,6 +3258,27 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3187
3258
  /* display: -webkit-box above beats the hidden attribute's own rule: an empty
3188
3259
  --wrap subtitle kept its place, and the title sat 1px off centre. */
3189
3260
  .glass-list__subtitle[hidden] { display: none; }
3261
+ /* Room beside the title and below the subtitle (since 1.35.0). __title-row
3262
+ holds the title and __title-trailing — a badge such as "AI", a mark —,
3263
+ which moves under the title where the row is too narrow; the title keeps
3264
+ its ellipsis. __extra below the subtitle takes a link ("Undo") or a line
3265
+ of chips. */
3266
+ .glass-list__title-row {
3267
+ display: flex; flex-wrap: wrap; align-items: center;
3268
+ gap: var(--gl-space-2xs) var(--gl-space-xs);
3269
+ min-width: 0;
3270
+ }
3271
+ .glass-list__title-row > .glass-list__title { flex: 0 1 auto; min-width: 0; }
3272
+ .glass-list__item--center .glass-list__title-row { justify-content: center; }
3273
+ .glass-list__title-trailing { flex: none; display: inline-flex; align-items: center; gap: var(--gl-space-2xs); }
3274
+ .glass-list__extra {
3275
+ display: flex; flex-wrap: wrap; align-items: center; gap: var(--gl-space-xs);
3276
+ margin-top: var(--gl-space-2xs);
3277
+ font-size: var(--gl-font-size-sm);
3278
+ color: var(--gl-color-text-muted);
3279
+ }
3280
+ .glass-list__title-trailing[hidden],
3281
+ .glass-list__extra[hidden] { display: none; }
3190
3282
 
3191
3283
  .glass-list__trailing {
3192
3284
  flex-shrink: 0;
@@ -3212,6 +3304,63 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3212
3304
  white-space: nowrap;
3213
3305
  }
3214
3306
 
3307
+ /* Tiles side by side (since 1.34.0): the list as a grid of panes of glass
3308
+ — components, apps, choices — each with the surface, edge light and
3309
+ shadow the list has as a whole, which itself has none. The icon stands
3310
+ at the top, the title and subtitle at the foot, the trailing content in
3311
+ the top end corner and a drag handle in the bottom end corner; no
3312
+ dividers. --gl-list-tile-width (140px) is the least width of a column,
3313
+ --gl-list-tile-gap (--gl-space-sm) the gap, --gl-list-tile-min-height
3314
+ (112px) the least height. In plain markup the items of a .glass-list
3315
+ --grid are tiles; GlassKit Elements puts .glass-list__item--tile on the
3316
+ rows of <glk-list grid>, which lie in shadow roots of their own. */
3317
+ .glass-list--grid {
3318
+ display: grid;
3319
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--gl-list-tile-width, 140px)), 1fr));
3320
+ gap: var(--gl-list-tile-gap, var(--gl-space-sm));
3321
+ background: none;
3322
+ backdrop-filter: none;
3323
+ -webkit-backdrop-filter: none;
3324
+ border: none;
3325
+ border-radius: 0;
3326
+ box-shadow: none;
3327
+ overflow: visible;
3328
+ }
3329
+ :where(.glass-list--grid) > .glass-list__item,
3330
+ .glass-list__item--tile {
3331
+ flex-direction: column;
3332
+ align-items: flex-start;
3333
+ gap: var(--gl-space-sm);
3334
+ height: 100%;
3335
+ min-height: var(--gl-list-tile-min-height, 112px);
3336
+ padding: var(--gl-space-md);
3337
+ border-radius: var(--gl-radius-btn);
3338
+ background: var(--gl-surface-1);
3339
+ backdrop-filter: blur(var(--gl-blur-light));
3340
+ -webkit-backdrop-filter: blur(var(--gl-blur-light));
3341
+ border: 1px solid var(--gl-border-subtle);
3342
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08), var(--gl-inset-subtle);
3343
+ }
3344
+ .glass-list--grid > .glass-list__item::after,
3345
+ .glass-list__item.glass-list__item--tile::after { content: none; }
3346
+ /* The text sits at the foot. It never shrinks below its lines — its
3347
+ overflow: hidden would let it, and cut the title's descenders —, so a
3348
+ tile with more to say grows. */
3349
+ :where(.glass-list--grid) > .glass-list__item .glass-list__content,
3350
+ .glass-list__item--tile .glass-list__content { flex: 1 0 auto; align-self: stretch; justify-content: flex-end; }
3351
+ :where(.glass-list--grid) > .glass-list__item .glass-list__trailing,
3352
+ .glass-list__item--tile .glass-list__trailing { position: absolute; top: var(--gl-space-sm); inset-inline-end: var(--gl-space-sm); }
3353
+ :where(.glass-list--grid) > .glass-list__item > .glass-sort__handle,
3354
+ .glass-list__item--tile > .glass-sort__handle { position: absolute; bottom: var(--gl-space-sm); inset-inline-end: var(--gl-space-sm); }
3355
+ /* The chosen tile is raised glass as a whole. */
3356
+ .glass-list--grid > .glass-list__item.is-selected:not(.is-sort-before, .is-sort-after, .is-sort-inside, .is-sort-refused)::before,
3357
+ .glass-list__item--tile.is-selected:not(.is-sort-before, .is-sort-after, .is-sort-inside, .is-sort-refused)::before { inset: -1px; border-radius: inherit; }
3358
+ /* The drop line stands in the middle of the gap. */
3359
+ .glass-list--grid > .glass-list__item.is-sort-inline.is-sort-before::before,
3360
+ .glass-list__item--tile.is-sort-inline.is-sort-before::before { inset-inline-start: calc(var(--gl-list-tile-gap, var(--gl-space-sm)) / -2 - 1px); }
3361
+ .glass-list--grid > .glass-list__item.is-sort-inline.is-sort-after::before,
3362
+ .glass-list__item--tile.is-sort-inline.is-sort-after::before { inset-inline-end: calc(var(--gl-list-tile-gap, var(--gl-space-sm)) / -2 - 1px); }
3363
+
3215
3364
 
3216
3365
  /* ============================================================
3217
3366
  25b. TREE
@@ -3278,15 +3427,18 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3278
3427
  animation: glass-tree-spin .8s linear infinite;
3279
3428
  }
3280
3429
  @keyframes glass-tree-spin { to { transform: rotate(360deg); } }
3430
+ /* The icon field is --gl-tree-icon-size square (since 1.34.0; 18px), and
3431
+ so is its SVG: a larger mark — a tinted 28px chip with a symbol, as list
3432
+ rows show — gets a field of its size instead of being squeezed into 18px. */
3281
3433
  .glass-tree__icon {
3282
- flex: none; width: 18px; height: 18px;
3434
+ flex: none; width: var(--gl-tree-icon-size, 18px); height: var(--gl-tree-icon-size, 18px);
3283
3435
  display: flex; align-items: center; justify-content: center;
3284
3436
  color: var(--gl-icon-default);
3285
3437
  }
3286
3438
  .glass-tree__icon:empty, .glass-tree__icon[hidden] { display: none; }
3287
3439
  .glass-tree__icon svg,
3288
3440
  .glass-tree__icon ::slotted(svg) {
3289
- width: 18px; height: 18px; fill: none;
3441
+ width: var(--gl-tree-icon-size, 18px); height: var(--gl-tree-icon-size, 18px); fill: none;
3290
3442
  stroke: currentColor; stroke-width: 1.8;
3291
3443
  stroke-linecap: round; stroke-linejoin: round;
3292
3444
  }
@@ -3413,11 +3565,24 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3413
3565
  }
3414
3566
  .is-sort-before::before { top: -1px; }
3415
3567
  .is-sort-after::before { bottom: -1px; }
3416
- .is-sort-inside {
3568
+ /* Items side by side — tiles in a grid, a row of them (since 1.34.0): with
3569
+ .is-sort-inline the line stands upright at the target's start or end
3570
+ edge, where the item lands. */
3571
+ .is-sort-inline.is-sort-before::before,
3572
+ .is-sort-inline.is-sort-after::before { inset-block: var(--gl-space-xs); width: 2px; height: auto; }
3573
+ .is-sort-inline.is-sort-before::before { inset-inline: -1px auto; }
3574
+ .is-sort-inline.is-sort-after::before { inset-inline: auto -1px; }
3575
+ /* On a list or tree row also over its hover and its chosen state (since
3576
+ 1.34.0; before, both covered the tint). */
3577
+ .is-sort-inside,
3578
+ .glass-list__item.is-sort-inside,
3579
+ .glass-tree__row.is-sort-inside {
3417
3580
  background: color-mix(in srgb, var(--gl-color-primary) 16%, transparent);
3418
3581
  box-shadow: inset 0 0 0 1.5px var(--gl-border-focus);
3419
3582
  }
3420
- .is-sort-refused {
3583
+ .is-sort-refused,
3584
+ .glass-list__item.is-sort-refused,
3585
+ .glass-tree__row.is-sort-refused {
3421
3586
  background: var(--gl-color-error-surface);
3422
3587
  box-shadow: inset 0 0 0 1.5px var(--gl-color-error-border);
3423
3588
  }
@@ -3659,7 +3824,7 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3659
3824
  .glass-prose ul, .glass-prose ol { padding-inline-start: 1.3em; }
3660
3825
  .glass-prose strong { color: var(--gl-color-text-heading); }
3661
3826
  /* Links in running text are underlined: colour alone does not mark them. */
3662
- .glass-prose a { color: var(--gl-color-primary-text); text-decoration: underline; text-underline-offset: 2px; }
3827
+ .glass-prose a { color: var(--gl-ctx-primary-text, var(--gl-color-primary-text)); text-decoration: underline; text-underline-offset: 2px; }
3663
3828
  .glass-prose code {
3664
3829
  font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 0.9em;
3665
3830
  background: var(--gl-surface-2); padding: 1px 5px; border-radius: 4px;
@@ -3697,7 +3862,9 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3697
3862
  .glass-segmented {
3698
3863
  display: inline-flex; gap: 4px; padding: 4px;
3699
3864
  max-width: 100%;
3700
- background: var(--gl-surface-1);
3865
+ /* --gl-segmented-bg (since 1.35.0); on the glass of a modal or a sheet
3866
+ in dark mode the track is a well, --gl-dialog-well. */
3867
+ background: var(--gl-segmented-bg, var(--gl-ctx-segmented-bg, var(--gl-surface-1)));
3701
3868
  border: 1px solid var(--gl-border-subtle);
3702
3869
  border-radius: var(--gl-radius-btn);
3703
3870
  box-shadow: var(--gl-inset-subtle);
@@ -3741,7 +3908,7 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3741
3908
  values; the drop of --droplet takes the same surface (18c). The shadow
3742
3909
  sits in shadow lists: switch it off with a zero shadow, not none. */
3743
3910
  .glass-segmented__item[aria-pressed="true"] {
3744
- background: var(--gl-segmented-active-bg, var(--gl-surface-5));
3911
+ background: var(--gl-segmented-active-bg, var(--gl-ctx-segmented-active-bg, var(--gl-surface-5)));
3745
3912
  color: var(--gl-segmented-active-color, var(--gl-color-text-heading));
3746
3913
  box-shadow: var(--gl-segmented-active-shadow, var(--gl-shadow-btn));
3747
3914
  }
@@ -3772,8 +3939,13 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3772
3939
  }
3773
3940
  .glass-segmented__icon[hidden] { display: none; }
3774
3941
  .glass-segmented__icon svg,
3775
- .glass-segmented__icon ::slotted(svg) {
3776
- width: 18px; height: 18px; fill: none;
3942
+ .glass-segmented__icon ::slotted(svg) { width: 18px; height: 18px; }
3943
+ /* A line icon strokes in the option's colour. --color (since 1.35.0) keeps
3944
+ a coloured logo's own fills and strokes; before, its shapes inherited the
3945
+ stroke and came out outlined in the text colour. */
3946
+ .glass-segmented__icon:not(.glass-segmented__icon--color) svg,
3947
+ .glass-segmented__icon:not(.glass-segmented__icon--color) ::slotted(svg) {
3948
+ fill: none;
3777
3949
  stroke: currentColor; stroke-width: 1.8;
3778
3950
  stroke-linecap: round; stroke-linejoin: round;
3779
3951
  }
@@ -3938,7 +4110,7 @@ a.glass-tab-bar__item { text-decoration: none; color: inherit; }
3938
4110
  layout instead of idling at opacity 0. <glk-sheet> in GlassKit Elements
3939
4111
  does exactly this. --inline embeds the panel in the flow, no overlay. */
3940
4112
  .glass-sheet-overlay {
3941
- position: fixed; inset: 0; z-index: 1000;
4113
+ position: fixed; inset: 0; z-index: var(--gl-sheet-z-index, 1000);
3942
4114
  display: flex; align-items: flex-end; justify-content: center;
3943
4115
  background: var(--gl-surface-overlay);
3944
4116
  /* Like the modal's dimmer: --gl-blur-overlay where set (1.25.0). */
@@ -3976,9 +4148,9 @@ dialog.glass-sheet-overlay::backdrop { background: transparent; }
3976
4148
  light in dark mode — with --gl-color-text on it the sheet read white
3977
4149
  on white-grey. The card glow gradient over heavy blur is what the
3978
4150
  text tokens are made for, in both themes. */
3979
- background: linear-gradient(to bottom,
3980
- var(--gl-card-glow-top) 0%, var(--gl-card-glow-bottom) 100%
3981
- );
4151
+ background: var(--gl-sheet-bg, linear-gradient(to bottom,
4152
+ var(--gl-dialog-glow-top, var(--gl-card-glow-top)) 0%, var(--gl-card-glow-bottom) 100%
4153
+ ));
3982
4154
  backdrop-filter: blur(var(--gl-blur-heavy));
3983
4155
  -webkit-backdrop-filter: blur(var(--gl-blur-heavy));
3984
4156
  color: var(--gl-color-text);
@@ -3993,12 +4165,106 @@ dialog.glass-sheet-overlay::backdrop { background: transparent; }
3993
4165
  .glass-sheet-overlay.is-active .glass-sheet { transform: translateY(0); }
3994
4166
  .glass-sheet--inline { border-radius: var(--gl-radius-card); box-shadow: var(--gl-shadow-card); }
3995
4167
 
4168
+ /* Controls on the glass of a modal or a sheet (since 1.35.0) take the
4169
+ theme's dialog values where the page set none of its own: a segmented
4170
+ control lies in --gl-dialog-well with its chosen option on
4171
+ --gl-dialog-raised, a tertiary button on --gl-dialog-control (all dark
4172
+ mode only), and badges and tertiary buttons take no blur of their own;
4173
+ accent text — a link, an accent row — takes --gl-color-primary-on-glass,
4174
+ as on a card. Inherited, so they reach the controls of GlassKit Elements in
4175
+ their shadow roots. */
4176
+ .glass-modal, .glass-sheet {
4177
+ --gl-ctx-segmented-bg: var(--gl-dialog-well);
4178
+ --gl-ctx-segmented-active-bg: var(--gl-dialog-raised);
4179
+ --gl-ctx-btn-tertiary-bg: var(--gl-dialog-control);
4180
+ --gl-ctx-control-backdrop: none;
4181
+ --gl-ctx-primary-text: var(--gl-color-primary-on-glass);
4182
+ }
4183
+
4184
+ /* At a side (since 1.35.0): --start or --end on the overlay puts the panel
4185
+ at that edge, as high as the window less --gl-sheet-side-inset (16px) at
4186
+ both ends and that far from its edge, --gl-sheet-side-width (440px) wide,
4187
+ with a card's corners. It slides in from that edge, has no grip, and its
4188
+ actions stand side by side at its foot. --modeless leaves the page
4189
+ usable: no scrim and no blur, and only the panel takes the pointer — for
4190
+ a sheet opened with show() instead of showModal(), beside a list whose
4191
+ chosen row stays in view. --gl-sheet-z-index (1000) stacks it. */
4192
+ /* The inset is the panel's margin: the dialog's own padding is undone. */
4193
+ .glass-sheet-overlay--start,
4194
+ .glass-sheet-overlay--end { align-items: stretch; }
4195
+ .glass-sheet-overlay--start { justify-content: flex-start; }
4196
+ .glass-sheet-overlay--end { justify-content: flex-end; }
4197
+ :is(.glass-sheet-overlay--start, .glass-sheet-overlay--end) .glass-sheet {
4198
+ width: min(var(--gl-sheet-side-width, 440px), 100% - 2 * var(--gl-sheet-side-inset, 16px)); max-height: none;
4199
+ margin: var(--gl-sheet-side-inset, 16px);
4200
+ display: flex; flex-direction: column;
4201
+ padding-top: var(--gl-space-lg);
4202
+ border-radius: var(--gl-radius-card);
4203
+ }
4204
+ .glass-sheet-overlay--end .glass-sheet,
4205
+ .glass-sheet-overlay--start:dir(rtl) .glass-sheet { transform: translateX(calc(100% + var(--gl-sheet-side-inset, 16px))); }
4206
+ .glass-sheet-overlay--start .glass-sheet,
4207
+ .glass-sheet-overlay--end:dir(rtl) .glass-sheet { transform: translateX(calc(-100% - var(--gl-sheet-side-inset, 16px))); }
4208
+ :is(.glass-sheet-overlay--start, .glass-sheet-overlay--end).is-active .glass-sheet { transform: none; }
4209
+ :is(.glass-sheet-overlay--start, .glass-sheet-overlay--end) .glass-sheet__grip { display: none; }
4210
+ :is(.glass-sheet-overlay--start, .glass-sheet-overlay--end) .glass-sheet__body { flex: 1 0 auto; }
4211
+ :is(.glass-sheet-overlay--start, .glass-sheet-overlay--end) .glass-sheet__actions { flex-direction: row; flex-wrap: wrap; justify-content: flex-end; }
4212
+ .glass-sheet-overlay--modeless {
4213
+ background: none;
4214
+ backdrop-filter: none;
4215
+ -webkit-backdrop-filter: none;
4216
+ pointer-events: none;
4217
+ }
4218
+ .glass-sheet-overlay--modeless .glass-sheet { pointer-events: auto; }
4219
+ /* The panel takes the focus only as a whole, to hand it on; no ring. */
4220
+ .glass-sheet:focus { outline: none; }
4221
+
3996
4222
  .glass-sheet__grip { width: 40px; height: 4px; margin: 4px auto 12px; border-radius: 2px; background: var(--gl-border-strong); }
3997
4223
  .glass-sheet__title {
3998
4224
  margin: 0 0 8px;
3999
4225
  font-size: var(--gl-font-size-modal); font-weight: var(--gl-font-weight-semibold);
4000
4226
  color: var(--gl-color-text-heading);
4001
4227
  }
4228
+ /* The head (since 1.35.0): the title with a short line above it
4229
+ (__eyebrow), something before it (__leading, a mark or an icon chip),
4230
+ something after it (__trailing, a badge) and a close button (__close) at
4231
+ its end. __head takes the title's place and its spacing; a title alone
4232
+ in it stands as it did without one. */
4233
+ .glass-sheet__head { display: flex; align-items: center; gap: var(--gl-space-sm); margin: 0 0 8px; }
4234
+ .glass-sheet__heading { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
4235
+ .glass-sheet__head .glass-sheet__title { margin: 0; }
4236
+ .glass-sheet__eyebrow {
4237
+ font-size: var(--gl-font-size-xs); font-weight: var(--gl-font-weight-semibold);
4238
+ letter-spacing: 0.3px; text-transform: uppercase;
4239
+ color: var(--gl-color-text-muted);
4240
+ }
4241
+ .glass-sheet__leading,
4242
+ .glass-sheet__trailing { flex: none; display: flex; align-items: center; gap: var(--gl-space-xs); }
4243
+ .glass-sheet__eyebrow[hidden],
4244
+ .glass-sheet__leading[hidden],
4245
+ .glass-sheet__trailing[hidden],
4246
+ .glass-sheet__close[hidden] { display: none; }
4247
+ /* A round glass button, 32px, with a 44px target. */
4248
+ .glass-sheet__close {
4249
+ -webkit-appearance: none; appearance: none;
4250
+ flex: none; position: relative;
4251
+ width: 32px; height: 32px; margin-inline-end: -4px; padding: 0;
4252
+ display: inline-flex; align-items: center; justify-content: center;
4253
+ border: 1px solid var(--gl-border-subtle); border-radius: 50%;
4254
+ background: var(--gl-surface-2);
4255
+ color: var(--gl-color-text-muted);
4256
+ box-shadow: var(--gl-inset-subtle);
4257
+ font: inherit; cursor: pointer;
4258
+ transition: var(--gl-transition-fast);
4259
+ outline: none; -webkit-tap-highlight-color: transparent;
4260
+ }
4261
+ .glass-sheet__close::after { content: ""; position: absolute; inset: -6px; }
4262
+ .glass-sheet__close:hover { background: var(--gl-surface-3); color: var(--gl-color-text); }
4263
+ .glass-sheet__close:focus-visible { box-shadow: var(--gl-shadow-focus), var(--gl-inset-subtle); }
4264
+ .glass-sheet__close svg {
4265
+ width: 16px; height: 16px; fill: none; stroke: currentColor;
4266
+ stroke-width: 2; stroke-linecap: round;
4267
+ }
4002
4268
  .glass-sheet__body { font-size: var(--gl-font-size-base); line-height: 1.55; }
4003
4269
  .glass-sheet__actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
4004
4270
  @media (prefers-reduced-motion: reduce) {