@guildofgleks/ui 21.7.2 → 21.9.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/styles/theme.css CHANGED
@@ -53,10 +53,38 @@
53
53
  --gog-text-sm: 0.875rem;
54
54
  --gog-text-md: 1rem;
55
55
  --gog-text-lg: 1.125rem;
56
+ /* 20px, between `lg` and `xl`. Named for the control size it serves rather than continuing the
57
+ t-shirt run, because that is what asked for it: `gog-button` and the field controls both
58
+ needed a step for their `slg` size and, having none, both wrote `1.25rem` as a literal — the
59
+ same value chosen twice, independently, which is a missing rung and not two opinions. The
60
+ gap from 1.125 to 1.5 is the widest in the scale, so it was the one likely to be filled by
61
+ hand. */
62
+ --gog-text-slg: 1.25rem;
56
63
  --gog-text-xl: 1.5rem;
57
64
  --gog-text-2xl: 2rem;
58
65
  --gog-text-3xl: 3rem;
59
66
 
67
+ /* Weight, the third character axis after casing and tracking — and the one 21.7.0's character
68
+ layer missed, which is how fifteen component tokens came to hold a bare number. A house style
69
+ that wants lighter chrome sets these four and nothing else; before them it meant finding and
70
+ re-listing every one. Four steps because four are used: no `normal`, because nothing in the
71
+ library paints 400 and an unused token is API nobody asked for. */
72
+ --gog-font-weight-medium: 500;
73
+ --gog-font-weight-semibold: 600;
74
+ --gog-font-weight-bold: 700;
75
+ --gog-font-weight-heavy: 900;
76
+
77
+ /* Leading, the fourth character axis. Twenty component tokens held a bare number — seven of
78
+ them the same 1.4 — so a house style that wanted roomier text had to find every one. Six
79
+ steps because six values are painted; `gog-panel`'s heading keeps its own 1.25, which is
80
+ off this scale on purpose the way an 11px chip is off the type scale. */
81
+ --gog-line-height-none: 1;
82
+ --gog-line-height-tight: 1.2;
83
+ --gog-line-height-snug: 1.3;
84
+ --gog-line-height-normal: 1.4;
85
+ --gog-line-height-relaxed: 1.5;
86
+ --gog-line-height-loose: 1.6;
87
+
60
88
  /* The "emphasis" casing character — labels, buttons, section and table headers all shout
61
89
  the same way by default. Not every uppercase/1px-tracking declaration in this file reads
62
90
  these two: only the ones that genuinely share this idea do. A few (gog-tabs among them)
@@ -128,6 +156,11 @@
128
156
  Five-tier scale: xsm/slg bookend the original sm/md/lg (restored below to
129
157
  their pre-compaction numbers) as new extremes for extra-tight or extra-roomy
130
158
  layouts. */
159
+ /* The clear (×) button's glyph, as a fraction of its box. One number written five times —
160
+ `gog-autocomplete`, `gog-datepicker`, `gog-inputfield`, `gog-multiselect` and `gog-select`
161
+ all had their own `0.7` for the same part. `gog-textarea` keeps its own `1` deliberately:
162
+ its clear button sits in a corner rather than in the field's icon row. */
163
+ --gog-control-clear-icon-ratio: 0.7;
131
164
  --gog-control-border-width: 2px;
132
165
  --gog-control-border-style: solid;
133
166
 
@@ -164,8 +197,6 @@
164
197
  --gog-field-icon-glyph-sm: 14px;
165
198
  --gog-field-icon-glyph: 16px;
166
199
 
167
- --gog-field-slg-font-size: 1.25rem;
168
-
169
200
  /* ── Float label geometry (input / textarea / select / multiselect) ─────────
170
201
  One scale for every field that can float its label. Each control reads these
171
202
  through its own `--gog-<block>-float-label-*` token in the derived layer below,
@@ -198,8 +229,11 @@
198
229
  /* ── Overlay stacking ───────────────────────────────────────────────────────
199
230
  Baseline for dropdown panels. gog-dialog re-declares this on its own panel so
200
231
  dropdowns opened inside a dialog stack above it. */
201
- --gog-dropdown-z: 300;
202
- --gog-spinner-overlay-z: 8000;
232
+ /* The library's stacking floor. Every layer below is `base + N`, so an app that has to put the
233
+ whole library above its own chrome moves this one number and keeps the internal order —
234
+ badge 1, toast 100, dropdowns and dialogs 300, tooltip 400, the blocking spinner overlay
235
+ 8000. Before this, shifting the stack meant editing five tokens and hoping none was missed. */
236
+ --gog-z-base: 0;
203
237
 
204
238
  /* ── Light palette (also the no-data-theme default) ───────────────────────── */
205
239
  color-scheme: light;
@@ -338,6 +372,47 @@
338
372
  /* ── Derived foundation tokens ───────────────────────────────────────────────
339
373
  Split out of the literal block above because they read other tokens: they have
340
374
  to re-resolve inside each theme scope. */
375
+
376
+ /* ── Text on a status fill ───────────────────────────────────────────────────
377
+ `--gog-accent-text-color` means "text on the accent fill" and flips with the theme, which
378
+ made it the obvious label for a status fill too — `gogBadge` used it for all four. It is
379
+ wrong for some of them, and silently: measured 2026-09-04, `material`'s amber under white
380
+ was 1.97:1 and `primeng`'s green 2.28:1, both far under AA, in a pair no check had. The
381
+ accent is one colour a theme tunes deliberately; the four statuses are four more, and
382
+ nothing says one label reads on all five.
383
+
384
+ So each status names its own, defaulting to the accent's answer because that is right in
385
+ seven of the eleven themes. A theme states one of these only where its own hue disagrees —
386
+ `material` puts near-black on its amber, which is Material 3's own convention, and `primeng`
387
+ does the same on all three of Aura's bright hues. Where *neither* label reached AA the hue
388
+ itself moved instead; see the preset files. */
389
+ --gog-success-text-color: var(--gog-accent-text-color, var(--gog-primary-color));
390
+ --gog-danger-text-color: var(--gog-accent-text-color, var(--gog-primary-color));
391
+ --gog-warning-text-color: var(--gog-accent-text-color, var(--gog-primary-color));
392
+ --gog-info-text-color: var(--gog-accent-text-color, var(--gog-primary-color));
393
+
394
+ /* Which way a status fill deepens when it is hovered or held: **away from its own label**, so
395
+ the step always makes the label easier to read rather than harder. That is the theme's ink
396
+ for a fill wearing the accent's white, which is nine of the eleven themes — and the other way
397
+ round for the four fills whose label is the ink itself, `material`'s amber and `primeng`'s
398
+ three, which say so in their own files. Mixing toward a fixed colour instead is what a first
399
+ pass did, and it cost `primeng`'s info button 6.44:1 down to 4.23:1 on press: deepening
400
+ toward the ink walked the fill into the label. */
401
+ --gog-success-shade: var(--gog-text-color);
402
+ --gog-danger-shade: var(--gog-text-color);
403
+ --gog-warning-shade: var(--gog-text-color);
404
+ --gog-info-shade: var(--gog-text-color);
405
+ /* ── Stacking layers ─────────────────────────────────────────────────────────
406
+ All five read `--gog-z-base`, so the whole library moves together. The gaps are
407
+ deliberate: an app that needs to slot its own element between two of these has room
408
+ without touching the library's numbers. */
409
+ --gog-badge-z: calc(var(--gog-z-base) + 1);
410
+ --gog-toast-base-z: calc(var(--gog-z-base) + 100);
411
+ --gog-dropdown-z: calc(var(--gog-z-base) + 300);
412
+ --gog-tooltip-z: calc(var(--gog-z-base) + 400);
413
+ /* The blocking overlay outranks everything, including a dialog it may be covering. */
414
+ --gog-spinner-overlay-z: calc(var(--gog-z-base) + 8000);
415
+
341
416
  --gog-space-2: calc(2px * var(--gog-density));
342
417
  --gog-space-4: calc(4px * var(--gog-density));
343
418
  --gog-space-6: calc(6px * var(--gog-density));
@@ -380,6 +455,11 @@
380
455
  --gog-panel-radius: calc(var(--gog-radius) + 8px);
381
456
  --gog-field-xsm-font-size: var(--gog-text-xs);
382
457
  --gog-field-sm-font-size: var(--gog-text-sm);
458
+ /* The only field metric that is a type size; the rest of this block is geometry. It lives
459
+ here rather than with them because it reads a token, and a derived value declared on the
460
+ literals-only `:root` freezes to that scope's scale (rule C). */
461
+ --gog-field-slg-font-size: var(--gog-text-slg);
462
+
383
463
  --gog-field-md-padding-y: var(--gog-control-padding-y);
384
464
  --gog-field-md-padding-x: var(--gog-control-padding-x);
385
465
 
@@ -419,13 +499,21 @@
419
499
  --gog-accordion-text-color: var(--gog-text-color);
420
500
  --gog-accordion-accent-color: var(--gog-accent-color);
421
501
  --gog-accordion-hover-bg: var(--gog-hover-color);
502
+ /* The header's label stays body text while hovered or held, and the lift is carried by the
503
+ background alone. It turned `--gog-accordion-accent-color` until 21.9.0, which is the accent
504
+ — on an accent-tinted strip that measured 3.61:1 in light, 3.79:1 in one-light and 4.09:1 in
505
+ ledger, and worse again once the press deepened the tint. Same trade as the ghost button's
506
+ hover, and made for the same reason: the accent is not a text colour on a ground that is
507
+ itself tinted with the accent. */
508
+ --gog-accordion-hover-color: var(--gog-accordion-text-color);
509
+ --gog-accordion-press-bg: var(--gog-border-color);
422
510
  --gog-accordion-hover-ring: var(--gog-accent-dim);
423
511
  --gog-accordion-focus-ring-width: var(--gog-focus-ring-width);
424
512
  --gog-accordion-body-color: var(--gog-text-color);
425
- --gog-accordion-body-line-height: 1.6;
513
+ --gog-accordion-body-line-height: var(--gog-line-height-loose);
426
514
  --gog-accordion-header-text-transform: var(--gog-text-transform);
427
515
  --gog-accordion-header-gap: var(--gog-space-12);
428
- --gog-accordion-disabled-opacity: 0.5;
516
+ --gog-accordion-disabled-opacity: var(--gog-disabled-opacity);
429
517
  --gog-accordion-transition-duration: var(--gog-duration-base);
430
518
  --gog-accordion-body-transition-duration: var(--gog-duration-slow);
431
519
  --gog-accordion-chevron-transition-duration: var(--gog-duration-slow);
@@ -450,7 +538,7 @@
450
538
  --gog-accordion-xsm-letter-spacing: 0.2px;
451
539
  --gog-accordion-xsm-content-gap: var(--gog-space-2);
452
540
  --gog-accordion-xsm-body-font-size: var(--gog-text-xs);
453
- --gog-accordion-xsm-body-line-height: 1.5;
541
+ --gog-accordion-xsm-body-line-height: var(--gog-line-height-relaxed);
454
542
  --gog-accordion-xsm-body-padding-top: var(--gog-space-4);
455
543
  --gog-accordion-xsm-body-padding-bottom: var(--gog-space-6);
456
544
  --gog-accordion-xsm-chevron-size: 11px;
@@ -530,24 +618,30 @@
530
618
  --gog-button-md-padding: var(--gog-space-12) var(--gog-space-20);
531
619
  --gog-button-lg-padding: var(--gog-space-16) var(--gog-space-24);
532
620
  --gog-button-slg-padding: var(--gog-space-20) var(--gog-space-28);
533
- --gog-button-xsm-font-size: 0.75rem;
534
- --gog-button-sm-font-size: 0.875rem;
535
- --gog-button-md-font-size: 1rem;
536
- --gog-button-lg-font-size: 1.125rem;
537
- --gog-button-slg-font-size: 1.25rem;
621
+ --gog-button-xsm-font-size: var(--gog-text-xs);
622
+ --gog-button-sm-font-size: var(--gog-text-sm);
623
+ --gog-button-md-font-size: var(--gog-text-md);
624
+ --gog-button-lg-font-size: var(--gog-text-lg);
625
+ --gog-button-slg-font-size: var(--gog-text-slg);
538
626
 
539
627
  --gog-button-font-family: var(--gog-font-heading);
540
- --gog-button-font-weight: 900;
628
+ --gog-button-font-weight: var(--gog-font-weight-heavy);
541
629
  --gog-button-letter-spacing: var(--gog-letter-spacing);
542
630
  --gog-button-text-transform: var(--gog-text-transform);
543
- --gog-button-line-height: 1;
631
+ --gog-button-line-height: var(--gog-line-height-none);
544
632
  --gog-button-gap: var(--gog-space-sm);
545
633
  --gog-button-radius: var(--gog-radius);
546
634
  --gog-button-border-width: var(--gog-control-border-width);
547
635
  --gog-button-border-style: var(--gog-control-border-style);
548
636
  --gog-button-transition-duration: var(--gog-duration-base);
549
637
  --gog-button-focus-ring-width: var(--gog-focus-ring-width);
550
- --gog-button-focus-ring-offset: 3px;
638
+ /* One pixel further out than the foundation ring: a filled surface needs the extra air for
639
+ the ring to read as separate from the fill. Written as the foundation plus that pixel
640
+ rather than a flat 3px, so a theme that moves the ring moves this with it. */
641
+ --gog-button-focus-ring-offset: calc(var(--gog-focus-ring-offset) + 1px);
642
+ /* Shipped since before the press had a colour, and left spelled `active` on purpose: renaming
643
+ a token consumers already override needs a deprecation cycle, and this is a patch. The state
644
+ it names is the same one `--gog-button-press-*` paints. */
551
645
  --gog-button-active-scale: 0.97;
552
646
  --gog-button-disabled-opacity: var(--gog-disabled-opacity);
553
647
  --gog-button-loading-opacity: 0.7;
@@ -580,7 +674,13 @@
580
674
  --gog-button-outline-border: var(--gog-accent-color);
581
675
  --gog-button-outline-shadow: none;
582
676
  --gog-button-outline-hover-bg: var(--gog-accent-color);
583
- --gog-button-outline-hover-color: var(--gog-primary-color);
677
+ /* The label sits on the accent fill once the button is hovered, so it takes the token that
678
+ means "text on an accent fill" — the same one the two filled variants use. It read
679
+ `--gog-primary-color` until 21.9.0, which is the colour of text on the *page*, and the
680
+ result failed WCAG AA in all 11 shipped themes: 1.11:1 in one-dark, 1.41:1 in dark, 3.65:1
681
+ in light at best. It was invisible to `check:contrast` because that script had no pair for
682
+ this label, the same way it had none for the hover fill until 2026-08-29. It has both now. */
683
+ --gog-button-outline-hover-color: var(--gog-accent-text-color, var(--gog-primary-color));
584
684
  --gog-button-outline-hover-shadow: none;
585
685
  --gog-button-outline-spinner-color: var(--gog-accent-color);
586
686
 
@@ -589,20 +689,135 @@
589
689
  --gog-button-ghost-border: transparent;
590
690
  --gog-button-ghost-shadow: none;
591
691
  --gog-button-ghost-hover-bg: var(--gog-hover-color);
592
- --gog-button-ghost-hover-color: var(--gog-button-ghost-color);
692
+ /* The label leaves the accent while the ground is tinted, and that is the only thing that
693
+ works here. Ghost's resting label *is* `--gog-accent-color`, and its hover tints the ground
694
+ with the same accent, so the two walk toward each other: measured across all 11 themes, the
695
+ label fell under 4.5:1 in `light` (3.94), `primeng` (4.18) and `one-light` (4.22). No ground
696
+ fixes it — a half-strength wash, a neutral `--gog-hover-color`, a text scrim and an
697
+ accent-dim wash were all measured, and `light` fails every one of them, because
698
+ `--gog-accent-color` as *text* on that theme's own background is 4.60:1 with no headroom to
699
+ spend. Moving the label to `--gog-text-color` clears 5.29:1 at worst (one-dark) and leaves
700
+ the ground exactly as it was, so the hover stays the subtle wash this variant is documented
701
+ to have. The press then goes the other way and fills — see `-press-bg` below. */
702
+ --gog-button-ghost-hover-color: var(--gog-text-color);
593
703
  --gog-button-ghost-hover-shadow: none;
594
704
  --gog-button-ghost-spinner-color: var(--gog-accent-color);
595
705
 
706
+ /* The held state, and the reason it is a colour rather than only the `--gog-button-active-scale`
707
+ it used to be: `prefers-reduced-motion` switches that transform off, which left a button with
708
+ no press feedback at all for the readers most likely to need it. A colour change is a state,
709
+ not a movement — reduced motion keeps it and only drops the scale, and with transitions off it
710
+ lands instantly. See docs/feedback-triage.md's closing section: reduced motion must remove the
711
+ animation, not the information.
712
+
713
+ Each variant goes one step *deeper* than its own hover, so pressing is distinguishable while
714
+ hovering, which is the normal case for a pointer. `--gog-accent-dim` is that step for the
715
+ three accent-carrying variants; ghost has no fill of its own to deepen, so it takes a
716
+ stronger wash of the same tint its hover uses (see the @supports block at the end of this
717
+ file for the mixed value and why the flat one above it is not a fallback but the value). */
718
+ /* The *toggle* state — `aria-pressed="true"`, a button that stays on — as an inset ring rather
719
+ than a fill. A fill cannot carry it: every other state already owns the background, so a
720
+ toggled button that is also hovered or held would lose the one thing saying it is on. A ring
721
+ composes with all of them, and it is the same reasoning that made `gog-button-toggle-group`'s
722
+ selected option a fill: there, nothing else was competing for the background.
723
+
724
+ The ring takes the colour that is guaranteed to read on its own variant — the label colour on
725
+ the filled two, the accent on the transparent two — so both are pairs `check:contrast`
726
+ already gates. While toggled, this replaces the variant's `box-shadow`, which costs
727
+ `primary` its hover glow: the ring is state and the glow is decoration, and a `box-shadow`
728
+ list cannot hold `none` as a layer, so keeping both was not on offer. */
729
+ --gog-button-toggled-ring-width: 2px;
730
+ --gog-button-primary-toggled-shadow: inset 0 0 0 var(--gog-button-toggled-ring-width)
731
+ var(--gog-accent-text-color, var(--gog-primary-color));
732
+ --gog-button-secondary-toggled-shadow: var(--gog-button-primary-toggled-shadow);
733
+ --gog-button-outline-toggled-shadow: inset 0 0 0 var(--gog-button-toggled-ring-width)
734
+ var(--gog-accent-color);
735
+ --gog-button-ghost-toggled-shadow: var(--gog-button-outline-toggled-shadow);
736
+
737
+ --gog-button-primary-press-bg: var(--gog-accent-dim);
738
+ --gog-button-primary-press-color: var(--gog-button-primary-color);
739
+ --gog-button-secondary-press-bg: var(--gog-accent-dim);
740
+ --gog-button-secondary-press-color: var(--gog-button-secondary-color);
741
+ --gog-button-outline-press-bg: var(--gog-accent-dim);
742
+ --gog-button-outline-press-color: var(--gog-button-outline-hover-color);
743
+ /* Ghost presses to the same deep fill as outline, rather than to a wash like every other
744
+ surface in this file. Measured across all 11 themes: a wash cannot work here, because this
745
+ button's *label* is the accent, so tinting its ground with the accent walks the two together
746
+ — a 24% wash put the label under 4.5:1 in seven themes, and `--gog-accent-pale` was either
747
+ no better or invisible against the hover. A filled press moves the label to
748
+ `--gog-accent-text-color` instead, which is the pair `check:contrast` already gates, so no
749
+ future theme can quietly break it. The other eight surfaces keep their washes: their labels
750
+ are body text, and their worst case across the 11 is 4.80:1. */
751
+ --gog-button-ghost-press-bg: var(--gog-accent-dim);
752
+ --gog-button-ghost-press-color: var(--gog-accent-text-color, var(--gog-primary-color));
753
+
754
+ /* ── Button severity ─────────────────────────────────────────────────────────
755
+ `severity` is orthogonal to `variant`: a destructive action can be a filled button, an
756
+ outlined one or a ghost, and it is still destructive. So this is not a fifth variant — it
757
+ re-points the *ingredients* the four variants are built from, and the shape rules in
758
+ `styles/button.css` apply them per variant. Four severities x six ingredients rather than
759
+ four x four variants x eleven properties, which is what a fifth-variant reading would have
760
+ cost.
761
+
762
+ `-fill` and `-on-fill` are the filled pair, and `-on-fill` is `--gog-<status>-text-color`
763
+ rather than `--gog-accent-text-color`: see that block near the top of this file for why one
764
+ label does not read on every status.
765
+
766
+ `-ink` is the label a *transparent* variant paints, and it is not the raw status colour. As
767
+ text on the page, the raw hue clears 4.5:1 in only five of the eleven themes — `primeng`'s
768
+ amber manages 2.05:1 — so it is mixed toward the theme's own ink until it does. The 50% is
769
+ measured rather than chosen: `material`'s amber is the binding case and needs the hue below
770
+ 54%, so 50 clears every theme with a little headroom. It costs saturation on the themes that
771
+ never needed it; a theme that wants the colour back overrides `--gog-button-<status>-ink`
772
+ directly, which is one token rather than a dial nobody would find. Mixing toward `--gog-text-color` rather than a
773
+ fixed black is what makes one number work on light and dark alike — the ink is dark on one
774
+ and light on the other, and both directions move *away* from the ground.
775
+
776
+ The hover and press fills move the same way, one small step and one larger, so a severity
777
+ button's states step the way an accent one's do. Moving toward the ink also moves away from
778
+ `-on-fill` in the seven themes where that is the accent's white-or-near-black, so the label
779
+ gets easier rather than harder; in the four where `-on-fill` *is* the ink, the rest state
780
+ starts at 6.44:1 or better and a 24% step cannot spend that. The flat values here are what a
781
+ browser without `color-mix()` renders — no step, the same graceful nothing the ghost button
782
+ degrades to — and the mixed ones are in the @supports block at the end of this file. */
783
+ --gog-button-success-fill: var(--gog-success-color);
784
+ --gog-button-success-on-fill: var(--gog-success-text-color);
785
+ --gog-button-success-fill-hover: var(--gog-success-color);
786
+ --gog-button-success-fill-press: var(--gog-success-color);
787
+ --gog-button-success-ink: var(--gog-success-color);
788
+ --gog-button-success-wash: transparent;
789
+
790
+ --gog-button-danger-fill: var(--gog-danger-color);
791
+ --gog-button-danger-on-fill: var(--gog-danger-text-color);
792
+ --gog-button-danger-fill-hover: var(--gog-danger-color);
793
+ --gog-button-danger-fill-press: var(--gog-danger-color);
794
+ --gog-button-danger-ink: var(--gog-danger-color);
795
+ --gog-button-danger-wash: transparent;
796
+
797
+ --gog-button-warning-fill: var(--gog-warning-color);
798
+ --gog-button-warning-on-fill: var(--gog-warning-text-color);
799
+ --gog-button-warning-fill-hover: var(--gog-warning-color);
800
+ --gog-button-warning-fill-press: var(--gog-warning-color);
801
+ --gog-button-warning-ink: var(--gog-warning-color);
802
+ --gog-button-warning-wash: transparent;
803
+
804
+ --gog-button-info-fill: var(--gog-info-color);
805
+ --gog-button-info-on-fill: var(--gog-info-text-color);
806
+ --gog-button-info-fill-hover: var(--gog-info-color);
807
+ --gog-button-info-fill-press: var(--gog-info-color);
808
+ --gog-button-info-ink: var(--gog-info-color);
809
+ --gog-button-info-wash: transparent;
810
+
596
811
  /* ── Button toggle group ───────────────────────────────────────────────────
597
812
  `--gog-button-toggle-bg`, `-color`, `-padding` and `-font-size` are intentionally NOT
598
813
  declared — they are the per-instance escape hatch the size classes fall back through.
599
814
  Padding/font-size reuse the `--gog-button-<size>-*` scale so a toggle group and a
600
815
  `<gog-button>` at the same `size` line up in a toolbar. */
601
816
  --gog-button-toggle-font-family: var(--gog-font-heading);
602
- --gog-button-toggle-font-weight: 700;
817
+ --gog-button-toggle-font-weight: var(--gog-font-weight-bold);
603
818
  --gog-button-toggle-letter-spacing: 0.5px;
604
819
  --gog-button-toggle-text-transform: var(--gog-text-transform);
605
- --gog-button-toggle-line-height: 1;
820
+ --gog-button-toggle-line-height: var(--gog-line-height-none);
606
821
  --gog-button-toggle-gap: var(--gog-space-sm);
607
822
  --gog-button-toggle-icon-size: 1.1em;
608
823
  --gog-button-toggle-radius: var(--gog-radius);
@@ -612,15 +827,19 @@
612
827
  --gog-button-toggle-rest-bg: transparent;
613
828
  --gog-button-toggle-rest-color: var(--gog-text-color);
614
829
  --gog-button-toggle-hover-bg: var(--gog-hover-color);
830
+ --gog-button-toggle-press-bg: var(--gog-border-color);
615
831
  --gog-button-toggle-hover-color: var(--gog-text-color);
616
832
  --gog-button-toggle-selected-bg: var(--gog-accent-color);
617
833
  --gog-button-toggle-selected-color: var(--gog-accent-text-color, var(--gog-primary-color));
618
834
  --gog-button-toggle-selected-border-color: var(--gog-accent-color);
835
+ /* A selected option is already filled with the accent, so its press deepens the fill the way
836
+ the filled button variants do rather than washing over it. */
837
+ --gog-button-toggle-selected-press-bg: var(--gog-accent-dim);
619
838
  --gog-button-toggle-separated-gap: var(--gog-space-sm);
620
839
  --gog-button-toggle-transition-duration: var(--gog-duration-base);
621
840
  --gog-button-toggle-disabled-opacity: var(--gog-disabled-opacity);
622
841
  --gog-button-toggle-focus-ring-width: var(--gog-focus-ring-width);
623
- --gog-button-toggle-focus-ring-offset: 2px;
842
+ --gog-button-toggle-focus-ring-offset: var(--gog-focus-ring-offset);
624
843
  --gog-button-toggle-focus-ring-color: var(--gog-accent-color);
625
844
 
626
845
  /* ── Calendar (the month grid inside gog-datepicker, and gog-calendar on its own) ── */
@@ -631,10 +850,10 @@
631
850
  --gog-calendar-max-width: max-content;
632
851
  --gog-calendar-padding: var(--gog-space-12);
633
852
  --gog-calendar-header-gap: var(--gog-space-4);
634
- --gog-calendar-header-margin: 8px;
853
+ --gog-calendar-header-margin: var(--gog-space-8);
635
854
  --gog-calendar-months-gap: var(--gog-space-16);
636
855
  --gog-calendar-title-color: var(--gog-text-color);
637
- --gog-calendar-title-font-weight: 700;
856
+ --gog-calendar-title-font-weight: var(--gog-font-weight-bold);
638
857
  --gog-calendar-nav-size: 28px;
639
858
  --gog-calendar-nav-radius: calc(var(--gog-radius) - 2px);
640
859
  --gog-calendar-nav-bg: transparent;
@@ -647,7 +866,7 @@
647
866
  --gog-calendar-weekday-padding: var(--gog-space-4) 0;
648
867
  --gog-calendar-weekday-color: var(--gog-muted-text-color);
649
868
  --gog-calendar-weekday-font-size: var(--gog-text-xs);
650
- --gog-calendar-weekday-font-weight: 600;
869
+ --gog-calendar-weekday-font-weight: var(--gog-font-weight-semibold);
651
870
  --gog-calendar-weekday-text-transform: var(--gog-text-transform);
652
871
  --gog-calendar-day-radius: calc(var(--gog-radius) - 2px);
653
872
  --gog-calendar-day-border-width: var(--gog-border-width);
@@ -657,10 +876,10 @@
657
876
  --gog-calendar-day-hover-bg: var(--gog-hover-color);
658
877
  --gog-calendar-day-outside-color: var(--gog-muted-text-color);
659
878
  --gog-calendar-today-border-color: var(--gog-accent-color);
660
- --gog-calendar-today-font-weight: 700;
879
+ --gog-calendar-today-font-weight: var(--gog-font-weight-bold);
661
880
  --gog-calendar-selected-bg: var(--gog-accent-color);
662
881
  --gog-calendar-selected-color: var(--gog-accent-text-color, var(--gog-primary-color));
663
- --gog-calendar-selected-font-weight: 700;
882
+ --gog-calendar-selected-font-weight: var(--gog-font-weight-bold);
664
883
  /* The wash between the two ends of a range: same hue, low enough to read as a band rather
665
884
  than as a second selection. */
666
885
  --gog-calendar-range-bg: var(--gog-accent-pale);
@@ -668,13 +887,16 @@
668
887
  --gog-calendar-disabled-opacity: var(--gog-disabled-opacity);
669
888
  --gog-calendar-transition-duration: var(--gog-duration-fast);
670
889
  --gog-calendar-focus-ring-width: var(--gog-focus-ring-width);
671
- --gog-calendar-focus-ring-offset: -2px;
890
+ /* Inset rather than outset: the month grid packs its cells edge to edge, so an outward ring
891
+ would sit on top of the neighbouring day. Negated from the foundation so a theme still
892
+ controls how far it sits from the cell edge. */
893
+ --gog-calendar-focus-ring-offset: calc(var(--gog-focus-ring-offset) * -1);
672
894
  --gog-calendar-focus-ring-color: var(--gog-accent-color);
673
895
  --gog-calendar-divider-width: 1px;
674
896
  --gog-calendar-divider-style: solid;
675
897
  --gog-calendar-divider-color: var(--gog-border-color);
676
898
  --gog-calendar-time-gap: var(--gog-space-6);
677
- --gog-calendar-time-margin: 10px;
899
+ --gog-calendar-time-margin: var(--gog-space-10);
678
900
  --gog-calendar-time-input-width: 3.5rem;
679
901
  --gog-calendar-time-input-padding: var(--gog-space-4) var(--gog-space-6);
680
902
  --gog-calendar-time-input-bg: var(--gog-background-color);
@@ -705,8 +927,8 @@
705
927
  --gog-card-heading-color: var(--gog-text-color);
706
928
  --gog-card-heading-font-family: var(--gog-font-heading);
707
929
  --gog-card-heading-font-size: var(--gog-text-lg);
708
- --gog-card-heading-font-weight: 600;
709
- --gog-card-heading-line-height: 1.3;
930
+ --gog-card-heading-font-weight: var(--gog-font-weight-semibold);
931
+ --gog-card-heading-line-height: var(--gog-line-height-snug);
710
932
 
711
933
  --gog-card-outlined-bg: var(--gog-surface-color);
712
934
  --gog-card-outlined-border-color: var(--gog-border-color);
@@ -762,7 +984,7 @@
762
984
  --gog-checkbox-checked-border: var(--gog-accent-color);
763
985
  --gog-checkbox-icon-color: var(--gog-accent-text-color, var(--gog-primary-color));
764
986
  --gog-checkbox-label-color: var(--gog-muted-text-color);
765
- --gog-checkbox-label-line-height: 1.3;
987
+ --gog-checkbox-label-line-height: var(--gog-line-height-snug);
766
988
  --gog-checkbox-focus-ring: var(--gog-accent-pale);
767
989
  --gog-checkbox-focus-ring-width: var(--gog-focus-ring-width);
768
990
  --gog-checkbox-focus-ring-offset: var(--gog-focus-ring-offset);
@@ -791,7 +1013,7 @@
791
1013
  --gog-radio-dot-color: var(--gog-accent-color);
792
1014
  --gog-radio-dot-size-ratio: 0.45;
793
1015
  --gog-radio-label-color: var(--gog-muted-text-color);
794
- --gog-radio-label-line-height: 1.3;
1016
+ --gog-radio-label-line-height: var(--gog-line-height-snug);
795
1017
  --gog-radio-focus-ring: var(--gog-accent-pale);
796
1018
  --gog-radio-focus-ring-width: var(--gog-focus-ring-width);
797
1019
  --gog-radio-focus-ring-offset: var(--gog-focus-ring-offset);
@@ -807,12 +1029,13 @@
807
1029
  --gog-chip-font-family: inherit;
808
1030
  --gog-chip-bg: var(--gog-surface-color);
809
1031
  --gog-chip-hover-bg: var(--gog-hover-color);
1032
+ --gog-chip-press-bg: var(--gog-border-color);
810
1033
  --gog-chip-border: var(--gog-border-color);
811
1034
  --gog-chip-border-width: var(--gog-border-width);
812
1035
  --gog-chip-border-style: var(--gog-border-style);
813
1036
  --gog-chip-color: var(--gog-text-color);
814
- --gog-chip-font-weight: 500;
815
- --gog-chip-line-height: 1.2;
1037
+ --gog-chip-font-weight: var(--gog-font-weight-medium);
1038
+ --gog-chip-line-height: var(--gog-line-height-tight);
816
1039
  --gog-chip-radius: max(var(--gog-radius), 2px);
817
1040
  --gog-chip-pill-radius: 9999px;
818
1041
  --gog-chip-remove-color: var(--gog-muted-text-color);
@@ -820,7 +1043,16 @@
820
1043
  --gog-chip-remove-scale: 1.1;
821
1044
  --gog-chip-avatar-inset-ratio: 0.9;
822
1045
  --gog-chip-remove-inset-ratio: 0.85;
823
- --gog-chip-disabled-opacity: 0.55;
1046
+ --gog-chip-disabled-opacity: var(--gog-disabled-opacity);
1047
+ /* A selected filter chip (`[(selected)]`, 21.9.0). An inset ring for the reason
1048
+ `--gog-button-primary-toggled-shadow` gives: hover and press own the background, and a
1049
+ selected chip has to stay selected while it is also hovered or held. The accent, so it is
1050
+ the same pair the focus ring is already gated on — and unlike the button there is only one
1051
+ chip variant, so one token covers it. Override this token on the host to restyle a single
1052
+ chip. */
1053
+ --gog-chip-selected-ring-width: 2px;
1054
+ --gog-chip-selected-shadow: inset 0 0 0 var(--gog-chip-selected-ring-width)
1055
+ var(--gog-accent-color);
824
1056
  --gog-chip-focus-ring-width: 2px;
825
1057
  --gog-chip-focus-ring-offset: var(--gog-focus-ring-offset);
826
1058
 
@@ -832,7 +1064,7 @@
832
1064
  --gog-chip-xsm-icon-size: 0.6875rem;
833
1065
  --gog-chip-xsm-remove-size: 0.75rem;
834
1066
 
835
- --gog-chip-sm-font-size: 0.75rem;
1067
+ --gog-chip-sm-font-size: var(--gog-text-xs);
836
1068
  --gog-chip-sm-padding-block: var(--gog-space-4);
837
1069
  --gog-chip-sm-padding-inline: var(--gog-space-8);
838
1070
  --gog-chip-sm-gap: var(--gog-space-6);
@@ -840,7 +1072,7 @@
840
1072
  --gog-chip-sm-icon-size: 0.75rem;
841
1073
  --gog-chip-sm-remove-size: 0.875rem;
842
1074
 
843
- --gog-chip-md-font-size: 0.875rem;
1075
+ --gog-chip-md-font-size: var(--gog-text-sm);
844
1076
  --gog-chip-md-padding-block: var(--gog-space-8);
845
1077
  --gog-chip-md-padding-inline: var(--gog-space-12);
846
1078
  --gog-chip-md-gap: var(--gog-space-8);
@@ -848,7 +1080,7 @@
848
1080
  --gog-chip-md-icon-size: 0.875rem;
849
1081
  --gog-chip-md-remove-size: 1rem;
850
1082
 
851
- --gog-chip-lg-font-size: 1rem;
1083
+ --gog-chip-lg-font-size: var(--gog-text-md);
852
1084
  --gog-chip-lg-padding-block: var(--gog-space-10);
853
1085
  --gog-chip-lg-padding-inline: var(--gog-space-14);
854
1086
  --gog-chip-lg-gap: var(--gog-space-10);
@@ -856,7 +1088,7 @@
856
1088
  --gog-chip-lg-icon-size: 1rem;
857
1089
  --gog-chip-lg-remove-size: 1.125rem;
858
1090
 
859
- --gog-chip-slg-font-size: 1.125rem;
1091
+ --gog-chip-slg-font-size: var(--gog-text-lg);
860
1092
  --gog-chip-slg-padding-block: var(--gog-space-12);
861
1093
  --gog-chip-slg-padding-inline: var(--gog-space-16);
862
1094
  --gog-chip-slg-gap: var(--gog-space-12);
@@ -889,7 +1121,7 @@
889
1121
  --gog-dialog-body-padding: var(--gog-space-20);
890
1122
  --gog-dialog-body-max-height: calc(var(--gog-dialog-max-height) - 60px);
891
1123
  --gog-dialog-close-size: 2rem;
892
- --gog-dialog-close-font-size: 0.875rem;
1124
+ --gog-dialog-close-font-size: var(--gog-text-sm);
893
1125
  --gog-dialog-close-color: var(--gog-muted-text-color);
894
1126
  --gog-dialog-close-hover-color: var(--gog-text-color);
895
1127
  --gog-dialog-close-hover-bg: var(--gog-hover-color);
@@ -918,7 +1150,7 @@
918
1150
  --gog-autocomplete-gap: var(--gog-space-4);
919
1151
  --gog-autocomplete-label-color: var(--gog-accent-color);
920
1152
  --gog-autocomplete-label-font-size: var(--gog-text-sm);
921
- --gog-autocomplete-label-font-weight: 600;
1153
+ --gog-autocomplete-label-font-weight: var(--gog-font-weight-semibold);
922
1154
  --gog-autocomplete-label-letter-spacing: var(--gog-letter-spacing);
923
1155
  --gog-autocomplete-label-text-transform: var(--gog-text-transform);
924
1156
  --gog-autocomplete-field-bg: var(--gog-surface-color);
@@ -929,7 +1161,7 @@
929
1161
  --gog-autocomplete-border-color: var(--gog-accent-dim);
930
1162
  --gog-autocomplete-hover-border-color: var(--gog-accent-color);
931
1163
  --gog-autocomplete-radius: var(--gog-radius);
932
- --gog-autocomplete-line-height: 1.4;
1164
+ --gog-autocomplete-line-height: var(--gog-line-height-normal);
933
1165
  --gog-autocomplete-transition-duration: var(--gog-duration-base);
934
1166
  --gog-autocomplete-disabled-opacity: var(--gog-disabled-opacity);
935
1167
  --gog-autocomplete-focus-ring-width: var(--gog-focus-ring-width);
@@ -949,7 +1181,7 @@
949
1181
  --gog-autocomplete-actions-reserve: 40px;
950
1182
  --gog-autocomplete-clear-color: var(--gog-autocomplete-placeholder-color);
951
1183
  --gog-autocomplete-clear-hover-color: var(--gog-autocomplete-label-color);
952
- --gog-autocomplete-clear-icon-ratio: 0.7;
1184
+ --gog-autocomplete-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
953
1185
  --gog-autocomplete-spinner-size: 0.875rem;
954
1186
  /* Panel */
955
1187
  --gog-autocomplete-panel-bg: var(--gog-surface-color);
@@ -968,9 +1200,15 @@
968
1200
  --gog-autocomplete-option-gap: var(--gog-space-10);
969
1201
  --gog-autocomplete-option-color: var(--gog-text-color);
970
1202
  --gog-autocomplete-option-hover-bg: var(--gog-hover-color);
1203
+ --gog-autocomplete-option-press-bg: var(--gog-border-color);
971
1204
  --gog-autocomplete-option-hover-color: var(--gog-text-color);
972
1205
  --gog-autocomplete-option-selected-bg: var(--gog-accent-pale);
973
- --gog-autocomplete-option-selected-color: var(--gog-accent-color);
1206
+ /* Body text, not the accent. The selected row is the one option that carries a tint *and* a
1207
+ coloured label, and the accent on that tint measured 4.12:1 in light — `--gog-accent-dim` is
1208
+ worse again (3.77:1 in one-dark). `gog-select` gets away with an accent label because its
1209
+ selected option has no tint behind it. The tint stays as the marker, alongside
1210
+ `aria-selected`. */
1211
+ --gog-autocomplete-option-selected-color: var(--gog-text-color);
974
1212
  /* Estimated row height fed into the panel's up/down placement math; not itself a real
975
1213
  layout property, so it has no effect unless the JS reads it. */
976
1214
  --gog-autocomplete-option-height: 36px;
@@ -984,8 +1222,8 @@
984
1222
  /* ── Badge (the `gogBadge` directive; its classes live in utilities.css) ───── */
985
1223
  --gog-badge-font-family: var(--gog-font-body);
986
1224
  --gog-badge-font-size: var(--gog-text-xs);
987
- --gog-badge-font-weight: 600;
988
- --gog-badge-line-height: 1;
1225
+ --gog-badge-font-weight: var(--gog-font-weight-semibold);
1226
+ --gog-badge-line-height: var(--gog-line-height-none);
989
1227
  /* Min-width *and* height: a one-digit badge stays a circle, a three-digit one grows
990
1228
  sideways only. */
991
1229
  --gog-badge-size: 1.25rem;
@@ -993,22 +1231,24 @@
993
1231
  --gog-badge-padding-inline: var(--gog-space-4);
994
1232
  --gog-badge-radius: 999px;
995
1233
  /* How far the badge hangs outside its host's corner. */
996
- --gog-badge-offset: 6px;
1234
+ --gog-badge-offset: var(--gog-space-6);
997
1235
  --gog-badge-border-width: 0;
998
1236
  --gog-badge-border-style: var(--gog-border-style);
999
1237
  --gog-badge-border-color: transparent;
1000
1238
  /* Above the host's own chrome but below any overlay panel (--gog-dropdown-z is 300). */
1001
- --gog-badge-z: 1;
1002
- /* `--gog-accent-text-color` is the palette's "text on a filled surface" colour and flips
1003
- with the theme, which is why a red badge reads white on light and near-black on dark. */
1239
+ /* Each label is its status's own "text on this fill" token, which flips with the theme — a red
1240
+ badge reads white on light and near-black on dark. It read `--gog-accent-text-color` for all
1241
+ four until 21.9.0, on the assumption that one label works on every fill; four themes proved
1242
+ otherwise, `material`'s amber under white at 1.97:1 the worst of them. See the
1243
+ `--gog-<status>-text-color` block near the top of this file. */
1004
1244
  --gog-badge-success-bg: var(--gog-success-color);
1005
- --gog-badge-success-color: var(--gog-accent-text-color, var(--gog-primary-color));
1245
+ --gog-badge-success-color: var(--gog-success-text-color);
1006
1246
  --gog-badge-danger-bg: var(--gog-danger-color);
1007
- --gog-badge-danger-color: var(--gog-accent-text-color, var(--gog-primary-color));
1247
+ --gog-badge-danger-color: var(--gog-danger-text-color);
1008
1248
  --gog-badge-warning-bg: var(--gog-warning-color);
1009
- --gog-badge-warning-color: var(--gog-accent-text-color, var(--gog-primary-color));
1249
+ --gog-badge-warning-color: var(--gog-warning-text-color);
1010
1250
  --gog-badge-info-bg: var(--gog-info-color);
1011
- --gog-badge-info-color: var(--gog-accent-text-color, var(--gog-primary-color));
1251
+ --gog-badge-info-color: var(--gog-info-text-color);
1012
1252
 
1013
1253
  /* ── Datepicker (the field; the grid inside it is themed by --gog-calendar-*) ───
1014
1254
  `--gog-datepicker-bg`, `-color`, `-font-size`, `-padding-x` and `-padding-y` are
@@ -1029,7 +1269,7 @@
1029
1269
  --gog-datepicker-border-color: var(--gog-accent-dim);
1030
1270
  --gog-datepicker-hover-border-color: var(--gog-accent-color);
1031
1271
  --gog-datepicker-radius: var(--gog-radius);
1032
- --gog-datepicker-line-height: 1.4;
1272
+ --gog-datepicker-line-height: var(--gog-line-height-normal);
1033
1273
  --gog-datepicker-transition-duration: var(--gog-duration-base);
1034
1274
  --gog-datepicker-disabled-opacity: var(--gog-disabled-opacity);
1035
1275
  --gog-datepicker-focus-ring-width: var(--gog-focus-ring-width);
@@ -1048,7 +1288,7 @@
1048
1288
  --gog-datepicker-icon-hover-color: var(--gog-accent-bright);
1049
1289
  --gog-datepicker-toggle-icon-size: 1rem;
1050
1290
  --gog-datepicker-clear-color: var(--gog-datepicker-placeholder-color);
1051
- --gog-datepicker-clear-icon-ratio: 0.7;
1291
+ --gog-datepicker-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1052
1292
  --gog-datepicker-panel-bg: var(--gog-surface-color);
1053
1293
  --gog-datepicker-panel-shadow: var(--gog-panel-shadow);
1054
1294
  --gog-datepicker-panel-border-width: var(--gog-panel-border-width);
@@ -1082,8 +1322,8 @@
1082
1322
  --gog-divider-label-color: var(--gog-muted-text-color);
1083
1323
  --gog-divider-label-font-family: var(--gog-font-body);
1084
1324
  --gog-divider-label-font-size: var(--gog-text-sm);
1085
- --gog-divider-label-font-weight: 500;
1086
- --gog-divider-label-line-height: 1.4;
1325
+ --gog-divider-label-font-weight: var(--gog-font-weight-medium);
1326
+ --gog-divider-label-line-height: var(--gog-line-height-normal);
1087
1327
 
1088
1328
  /* ── Icon ──────────────────────────────────────────────────────────────────── */
1089
1329
  --gog-icon-fallback-size: 1em;
@@ -1110,7 +1350,13 @@
1110
1350
  --gog-input-focus-ring-offset: var(--gog-focus-ring-offset);
1111
1351
  --gog-input-error-color: var(--gog-danger-color);
1112
1352
  --gog-input-error-font-size: var(--gog-text-xs);
1113
- --gog-input-error-offset: 2px;
1353
+ /* Extra space above the error line, *on top of* the host's own `--gog-input-gap`, which
1354
+ already separates every child of the field. It shipped as `2px` and put this field's error
1355
+ 6px under it while `gog-select`, `gog-autocomplete` and `gog-datepicker` — same gap, no
1356
+ offset — sat at 4px; in one form the six did not line up. Zero by default since 21.9.0, so
1357
+ one mechanism spaces the error line everywhere. Set it if you want this field's error
1358
+ pushed further than the rest. */
1359
+ --gog-input-error-offset: 0px;
1114
1360
  --gog-input-icon-color: var(--gog-muted-text-color);
1115
1361
  --gog-input-icon-hover-color: var(--gog-accent-color);
1116
1362
  --gog-input-icon-action-radius: calc(var(--gog-radius) - 4px);
@@ -1121,9 +1367,20 @@
1121
1367
  --gog-input-disabled-opacity: var(--gog-disabled-opacity);
1122
1368
  --gog-input-transition-duration: var(--gog-duration-base);
1123
1369
  /* Float label — also used by gog-textarea, which shares the --gog-input-* block. */
1124
- /* Clear button — only rendered once the field has text, see `clearable`. */
1125
- --gog-input-clear-radius: 2px;
1126
- --gog-input-clear-icon-ratio: 0.7;
1370
+ /* Clear button — only rendered once the field has text, see `clearable`.
1371
+
1372
+ A quarter of the corner radius rather than a flat `2px`, which is what this was until
1373
+ 21.9.0: at the default `--gog-radius: 8px` it computes to the same 2px, so nothing moves in
1374
+ any shipped theme, but a theme that rounds its corners now rounds this button too. The
1375
+ literal was invisible to `check-tokens` rule G by design — that rule flags a literal only
1376
+ when its value *equals* a character token's current one, so a pill's `999px` is correctly
1377
+ left alone and a small arbitrary number like this one is correctly not detectable. The two
1378
+ sibling controls below carry the same fix.
1379
+
1380
+ `gog-toast` and `gog-accordion` keep their flat `0px` on purpose: those are a chosen shape,
1381
+ not a number that forgot where it came from. */
1382
+ --gog-input-clear-radius: calc(var(--gog-radius) / 4);
1383
+ --gog-input-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1127
1384
  /*
1128
1385
  The textarea's clear button gets a full-size glyph. The 0.7 ratio above suits the dense
1129
1386
  single-line trigger of a dropdown; on a large multi-line box it reads as a speck.
@@ -1148,7 +1405,7 @@
1148
1405
  */
1149
1406
  --gog-textarea-resize-inset-right: 0px;
1150
1407
  --gog-textarea-resize-inset-bottom: 0px;
1151
- --gog-input-clear-inset: 8px;
1408
+ --gog-input-clear-inset: var(--gog-space-8);
1152
1409
  /*
1153
1410
  Width of one stepper button, and so of the whole stepper column. Scales with the field's
1154
1411
  own font size rather than being a fixed px value, so it stays proportional across the five
@@ -1189,21 +1446,23 @@
1189
1446
  --gog-multiselect-focus-ring-offset: var(--gog-focus-ring-offset);
1190
1447
  --gog-multiselect-error-color: var(--gog-danger-color);
1191
1448
  --gog-multiselect-error-font-size: var(--gog-text-xs);
1192
- --gog-multiselect-error-offset: 2px;
1449
+ /* Zero by default since 21.9.0 — see `--gog-input-error-offset` for why. */
1450
+ --gog-multiselect-error-offset: 0px;
1193
1451
  --gog-multiselect-border-color: var(--gog-accent-color);
1194
1452
  --gog-multiselect-panel-bg: var(--gog-surface-color);
1195
1453
  --gog-multiselect-panel-border: var(--gog-accent-color);
1196
1454
  --gog-multiselect-panel-shadow: var(--gog-panel-shadow);
1197
1455
  --gog-multiselect-panel-max-height: 260px;
1198
- --gog-multiselect-panel-offset: 2px;
1456
+ --gog-multiselect-panel-offset: var(--gog-space-2);
1199
1457
  --gog-multiselect-option-hover-bg: var(--gog-hover-color);
1458
+ --gog-multiselect-option-press-bg: var(--gog-border-color);
1200
1459
  --gog-multiselect-option-color: var(--gog-text-color);
1201
1460
  --gog-multiselect-option-gap-inline: var(--gog-space-10);
1202
1461
  /* Estimated row height fed into the panel's up/down placement math; not itself a real
1203
1462
  layout property, so it has no effect unless the JS reads it. */
1204
1463
  --gog-multiselect-option-height: 40px;
1205
1464
  --gog-multiselect-option-radius: calc(var(--gog-radius) - 2px);
1206
- --gog-multiselect-option-disabled-opacity: 0.5;
1465
+ --gog-multiselect-option-disabled-opacity: var(--gog-disabled-opacity);
1207
1466
  --gog-multiselect-option-transition-duration: var(--gog-duration-fast);
1208
1467
  --gog-multiselect-checkbox-border: var(--gog-accent-dim);
1209
1468
  --gog-multiselect-checkbox-bg: var(--gog-background-color);
@@ -1232,7 +1491,8 @@
1232
1491
  --gog-multiselect-min-width: 120px;
1233
1492
  --gog-multiselect-panel-max-width: 420px;
1234
1493
  --gog-multiselect-actions-inset: var(--gog-control-icon-offset);
1235
- --gog-multiselect-clear-radius: 2px;
1494
+ /* A quarter of the corner radius — see `--gog-input-clear-radius` for why. */
1495
+ --gog-multiselect-clear-radius: calc(var(--gog-radius) / 4);
1236
1496
  --gog-multiselect-disabled-opacity: var(--gog-disabled-opacity);
1237
1497
  --gog-multiselect-transition-duration: var(--gog-duration-base);
1238
1498
  --gog-multiselect-float-label-reserve: var(--gog-field-float-label-reserve);
@@ -1241,7 +1501,7 @@
1241
1501
  --gog-multiselect-float-label-over-reserve: var(--gog-field-float-label-over-reserve);
1242
1502
  --gog-multiselect-arrow-transition-duration: var(--gog-duration-slow);
1243
1503
  /* Icon geometry, expressed as a ratio of the control's font size. */
1244
- --gog-multiselect-clear-icon-ratio: 0.7;
1504
+ --gog-multiselect-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1245
1505
  --gog-multiselect-arrow-icon-ratio: 0.875;
1246
1506
  --gog-multiselect-mark-size-ratio: 1.2375;
1247
1507
  --gog-multiselect-mark-icon-ratio: 1.125;
@@ -1259,7 +1519,7 @@
1259
1519
  --gog-menu-font-family: var(--gog-font-body);
1260
1520
  --gog-menu-padding: var(--gog-space-4);
1261
1521
  --gog-menu-gap: var(--gog-space-2);
1262
- --gog-menu-offset: 4px;
1522
+ --gog-menu-offset: var(--gog-space-4);
1263
1523
  --gog-menu-min-width: 180px;
1264
1524
  --gog-menu-max-width: 320px;
1265
1525
  --gog-menu-max-height: 320px;
@@ -1268,6 +1528,11 @@
1268
1528
  --gog-menu-focus-ring-width: var(--gog-focus-ring-width);
1269
1529
  --gog-menu-item-color: var(--gog-text-color);
1270
1530
  --gog-menu-item-hover-bg: var(--gog-hover-color);
1531
+ /* The held state, same idea as the button's: one step past this surface's own hover, as a
1532
+ colour rather than a movement, so `prefers-reduced-motion` cannot take it away. The flat
1533
+ value here is what a browser without `color-mix()` gets; the tinted one is in the @supports
1534
+ block at the end of the file. */
1535
+ --gog-menu-item-press-bg: var(--gog-border-color);
1271
1536
  --gog-menu-item-hover-color: var(--gog-text-color);
1272
1537
  --gog-menu-item-font-size: var(--gog-text-sm);
1273
1538
  --gog-menu-item-padding: var(--gog-space-8) var(--gog-space-12);
@@ -1275,7 +1540,7 @@
1275
1540
  --gog-menu-item-gap: var(--gog-space-sm);
1276
1541
  --gog-menu-item-disabled-opacity: var(--gog-disabled-opacity);
1277
1542
  --gog-menu-item-disabled-color: var(--gog-muted-text-color);
1278
- --gog-menu-item-line-height: 1.4;
1543
+ --gog-menu-item-line-height: var(--gog-line-height-normal);
1279
1544
  --gog-menu-item-icon-size: 1em;
1280
1545
 
1281
1546
  /* ── Paginator ─────────────────────────────────────────────────────────────── */
@@ -1305,7 +1570,7 @@
1305
1570
  --gog-panel-heading-color: var(--gog-text-color);
1306
1571
  --gog-panel-heading-font-family: var(--gog-font-heading);
1307
1572
  --gog-panel-heading-font-size: var(--gog-text-xl);
1308
- --gog-panel-heading-font-weight: 600;
1573
+ --gog-panel-heading-font-weight: var(--gog-font-weight-semibold);
1309
1574
  --gog-panel-heading-line-height: 1.25;
1310
1575
 
1311
1576
  --gog-panel-outlined-bg: var(--gog-surface-color);
@@ -1469,8 +1734,9 @@
1469
1734
  --gog-select-filter-empty-padding: var(--gog-space-10);
1470
1735
  --gog-select-filter-empty-color: var(--gog-select-placeholder-color);
1471
1736
  /* Clear button — only rendered once a value is selected, see `clearable`. */
1472
- --gog-select-clear-radius: 2px;
1473
- --gog-select-clear-icon-ratio: 0.7;
1737
+ /* A quarter of the corner radius — see `--gog-input-clear-radius` for why. */
1738
+ --gog-select-clear-radius: calc(var(--gog-radius) / 4);
1739
+ --gog-select-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1474
1740
  --gog-select-clear-gap: var(--gog-space-6);
1475
1741
  --gog-select-clear-color: var(--gog-select-placeholder-color);
1476
1742
  --gog-select-clear-hover-color: var(--gog-select-label-color);
@@ -1478,15 +1744,16 @@
1478
1744
  --gog-select-panel-bg: var(--gog-surface-color);
1479
1745
  --gog-select-panel-shadow: var(--gog-panel-shadow);
1480
1746
  --gog-select-panel-max-height: 260px;
1481
- --gog-select-panel-offset: 2px;
1747
+ --gog-select-panel-offset: var(--gog-space-2);
1482
1748
  --gog-select-option-hover-bg: var(--gog-hover-color);
1749
+ --gog-select-option-press-bg: var(--gog-border-color);
1483
1750
  --gog-select-option-selected-color: var(--gog-accent-color);
1484
1751
  --gog-select-option-color: var(--gog-text-color);
1485
1752
  --gog-select-option-gap: var(--gog-space-10);
1486
1753
  /* Estimated row height fed into the panel's up/down placement math; not itself a real
1487
1754
  layout property, so it has no effect unless the JS reads it. */
1488
1755
  --gog-select-option-height: 40px;
1489
- --gog-select-option-disabled-opacity: 0.5;
1756
+ --gog-select-option-disabled-opacity: var(--gog-disabled-opacity);
1490
1757
  --gog-select-option-transition-duration: var(--gog-duration-fast);
1491
1758
  /* Icon geometry, expressed as a ratio of the control's font size. */
1492
1759
  --gog-select-chevron-icon-ratio: 0.875;
@@ -1679,16 +1946,24 @@
1679
1946
  `--gog-tabs-indicator-offset` / `-length` are written as inline styles from the measured
1680
1947
  header geometry, so they are not declared either. */
1681
1948
  --gog-tabs-font-family: var(--gog-font-heading);
1682
- --gog-tabs-font-weight: 700;
1949
+ --gog-tabs-font-weight: var(--gog-font-weight-bold);
1683
1950
  --gog-tabs-letter-spacing: 0.4px;
1684
1951
  --gog-tabs-text-transform: none;
1685
- --gog-tabs-line-height: 1.2;
1952
+ --gog-tabs-line-height: var(--gog-line-height-tight);
1686
1953
  --gog-tabs-gap: 0px;
1687
1954
  --gog-tabs-tab-gap: var(--gog-space-sm);
1688
1955
  --gog-tabs-icon-size: 1.1em;
1689
1956
  --gog-tabs-rest-bg: transparent;
1690
1957
  --gog-tabs-rest-color: var(--gog-muted-text-color);
1691
1958
  --gog-tabs-hover-color: var(--gog-text-color);
1959
+ /* Tabs paint no background at rest and none on hover — the press is the only one they get,
1960
+ which is why this token has no hover counterpart to step past. */
1961
+ --gog-tabs-press-bg: var(--gog-border-color);
1962
+ /* A resting tab's label is deliberately muted, and muted text has no contrast headroom to
1963
+ spend on a tinted ground: on the press wash it fell to 3.24:1 in one-dark and under 4.5 in
1964
+ six other themes. The press takes the full text colour instead — which is also what pressing
1965
+ a tab is about to make it. */
1966
+ --gog-tabs-press-color: var(--gog-text-color);
1692
1967
  --gog-tabs-active-color: var(--gog-accent-color);
1693
1968
  --gog-tabs-header-border-width: var(--gog-border-width);
1694
1969
  --gog-tabs-header-border-style: var(--gog-border-style);
@@ -1699,7 +1974,8 @@
1699
1974
  --gog-tabs-transition-duration: var(--gog-duration-base);
1700
1975
  --gog-tabs-disabled-opacity: var(--gog-disabled-opacity);
1701
1976
  --gog-tabs-focus-ring-width: var(--gog-focus-ring-width);
1702
- --gog-tabs-focus-ring-offset: -2px;
1977
+ /* Inset, for the same reason as the calendar cell: tabs sit shoulder to shoulder. */
1978
+ --gog-tabs-focus-ring-offset: calc(var(--gog-focus-ring-offset) * -1);
1703
1979
  --gog-tabs-focus-ring-color: var(--gog-accent-color);
1704
1980
  --gog-tabs-panel-padding: var(--gog-space-md);
1705
1981
  --gog-tabs-panel-color: var(--gog-text-color);
@@ -1730,8 +2006,8 @@
1730
2006
  --gog-tag-border-width: var(--gog-border-width);
1731
2007
  --gog-tag-border-style: var(--gog-border-style);
1732
2008
  --gog-tag-inner-border-width: var(--gog-border-width);
1733
- --gog-tag-font-weight: 600;
1734
- --gog-tag-line-height: 1;
2009
+ --gog-tag-font-weight: var(--gog-font-weight-semibold);
2010
+ --gog-tag-line-height: var(--gog-line-height-none);
1735
2011
  --gog-tag-radius: max(var(--gog-radius), 2px);
1736
2012
  --gog-tag-pill-radius: 9999px;
1737
2013
 
@@ -1741,25 +2017,25 @@
1741
2017
  --gog-tag-xsm-gap: var(--gog-space-2);
1742
2018
  --gog-tag-xsm-icon-size: 0.6875rem;
1743
2019
 
1744
- --gog-tag-sm-font-size: 0.75rem;
2020
+ --gog-tag-sm-font-size: var(--gog-text-xs);
1745
2021
  --gog-tag-sm-padding-block: var(--gog-space-4);
1746
2022
  --gog-tag-sm-padding-inline: var(--gog-space-8);
1747
2023
  --gog-tag-sm-gap: var(--gog-space-4);
1748
2024
  --gog-tag-sm-icon-size: 0.75rem;
1749
2025
 
1750
- --gog-tag-md-font-size: 0.875rem;
2026
+ --gog-tag-md-font-size: var(--gog-text-sm);
1751
2027
  --gog-tag-md-padding-block: var(--gog-space-6);
1752
2028
  --gog-tag-md-padding-inline: var(--gog-space-12);
1753
2029
  --gog-tag-md-gap: var(--gog-space-6);
1754
2030
  --gog-tag-md-icon-size: 0.875rem;
1755
2031
 
1756
- --gog-tag-lg-font-size: 1rem;
2032
+ --gog-tag-lg-font-size: var(--gog-text-md);
1757
2033
  --gog-tag-lg-padding-block: var(--gog-space-8);
1758
2034
  --gog-tag-lg-padding-inline: var(--gog-space-14);
1759
2035
  --gog-tag-lg-gap: var(--gog-space-8);
1760
2036
  --gog-tag-lg-icon-size: 1rem;
1761
2037
 
1762
- --gog-tag-slg-font-size: 1.125rem;
2038
+ --gog-tag-slg-font-size: var(--gog-text-lg);
1763
2039
  --gog-tag-slg-padding-block: var(--gog-space-10);
1764
2040
  --gog-tag-slg-padding-inline: var(--gog-space-16);
1765
2041
  --gog-tag-slg-gap: var(--gog-space-10);
@@ -1782,17 +2058,16 @@
1782
2058
  --gog-toast-main-gap: var(--gog-space-sm);
1783
2059
  --gog-toast-actions-gap: var(--gog-space-6);
1784
2060
  --gog-toast-message-font-size: var(--gog-text-sm);
1785
- --gog-toast-message-line-height: 1.5;
2061
+ --gog-toast-message-line-height: var(--gog-line-height-relaxed);
1786
2062
  --gog-toast-icon-size: 1rem;
1787
- --gog-toast-icon-line-height: 1.4;
2063
+ --gog-toast-icon-line-height: var(--gog-line-height-normal);
1788
2064
  --gog-toast-action-padding: var(--gog-space-4) var(--gog-space-8);
1789
- --gog-toast-action-font-size: 0.75rem;
2065
+ --gog-toast-action-font-size: var(--gog-text-xs);
1790
2066
  --gog-toast-close-padding: var(--gog-space-2) var(--gog-space-4);
1791
- --gog-toast-close-font-size: 0.75rem;
2067
+ --gog-toast-close-font-size: var(--gog-text-xs);
1792
2068
  --gog-toast-progress-height: 3px;
1793
2069
  --gog-toast-progress-opacity: 30%;
1794
2070
  --gog-toast-transition-duration: 0.25s;
1795
- --gog-toast-base-z: 100;
1796
2071
  /* Card-stack geometry */
1797
2072
  --gog-toast-stack-peek: 14px;
1798
2073
  --gog-toast-stack-scale-step: 0.06;
@@ -1822,16 +2097,16 @@
1822
2097
  --gog-toggle-transition-duration: var(--gog-duration-base);
1823
2098
  --gog-toggle-disabled-opacity: var(--gog-disabled-opacity);
1824
2099
  --gog-toggle-label-color: var(--gog-text-color);
1825
- --gog-toggle-label-line-height: 1.4;
2100
+ --gog-toggle-label-line-height: var(--gog-line-height-normal);
1826
2101
  --gog-toggle-focus-ring-width: var(--gog-focus-ring-width);
1827
2102
  --gog-toggle-focus-ring-offset: var(--gog-focus-ring-offset);
1828
2103
  --gog-toggle-focus-ring-color: var(--gog-accent-color);
1829
2104
  /* In-track on/off wording */
1830
2105
  --gog-toggle-state-color: var(--gog-accent-text-color, var(--gog-primary-color));
1831
- --gog-toggle-state-font-weight: 600;
2106
+ --gog-toggle-state-font-weight: var(--gog-font-weight-semibold);
1832
2107
  --gog-toggle-state-letter-spacing: 0.04em;
1833
2108
  --gog-toggle-state-padding-inline: var(--gog-space-4);
1834
- --gog-toggle-state-offset: 6px;
2109
+ --gog-toggle-state-offset: var(--gog-space-6);
1835
2110
  /* Gap between the wording and the thumb parked at the opposite end. The clearance itself
1836
2111
  (thumb size + this) is computed in the component stylesheet, not here: a `var(` to a
1837
2112
  size-class token is substituted where it is *declared*, so doing that calc on :root would
@@ -1856,7 +2131,7 @@
1856
2131
  --gog-toggle-lg-track-height: 32px;
1857
2132
  --gog-toggle-lg-thumb-size: 26px;
1858
2133
  --gog-toggle-lg-label-size: var(--gog-control-checkbox-label-size-lg);
1859
- --gog-toggle-lg-state-font-size: 0.75rem;
2134
+ --gog-toggle-lg-state-font-size: var(--gog-text-xs);
1860
2135
  --gog-toggle-slg-track-width: 68px;
1861
2136
  --gog-toggle-slg-track-height: 40px;
1862
2137
  --gog-toggle-slg-thumb-size: 34px;
@@ -1866,7 +2141,7 @@
1866
2141
  /* ── Tooltip ──────────────────────────────────────────────────────────────── */
1867
2142
  --gog-tooltip-font-family: var(--gog-font-body);
1868
2143
  --gog-tooltip-font-size: var(--gog-text-xs);
1869
- --gog-tooltip-line-height: 1.4;
2144
+ --gog-tooltip-line-height: var(--gog-line-height-normal);
1870
2145
  --gog-tooltip-padding: var(--gog-space-6) var(--gog-space-10);
1871
2146
  --gog-tooltip-radius: var(--gog-radius);
1872
2147
  --gog-tooltip-max-width: 280px;
@@ -1889,7 +2164,6 @@
1889
2164
  /* Space kept between the trigger and the bubble. Read by the directive itself (not just
1890
2165
  CSS) to feed the placement math — see `readPxToken` in `tooltip.directive.ts`. */
1891
2166
  --gog-tooltip-gap: var(--gog-space-8);
1892
- --gog-tooltip-z: 400;
1893
2167
  --gog-tooltip-transition-duration: var(--gog-duration-fast);
1894
2168
  }
1895
2169
 
@@ -1937,6 +2211,85 @@
1937
2211
  --gog-button-primary-hover-shadow: 0 0 16px
1938
2212
  color-mix(in srgb, var(--gog-accent-bright) 45%, transparent);
1939
2213
  --gog-button-ghost-hover-bg: color-mix(in srgb, var(--gog-accent-color) 12%, transparent);
2214
+ /* Every other pressable surface, one rule: 20% of the same ingredient its own hover mixes at
2215
+ 10-12%, so the press is a clear step past the hover without becoming a fill. 20 rather than
2216
+ a rounder 25 is measured, not chosen: `check:contrast` resolves these washes over the
2217
+ surface each one actually sits on, and 21% puts one-dark's mid-grey text under 4.5:1 on the
2218
+ tab, accordion and button-toggle presses. The accordion mixes `--gog-accent-dim` because
2219
+ its hover does — its header sits on a strip where a full-accent wash was too loud
2220
+ (21.7.1). */
2221
+ --gog-accordion-press-bg: color-mix(in srgb, var(--gog-accent-dim) 20%, transparent);
2222
+ --gog-autocomplete-option-press-bg: color-mix(
2223
+ in srgb,
2224
+ var(--gog-accent-color) 20%,
2225
+ transparent
2226
+ );
2227
+ --gog-button-toggle-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2228
+ --gog-chip-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2229
+ --gog-menu-item-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2230
+ --gog-multiselect-option-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2231
+ --gog-select-option-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2232
+ --gog-tabs-press-bg: color-mix(in srgb, var(--gog-accent-color) 20%, transparent);
2233
+
2234
+ /* Button severity — see the block of the same name above for what each ingredient is and
2235
+ why the ink mix is 50%. Four severities, one recipe each, so a new status colour would
2236
+ need four lines rather than a design decision. */
2237
+ --gog-button-success-fill-hover: color-mix(
2238
+ in srgb,
2239
+ var(--gog-success-color) 88%,
2240
+ var(--gog-success-shade)
2241
+ );
2242
+ --gog-button-success-fill-press: color-mix(
2243
+ in srgb,
2244
+ var(--gog-success-color) 76%,
2245
+ var(--gog-success-shade)
2246
+ );
2247
+ --gog-button-success-ink: color-mix(
2248
+ in srgb,
2249
+ var(--gog-success-color) 50%,
2250
+ var(--gog-text-color)
2251
+ );
2252
+ --gog-button-success-wash: color-mix(in srgb, var(--gog-success-color) 12%, transparent);
2253
+ --gog-button-danger-fill-hover: color-mix(
2254
+ in srgb,
2255
+ var(--gog-danger-color) 88%,
2256
+ var(--gog-danger-shade)
2257
+ );
2258
+ --gog-button-danger-fill-press: color-mix(
2259
+ in srgb,
2260
+ var(--gog-danger-color) 76%,
2261
+ var(--gog-danger-shade)
2262
+ );
2263
+ --gog-button-danger-ink: color-mix(in srgb, var(--gog-danger-color) 50%, var(--gog-text-color));
2264
+ --gog-button-danger-wash: color-mix(in srgb, var(--gog-danger-color) 12%, transparent);
2265
+ --gog-button-warning-fill-hover: color-mix(
2266
+ in srgb,
2267
+ var(--gog-warning-color) 88%,
2268
+ var(--gog-warning-shade)
2269
+ );
2270
+ --gog-button-warning-fill-press: color-mix(
2271
+ in srgb,
2272
+ var(--gog-warning-color) 76%,
2273
+ var(--gog-warning-shade)
2274
+ );
2275
+ --gog-button-warning-ink: color-mix(
2276
+ in srgb,
2277
+ var(--gog-warning-color) 50%,
2278
+ var(--gog-text-color)
2279
+ );
2280
+ --gog-button-warning-wash: color-mix(in srgb, var(--gog-warning-color) 12%, transparent);
2281
+ --gog-button-info-fill-hover: color-mix(
2282
+ in srgb,
2283
+ var(--gog-info-color) 88%,
2284
+ var(--gog-info-shade)
2285
+ );
2286
+ --gog-button-info-fill-press: color-mix(
2287
+ in srgb,
2288
+ var(--gog-info-color) 76%,
2289
+ var(--gog-info-shade)
2290
+ );
2291
+ --gog-button-info-ink: color-mix(in srgb, var(--gog-info-color) 50%, var(--gog-text-color));
2292
+ --gog-button-info-wash: color-mix(in srgb, var(--gog-info-color) 12%, transparent);
1940
2293
  --gog-calendar-range-bg: color-mix(in srgb, var(--gog-accent-color) 16%, transparent);
1941
2294
  --gog-card-filled-bg: color-mix(in srgb, var(--gog-accent-dim) 8%, var(--gog-surface-color));
1942
2295
  --gog-card-hover-border-color: color-mix(in srgb, var(--gog-accent-color) 45%, transparent);